feat: Implement the ChatGPT Owner Demotion Console with new frontend and backend components.
This commit is contained in:
36
backend/internal/api/demote.go
Normal file
36
backend/internal/api/demote.go
Normal file
@@ -0,0 +1,36 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
"codex-pool/internal/demote"
|
||||
)
|
||||
|
||||
// HandleDemoteOwner POST /api/demote/owner - Owner 降级
|
||||
func HandleDemoteOwner(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != http.MethodPost {
|
||||
Error(w, http.StatusMethodNotAllowed, "仅支持 POST")
|
||||
return
|
||||
}
|
||||
|
||||
var req demote.DemoteRequest
|
||||
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
||||
Error(w, http.StatusBadRequest, "无效的请求: "+err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
if req.AccessToken == "" {
|
||||
Error(w, http.StatusBadRequest, "access_token 不能为空")
|
||||
return
|
||||
}
|
||||
|
||||
// 默认角色
|
||||
if req.Role == "" {
|
||||
req.Role = "standard-user"
|
||||
}
|
||||
|
||||
result := demote.DemoteOwner(req)
|
||||
|
||||
Success(w, result)
|
||||
}
|
||||
@@ -12,6 +12,7 @@ import (
|
||||
"codex-pool/internal/auth"
|
||||
"codex-pool/internal/config"
|
||||
"codex-pool/internal/database"
|
||||
"codex-pool/internal/demote"
|
||||
"codex-pool/internal/invite"
|
||||
"codex-pool/internal/logger"
|
||||
"codex-pool/internal/mail"
|
||||
@@ -460,6 +461,24 @@ func processSingleTeam(idx int, req TeamProcessRequest) (result TeamProcessResul
|
||||
database.Instance.MarkOwnerAsUsed(owner.Email)
|
||||
database.Instance.DeleteTeamOwnerByEmail(owner.Email)
|
||||
logger.Info(fmt.Sprintf("%s 母号已使用并删除: %s", logPrefix, owner.Email), owner.Email, "team")
|
||||
|
||||
// 如果开启了母号降级,尝试降级
|
||||
if config.Global != nil && config.Global.DemoteAfterUse {
|
||||
go func() {
|
||||
logger.Info(fmt.Sprintf("%s 尝试降级母号...", logPrefix), owner.Email, "team")
|
||||
result := demote.DemoteOwner(demote.DemoteRequest{
|
||||
AccessToken: owner.Token,
|
||||
AccountID: owner.AccountID,
|
||||
Role: "standard-user",
|
||||
Proxy: req.Proxy,
|
||||
})
|
||||
if result.Success {
|
||||
logger.Success(fmt.Sprintf("%s 母号已降级为普通成员", logPrefix), owner.Email, "team")
|
||||
} else {
|
||||
logger.Warning(fmt.Sprintf("%s 母号降级失败: %s", logPrefix, result.Error), owner.Email, "team")
|
||||
}
|
||||
}()
|
||||
}
|
||||
} else {
|
||||
// 失败时恢复为 valid,允许重试
|
||||
database.Instance.MarkOwnerAsFailed(owner.Email)
|
||||
@@ -658,7 +677,7 @@ func processSingleTeam(idx int, req TeamProcessRequest) (result TeamProcessResul
|
||||
config.Global.S2AAdminKey,
|
||||
s2aResp.Data.SessionID,
|
||||
code,
|
||||
memberEmail,
|
||||
"team-"+memberEmail,
|
||||
config.Global.Concurrency,
|
||||
config.Global.Priority,
|
||||
config.Global.GroupIDs,
|
||||
@@ -907,7 +926,7 @@ func processSingleTeam(idx int, req TeamProcessRequest) (result TeamProcessResul
|
||||
config.Global.S2AAdminKey,
|
||||
s2aResp.Data.SessionID,
|
||||
code,
|
||||
owner.Email,
|
||||
"team-"+owner.Email,
|
||||
config.Global.Concurrency,
|
||||
config.Global.Priority,
|
||||
config.Global.GroupIDs,
|
||||
|
||||
Reference in New Issue
Block a user