feat: Add automated ChatGPT account registration with backend API, TLS client, and fingerprinting, alongside new frontend pages for configuration, monitoring, and upload.

This commit is contained in:
2026-02-03 02:39:08 +08:00
parent 389b8eca28
commit 51ba54856d
18 changed files with 1382 additions and 674 deletions

View File

@@ -125,6 +125,20 @@ func (d *DB) createTables() error {
);
CREATE INDEX IF NOT EXISTS idx_batch_team_results_batch_id ON batch_team_results(batch_id);
-- CodexAuth 代理池表
CREATE TABLE IF NOT EXISTS codex_auth_proxies (
id INTEGER PRIMARY KEY AUTOINCREMENT,
proxy_url TEXT NOT NULL UNIQUE,
description TEXT,
is_enabled INTEGER DEFAULT 1,
last_used_at DATETIME,
success_count INTEGER DEFAULT 0,
fail_count INTEGER DEFAULT 0,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX IF NOT EXISTS idx_codex_auth_proxies_enabled ON codex_auth_proxies(is_enabled);
`)
return err
}
@@ -737,6 +751,189 @@ func (d *DB) GetBatchRunWithResults(batchID int64) (*BatchRun, []BatchTeamResult
return &run, results, nil
}
// CodexProxy CodexAuth 代理配置
type CodexProxy struct {
ID int64 `json:"id"`
ProxyURL string `json:"proxy_url"`
Description string `json:"description"`
IsEnabled bool `json:"is_enabled"`
LastUsedAt *time.Time `json:"last_used_at,omitempty"`
SuccessCount int `json:"success_count"`
FailCount int `json:"fail_count"`
CreatedAt time.Time `json:"created_at"`
}
// AddCodexProxy 添加代理
func (d *DB) AddCodexProxy(proxyURL, description string) (int64, error) {
result, err := d.db.Exec(`
INSERT INTO codex_auth_proxies (proxy_url, description, is_enabled, created_at)
VALUES (?, ?, 1, CURRENT_TIMESTAMP)
`, proxyURL, description)
if err != nil {
return 0, err
}
return result.LastInsertId()
}
// AddCodexProxies 批量添加代理
func (d *DB) AddCodexProxies(proxies []string) (int, error) {
tx, err := d.db.Begin()
if err != nil {
return 0, err
}
defer tx.Rollback()
stmt, err := tx.Prepare(`
INSERT OR IGNORE INTO codex_auth_proxies (proxy_url, is_enabled, created_at)
VALUES (?, 1, CURRENT_TIMESTAMP)
`)
if err != nil {
return 0, err
}
defer stmt.Close()
count := 0
for _, proxy := range proxies {
result, err := stmt.Exec(proxy)
if err != nil {
continue
}
affected, _ := result.RowsAffected()
if affected > 0 {
count++
}
}
if err := tx.Commit(); err != nil {
return 0, err
}
return count, nil
}
// GetCodexProxies 获取代理列表
func (d *DB) GetCodexProxies() ([]CodexProxy, error) {
rows, err := d.db.Query(`
SELECT id, proxy_url, COALESCE(description, ''), is_enabled, last_used_at, success_count, fail_count, created_at
FROM codex_auth_proxies
ORDER BY created_at DESC
`)
if err != nil {
return nil, err
}
defer rows.Close()
var proxies []CodexProxy
for rows.Next() {
var p CodexProxy
var lastUsedAt sql.NullTime
err := rows.Scan(&p.ID, &p.ProxyURL, &p.Description, &p.IsEnabled, &lastUsedAt, &p.SuccessCount, &p.FailCount, &p.CreatedAt)
if err != nil {
continue
}
if lastUsedAt.Valid {
p.LastUsedAt = &lastUsedAt.Time
}
proxies = append(proxies, p)
}
return proxies, nil
}
// GetEnabledCodexProxies 获取已启用的代理列表
func (d *DB) GetEnabledCodexProxies() ([]CodexProxy, error) {
rows, err := d.db.Query(`
SELECT id, proxy_url, COALESCE(description, ''), is_enabled, last_used_at, success_count, fail_count, created_at
FROM codex_auth_proxies
WHERE is_enabled = 1
ORDER BY success_count DESC, fail_count ASC
`)
if err != nil {
return nil, err
}
defer rows.Close()
var proxies []CodexProxy
for rows.Next() {
var p CodexProxy
var lastUsedAt sql.NullTime
err := rows.Scan(&p.ID, &p.ProxyURL, &p.Description, &p.IsEnabled, &lastUsedAt, &p.SuccessCount, &p.FailCount, &p.CreatedAt)
if err != nil {
continue
}
if lastUsedAt.Valid {
p.LastUsedAt = &lastUsedAt.Time
}
proxies = append(proxies, p)
}
return proxies, nil
}
// GetRandomCodexProxy 随机获取一个已启用的代理
func (d *DB) GetRandomCodexProxy() (string, error) {
var proxyURL string
err := d.db.QueryRow(`
SELECT proxy_url FROM codex_auth_proxies
WHERE is_enabled = 1
ORDER BY RANDOM()
LIMIT 1
`).Scan(&proxyURL)
if err == sql.ErrNoRows {
return "", nil
}
if err != nil {
return "", err
}
// 更新最后使用时间
d.db.Exec("UPDATE codex_auth_proxies SET last_used_at = CURRENT_TIMESTAMP WHERE proxy_url = ?", proxyURL)
return proxyURL, nil
}
// UpdateCodexProxyStats 更新代理统计
func (d *DB) UpdateCodexProxyStats(proxyURL string, success bool) error {
if success {
_, err := d.db.Exec("UPDATE codex_auth_proxies SET success_count = success_count + 1, last_used_at = CURRENT_TIMESTAMP WHERE proxy_url = ?", proxyURL)
return err
}
_, err := d.db.Exec("UPDATE codex_auth_proxies SET fail_count = fail_count + 1, last_used_at = CURRENT_TIMESTAMP WHERE proxy_url = ?", proxyURL)
return err
}
// ToggleCodexProxy 切换代理启用状态
func (d *DB) ToggleCodexProxy(id int64) error {
_, err := d.db.Exec("UPDATE codex_auth_proxies SET is_enabled = 1 - is_enabled WHERE id = ?", id)
return err
}
// DeleteCodexProxy 删除代理
func (d *DB) DeleteCodexProxy(id int64) error {
_, err := d.db.Exec("DELETE FROM codex_auth_proxies WHERE id = ?", id)
return err
}
// ClearCodexProxies 清空所有代理
func (d *DB) ClearCodexProxies() error {
_, err := d.db.Exec("DELETE FROM codex_auth_proxies")
return err
}
// GetCodexProxyStats 获取代理统计
func (d *DB) GetCodexProxyStats() map[string]int {
stats := map[string]int{
"total": 0,
"enabled": 0,
"disabled": 0,
}
var total, enabled, disabled int
d.db.QueryRow("SELECT COUNT(*) FROM codex_auth_proxies").Scan(&total)
d.db.QueryRow("SELECT COUNT(*) FROM codex_auth_proxies WHERE is_enabled = 1").Scan(&enabled)
d.db.QueryRow("SELECT COUNT(*) FROM codex_auth_proxies WHERE is_enabled = 0").Scan(&disabled)
stats["total"] = total
stats["enabled"] = enabled
stats["disabled"] = disabled
return stats
}
// Close 关闭数据库
func (d *DB) Close() error {
if d.db != nil {