chore: gofmt 对齐(远端提交带入的未格式化文件)

This commit is contained in:
Sakurasan committed 2026-10-30 01:42:54 +08:00
1 parent dfe31b5b4f
commit 263bfb7845
8 files changed
+51 -51

No files matched your search

+1 -1
View File
@@ -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 {
+4 -4
View File
@@ -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),
+13 -13
View File
@@ -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})
+1 -1
View File
@@ -175,4 +175,4 @@ func randomPassword(n int) (string, error) {
buf[i] = pwAlphabet[k.Int64()]
}
return string(buf), nil
}
}
+1 -1
View File
@@ -24,4 +24,4 @@ var rootCmd = &cobra.Command{
RunE: func(c *cobra.Command, args []string) error {
return serve()
},
}
}
+4 -4
View File
@@ -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) {
+24 -24
View File
@@ -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)
+3 -3
View File
@@ -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)