From ee29b9428b4484a28fd27e4c7d1b627256b399e2 Mon Sep 17 00:00:00 2001 From: ianshaw Date: Sun, 4 Jan 2026 20:51:37 -0800 Subject: [PATCH] =?UTF-8?q?fix(frontend):=20=E4=BF=AE=E5=A4=8D=E9=87=8D?= =?UTF-8?q?=E6=9E=84=E9=A1=B5=E9=9D=A2=E7=9A=84=E9=81=97=E6=BC=8F=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 添加 en.ts 中缺失的 admin.redeem.types 翻译 - RedeemView 状态筛选器添加 expired 选项 - SubscriptionsView 用量进度条添加 null/undefined 兜底 - SubscriptionsView 添加 validity_days 表单校验 - GroupsView/ProxiesView 搜索图标添加 dark mode 样式 --- frontend/src/i18n/locales/en.ts | 6 ++++++ frontend/src/i18n/locales/zh.ts | 1 + frontend/src/views/admin/GroupsView.vue | 2 +- frontend/src/views/admin/ProxiesView.vue | 2 +- frontend/src/views/admin/RedeemView.vue | 3 ++- frontend/src/views/admin/SubscriptionsView.vue | 14 ++++++++++---- 6 files changed, 21 insertions(+), 7 deletions(-) diff --git a/frontend/src/i18n/locales/en.ts b/frontend/src/i18n/locales/en.ts index 2b309af1..ae27d9cf 100644 --- a/frontend/src/i18n/locales/en.ts +++ b/frontend/src/i18n/locales/en.ts @@ -914,6 +914,7 @@ export default { failedToRevoke: 'Failed to revoke subscription', pleaseSelectUser: 'Please select a user', pleaseSelectGroup: 'Please select a group', + validityDaysRequired: 'Please enter a valid number of days (at least 1)', revokeConfirm: "Are you sure you want to revoke the subscription for '{user}'? This action cannot be undone." }, @@ -1652,6 +1653,11 @@ export default { failedToDelete: 'Failed to delete code', failedToDeleteUnused: 'Failed to delete unused codes', failedToCopy: 'Failed to copy codes', + types: { + balance: 'Balance', + concurrency: 'Concurrency', + subscription: 'Subscription' + }, selectGroup: 'Select Group', selectGroupPlaceholder: 'Choose a subscription group', validityDays: 'Validity Days', diff --git a/frontend/src/i18n/locales/zh.ts b/frontend/src/i18n/locales/zh.ts index 25dd929c..f401d9a0 100644 --- a/frontend/src/i18n/locales/zh.ts +++ b/frontend/src/i18n/locales/zh.ts @@ -991,6 +991,7 @@ export default { failedToRevoke: '撤销订阅失败', pleaseSelectUser: '请选择用户', pleaseSelectGroup: '请选择分组', + validityDaysRequired: '请输入有效的天数(至少1天)', revokeConfirm: "确定要撤销 '{user}' 的订阅吗?此操作无法撤销。" }, diff --git a/frontend/src/views/admin/GroupsView.vue b/frontend/src/views/admin/GroupsView.vue index 95918e6e..d8400041 100644 --- a/frontend/src/views/admin/GroupsView.vue +++ b/frontend/src/views/admin/GroupsView.vue @@ -7,7 +7,7 @@
[ const filterStatusOptions = computed(() => [ { value: '', label: t('admin.redeem.allStatus') }, { value: 'unused', label: t('admin.redeem.unused') }, - { value: 'used', label: t('admin.redeem.used') } + { value: 'used', label: t('admin.redeem.used') }, + { value: 'expired', label: t('admin.redeem.status.expired') } ]) const codes = ref([]) diff --git a/frontend/src/views/admin/SubscriptionsView.vue b/frontend/src/views/admin/SubscriptionsView.vue index a0b78062..50fe4cbe 100644 --- a/frontend/src/views/admin/SubscriptionsView.vue +++ b/frontend/src/views/admin/SubscriptionsView.vue @@ -877,6 +877,10 @@ const handleAssignSubscription = async () => { appStore.showError(t('admin.subscriptions.pleaseSelectGroup')) return } + if (!assignForm.validity_days || assignForm.validity_days < 1) { + appStore.showError(t('admin.subscriptions.validityDaysRequired')) + return + } submitting.value = true try { @@ -960,15 +964,17 @@ const isExpiringSoon = (expiresAt: string): boolean => { return days !== null && days <= 7 } -const getProgressWidth = (used: number, limit: number | null): string => { +const getProgressWidth = (used: number | null | undefined, limit: number | null): string => { if (!limit || limit === 0) return '0%' - const percentage = Math.min((used / limit) * 100, 100) + const usedValue = used ?? 0 + const percentage = Math.min((usedValue / limit) * 100, 100) return `${percentage}%` } -const getProgressClass = (used: number, limit: number | null): string => { +const getProgressClass = (used: number | null | undefined, limit: number | null): string => { if (!limit || limit === 0) return 'bg-gray-400' - const percentage = (used / limit) * 100 + const usedValue = used ?? 0 + const percentage = (usedValue / limit) * 100 if (percentage >= 90) return 'bg-red-500' if (percentage >= 70) return 'bg-orange-500' return 'bg-green-500'