feat: implement core backend for team owner management with SQLite, auto-add APIs, and a frontend owner list component.
This commit is contained in:
@@ -206,12 +206,21 @@ func getS2AAccountCount() (int, error) {
|
||||
}
|
||||
|
||||
var result struct {
|
||||
NormalAccounts int `json:"normal_accounts"`
|
||||
Code int `json:"code"`
|
||||
Message string `json:"message"`
|
||||
Data struct {
|
||||
NormalAccounts int `json:"normal_accounts"`
|
||||
} `json:"data"`
|
||||
}
|
||||
|
||||
if err := decodeJSON(resp.Body, &result); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return result.NormalAccounts, nil
|
||||
// S2A 返回 code=0 表示成功
|
||||
if result.Code != 0 {
|
||||
return 0, fmt.Errorf("S2A 返回错误: %s", result.Message)
|
||||
}
|
||||
|
||||
return result.Data.NormalAccounts, nil
|
||||
}
|
||||
|
||||
@@ -292,7 +292,8 @@ func processSingleTeam(idx int, req TeamProcessRequest) TeamProcessResult {
|
||||
Errors: make([]string, 0),
|
||||
}
|
||||
|
||||
logPrefix := fmt.Sprintf("[Team %d]", idx+1)
|
||||
// 固定宽度的 Team 编号 (支持到 Team 99)
|
||||
logPrefix := fmt.Sprintf("[Team %2d]", idx+1)
|
||||
logger.Info(fmt.Sprintf("%s 开始处理 | 母号: %s", logPrefix, owner.Email), owner.Email, "team")
|
||||
|
||||
// 标记 owner 为处理中
|
||||
@@ -385,12 +386,23 @@ func processSingleTeam(idx int, req TeamProcessRequest) TeamProcessResult {
|
||||
// 重试时使用新邮箱
|
||||
currentEmail = mail.GenerateEmail()
|
||||
currentPassword = register.GeneratePassword()
|
||||
logger.Warning(fmt.Sprintf("%s [成员 %d] 重试,新邮箱: %s", logPrefix, memberIdx+1, currentEmail), currentEmail, "team")
|
||||
logger.Warning(fmt.Sprintf("%s [成员 %d] 重试, 新邮箱: %s", logPrefix, memberIdx+1, currentEmail), currentEmail, "team")
|
||||
}
|
||||
|
||||
// 发送邀请
|
||||
if err := inviter.SendInvites([]string{currentEmail}); err != nil {
|
||||
errStr := err.Error()
|
||||
logger.Error(fmt.Sprintf("%s [成员 %d] 邀请失败: %v", logPrefix, memberIdx+1, err), currentEmail, "team")
|
||||
|
||||
// 检测 Team 已达邀请上限
|
||||
if strings.Contains(errStr, "maximum number of seats") {
|
||||
logger.Warning(fmt.Sprintf("%s Team 邀请已满,标记母号为已使用", logPrefix), owner.Email, "team")
|
||||
if database.Instance != nil {
|
||||
database.Instance.MarkOwnerAsUsed(owner.Email)
|
||||
}
|
||||
// 跳出重试,该成员不再处理
|
||||
return false
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -538,7 +550,7 @@ func processSingleTeam(idx int, req TeamProcessRequest) TeamProcessResult {
|
||||
result.Errors = append(result.Errors, fmt.Sprintf("Owner S2A: %v", err))
|
||||
} else {
|
||||
result.AddedToS2A++
|
||||
logger.Success(fmt.Sprintf("%s [母号] ✓ 入库成功", logPrefix), owner.Email, "team")
|
||||
logger.Success(fmt.Sprintf("%s [母号 ] ✓ 入库成功", logPrefix), owner.Email, "team")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user