feat: Implement SQLite database for team owner management, configuration, batch processing, and proxies, introducing new auto-add API and Accounts UI.

This commit is contained in:
2026-02-03 06:54:40 +08:00
parent b20399a00a
commit f2757cf313
3 changed files with 120 additions and 6 deletions

View File

@@ -13,10 +13,12 @@ import (
)
var (
autoAddRunning bool
autoAddMu sync.Mutex
autoAddStopChan chan struct{}
lastAutoAddTime time.Time
autoAddRunning bool
autoAddMu sync.Mutex
autoAddStopChan chan struct{}
lastAutoAddTime time.Time
lastAutoRegTime time.Time // 上次自动注册时间
autoRegisterRunning bool // 自动注册是否正在运行
)
// StartAutoAddService 启动自动补号服务(后台检查器)
@@ -148,6 +150,8 @@ func checkAndAutoAdd() {
if len(owners) == 0 {
logger.Warning("没有可用的 Owner 账号,无法自动补号", "", "auto-add")
// 检查是否开启自动注册
tryAutoRegisterOwners(teamsNeeded, 0)
return
}
@@ -155,6 +159,9 @@ func checkAndAutoAdd() {
actualTeams := teamsNeeded
if actualTeams > len(owners) {
logger.Warning(fmt.Sprintf("可用 Owner 不足: 需要 %d 个, 仅有 %d 个可用", teamsNeeded, len(owners)), "", "auto-add")
// 检查是否开启自动注册,补充不足的母号
shortfall := teamsNeeded - len(owners)
tryAutoRegisterOwners(shortfall, len(owners))
actualTeams = len(owners)
}
@@ -209,7 +216,7 @@ func checkAndAutoAdd() {
Owners: reqOwners,
MembersPerTeam: membersPerTeam,
ConcurrentTeams: concurrentTeams,
S2AConcurrency: s2aConcurrency,
ConcurrentS2A: s2aConcurrency,
IncludeOwner: false,
Headless: true,
BrowserType: browserType,
@@ -295,3 +302,104 @@ func getS2AAccountCount() (int, error) {
return result.Data.NormalAccounts, nil
}
// tryAutoRegisterOwners 尝试自动注册母号
// count: 需要注册的数量
// currentOwners: 当前可用的母号数量(用于日志)
func tryAutoRegisterOwners(count int, currentOwners int) {
if database.Instance == nil {
return
}
// 检查是否开启自动注册
autoRegEnabled := false
if val, _ := database.Instance.GetConfig("monitor_auto_register"); val == "true" {
autoRegEnabled = true
}
if !autoRegEnabled {
logger.Info("自动注册未开启,跳过母号注册", "", "auto-add")
return
}
// 检查是否有注册任务在运行
autoAddMu.Lock()
if autoRegisterRunning {
autoAddMu.Unlock()
logger.Info("已有自动注册任务在运行,跳过", "", "auto-add")
return
}
// 检查 Team 注册是否在运行
teamRegState.mu.Lock()
teamRegRunning := teamRegState.Running
teamRegState.mu.Unlock()
if teamRegRunning {
autoAddMu.Unlock()
logger.Info("Team 注册任务正在运行,跳过自动注册", "", "auto-add")
return
}
// 检查距离上次自动注册的间隔(至少 5 分钟)
if time.Since(lastAutoRegTime) < 5*time.Minute {
autoAddMu.Unlock()
remaining := 5*time.Minute - time.Since(lastAutoRegTime)
logger.Info(fmt.Sprintf("自动注册: 冷却中 (还需 %.0f 秒)", remaining.Seconds()), "", "auto-add")
return
}
autoRegisterRunning = true
lastAutoRegTime = time.Now()
autoAddMu.Unlock()
// 读取自动注册配置
concurrency := 2
if val, _ := database.Instance.GetConfig("monitor_auto_reg_concurrency"); val != "" {
if v, err := strconv.Atoi(val); err == nil && v >= 1 && v <= 10 {
concurrency = v
}
}
useProxy := false
if val, _ := database.Instance.GetConfig("monitor_auto_reg_use_proxy"); val == "true" {
useProxy = true
}
// 获取代理地址
proxyURL := ""
if useProxy && config.Global != nil {
proxyURL = config.Global.DefaultProxy
}
// 限制单次注册数量(最多 20 个)
if count > 20 {
count = 20
}
if count < 1 {
count = 1
}
logger.Info(fmt.Sprintf("自动注册: 当前母号 %d 个不足,将注册 %d 个新账号 (并发: %d, 代理: %v)",
currentOwners, count, concurrency, useProxy), "", "auto-add")
// 构建注册配置
regConfig := TeamRegConfig{
Count: count,
Concurrency: concurrency,
Proxy: proxyURL,
AutoImport: true, // 自动导入到数据库
}
// 异步执行注册
go func() {
defer func() {
autoAddMu.Lock()
autoRegisterRunning = false
autoAddMu.Unlock()
}()
// 调用 Team 注册流程
runTeamRegProcess(regConfig)
logger.Info("自动注册任务已完成", "", "auto-add")
}()
}

View File

@@ -943,6 +943,12 @@ func (d *DB) DeleteCodexProxy(id int64) error {
return err
}
// ClearCodexProxies 清空所有代理
func (d *DB) ClearCodexProxies() error {
_, err := d.db.Exec("DELETE FROM codex_auth_proxies")
return err
}
// GetCodexProxyByID 获取指定 ID 的代理地址
func (d *DB) GetCodexProxyByID(id int64) (string, error) {
var proxyURL string