From 263bfb7845498cd9ae838894b47c030d3a824b1e Mon Sep 17 00:00:00 2001 From: Sakurasan <26715255+Sakurasan@users.noreply.github.com> Date: Fri, 30 Oct 2026 01:42:54 +0800 Subject: [PATCH] =?UTF-8?q?chore:=20gofmt=20=E5=AF=B9=E9=BD=90=EF=BC=88?= =?UTF-8?q?=E8=BF=9C=E7=AB=AF=E6=8F=90=E4=BA=A4=E5=B8=A6=E5=85=A5=E7=9A=84?= =?UTF-8?q?=E6=9C=AA=E6=A0=BC=E5=BC=8F=E5=8C=96=E6=96=87=E4=BB=B6=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/internal/api/admin_channel_models.go | 2 +- server/internal/api/admin_channels.go | 8 ++-- server/internal/app/app.go | 26 +++++------ server/internal/cli/reset_admin.go | 2 +- server/internal/cli/root.go | 2 +- server/internal/passkey/passkey.go | 8 ++-- server/internal/store/models.go | 48 ++++++++++----------- server/internal/store/url_test.go | 6 +-- 8 files changed, 51 insertions(+), 51 deletions(-) diff --git a/server/internal/api/admin_channel_models.go b/server/internal/api/admin_channel_models.go index cd9e938..7134b66 100644 --- a/server/internal/api/admin_channel_models.go +++ b/server/internal/api/admin_channel_models.go @@ -104,7 +104,7 @@ func (h *Handler) AdminChannelAddModel(c *gin.Context) { } var req struct { UpstreamModel string `json:"upstream_model" binding:"required"` // 渠道侧真实模型名 - CustomName string `json:"custom_name"` // 客户端调用名,空=用上游名 + CustomName string `json:"custom_name"` // 客户端调用名,空=用上游名 Weight *int `json:"weight"` } if err := c.ShouldBindJSON(&req); err != nil { diff --git a/server/internal/api/admin_channels.go b/server/internal/api/admin_channels.go index a039b03..6dd1647 100644 --- a/server/internal/api/admin_channels.go +++ b/server/internal/api/admin_channels.go @@ -56,9 +56,9 @@ func (h *Handler) channelRuntime(id uint64) (fails int, cooldownSeconds int64) { type channelBody struct { Name string `json:"name" binding:"required,min=1,max=64"` - Provider string `json:"provider"` // 可选:为空时按 formats 推断(兼容旧数据) - Formats []string `json:"formats"` // 原生支持的协议 chat|responses|messages(主配置) - BaseURL string `json:"base_url"` // 可选:留空按供应商默认;支持前缀或完整端点 + Provider string `json:"provider"` // 可选:为空时按 formats 推断(兼容旧数据) + Formats []string `json:"formats"` // 原生支持的协议 chat|responses|messages(主配置) + BaseURL string `json:"base_url"` // 可选:留空按供应商默认;支持前缀或完整端点 BaseURLs map[string]string `json:"base_urls"` // 分协议 base_url 覆盖(chat/responses/messages) APIKey string `json:"api_key"` Weight *int `json:"weight"` @@ -194,7 +194,7 @@ func (h *Handler) AdminCreateChannel(c *gin.Context) { } ch := store.Channel{ Name: req.Name, Provider: req.Provider, Formats: formats, BaseURL: baseURL, - BaseURLs: normalizeBaseURLs(req.BaseURLs), + BaseURLs: normalizeBaseURLs(req.BaseURLs), APIKeyEnc: enc, Weight: intOr(req.Weight, 1), Priority: intOr(req.Priority, 0), TimeoutMS: intOr(req.TimeoutMS, 300000), MaxConcurrency: intOr(req.MaxConcurrency, 16), HealthStatus: store.ChannelHealthHealthy, Enabled: boolOr(req.Enabled, true), diff --git a/server/internal/app/app.go b/server/internal/app/app.go index 10f9d01..8117d8d 100644 --- a/server/internal/app/app.go +++ b/server/internal/app/app.go @@ -118,27 +118,27 @@ func (a *App) Seed() error { return err } ch := store.Channel{ - Name: a.Cfg.Proxy.DefaultChannelName, - Provider: store.ChannelProviderOpenAI, - Formats: []string{store.FormatChat, store.FormatResponses}, - BaseURL: a.Cfg.Proxy.UpstreamBaseURL, - APIKeyEnc: enc, - Weight: 1, - Priority: 0, - TimeoutMS: int(a.Cfg.Proxy.Timeout / time.Millisecond), + Name: a.Cfg.Proxy.DefaultChannelName, + Provider: store.ChannelProviderOpenAI, + Formats: []string{store.FormatChat, store.FormatResponses}, + BaseURL: a.Cfg.Proxy.UpstreamBaseURL, + APIKeyEnc: enc, + Weight: 1, + Priority: 0, + TimeoutMS: int(a.Cfg.Proxy.Timeout / time.Millisecond), MaxConcurrency: 16, - HealthStatus: store.ChannelHealthHealthy, - Enabled: true, + HealthStatus: store.ChannelHealthHealthy, + Enabled: true, } if err := a.DB.Create(&ch).Error; err != nil { return err } // 默认模型 + 绑定 m := store.Model{ - Name: a.Cfg.Proxy.DefaultModel, - InputPrice: 0.15, // 每百万 token,示例价 + Name: a.Cfg.Proxy.DefaultModel, + InputPrice: 0.15, // 每百万 token,示例价 OutputPrice: 0.60, - Enabled: true, + Enabled: true, } if err := a.DB.Create(&m).Error; err == nil { a.DB.Create(&store.ChannelModelBinding{ChannelID: ch.ID, ModelID: m.ID, UpstreamModel: m.Name}) diff --git a/server/internal/cli/reset_admin.go b/server/internal/cli/reset_admin.go index 178044a..3a1dcee 100644 --- a/server/internal/cli/reset_admin.go +++ b/server/internal/cli/reset_admin.go @@ -175,4 +175,4 @@ func randomPassword(n int) (string, error) { buf[i] = pwAlphabet[k.Int64()] } return string(buf), nil -} \ No newline at end of file +} diff --git a/server/internal/cli/root.go b/server/internal/cli/root.go index 633f1e3..40fc629 100644 --- a/server/internal/cli/root.go +++ b/server/internal/cli/root.go @@ -24,4 +24,4 @@ var rootCmd = &cobra.Command{ RunE: func(c *cobra.Command, args []string) error { return serve() }, -} \ No newline at end of file +} diff --git a/server/internal/passkey/passkey.go b/server/internal/passkey/passkey.go index f8ced7a..a260477 100644 --- a/server/internal/passkey/passkey.go +++ b/server/internal/passkey/passkey.go @@ -61,10 +61,10 @@ type webUser struct { credentials []webauthn.Credential } -func (u *webUser) WebAuthnID() []byte { return []byte(strconv.FormatUint(u.id, 10)) } -func (u *webUser) WebAuthnName() string { return u.name } -func (u *webUser) WebAuthnDisplayName() string { return u.displayName } -func (u *webUser) WebAuthnIcon() string { return "" } +func (u *webUser) WebAuthnID() []byte { return []byte(strconv.FormatUint(u.id, 10)) } +func (u *webUser) WebAuthnName() string { return u.name } +func (u *webUser) WebAuthnDisplayName() string { return u.displayName } +func (u *webUser) WebAuthnIcon() string { return "" } func (u *webUser) WebAuthnCredentials() []webauthn.Credential { return u.credentials } func (s *Service) loadWebUser(u *store.User) (*webUser, error) { diff --git a/server/internal/store/models.go b/server/internal/store/models.go index d72f259..ba63eb6 100644 --- a/server/internal/store/models.go +++ b/server/internal/store/models.go @@ -56,7 +56,7 @@ type User struct { Role string `gorm:"size:16;not null;default:user" json:"role"` Balance float64 `gorm:"type:numeric(20,8);not null;default:0" json:"balance"` Status string `gorm:"size:16;not null;default:active" json:"status"` - TokenVersion int `gorm:"not null;default:0" json:"-"` // 会话版本:改密/登出递增,低于当前版本的 token 全部失效 + TokenVersion int `gorm:"not null;default:0" json:"-"` // 会话版本:改密/登出递增,低于当前版本的 token 全部失效 AllowedModels []string `gorm:"type:jsonb;serializer:json" json:"allowed_models,omitempty"` // 用户级模型白名单(空=不限制) DeniedModels []string `gorm:"type:jsonb;serializer:json" json:"denied_models,omitempty"` // 用户级模型黑名单 InviteCode *string `json:"invite_code,omitempty"` @@ -183,30 +183,30 @@ type ChannelModelBinding struct { // UsageLog 请求级用量明细(PLANNING §6.5) type UsageLog struct { - ID uint64 `gorm:"primaryKey;autoIncrement" json:"id"` - RequestID string `gorm:"size:128" json:"request_id"` // 上游 request id - TraceID string `gorm:"size:64;index" json:"trace_id"` - UserID uint64 `gorm:"index:idx_user_created,priority:1;not null" json:"user_id"` - KeyID uint64 `gorm:"index" json:"key_id"` - ChannelID uint64 `gorm:"index:idx_channel_created,priority:1" json:"channel_id"` - ModelID uint64 `json:"model_id"` - ModelName string `gorm:"size:128" json:"model_name"` - Protocol string `gorm:"size:32" json:"protocol"` // responses|chat|messages - InputTokens int64 `json:"input_tokens"` - OutputTokens int64 `json:"output_tokens"` - CacheReadTokens int64 `json:"cache_read_tokens"` - CacheCreationTokens int64 `json:"cache_creation_tokens"` - InputPrice float64 `gorm:"type:numeric(20,8)" json:"input_price"` // 快照 - OutputPrice float64 `gorm:"type:numeric(20,8)" json:"output_price"` // 快照 - CacheReadPrice float64 `gorm:"type:numeric(20,8)" json:"cache_read_price"` // 快照 - Cost float64 `gorm:"type:numeric(20,8)" json:"cost"` - LatencyMS int `json:"latency_ms"` - Status string `gorm:"size:16;not null" json:"status"` - ErrorCode *string `json:"error_code,omitempty"` - RawRequest string `gorm:"type:text" json:"raw_request"` // 客户端原始请求体(未转换) - RawResponse string `gorm:"type:text" json:"raw_response"` // 上游原始响应(未转换;流式为全部 SSE 事件) + ID uint64 `gorm:"primaryKey;autoIncrement" json:"id"` + RequestID string `gorm:"size:128" json:"request_id"` // 上游 request id + TraceID string `gorm:"size:64;index" json:"trace_id"` + UserID uint64 `gorm:"index:idx_user_created,priority:1;not null" json:"user_id"` + KeyID uint64 `gorm:"index" json:"key_id"` + ChannelID uint64 `gorm:"index:idx_channel_created,priority:1" json:"channel_id"` + ModelID uint64 `json:"model_id"` + ModelName string `gorm:"size:128" json:"model_name"` + Protocol string `gorm:"size:32" json:"protocol"` // responses|chat|messages + InputTokens int64 `json:"input_tokens"` + OutputTokens int64 `json:"output_tokens"` + CacheReadTokens int64 `json:"cache_read_tokens"` + CacheCreationTokens int64 `json:"cache_creation_tokens"` + InputPrice float64 `gorm:"type:numeric(20,8)" json:"input_price"` // 快照 + OutputPrice float64 `gorm:"type:numeric(20,8)" json:"output_price"` // 快照 + CacheReadPrice float64 `gorm:"type:numeric(20,8)" json:"cache_read_price"` // 快照 + Cost float64 `gorm:"type:numeric(20,8)" json:"cost"` + LatencyMS int `json:"latency_ms"` + Status string `gorm:"size:16;not null" json:"status"` + ErrorCode *string `json:"error_code,omitempty"` + RawRequest string `gorm:"type:text" json:"raw_request"` // 客户端原始请求体(未转换) + RawResponse string `gorm:"type:text" json:"raw_response"` // 上游原始响应(未转换;流式为全部 SSE 事件) // CreatedAt 同时参与 user/channel 两个复合索引(时间窗过滤),自身单列索引保留给全表时间扫 - CreatedAt time.Time `gorm:"index;index:idx_user_created,priority:2;index:idx_channel_created,priority:2" json:"created_at"` + CreatedAt time.Time `gorm:"index;index:idx_user_created,priority:2;index:idx_channel_created,priority:2" json:"created_at"` } // UsageDaily 日粒度预聚合(PLANNING §6.6) diff --git a/server/internal/store/url_test.go b/server/internal/store/url_test.go index 38adcde..00a8206 100644 --- a/server/internal/store/url_test.go +++ b/server/internal/store/url_test.go @@ -37,9 +37,9 @@ func TestChannelUpstreamURL(t *testing.T) { } cases2 := []struct{ proto, path, want string }{ {"chat", "/chat/completions", "https://open.bigmodel.cn/api/paas/v4/chat/completions"}, // 用主 base - {"responses", "/responses", "https://resp.example.com/v4/responses"}, // 用覆盖 base - {"messages", "/messages", "https://msg.example.com/v1/messages"}, // 用覆盖 base - {"", "/models", "https://open.bigmodel.cn/api/paas/v4/models"}, // 空协议用主 base + {"responses", "/responses", "https://resp.example.com/v4/responses"}, // 用覆盖 base + {"messages", "/messages", "https://msg.example.com/v1/messages"}, // 用覆盖 base + {"", "/models", "https://open.bigmodel.cn/api/paas/v4/models"}, // 空协议用主 base } for _, c := range cases2 { got := ch.UpstreamURL(c.proto, c.path)