From 60fce4f1dcd71caf1a6c8f94bf5c887c6ac0ee1f Mon Sep 17 00:00:00 2001 From: wioos Date: Fri, 6 Mar 2026 16:20:15 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=20lite=20=E6=A8=A1?= =?UTF-8?q?=E5=BC=8F=E8=B7=B3=E8=BF=87=E7=AA=97=E5=8F=A3=E8=B4=B9=E7=94=A8?= =?UTF-8?q?=E6=9F=A5=E8=AF=A2=E5=AF=BC=E8=87=B4=20$0.00=20=E6=98=BE?= =?UTF-8?q?=E7=A4=BA=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 80ae592c 引入 lite 模式优化首次加载性能,但将窗口费用查询也一起跳过了。 commit 491a7444 尝试用 30 秒快照缓存修复,但缓存过期后问题复现。 移除窗口费用查询的 lite/非 lite 区分,始终执行 PostgreSQL 聚合查询。 同时删除不再需要的 account_window_cost_cache.go 文件。 Co-Authored-By: Claude Opus 4.6 --- .../internal/handler/admin/account_handler.go | 60 +++++++------------ .../admin/account_window_cost_cache.go | 25 -------- 2 files changed, 22 insertions(+), 63 deletions(-) delete mode 100644 backend/internal/handler/admin/account_window_cost_cache.go diff --git a/backend/internal/handler/admin/account_handler.go b/backend/internal/handler/admin/account_handler.go index f42159a8..358d71f6 100644 --- a/backend/internal/handler/admin/account_handler.go +++ b/backend/internal/handler/admin/account_handler.go @@ -288,48 +288,32 @@ func (h *AccountHandler) List(c *gin.Context) { } } - // 窗口费用获取:lite 模式从快照缓存读取,非 lite 模式执行 PostgreSQL 查询后写入缓存 + // 始终获取窗口费用(PostgreSQL 聚合查询) if len(windowCostAccountIDs) > 0 { - if lite { - // lite 模式:尝试从快照缓存读取 - cacheKey := buildWindowCostCacheKey(windowCostAccountIDs) - if cached, ok := accountWindowCostCache.Get(cacheKey); ok { - if costs, ok := cached.Payload.(map[int64]float64); ok { - windowCosts = costs - } - } - // 缓存未命中则 windowCosts 保持 nil(仅发生在服务刚启动时) - } else { - // 非 lite 模式:执行 PostgreSQL 聚合查询(高开销) - windowCosts = make(map[int64]float64) - var mu sync.Mutex - g, gctx := errgroup.WithContext(c.Request.Context()) - g.SetLimit(10) // 限制并发数 + windowCosts = make(map[int64]float64) + var mu sync.Mutex + g, gctx := errgroup.WithContext(c.Request.Context()) + g.SetLimit(10) // 限制并发数 - for i := range accounts { - acc := &accounts[i] - if !acc.IsAnthropicOAuthOrSetupToken() || acc.GetWindowCostLimit() <= 0 { - continue - } - accCopy := acc // 闭包捕获 - g.Go(func() error { - // 使用统一的窗口开始时间计算逻辑(考虑窗口过期情况) - startTime := accCopy.GetCurrentWindowStartTime() - stats, err := h.accountUsageService.GetAccountWindowStats(gctx, accCopy.ID, startTime) - if err == nil && stats != nil { - mu.Lock() - windowCosts[accCopy.ID] = stats.StandardCost // 使用标准费用 - mu.Unlock() - } - return nil // 不返回错误,允许部分失败 - }) + for i := range accounts { + acc := &accounts[i] + if !acc.IsAnthropicOAuthOrSetupToken() || acc.GetWindowCostLimit() <= 0 { + continue } - _ = g.Wait() - - // 查询完毕后写入快照缓存,供 lite 模式使用 - cacheKey := buildWindowCostCacheKey(windowCostAccountIDs) - accountWindowCostCache.Set(cacheKey, windowCosts) + accCopy := acc // 闭包捕获 + g.Go(func() error { + // 使用统一的窗口开始时间计算逻辑(考虑窗口过期情况) + startTime := accCopy.GetCurrentWindowStartTime() + stats, err := h.accountUsageService.GetAccountWindowStats(gctx, accCopy.ID, startTime) + if err == nil && stats != nil { + mu.Lock() + windowCosts[accCopy.ID] = stats.StandardCost // 使用标准费用 + mu.Unlock() + } + return nil // 不返回错误,允许部分失败 + }) } + _ = g.Wait() } // Build response with concurrency info diff --git a/backend/internal/handler/admin/account_window_cost_cache.go b/backend/internal/handler/admin/account_window_cost_cache.go deleted file mode 100644 index 3271b630..00000000 --- a/backend/internal/handler/admin/account_window_cost_cache.go +++ /dev/null @@ -1,25 +0,0 @@ -package admin - -import ( - "strconv" - "strings" - "time" -) - -var accountWindowCostCache = newSnapshotCache(30 * time.Second) - -func buildWindowCostCacheKey(accountIDs []int64) string { - if len(accountIDs) == 0 { - return "accounts_window_cost_empty" - } - var b strings.Builder - b.Grow(len(accountIDs) * 6) - _, _ = b.WriteString("accounts_window_cost:") - for i, id := range accountIDs { - if i > 0 { - _ = b.WriteByte(',') - } - _, _ = b.WriteString(strconv.FormatInt(id, 10)) - } - return b.String() -}