Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0484db4b3a |
@@ -29,7 +29,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
version = "1.4.0"
|
version = "1.4.1"
|
||||||
upstreamBase = "https://copilot.tencent.com"
|
upstreamBase = "https://copilot.tencent.com"
|
||||||
clientUA = "CLI/2.143.1 CodeBuddy/2.143.1"
|
clientUA = "CLI/2.143.1 CodeBuddy/2.143.1"
|
||||||
originReferer = "https://www.codebuddy.cn"
|
originReferer = "https://www.codebuddy.cn"
|
||||||
@@ -778,6 +778,57 @@ func refreshTokenPayload(sa *StoredAuth) (int, error) {
|
|||||||
// CLI 子命令实现: login, status, refresh
|
// CLI 子命令实现: login, status, refresh
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// formatAccountStatus 生成单个账号的完整状态文本(status 命令与 serve 启动横幅共用)。
|
||||||
|
// idx 从 1 开始的账号序号;now 为当前时间(用于冷却/过期判定)。
|
||||||
|
func formatAccountStatus(acc *Account, idx int, now time.Time) string {
|
||||||
|
var sb strings.Builder
|
||||||
|
sb.WriteString(fmt.Sprintf("\n--- 账号 #%d ---\n", idx))
|
||||||
|
sb.WriteString(fmt.Sprintf("凭据文件: %s\n", acc.Path))
|
||||||
|
|
||||||
|
if acc.Disabled {
|
||||||
|
// 失效账号(Auth 可能为 nil:凭据文件已删除,信息来自失效标记)
|
||||||
|
nickname := acc.Nickname
|
||||||
|
uid := acc.UID
|
||||||
|
if acc.Auth != nil {
|
||||||
|
nickname = acc.Auth.Account.Nickname
|
||||||
|
uid = acc.Auth.Account.UID
|
||||||
|
}
|
||||||
|
sb.WriteString(fmt.Sprintf("用户昵称: %s\n", ifEmpty(nickname, "(未知)")))
|
||||||
|
sb.WriteString(fmt.Sprintf("用户 UID: %s\n", ifEmpty(uid, "(未知)")))
|
||||||
|
sb.WriteString("账号状态: ❌ 授权失效(禁止调度)\n")
|
||||||
|
sb.WriteString(fmt.Sprintf("失效原因: %s\n", truncate(acc.DisabledReason, 200)))
|
||||||
|
sb.WriteString(fmt.Sprintf("处理建议: ⚠️ 凭据文件已删除,请重新执行: workbuddy-gateway login -auth %s\n", acc.Path))
|
||||||
|
return sb.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
if acc.Auth == nil {
|
||||||
|
return sb.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
expTime := time.Unix(acc.Auth.Auth.ExpiresAt, 0)
|
||||||
|
remaining := time.Until(expTime)
|
||||||
|
statusStr := "有效"
|
||||||
|
if remaining <= 0 {
|
||||||
|
statusStr = "已过期"
|
||||||
|
}
|
||||||
|
|
||||||
|
sb.WriteString(fmt.Sprintf("用户昵称: %s\n", acc.Auth.Account.Nickname))
|
||||||
|
sb.WriteString(fmt.Sprintf("用户 UID: %s\n", acc.Auth.Account.UID))
|
||||||
|
sb.WriteString(fmt.Sprintf("企业 ID: %s\n", ifEmpty(acc.Auth.Account.EnterpriseID, "(个人账号)")))
|
||||||
|
sb.WriteString(fmt.Sprintf("认证域名: %s\n", ifEmpty(acc.Auth.Auth.Domain, "www.codebuddy.cn")))
|
||||||
|
if acc.CooldownUntil.After(now) {
|
||||||
|
sb.WriteString(fmt.Sprintf("冷却状态: 🔒 冷却中 (解封: %s, 剩余 %v)\n",
|
||||||
|
acc.CooldownUntil.Format("2006-01-02 15:04:05"),
|
||||||
|
time.Until(acc.CooldownUntil).Round(time.Minute)))
|
||||||
|
sb.WriteString(fmt.Sprintf("冷却原因: %s\n", truncate(acc.CooldownMsg, 120)))
|
||||||
|
} else {
|
||||||
|
sb.WriteString("冷却状态: ✅ 可用\n")
|
||||||
|
}
|
||||||
|
sb.WriteString(fmt.Sprintf("Token 状态: %s\n", statusStr))
|
||||||
|
sb.WriteString(fmt.Sprintf("过期时间: %s (剩余 %v)\n", expTime.Format("2006-01-02 15:04:05"), remaining.Round(time.Minute)))
|
||||||
|
return sb.String()
|
||||||
|
}
|
||||||
|
|
||||||
func runStatus() {
|
func runStatus() {
|
||||||
if err := loadAccounts(); err != nil {
|
if err := loadAccounts(); err != nil {
|
||||||
fmt.Printf("未找到有效凭据: %v\n请先执行: workbuddy-gateway login 扫码登录。\n", err)
|
fmt.Printf("未找到有效凭据: %v\n请先执行: workbuddy-gateway login 扫码登录。\n", err)
|
||||||
@@ -791,50 +842,7 @@ func runStatus() {
|
|||||||
fmt.Printf("账号总数: %d\n", len(accounts))
|
fmt.Printf("账号总数: %d\n", len(accounts))
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
for i, acc := range accounts {
|
for i, acc := range accounts {
|
||||||
fmt.Printf("\n--- 账号 #%d ---\n", i+1)
|
fmt.Print(formatAccountStatus(acc, i+1, now))
|
||||||
fmt.Printf("凭据文件: %s\n", acc.Path)
|
|
||||||
|
|
||||||
if acc.Disabled {
|
|
||||||
// 失效账号(Auth 可能为 nil:凭据文件已删除,信息来自失效标记)
|
|
||||||
nickname := acc.Nickname
|
|
||||||
uid := acc.UID
|
|
||||||
if acc.Auth != nil {
|
|
||||||
nickname = acc.Auth.Account.Nickname
|
|
||||||
uid = acc.Auth.Account.UID
|
|
||||||
}
|
|
||||||
fmt.Printf("用户昵称: %s\n", ifEmpty(nickname, "(未知)"))
|
|
||||||
fmt.Printf("用户 UID: %s\n", ifEmpty(uid, "(未知)"))
|
|
||||||
fmt.Printf("账号状态: ❌ 授权失效(禁止调度)\n")
|
|
||||||
fmt.Printf("失效原因: %s\n", truncate(acc.DisabledReason, 200))
|
|
||||||
fmt.Printf("处理建议: ⚠️ 凭据文件已删除,请重新执行: workbuddy-gateway login -auth %s\n", acc.Path)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if acc.Auth == nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
expTime := time.Unix(acc.Auth.Auth.ExpiresAt, 0)
|
|
||||||
remaining := time.Until(expTime)
|
|
||||||
statusStr := "有效"
|
|
||||||
if remaining <= 0 {
|
|
||||||
statusStr = "已过期"
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Printf("用户昵称: %s\n", acc.Auth.Account.Nickname)
|
|
||||||
fmt.Printf("用户 UID: %s\n", acc.Auth.Account.UID)
|
|
||||||
fmt.Printf("企业 ID: %s\n", ifEmpty(acc.Auth.Account.EnterpriseID, "(个人账号)"))
|
|
||||||
fmt.Printf("认证域名: %s\n", ifEmpty(acc.Auth.Auth.Domain, "www.codebuddy.cn"))
|
|
||||||
if acc.CooldownUntil.After(now) {
|
|
||||||
fmt.Printf("冷却状态: 🔒 冷却中 (解封: %s, 剩余 %v)\n",
|
|
||||||
acc.CooldownUntil.Format("2006-01-02 15:04:05"),
|
|
||||||
time.Until(acc.CooldownUntil).Round(time.Minute))
|
|
||||||
fmt.Printf("冷却原因: %s\n", truncate(acc.CooldownMsg, 120))
|
|
||||||
} else {
|
|
||||||
fmt.Printf("冷却状态: ✅ 可用\n")
|
|
||||||
}
|
|
||||||
fmt.Printf("Token 状态: %s\n", statusStr)
|
|
||||||
fmt.Printf("过期时间: %s (剩余 %v)\n", expTime.Format("2006-01-02 15:04:05"), remaining.Round(time.Minute))
|
|
||||||
}
|
}
|
||||||
fmt.Println("\n=======================================================")
|
fmt.Println("\n=======================================================")
|
||||||
}
|
}
|
||||||
@@ -972,28 +980,13 @@ func runServe() {
|
|||||||
fmt.Printf("警告: 未检测到有效凭据 (%v)。\n请先执行: workbuddy-gateway login 扫码登录,或确保凭据文件存在。\n\n", err)
|
fmt.Printf("警告: 未检测到有效凭据 (%v)。\n请先执行: workbuddy-gateway login 扫码登录,或确保凭据文件存在。\n\n", err)
|
||||||
} else {
|
} else {
|
||||||
accountMu.Lock()
|
accountMu.Lock()
|
||||||
accCount := len(accounts)
|
|
||||||
activeCount := 0
|
|
||||||
disabledCount := 0
|
|
||||||
for _, acc := range accounts {
|
for _, acc := range accounts {
|
||||||
if acc.Disabled || acc.Auth == nil {
|
if acc.Disabled || acc.Auth == nil {
|
||||||
disabledCount++
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
activeCount++
|
|
||||||
_ = ensureValidTokenFor(acc)
|
_ = ensureValidTokenFor(acc)
|
||||||
}
|
}
|
||||||
accountMu.Unlock()
|
accountMu.Unlock()
|
||||||
fmt.Printf("已就绪账号池: %d 个账号 (有效 %d, 失效 %d)\n", accCount, activeCount, disabledCount)
|
|
||||||
for i, acc := range accounts {
|
|
||||||
if acc.Disabled || acc.Auth == nil {
|
|
||||||
fmt.Printf(" #%d ❌ %s (授权失效,凭据文件已删除,请重新登录)\n", i+1, acc.Path)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
fmt.Printf(" #%d ✅ %s (UID: %s, 有效期至: %s)\n",
|
|
||||||
i+1, acc.Auth.Account.Nickname, acc.Auth.Account.UID,
|
|
||||||
time.Unix(acc.Auth.Auth.ExpiresAt, 0).Format("2006-01-02 15:04:05"))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 启动后台自动刷新协程
|
// 启动后台自动刷新协程
|
||||||
@@ -1030,6 +1023,30 @@ func runServe() {
|
|||||||
if cfg.ProxyURL != "" {
|
if cfg.ProxyURL != "" {
|
||||||
fmt.Printf(" 上游出口代理: %s\n", cfg.ProxyURL)
|
fmt.Printf(" 上游出口代理: %s\n", cfg.ProxyURL)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 启动时展示所有账号状态(与 status 命令一致)
|
||||||
|
accountMu.Lock()
|
||||||
|
accCount := len(accounts)
|
||||||
|
activeCount := 0
|
||||||
|
disabledCount := 0
|
||||||
|
now := time.Now()
|
||||||
|
for _, acc := range accounts {
|
||||||
|
if acc.Disabled || acc.Auth == nil {
|
||||||
|
disabledCount++
|
||||||
|
} else {
|
||||||
|
activeCount++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fmt.Printf(" 账号池: %d 个账号 (有效 %d, 失效 %d)\n", accCount, activeCount, disabledCount)
|
||||||
|
if accCount > 0 {
|
||||||
|
fmt.Println(" ----------------------------------------------------------")
|
||||||
|
for i, acc := range accounts {
|
||||||
|
fmt.Print(formatAccountStatus(acc, i+1, now))
|
||||||
|
}
|
||||||
|
fmt.Println(" ----------------------------------------------------------")
|
||||||
|
}
|
||||||
|
accountMu.Unlock()
|
||||||
|
|
||||||
fmt.Println("================================================================")
|
fmt.Println("================================================================")
|
||||||
fmt.Println("等待客户端请求中 (按 Ctrl+C 安全停止)...")
|
fmt.Println("等待客户端请求中 (按 Ctrl+C 安全停止)...")
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user