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:
@@ -17,6 +17,8 @@ var (
|
||||
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")
|
||||
}()
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -125,7 +125,7 @@ export default function Accounts() {
|
||||
<Select
|
||||
value={statusFilter}
|
||||
onChange={(e) => {
|
||||
setStatusFilter(e.target.value)
|
||||
setStatusFilter(String(e.target.value))
|
||||
setPage(1)
|
||||
}}
|
||||
options={[
|
||||
|
||||
Reference in New Issue
Block a user