Files
Atlas/internal/store/providers.go
T
renjue 4009214cbc
CI / docker (push) Successful in 7m4s
实现 Atlas AI 平台一期能力并完成品牌化改造。
引入用户端对话/生图与管理端 Provider 配置,统一 invoke 编排、Gateway、请求日志与模型管理;前端按设计规范拆分布局,Go module 更名为 github.com/rose_cat707/Atlas;生图长任务 SSE 推送;管理端登录防爆破;协议与服务类型联动;Replicate 模型同步修复;用户端创作台 UI 重构;管理端创作历史替代请求日志。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-29 21:08:57 +08:00

137 lines
4.1 KiB
Go

package store
import (
"context"
"database/sql"
"fmt"
"github.com/rose_cat707/Atlas/internal/domain"
)
type Provider struct {
ID int64 `json:"id"`
Name string `json:"name"`
Protocol string `json:"protocol"`
BaseURL string `json:"base_url"`
APIKey string `json:"api_key,omitempty"`
ServiceType string `json:"service_type"`
IsDefault bool `json:"is_default"`
Enabled bool `json:"enabled"`
ExtraJSON string `json:"extra_json"`
CreatedAt string `json:"created_at"`
UpdatedAt string `json:"updated_at"`
}
func (s *Store) ListProviders(ctx context.Context, serviceType string, enabledOnly bool) ([]Provider, error) {
q := `SELECT id, name, protocol, base_url, api_key, service_type, is_default, enabled, extra_json, created_at, updated_at FROM providers WHERE 1=1`
args := []any{}
if serviceType != "" {
q += ` AND service_type = ?`
args = append(args, serviceType)
}
if enabledOnly {
q += ` AND enabled = 1`
}
q += ` ORDER BY is_default DESC, id ASC`
rows, err := s.db.QueryContext(ctx, q, args...)
if err != nil {
return nil, err
}
defer rows.Close()
var items []Provider
for rows.Next() {
var p Provider
var isDef, en int
if err := rows.Scan(&p.ID, &p.Name, &p.Protocol, &p.BaseURL, &p.APIKey, &p.ServiceType, &isDef, &en, &p.ExtraJSON, &p.CreatedAt, &p.UpdatedAt); err != nil {
return nil, err
}
p.IsDefault = isDef == 1
p.Enabled = en == 1
items = append(items, p)
}
return items, rows.Err()
}
func (s *Store) GetProvider(ctx context.Context, id int64) (*Provider, error) {
var p Provider
var isDef, en int
err := s.db.QueryRowContext(ctx,
`SELECT id, name, protocol, base_url, api_key, service_type, is_default, enabled, extra_json, created_at, updated_at FROM providers WHERE id = ?`, id,
).Scan(&p.ID, &p.Name, &p.Protocol, &p.BaseURL, &p.APIKey, &p.ServiceType, &isDef, &en, &p.ExtraJSON, &p.CreatedAt, &p.UpdatedAt)
if err != nil {
return nil, err
}
p.IsDefault = isDef == 1
p.Enabled = en == 1
return &p, nil
}
func (s *Store) CreateProvider(ctx context.Context, p *Provider) (int64, error) {
if p.IsDefault {
if _, err := s.db.ExecContext(ctx, `UPDATE providers SET is_default = 0 WHERE service_type = ?`, p.ServiceType); err != nil {
return 0, err
}
}
res, err := s.db.ExecContext(ctx,
`INSERT INTO providers (name, protocol, base_url, api_key, service_type, is_default, enabled, extra_json) VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,
p.Name, p.Protocol, p.BaseURL, p.APIKey, p.ServiceType, boolInt(p.IsDefault), boolInt(p.Enabled), p.ExtraJSON,
)
if err != nil {
return 0, err
}
return res.LastInsertId()
}
func (s *Store) UpdateProvider(ctx context.Context, p *Provider) error {
if p.IsDefault {
if _, err := s.db.ExecContext(ctx, `UPDATE providers SET is_default = 0 WHERE service_type = ? AND id != ?`, p.ServiceType, p.ID); err != nil {
return err
}
}
_, err := s.db.ExecContext(ctx,
`UPDATE providers SET name=?, protocol=?, base_url=?, api_key=?, service_type=?, is_default=?, enabled=?, extra_json=?, updated_at=datetime('now') WHERE id=?`,
p.Name, p.Protocol, p.BaseURL, p.APIKey, p.ServiceType, boolInt(p.IsDefault), boolInt(p.Enabled), p.ExtraJSON, p.ID,
)
return err
}
func (s *Store) DeleteProvider(ctx context.Context, id int64) error {
_, err := s.db.ExecContext(ctx, `DELETE FROM providers WHERE id = ?`, id)
return err
}
func boolInt(v bool) int {
if v {
return 1
}
return 0
}
func (s *Store) DefaultProvider(ctx context.Context, serviceType string) (*Provider, error) {
providers, err := s.ListProviders(ctx, serviceType, true)
if err != nil {
return nil, err
}
for _, p := range providers {
if p.IsDefault {
return &p, nil
}
}
if len(providers) > 0 {
return &providers[0], nil
}
return nil, sql.ErrNoRows
}
func MaskProvider(p Provider) Provider {
p.APIKey = MaskSecret(p.APIKey)
return p
}
func ValidateProvider(p *Provider) error {
if p.Name == "" || p.Protocol == "" || p.BaseURL == "" || p.ServiceType == "" {
return fmt.Errorf("name, protocol, base_url, service_type required")
}
return domain.ValidateProviderBinding(p.Protocol, p.ServiceType)
}