feat: Implement ChatGPT account registration flow and establish core backend API infrastructure with logging utilities.
This commit is contained in:
@@ -1050,7 +1050,7 @@ func handleProxyTest(w http.ResponseWriter, r *http.Request) {
|
|||||||
ipKey = "team_reg_proxy_test_ip"
|
ipKey = "team_reg_proxy_test_ip"
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.Info(fmt.Sprintf("测试代理连接: %s", proxyURL), "", "proxy")
|
logger.Status(fmt.Sprintf("测试代理连接中: %s", proxyURL), "", "proxy")
|
||||||
|
|
||||||
// 解析代理 URL
|
// 解析代理 URL
|
||||||
proxyParsed, err := parseProxyURL(proxyURL)
|
proxyParsed, err := parseProxyURL(proxyURL)
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ func checkAndCleanErrors() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 执行清理
|
// 执行清理
|
||||||
logger.Info("开始定期清理错误账号...", "", "cleaner")
|
logger.Status("定期清理错误账号中...", "", "cleaner")
|
||||||
|
|
||||||
errorAccounts, err := fetchAllErrorAccounts()
|
errorAccounts, err := fetchAllErrorAccounts()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -309,7 +309,7 @@ func runBanCheckTask(owners []database.TeamOwner, concurrency int) {
|
|||||||
lastBanCheckTime = time.Now()
|
lastBanCheckTime = time.Now()
|
||||||
}()
|
}()
|
||||||
|
|
||||||
logger.Info(fmt.Sprintf("开始封禁检查: 共 %d 个母号, 并发数: %d", len(owners), concurrency), "", "ban-check")
|
logger.Status(fmt.Sprintf("封禁检查中: 共 %d 个母号, 并发数: %d", len(owners), concurrency), "", "ban-check")
|
||||||
|
|
||||||
// 任务队列
|
// 任务队列
|
||||||
taskChan := make(chan database.TeamOwner, len(owners))
|
taskChan := make(chan database.TeamOwner, len(owners))
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ func HandleCleanErrorAccounts(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.Info("开始清理错误账号...", "", "s2a")
|
logger.Status("清理错误账号中...", "", "s2a")
|
||||||
|
|
||||||
// Step 1: 获取所有错误账号
|
// Step 1: 获取所有错误账号
|
||||||
errorAccounts, err := fetchAllErrorAccounts()
|
errorAccounts, err := fetchAllErrorAccounts()
|
||||||
@@ -68,7 +68,7 @@ func HandleCleanErrorAccounts(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.Info(fmt.Sprintf("找到 %d 个错误账号,开始删除...", len(errorAccounts)), "", "s2a")
|
logger.Status(fmt.Sprintf("找到 %d 个错误账号,删除中...", len(errorAccounts)), "", "s2a")
|
||||||
|
|
||||||
// Step 2: 逐条删除
|
// Step 2: 逐条删除
|
||||||
success := 0
|
success := 0
|
||||||
|
|||||||
@@ -740,7 +740,7 @@ func processSingleTeam(idx int, req TeamProcessRequest) (result TeamProcessResul
|
|||||||
memberStartTime := time.Now()
|
memberStartTime := time.Now()
|
||||||
memberLogPrefix := fmt.Sprintf("%s [成员 %d]", logPrefix, memberIdx+1)
|
memberLogPrefix := fmt.Sprintf("%s [成员 %d]", logPrefix, memberIdx+1)
|
||||||
|
|
||||||
logger.Info(fmt.Sprintf("%s 开始入库 | 邮箱: %s", memberLogPrefix, memberChild.Email), memberChild.Email, "team")
|
logger.Status(fmt.Sprintf("%s 入库中... | 邮箱: %s", memberLogPrefix, memberChild.Email), memberChild.Email, "team")
|
||||||
|
|
||||||
var s2aSuccess bool
|
var s2aSuccess bool
|
||||||
var lastError string
|
var lastError string
|
||||||
@@ -852,7 +852,7 @@ func processSingleTeam(idx int, req TeamProcessRequest) (result TeamProcessResul
|
|||||||
if req.IncludeOwner && teamProcessState.Running {
|
if req.IncludeOwner && teamProcessState.Running {
|
||||||
ownerLogPrefix := fmt.Sprintf("%s [母号 ]", logPrefix)
|
ownerLogPrefix := fmt.Sprintf("%s [母号 ]", logPrefix)
|
||||||
ownerStartTime := time.Now()
|
ownerStartTime := time.Now()
|
||||||
logger.Info(fmt.Sprintf("%s 开始母号入库...", ownerLogPrefix), owner.Email, "team")
|
logger.Status(fmt.Sprintf("%s 母号入库中...", ownerLogPrefix), owner.Email, "team")
|
||||||
|
|
||||||
var ownerSuccess bool
|
var ownerSuccess bool
|
||||||
var lastError string
|
var lastError string
|
||||||
|
|||||||
@@ -83,9 +83,9 @@ func HandleUploadValidate(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 并发验证账号并获取 account_id(只保留 team 账号)
|
// 并发验证账号并获取 account_id(只保留 team 账号)
|
||||||
logger.Info(fmt.Sprintf("开始验证账号: 共 %d 个,只导入 plan 为 team 的账号", len(owners)), "", "upload")
|
logger.Status(fmt.Sprintf("验证账号中: 共 %d 个,只导入 plan 为 team 的账号", len(owners)), "", "upload")
|
||||||
validOwners, teamCount, nonTeamCount, failCount := validateAndFetchAccountIDs(owners, 20)
|
validOwners, teamCount, nonTeamCount, failCount := validateAndFetchAccountIDs(owners, 20)
|
||||||
logger.Info(fmt.Sprintf("验证完成: team=%d, 非team=%d, 失败=%d", teamCount, nonTeamCount, failCount), "", "upload")
|
logger.Success(fmt.Sprintf("验证完成: team=%d, 非team=%d, 失败=%d", teamCount, nonTeamCount, failCount), "", "upload")
|
||||||
|
|
||||||
if len(validOwners) == 0 {
|
if len(validOwners) == 0 {
|
||||||
Error(w, http.StatusBadRequest, fmt.Sprintf("没有有效的 team 账号(共 %d 个,非team: %d,失败: %d)", len(owners), nonTeamCount, failCount))
|
Error(w, http.StatusBadRequest, fmt.Sprintf("没有有效的 team 账号(共 %d 个,非team: %d,失败: %d)", len(owners), nonTeamCount, failCount))
|
||||||
@@ -141,7 +141,7 @@ func HandleRefetchAccountIDs(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.Info(fmt.Sprintf("开始重新获取 account_id: 共 %d 个", len(owners)), "", "upload")
|
logger.Status(fmt.Sprintf("重新获取 account_id 中: 共 %d 个", len(owners)), "", "upload")
|
||||||
|
|
||||||
// 并发获取 account_id
|
// 并发获取 account_id
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
|
|||||||
@@ -25,6 +25,20 @@ var (
|
|||||||
listMu sync.RWMutex
|
listMu sync.RWMutex
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// 旋转动画字符
|
||||||
|
var spinnerFrames = []string{"⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"}
|
||||||
|
var spinnerIndex int
|
||||||
|
var spinnerMu sync.Mutex
|
||||||
|
|
||||||
|
// getSpinnerChar 获取下一个旋转字符
|
||||||
|
func getSpinnerChar() string {
|
||||||
|
spinnerMu.Lock()
|
||||||
|
defer spinnerMu.Unlock()
|
||||||
|
char := spinnerFrames[spinnerIndex%len(spinnerFrames)]
|
||||||
|
spinnerIndex++
|
||||||
|
return char
|
||||||
|
}
|
||||||
|
|
||||||
// AddListener 添加日志监听器
|
// AddListener 添加日志监听器
|
||||||
func AddListener(id string) chan LogEntry {
|
func AddListener(id string) chan LogEntry {
|
||||||
listMu.Lock()
|
listMu.Lock()
|
||||||
@@ -130,6 +144,10 @@ func log(level, message, email, module string) {
|
|||||||
case "warning":
|
case "warning":
|
||||||
prefix = "WARN "
|
prefix = "WARN "
|
||||||
color = colorYellow
|
color = colorYellow
|
||||||
|
case "status":
|
||||||
|
// 状态日志使用旋转动画字符
|
||||||
|
prefix = getSpinnerChar() + " WAIT "
|
||||||
|
color = colorCyan
|
||||||
}
|
}
|
||||||
|
|
||||||
// 模块名固定宽度(8字符)
|
// 模块名固定宽度(8字符)
|
||||||
@@ -184,6 +202,11 @@ func Warning(message, email, module string) {
|
|||||||
log("warning", message, email, module)
|
log("warning", message, email, module)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Status 记录状态日志(带旋转动画字符,用于等待中的操作)
|
||||||
|
func Status(message, email, module string) {
|
||||||
|
log("status", message, email, module)
|
||||||
|
}
|
||||||
|
|
||||||
// GetLogs 获取日志
|
// GetLogs 获取日志
|
||||||
func GetLogs(limit int) []LogEntry {
|
func GetLogs(limit int) []LogEntry {
|
||||||
logsMu.RLock()
|
logsMu.RLock()
|
||||||
|
|||||||
@@ -301,7 +301,7 @@ func APIRegister(email, password, realName, birthdate, proxy string, logPrefix s
|
|||||||
|
|
||||||
fpInfo := reg.Client.GetFingerprintInfo()
|
fpInfo := reg.Client.GetFingerprintInfo()
|
||||||
if retry == 0 {
|
if retry == 0 {
|
||||||
logger.Info(fmt.Sprintf("%s 初始化会话... [%s]", logPrefix, fpInfo), email, "register")
|
logger.Status(fmt.Sprintf("%s 初始化会话... [%s]", logPrefix, fpInfo), email, "register")
|
||||||
} else {
|
} else {
|
||||||
logger.Warning(fmt.Sprintf("%s 403 重试 %d/3,换指纹 [%s]", logPrefix, retry, fpInfo), email, "register")
|
logger.Warning(fmt.Sprintf("%s 403 重试 %d/3,换指纹 [%s]", logPrefix, retry, fpInfo), email, "register")
|
||||||
}
|
}
|
||||||
@@ -343,10 +343,9 @@ func APIRegister(email, password, realName, birthdate, proxy string, logPrefix s
|
|||||||
if err := reg.SendVerificationEmail(); err != nil {
|
if err := reg.SendVerificationEmail(); err != nil {
|
||||||
return nil, fmt.Errorf("发送验证邮件失败: %v", err)
|
return nil, fmt.Errorf("发送验证邮件失败: %v", err)
|
||||||
}
|
}
|
||||||
logger.Success(fmt.Sprintf("%s 已发送验证邮件", logPrefix), email, "register")
|
|
||||||
|
|
||||||
// 获取验证码 (带超时 90s)
|
// 获取验证码 (带超时 90s) - 合并日志,使用 Status 显示等待状态
|
||||||
logger.Info(fmt.Sprintf("%s 等待验证码...", logPrefix), email, "register")
|
logger.Status(fmt.Sprintf("%s 验证邮箱中...", logPrefix), email, "register")
|
||||||
otpCode, err := mail.GetVerificationCode(email, 90*time.Second)
|
otpCode, err := mail.GetVerificationCode(email, 90*time.Second)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|||||||
Reference in New Issue
Block a user