diff --git a/frontend/src/components/account/EditAccountModal.vue b/frontend/src/components/account/EditAccountModal.vue index 665e4e95..ebdfb3b4 100644 --- a/frontend/src/components/account/EditAccountModal.vue +++ b/frontend/src/components/account/EditAccountModal.vue @@ -762,21 +762,58 @@
- -
- $ - +
+

{{ t('admin.accounts.quotaLimit') }}

+

+ {{ t('admin.accounts.quotaLimitHint') }} +

+
+ +
+
+
+ +

+ {{ t('admin.accounts.quotaLimitToggleHint') }} +

+
+ +
+ +
+
+ +
+ $ + +
+

{{ t('admin.accounts.quotaLimitAmountHint') }}

+
+
-

{{ t('admin.accounts.quotaLimitHint') }}

@@ -1407,6 +1444,7 @@ const openaiAPIKeyResponsesWebSocketV2Mode = ref(OPENAI_WS_MODE_OF const codexCLIOnlyEnabled = ref(false) const anthropicPassthroughEnabled = ref(false) const editQuotaLimit = ref(null) +const quotaLimitEnabled = ref(false) const openAIWSModeOptions = computed(() => [ { value: OPENAI_WS_MODE_OFF, label: t('admin.accounts.openai.wsModeOff') }, // TODO: ctx_pool 选项暂时隐藏,待测试完成后恢复 @@ -1435,6 +1473,13 @@ const isOpenAIModelRestrictionDisabled = computed(() => props.account?.platform === 'openai' && openaiPassthroughEnabled.value ) +// When quota limit toggle is turned off, clear the value +watch(quotaLimitEnabled, (enabled) => { + if (!enabled) { + editQuotaLimit.value = null + } +}) + // Computed: current preset mappings based on platform const presetMappings = computed(() => getPresetMappingsByPlatform(props.account?.platform || 'anthropic')) const tempUnschedPresets = computed(() => [ @@ -1565,8 +1610,10 @@ watch( // Load quota limit for apikey accounts if (newAccount.type === 'apikey') { const quotaVal = extra?.quota_limit as number | undefined + quotaLimitEnabled.value = !!(quotaVal && quotaVal > 0) editQuotaLimit.value = (quotaVal && quotaVal > 0) ? quotaVal : null } else { + quotaLimitEnabled.value = false editQuotaLimit.value = null } @@ -2317,7 +2364,7 @@ const handleSubmit = async () => { const currentExtra = (updatePayload.extra as Record) || (props.account.extra as Record) || {} const newExtra: Record = { ...currentExtra } - if (editQuotaLimit.value != null && editQuotaLimit.value > 0) { + if (quotaLimitEnabled.value && editQuotaLimit.value != null && editQuotaLimit.value > 0) { newExtra.quota_limit = editQuotaLimit.value } else { delete newExtra.quota_limit diff --git a/frontend/src/i18n/locales/en.ts b/frontend/src/i18n/locales/en.ts index 4be07f85..84e83850 100644 --- a/frontend/src/i18n/locales/en.ts +++ b/frontend/src/i18n/locales/en.ts @@ -1787,6 +1787,10 @@ export default { quotaLimit: 'Quota Limit', quotaLimitPlaceholder: '0 means unlimited', quotaLimitHint: 'Set max spending limit (USD). Account will be paused when reached. Changing limit won\'t reset usage.', + quotaLimitToggle: 'Enable Quota Limit', + quotaLimitToggleHint: 'When enabled, account will be paused when usage reaches the set limit', + quotaLimitAmount: 'Limit Amount', + quotaLimitAmountHint: 'Maximum spending limit (USD). Account will be auto-paused when reached. Changing limit won\'t reset usage.', testConnection: 'Test Connection', reAuthorize: 'Re-Authorize', refreshToken: 'Refresh Token', diff --git a/frontend/src/i18n/locales/zh.ts b/frontend/src/i18n/locales/zh.ts index ce262a2a..c37b497a 100644 --- a/frontend/src/i18n/locales/zh.ts +++ b/frontend/src/i18n/locales/zh.ts @@ -1794,6 +1794,10 @@ export default { quotaLimit: '配额限制', quotaLimitPlaceholder: '0 表示不限制', quotaLimitHint: '设置最大使用额度(美元),达到后账号暂停调度。修改限额不会重置已用额度。', + quotaLimitToggle: '启用配额限制', + quotaLimitToggleHint: '开启后,当账号用量达到设定额度时自动暂停调度', + quotaLimitAmount: '限额金额', + quotaLimitAmountHint: '账号最大可用额度(美元),达到后自动暂停。修改限额不会重置已用额度。', testConnection: '测试连接', reAuthorize: '重新授权', refreshToken: '刷新令牌',