fix: 修复NeedsRefresh bug导致刷新失败的问题
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -32,6 +32,7 @@ frontend/node_modules/
|
|||||||
frontend/dist/
|
frontend/dist/
|
||||||
*.local
|
*.local
|
||||||
*.tsbuildinfo
|
*.tsbuildinfo
|
||||||
|
vite.config.d.ts
|
||||||
|
|
||||||
# 日志
|
# 日志
|
||||||
npm-debug.log*
|
npm-debug.log*
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package service
|
package service
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
@@ -94,6 +95,9 @@ func (a *Account) GetCredential(key string) string {
|
|||||||
switch val := v.(type) {
|
switch val := v.(type) {
|
||||||
case string:
|
case string:
|
||||||
return val
|
return val
|
||||||
|
case json.Number:
|
||||||
|
// GORM datatypes.JSONMap 使用 UseNumber() 解析,数字类型为 json.Number
|
||||||
|
return val.String()
|
||||||
case float64:
|
case float64:
|
||||||
// JSON 解析后数字默认为 float64
|
// JSON 解析后数字默认为 float64
|
||||||
return strconv.FormatInt(int64(val), 10)
|
return strconv.FormatInt(int64(val), 10)
|
||||||
|
|||||||
@@ -106,6 +106,9 @@ func (s *TokenRefreshService) processRefresh() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
totalAccounts := len(accounts)
|
||||||
|
oauthAccounts := 0 // 可刷新的OAuth账号数
|
||||||
|
needsRefresh := 0 // 需要刷新的账号数
|
||||||
refreshed, failed := 0, 0
|
refreshed, failed := 0, 0
|
||||||
|
|
||||||
for i := range accounts {
|
for i := range accounts {
|
||||||
@@ -117,11 +120,15 @@ func (s *TokenRefreshService) processRefresh() {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
oauthAccounts++
|
||||||
|
|
||||||
// 检查是否需要刷新
|
// 检查是否需要刷新
|
||||||
if !refresher.NeedsRefresh(account, refreshWindow) {
|
if !refresher.NeedsRefresh(account, refreshWindow) {
|
||||||
continue
|
break // 不需要刷新,跳过
|
||||||
}
|
}
|
||||||
|
|
||||||
|
needsRefresh++
|
||||||
|
|
||||||
// 执行刷新
|
// 执行刷新
|
||||||
if err := s.refreshWithRetry(ctx, account, refresher); err != nil {
|
if err := s.refreshWithRetry(ctx, account, refresher); err != nil {
|
||||||
log.Printf("[TokenRefresh] Account %d (%s) failed: %v", account.ID, account.Name, err)
|
log.Printf("[TokenRefresh] Account %d (%s) failed: %v", account.ID, account.Name, err)
|
||||||
@@ -136,9 +143,9 @@ func (s *TokenRefreshService) processRefresh() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if refreshed > 0 || failed > 0 {
|
// 始终打印周期日志,便于跟踪服务运行状态
|
||||||
log.Printf("[TokenRefresh] Cycle complete: %d refreshed, %d failed", refreshed, failed)
|
log.Printf("[TokenRefresh] Cycle complete: total=%d, oauth=%d, needs_refresh=%d, refreshed=%d, failed=%d",
|
||||||
}
|
totalAccounts, oauthAccounts, needsRefresh, refreshed, failed)
|
||||||
}
|
}
|
||||||
|
|
||||||
// listActiveAccounts 获取所有active状态的账号
|
// listActiveAccounts 获取所有active状态的账号
|
||||||
|
|||||||
@@ -43,19 +43,13 @@ func (r *ClaudeTokenRefresher) CanRefresh(account *Account) bool {
|
|||||||
// NeedsRefresh 检查token是否需要刷新
|
// NeedsRefresh 检查token是否需要刷新
|
||||||
// 基于 expires_at 字段判断是否在刷新窗口内
|
// 基于 expires_at 字段判断是否在刷新窗口内
|
||||||
func (r *ClaudeTokenRefresher) NeedsRefresh(account *Account, refreshWindow time.Duration) bool {
|
func (r *ClaudeTokenRefresher) NeedsRefresh(account *Account, refreshWindow time.Duration) bool {
|
||||||
var expiresAt int64
|
s := account.GetCredential("expires_at")
|
||||||
|
if s == "" {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
// 方式1: 通过 GetCredential 获取(处理字符串和部分数字类型)
|
expiresAt, err := strconv.ParseInt(s, 10, 64)
|
||||||
if s := account.GetCredential("expires_at"); s != "" {
|
if err != nil {
|
||||||
v, err := strconv.ParseInt(s, 10, 64)
|
|
||||||
if err != nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
expiresAt = v
|
|
||||||
} else if v, ok := account.Credentials["expires_at"].(float64); ok {
|
|
||||||
// 方式2: 直接获取 float64(处理某些 JSON 解码器将数字解析为 float64 的情况)
|
|
||||||
expiresAt = int64(v)
|
|
||||||
} else {
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
2
frontend/vite.config.d.ts
vendored
2
frontend/vite.config.d.ts
vendored
@@ -1,2 +0,0 @@
|
|||||||
declare const _default: import('vite').UserConfig
|
|
||||||
export default _default
|
|
||||||
Reference in New Issue
Block a user