From 9b213115e73e8cb70da77fb47d08f8375b129588 Mon Sep 17 00:00:00 2001 From: erio Date: Wed, 1 Apr 2026 23:13:58 +0800 Subject: [PATCH] fix: address audit findings - cache sync, validation, consistency MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - clearCreditsExhausted: sync Redis scheduler cache after DB update - Image billing mode UI: write to per_request_price instead of image_output_price - OpenAI RecordUsage: use BillingModelSourceRequested constant, add s.cfg nil guard - Fix i18n key path: admin.channels.perRequestPriceRequired → admin.channels.form.perRequestPriceRequired --- backend/internal/service/antigravity_credits_overages.go | 4 ++++ backend/internal/service/openai_gateway_service.go | 7 +++++-- frontend/src/components/admin/channel/PricingEntryCard.vue | 4 ++-- frontend/src/views/admin/ChannelsView.vue | 2 +- 4 files changed, 12 insertions(+), 5 deletions(-) diff --git a/backend/internal/service/antigravity_credits_overages.go b/backend/internal/service/antigravity_credits_overages.go index 1cfc9504..99ec7d08 100644 --- a/backend/internal/service/antigravity_credits_overages.go +++ b/backend/internal/service/antigravity_credits_overages.go @@ -140,6 +140,10 @@ func (s *AntigravityGatewayService) clearCreditsExhausted(ctx context.Context, a }); err != nil { logger.LegacyPrintf("service.antigravity_gateway", "clear credits exhausted failed: account=%d err=%v", account.ID, err) } + // 同步更新 Redis 调度快照,避免其他节点/请求延迟感知 + if s.schedulerSnapshot != nil { + _ = s.schedulerSnapshot.UpdateAccountInCache(ctx, account) + } } // classifyAntigravity429 将 Antigravity 的 429 响应归类为配额耗尽、限流或未知。 diff --git a/backend/internal/service/openai_gateway_service.go b/backend/internal/service/openai_gateway_service.go index 6f95c8c6..beff1879 100644 --- a/backend/internal/service/openai_gateway_service.go +++ b/backend/internal/service/openai_gateway_service.go @@ -4182,7 +4182,10 @@ func (s *OpenAIGatewayService) RecordUsage(ctx context.Context, input *OpenAIRec } // Get rate multiplier - multiplier := s.cfg.Default.RateMultiplier + multiplier := 1.0 + if s.cfg != nil { + multiplier = s.cfg.Default.RateMultiplier + } if apiKey.GroupID != nil && apiKey.Group != nil { resolver := s.userGroupRateResolver if resolver == nil { @@ -4200,7 +4203,7 @@ func (s *OpenAIGatewayService) RecordUsage(ctx context.Context, input *OpenAIRec if input.BillingModelSource == BillingModelSourceChannelMapped && input.ChannelMappedModel != "" { billingModel = input.ChannelMappedModel } - if input.BillingModelSource == "requested" && input.OriginalModel != "" { + if input.BillingModelSource == BillingModelSourceRequested && input.OriginalModel != "" { billingModel = input.OriginalModel } serviceTier := "" diff --git a/frontend/src/components/admin/channel/PricingEntryCard.vue b/frontend/src/components/admin/channel/PricingEntryCard.vue index b2d41e2a..e98853c3 100644 --- a/frontend/src/components/admin/channel/PricingEntryCard.vue +++ b/frontend/src/components/admin/channel/PricingEntryCard.vue @@ -191,13 +191,13 @@
- +
-
diff --git a/frontend/src/views/admin/ChannelsView.vue b/frontend/src/views/admin/ChannelsView.vue index 9a8c396e..4d4150fb 100644 --- a/frontend/src/views/admin/ChannelsView.vue +++ b/frontend/src/views/admin/ChannelsView.vue @@ -916,7 +916,7 @@ async function handleSubmit() { if ((entry.billing_mode === 'per_request' || entry.billing_mode === 'image') && (entry.per_request_price == null || entry.per_request_price === '') && (!entry.intervals || entry.intervals.length === 0)) { - appStore.showError(t('admin.channels.perRequestPriceRequired', '按次/图片计费模式必须设置默认价格或至少一个计费层级')) + appStore.showError(t('admin.channels.form.perRequestPriceRequired', '按次/图片计费模式必须设置默认价格或至少一个计费层级')) return } }