feat: WebSearch tri-state, account stats pricing fix, quota cache fix, usage tooltip

WebSearch tri-state switch:
- Account-level web_search_emulation changed from bool to tri-state
  string: "default" (follow channel) / "enabled" / "disabled"
- shouldEmulateWebSearch checks channel config when account is "default"
- SQL migration converts old bool values
- Frontend select replaces toggle in Edit/CreateAccountModal

Account stats pricing:
- resolveAccountStatsCost uses upstream model (post-mapping) for matching
- Priority: custom rules → model pricing file (when toggle on) → default
- Custom rules always configurable, independent of toggle
- Account ID field changed to searchable selector filtered by platform
- Description updated to reflect new behavior

Quota notification cache fix:
- CheckAccountQuotaAfterIncrement fetches real-time account from DB
- Reconstructs pre-increment usage for accurate threshold crossing detection
- New AccountQuotaReader interface (minimal: GetByID only)

Usage tooltip:
- Per-request/image billing shows per-request price instead of $0 token price
- Token billing continues to show input/output price per million tokens
This commit is contained in:
erio
2026-04-13 11:37:08 +08:00
parent 11c4606874
commit 1262654d97
18 changed files with 346 additions and 79 deletions

View File

@@ -774,6 +774,8 @@ export default {
inputTokenPrice: 'Input price',
outputTokenPrice: 'Output price',
perMillionTokens: '/ 1M tokens',
unitPrice: 'Per-request price',
imageUnitPrice: 'Per-image price',
cacheRead: 'Read',
cacheWrite: 'Write',
serviceTier: 'Service tier',
@@ -1877,14 +1879,15 @@ export default {
pricingEntry: 'Pricing Entry',
noModels: 'No models added',
applyPricingToAccountStats: 'Apply Pricing to Account Stats',
applyPricingToAccountStatsDesc: 'When enabled, custom account stats model pricing rules will be applied.',
applyPricingToAccountStatsDesc: 'When enabled, requests not matched by custom rules will use standard model pricing for account stats calculation',
accountStatsPricingRules: 'Custom Account Stats Pricing Rules',
addRule: 'Add Rule',
noRulesConfigured: 'No custom rules configured. Channel model pricing above will be used.',
ruleName: 'Rule name (optional)',
ruleGroups: 'Groups',
ruleAccounts: 'Account IDs',
ruleAccountsPlaceholder: 'Enter account IDs, comma-separated',
ruleAccounts: 'Accounts',
searchAccountPlaceholder: 'Search accounts...',
ruleAccountsHint: 'Leave empty to match all accounts',
ruleModelPricing: 'Model Pricing',
noGroupsInChannel: 'No groups selected in platform tabs above'
}
@@ -2380,6 +2383,9 @@ export default {
webSearchEmulation: 'Web Search Emulation',
webSearchEmulationDesc:
'Enable web search emulation for this API Key account. When a pure web_search request is detected, the gateway calls a third-party search API and constructs the response locally.',
webSearchDefault: 'Default (follow channel)',
webSearchEnabled: 'Enabled',
webSearchDisabled: 'Disabled',
},
modelRestriction: 'Model Restriction (Optional)',
modelWhitelist: 'Model Whitelist',