feat: Implement core backend infrastructure including configuration management, SQLite database with team owners and app settings, and initial owner-related APIs and frontend components.
This commit is contained in:
@@ -36,6 +36,14 @@ type AccountCheckResponse struct {
|
||||
} `json:"accounts"`
|
||||
}
|
||||
|
||||
// AccountStatus 账户状态检查结果
|
||||
type AccountStatus struct {
|
||||
Status string // active, banned, token_expired, error
|
||||
PlanType string // team, plus, free 等
|
||||
AccountID string // 账户 ID
|
||||
Error string // 错误信息
|
||||
}
|
||||
|
||||
// New 创建邀请器 (使用默认代理)
|
||||
func New(accessToken string) *TeamInviter {
|
||||
c, _ := client.New(DefaultProxy)
|
||||
@@ -59,6 +67,77 @@ func (t *TeamInviter) SetAccountID(accountID string) {
|
||||
t.accountID = accountID
|
||||
}
|
||||
|
||||
// CheckAccountStatus 检查账户状态(封禁检测)
|
||||
// 基于 check_ban.py 的逻辑:
|
||||
// - HTTP 200 + 有账户数据 → active
|
||||
// - HTTP 200 + 无账户数据 → banned
|
||||
// - HTTP 401 → token_expired
|
||||
// - HTTP 403 → banned
|
||||
func (t *TeamInviter) CheckAccountStatus() AccountStatus {
|
||||
result := AccountStatus{Status: "error"}
|
||||
|
||||
req, _ := http.NewRequest("GET", "https://chatgpt.com/backend-api/accounts/check/v4-2023-04-27", nil)
|
||||
req.Header.Set("Authorization", "Bearer "+t.accessToken)
|
||||
req.Header.Set("Accept", "application/json")
|
||||
req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36")
|
||||
|
||||
resp, err := t.client.Do(req)
|
||||
if err != nil {
|
||||
result.Error = fmt.Sprintf("请求失败: %v", err)
|
||||
return result
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
body, _ := io.ReadAll(resp.Body)
|
||||
|
||||
switch resp.StatusCode {
|
||||
case 200:
|
||||
var checkResp AccountCheckResponse
|
||||
if err := json.Unmarshal(body, &checkResp); err != nil {
|
||||
result.Error = fmt.Sprintf("解析失败: %v", err)
|
||||
return result
|
||||
}
|
||||
|
||||
// 检查是否有账户数据
|
||||
if len(checkResp.Accounts) == 0 {
|
||||
result.Status = "banned"
|
||||
result.Error = "无账户数据"
|
||||
return result
|
||||
}
|
||||
|
||||
// 查找非 default 的账户
|
||||
for accountID, info := range checkResp.Accounts {
|
||||
if accountID == "default" {
|
||||
continue
|
||||
}
|
||||
result.Status = "active"
|
||||
result.AccountID = accountID
|
||||
result.PlanType = info.Account.PlanType
|
||||
t.accountID = accountID
|
||||
return result
|
||||
}
|
||||
|
||||
// 只有 default 账户,也视为正常
|
||||
result.Status = "active"
|
||||
result.PlanType = "default"
|
||||
return result
|
||||
|
||||
case 401:
|
||||
result.Status = "token_expired"
|
||||
result.Error = "Token 已过期"
|
||||
return result
|
||||
|
||||
case 403:
|
||||
result.Status = "banned"
|
||||
result.Error = "账户被封禁 (403)"
|
||||
return result
|
||||
|
||||
default:
|
||||
result.Error = fmt.Sprintf("HTTP %d", resp.StatusCode)
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
// GetAccountID 获取 Team 的 account_id (workspace_id)
|
||||
func (t *TeamInviter) GetAccountID() (string, error) {
|
||||
req, _ := http.NewRequest("GET", "https://chatgpt.com/backend-api/accounts/check/v4-2023-04-27", nil)
|
||||
|
||||
Reference in New Issue
Block a user