// Package config 配置管理模块 // 负责账号、设置、统计数据的持久化存储 package config import ( "crypto/rand" "encoding/json" "fmt" "os" "sync" ) // GenerateMachineId 生成 UUID v4 格式的机器码 func GenerateMachineId() string { bytes := make([]byte, 16) rand.Read(bytes) bytes[6] = (bytes[6] & 0x0f) | 0x40 // 版本 4 bytes[8] = (bytes[8] & 0x3f) | 0x80 // 变体 return fmt.Sprintf("%08x-%04x-%04x-%04x-%012x", bytes[0:4], bytes[4:6], bytes[6:8], bytes[8:10], bytes[10:16]) } // Account 账号信息 type Account struct { // 基本信息 ID string `json:"id"` Email string `json:"email,omitempty"` UserId string `json:"userId,omitempty"` Nickname string `json:"nickname,omitempty"` // 认证信息 AccessToken string `json:"accessToken"` RefreshToken string `json:"refreshToken"` ClientID string `json:"clientId,omitempty"` ClientSecret string `json:"clientSecret,omitempty"` AuthMethod string `json:"authMethod"` // idc | social Provider string `json:"provider,omitempty"` Region string `json:"region"` StartUrl string `json:"startUrl,omitempty"` ExpiresAt int64 `json:"expiresAt,omitempty"` MachineId string `json:"machineId,omitempty"` // UUID 格式机器码 // 状态 Enabled bool `json:"enabled"` // 订阅信息 SubscriptionType string `json:"subscriptionType,omitempty"` // FREE | PRO | PRO_PLUS | POWER SubscriptionTitle string `json:"subscriptionTitle,omitempty"` DaysRemaining int `json:"daysRemaining,omitempty"` // 使用量 UsageCurrent float64 `json:"usageCurrent,omitempty"` UsageLimit float64 `json:"usageLimit,omitempty"` UsagePercent float64 `json:"usagePercent,omitempty"` NextResetDate string `json:"nextResetDate,omitempty"` LastRefresh int64 `json:"lastRefresh,omitempty"` // 运行时统计 RequestCount int `json:"requestCount,omitempty"` ErrorCount int `json:"errorCount,omitempty"` LastUsed int64 `json:"lastUsed,omitempty"` TotalTokens int `json:"totalTokens,omitempty"` TotalCredits float64 `json:"totalCredits,omitempty"` } // Config 全局配置 type Config struct { Password string `json:"password"` Port int `json:"port"` Host string `json:"host"` ApiKey string `json:"apiKey,omitempty"` RequireApiKey bool `json:"requireApiKey"` Accounts []Account `json:"accounts"` // 全局统计 TotalRequests int `json:"totalRequests,omitempty"` SuccessRequests int `json:"successRequests,omitempty"` FailedRequests int `json:"failedRequests,omitempty"` TotalTokens int `json:"totalTokens,omitempty"` TotalCredits float64 `json:"totalCredits,omitempty"` } // AccountInfo 账户信息更新结构 type AccountInfo struct { Email string UserId string SubscriptionType string SubscriptionTitle string DaysRemaining int UsageCurrent float64 UsageLimit float64 UsagePercent float64 NextResetDate string LastRefresh int64 } var ( cfg *Config cfgLock sync.RWMutex cfgPath string ) // Init 初始化配置 func Init(path string) error { cfgPath = path return Load() } // Load 从文件加载配置 func Load() error { cfgLock.Lock() defer cfgLock.Unlock() data, err := os.ReadFile(cfgPath) if err != nil { if os.IsNotExist(err) { // 创建默认配置 cfg = &Config{ Password: "changeme", Port: 8080, Host: "127.0.0.1", RequireApiKey: false, Accounts: []Account{}, } return Save() } return err } var c Config if err := json.Unmarshal(data, &c); err != nil { return err } cfg = &c return nil } // Save 保存配置到文件 func Save() error { data, err := json.MarshalIndent(cfg, "", " ") if err != nil { return err } return os.WriteFile(cfgPath, data, 0600) } // SetPassword 设置密码(用于环境变量覆盖) func SetPassword(password string) { cfgLock.Lock() defer cfgLock.Unlock() cfg.Password = password } func Get() *Config { cfgLock.RLock() defer cfgLock.RUnlock() return cfg } func GetPassword() string { cfgLock.RLock() defer cfgLock.RUnlock() return cfg.Password } func GetPort() int { cfgLock.RLock() defer cfgLock.RUnlock() if cfg.Port == 0 { return 8080 } return cfg.Port } func GetHost() string { cfgLock.RLock() defer cfgLock.RUnlock() if cfg.Host == "" { return "127.0.0.1" } return cfg.Host } func GetAccounts() []Account { cfgLock.RLock() defer cfgLock.RUnlock() accounts := make([]Account, len(cfg.Accounts)) copy(accounts, cfg.Accounts) return accounts } func GetEnabledAccounts() []Account { cfgLock.RLock() defer cfgLock.RUnlock() var accounts []Account for _, a := range cfg.Accounts { if a.Enabled { accounts = append(accounts, a) } } return accounts } func AddAccount(account Account) error { cfgLock.Lock() defer cfgLock.Unlock() cfg.Accounts = append(cfg.Accounts, account) return Save() } func UpdateAccount(id string, account Account) error { cfgLock.Lock() defer cfgLock.Unlock() for i, a := range cfg.Accounts { if a.ID == id { cfg.Accounts[i] = account return Save() } } return nil } func DeleteAccount(id string) error { cfgLock.Lock() defer cfgLock.Unlock() for i, a := range cfg.Accounts { if a.ID == id { cfg.Accounts = append(cfg.Accounts[:i], cfg.Accounts[i+1:]...) return Save() } } return nil } func UpdateAccountToken(id, accessToken, refreshToken string, expiresAt int64) error { cfgLock.Lock() defer cfgLock.Unlock() for i, a := range cfg.Accounts { if a.ID == id { cfg.Accounts[i].AccessToken = accessToken if refreshToken != "" { cfg.Accounts[i].RefreshToken = refreshToken } cfg.Accounts[i].ExpiresAt = expiresAt return Save() } } return nil } func GetApiKey() string { cfgLock.RLock() defer cfgLock.RUnlock() return cfg.ApiKey } func IsApiKeyRequired() bool { cfgLock.RLock() defer cfgLock.RUnlock() return cfg.RequireApiKey } func UpdateSettings(apiKey string, requireApiKey bool, password string) error { cfgLock.Lock() defer cfgLock.Unlock() cfg.ApiKey = apiKey cfg.RequireApiKey = requireApiKey if password != "" { cfg.Password = password } return Save() } func UpdateStats(totalReq, successReq, failedReq, totalTokens int, totalCredits float64) error { cfgLock.Lock() defer cfgLock.Unlock() cfg.TotalRequests = totalReq cfg.SuccessRequests = successReq cfg.FailedRequests = failedReq cfg.TotalTokens = totalTokens cfg.TotalCredits = totalCredits return Save() } func GetStats() (int, int, int, int, float64) { cfgLock.RLock() defer cfgLock.RUnlock() return cfg.TotalRequests, cfg.SuccessRequests, cfg.FailedRequests, cfg.TotalTokens, cfg.TotalCredits } func UpdateAccountStats(id string, requestCount, errorCount, totalTokens int, totalCredits float64, lastUsed int64) error { cfgLock.Lock() defer cfgLock.Unlock() for i, a := range cfg.Accounts { if a.ID == id { cfg.Accounts[i].RequestCount = requestCount cfg.Accounts[i].ErrorCount = errorCount cfg.Accounts[i].TotalTokens = totalTokens cfg.Accounts[i].TotalCredits = totalCredits cfg.Accounts[i].LastUsed = lastUsed return Save() } } return nil } // UpdateAccountInfo 更新账户的订阅和使用量信息 func UpdateAccountInfo(id string, info AccountInfo) error { cfgLock.Lock() defer cfgLock.Unlock() for i, a := range cfg.Accounts { if a.ID == id { if info.Email != "" { cfg.Accounts[i].Email = info.Email } if info.UserId != "" { cfg.Accounts[i].UserId = info.UserId } cfg.Accounts[i].SubscriptionType = info.SubscriptionType cfg.Accounts[i].SubscriptionTitle = info.SubscriptionTitle cfg.Accounts[i].DaysRemaining = info.DaysRemaining cfg.Accounts[i].UsageCurrent = info.UsageCurrent cfg.Accounts[i].UsageLimit = info.UsageLimit cfg.Accounts[i].UsagePercent = info.UsagePercent cfg.Accounts[i].NextResetDate = info.NextResetDate cfg.Accounts[i].LastRefresh = info.LastRefresh return Save() } } return nil }