From b05e90e4e44f5a055d39a5765d42086a9177096a Mon Sep 17 00:00:00 2001 From: ianshaw Date: Sun, 4 Jan 2026 19:34:08 -0800 Subject: [PATCH 01/28] =?UTF-8?q?fix(frontend):=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E8=B4=A6=E5=8F=B7=E7=AE=A1=E7=90=86=E9=A1=B5=E9=9D=A2=E7=BB=84?= =?UTF-8?q?=E4=BB=B6=E6=8B=86=E5=88=86=E6=97=B6=E9=81=97=E6=BC=8F=E7=9A=84?= =?UTF-8?q?=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - AccountTableFilters: 添加 Antigravity 平台选项、类型筛选器、inactive 状态 - AccountActionMenu: 恢复重置状态和清除限速按钮,添加 dark mode 样式 - AccountsView: 修正 handleClearRateLimit 调用正确的 API --- .../admin/account/AccountActionMenu.vue | 19 ++++++++++++++----- .../admin/account/AccountTableFilters.vue | 6 ++++-- frontend/src/views/admin/AccountsView.vue | 2 +- 3 files changed, 19 insertions(+), 8 deletions(-) diff --git a/frontend/src/components/admin/account/AccountActionMenu.vue b/frontend/src/components/admin/account/AccountActionMenu.vue index 9fa7d718..ebf574d5 100644 --- a/frontend/src/components/admin/account/AccountActionMenu.vue +++ b/frontend/src/components/admin/account/AccountActionMenu.vue @@ -3,12 +3,15 @@
@@ -16,6 +19,12 @@ \ No newline at end of file diff --git a/frontend/src/components/admin/account/AccountTableFilters.vue b/frontend/src/components/admin/account/AccountTableFilters.vue index 3721acc6..dfa816f8 100644 --- a/frontend/src/components/admin/account/AccountTableFilters.vue +++ b/frontend/src/components/admin/account/AccountTableFilters.vue @@ -10,6 +10,7 @@
+
+ + +
+ + +
+ @@ -11,19 +26,24 @@ \ No newline at end of file From 85f53ef2dd3380be76d1a47524bb273a0b382f45 Mon Sep 17 00:00:00 2001 From: ianshaw Date: Sun, 4 Jan 2026 20:22:59 -0800 Subject: [PATCH 03/28] =?UTF-8?q?fix(frontend):=20=E5=AE=8C=E5=96=84?= =?UTF-8?q?=E8=A1=A8=E5=8D=95=E6=A0=A1=E9=AA=8C=E5=B9=B6=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E9=94=99=E8=AF=AF=E6=8F=90=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - UserEditModal: 添加 email 必填和 concurrency 最小值校验 - UserAttributesConfigModal: 添加 key/name 必填和 options 非空校验 - GroupsView: 添加 name 必填校验 - ProxiesView: 添加 name/host 必填和 port 范围校验 - UserBalanceModal: 添加 amount 有效性和余额充足性校验 - RedeemView: 添加空兑换码错误提示 - i18n: 添加所有新增校验的中英文翻译 --- .../admin/user/UserBalanceModal.vue | 15 ++++++++++-- .../components/admin/user/UserEditModal.vue | 8 +++++++ .../user/UserAttributesConfigModal.vue | 12 ++++++++++ frontend/src/i18n/locales/en.ts | 15 ++++++++++-- frontend/src/i18n/locales/zh.ts | 15 ++++++++++-- frontend/src/views/admin/GroupsView.vue | 8 +++++++ frontend/src/views/admin/ProxiesView.vue | 24 +++++++++++++++++++ frontend/src/views/user/RedeemView.vue | 1 + 8 files changed, 92 insertions(+), 6 deletions(-) diff --git a/frontend/src/components/admin/user/UserBalanceModal.vue b/frontend/src/components/admin/user/UserBalanceModal.vue index 19e9ccab..31e242f2 100644 --- a/frontend/src/components/admin/user/UserBalanceModal.vue +++ b/frontend/src/components/admin/user/UserBalanceModal.vue @@ -37,10 +37,21 @@ watch(() => props.show, (v) => { if(v) { form.amount = 0; form.notes = '' } }) const calculateNewBalance = () => (props.user ? (props.operation === 'add' ? props.user.balance + form.amount : props.user.balance - form.amount) : 0) const handleBalanceSubmit = async () => { - if (!props.user) return; submitting.value = true + if (!props.user) return + if (!form.amount || form.amount <= 0) { + appStore.showError(t('admin.users.amountRequired')) + return + } + if (props.operation === 'subtract' && form.amount > props.user.balance) { + appStore.showError(t('admin.users.insufficientBalance')) + return + } + submitting.value = true try { await adminAPI.users.updateBalance(props.user.id, form.amount, props.operation, form.notes) appStore.showSuccess(t('common.success')); emit('success'); emit('close') - } catch {} finally { submitting.value = false } + } catch (e: any) { + appStore.showError(e.response?.data?.detail || t('common.error')) + } finally { submitting.value = false } } \ No newline at end of file diff --git a/frontend/src/components/admin/user/UserEditModal.vue b/frontend/src/components/admin/user/UserEditModal.vue index 3f6fd206..43f677d3 100644 --- a/frontend/src/components/admin/user/UserEditModal.vue +++ b/frontend/src/components/admin/user/UserEditModal.vue @@ -86,6 +86,14 @@ const copyPassword = async () => { } const handleUpdateUser = async () => { if (!props.user) return + if (!form.email.trim()) { + appStore.showError(t('admin.users.emailRequired')) + return + } + if (form.concurrency < 1) { + appStore.showError(t('admin.users.concurrencyMin')) + return + } submitting.value = true try { const data: any = { email: form.email, username: form.username, notes: form.notes, concurrency: form.concurrency } diff --git a/frontend/src/components/user/UserAttributesConfigModal.vue b/frontend/src/components/user/UserAttributesConfigModal.vue index 07b9816d..3e1186e4 100644 --- a/frontend/src/components/user/UserAttributesConfigModal.vue +++ b/frontend/src/components/user/UserAttributesConfigModal.vue @@ -344,6 +344,18 @@ const removeOption = (index: number) => { } const handleSave = async () => { + if (!form.key.trim()) { + appStore.showError(t('admin.users.attributes.keyRequired')) + return + } + if (!form.name.trim()) { + appStore.showError(t('admin.users.attributes.nameRequired')) + return + } + if ((form.type === 'select' || form.type === 'multi_select') && form.options.length === 0) { + appStore.showError(t('admin.users.attributes.optionsRequired')) + return + } saving.value = true try { const data = { diff --git a/frontend/src/i18n/locales/en.ts b/frontend/src/i18n/locales/en.ts index 29328fe0..2b309af1 100644 --- a/frontend/src/i18n/locales/en.ts +++ b/frontend/src/i18n/locales/en.ts @@ -462,7 +462,8 @@ export default { days: ' days', codeRedeemSuccess: 'Code redeemed successfully!', failedToRedeem: 'Failed to redeem code. Please check the code and try again.', - subscriptionRefreshFailed: 'Redeemed successfully, but failed to refresh subscription status.' + subscriptionRefreshFailed: 'Redeemed successfully, but failed to refresh subscription status.', + pleaseEnterCode: 'Please enter a redeem code' }, // Profile @@ -658,6 +659,10 @@ export default { failedToDelete: 'Failed to delete user', failedToToggle: 'Failed to update user status', failedToLoadApiKeys: 'Failed to load user API keys', + emailRequired: 'Please enter email', + concurrencyMin: 'Concurrency must be at least 1', + amountRequired: 'Please enter a valid amount', + insufficientBalance: 'Insufficient balance', deleteConfirm: "Are you sure you want to delete '{email}'? This action cannot be undone.", setAllowedGroups: 'Set Allowed Groups', allowedGroupsHint: @@ -689,7 +694,6 @@ export default { failedToDeposit: 'Failed to deposit', failedToWithdraw: 'Failed to withdraw', useDepositWithdrawButtons: 'Please use deposit/withdraw buttons to adjust balance', - insufficientBalance: 'Insufficient balance, balance cannot be negative after withdrawal', roles: { admin: 'Admin', user: 'User' @@ -749,6 +753,9 @@ export default { failedToLoad: 'Failed to load attributes', failedToCreate: 'Failed to create attribute', failedToUpdate: 'Failed to update attribute', + keyRequired: 'Please enter attribute key', + nameRequired: 'Please enter display name', + optionsRequired: 'Please add at least one option', failedToDelete: 'Failed to delete attribute', failedToReorder: 'Failed to update order', keyExists: 'Attribute key already exists', @@ -816,6 +823,7 @@ export default { failedToCreate: 'Failed to create group', failedToUpdate: 'Failed to update group', failedToDelete: 'Failed to delete group', + nameRequired: 'Please enter group name', platforms: { all: 'All Platforms', anthropic: 'Anthropic', @@ -1584,6 +1592,9 @@ export default { failedToUpdate: 'Failed to update proxy', failedToDelete: 'Failed to delete proxy', failedToTest: 'Failed to test proxy', + nameRequired: 'Please enter proxy name', + hostRequired: 'Please enter host address', + portInvalid: 'Port must be between 1-65535', deleteConfirm: "Are you sure you want to delete '{name}'? Accounts using this proxy will have their proxy removed." }, diff --git a/frontend/src/i18n/locales/zh.ts b/frontend/src/i18n/locales/zh.ts index cf4b91fc..25dd929c 100644 --- a/frontend/src/i18n/locales/zh.ts +++ b/frontend/src/i18n/locales/zh.ts @@ -459,7 +459,8 @@ export default { days: '天', codeRedeemSuccess: '兑换成功!', failedToRedeem: '兑换失败,请检查兑换码后重试。', - subscriptionRefreshFailed: '兑换成功,但订阅状态刷新失败。' + subscriptionRefreshFailed: '兑换成功,但订阅状态刷新失败。', + pleaseEnterCode: '请输入兑换码' }, // Profile @@ -716,6 +717,10 @@ export default { concurrencyAdjustedSuccess: '并发数调整成功', failedToSave: '保存用户失败', failedToAdjust: '调整失败', + emailRequired: '请输入邮箱', + concurrencyMin: '并发数不能小于1', + amountRequired: '请输入有效金额', + insufficientBalance: '余额不足', setAllowedGroups: '设置允许分组', allowedGroupsHint: '选择此用户可以使用的标准分组。订阅类型分组请在订阅管理中配置。', noStandardGroups: '暂无标准分组', @@ -742,7 +747,6 @@ export default { failedToDeposit: '充值失败', failedToWithdraw: '退款失败', useDepositWithdrawButtons: '请使用充值/退款按钮调整余额', - insufficientBalance: '余额不足,退款后余额不能为负数', // Settings Dropdowns filterSettings: '筛选设置', columnSettings: '列设置', @@ -798,6 +802,9 @@ export default { failedToLoad: '加载属性列表失败', failedToCreate: '创建属性失败', failedToUpdate: '更新属性失败', + keyRequired: '请输入属性键', + nameRequired: '请输入显示名称', + optionsRequired: '请至少添加一个选项', failedToDelete: '删除属性失败', failedToReorder: '更新排序失败', keyExists: '属性键已存在', @@ -905,6 +912,7 @@ export default { groupDeleted: '分组删除成功', failedToCreate: '创建分组失败', failedToUpdate: '更新分组失败', + nameRequired: '请输入分组名称', subscription: { title: '订阅设置', type: '计费类型', @@ -1694,6 +1702,9 @@ export default { failedToCreate: '创建代理失败', failedToUpdate: '更新代理失败', failedToTest: '测试代理失败', + nameRequired: '请输入代理名称', + hostRequired: '请输入主机地址', + portInvalid: '端口必须在 1-65535 之间', deleteConfirm: "确定要删除代理 '{name}' 吗?使用此代理的账号将被移除代理设置。" }, diff --git a/frontend/src/views/admin/GroupsView.vue b/frontend/src/views/admin/GroupsView.vue index f22d1e0d..95918e6e 100644 --- a/frontend/src/views/admin/GroupsView.vue +++ b/frontend/src/views/admin/GroupsView.vue @@ -871,6 +871,10 @@ const closeCreateModal = () => { } const handleCreateGroup = async () => { + if (!createForm.name.trim()) { + appStore.showError(t('admin.groups.nameRequired')) + return + } submitting.value = true try { await adminAPI.groups.create(createForm) @@ -912,6 +916,10 @@ const closeEditModal = () => { const handleUpdateGroup = async () => { if (!editingGroup.value) return + if (!editForm.name.trim()) { + appStore.showError(t('admin.groups.nameRequired')) + return + } submitting.value = true try { diff --git a/frontend/src/views/admin/ProxiesView.vue b/frontend/src/views/admin/ProxiesView.vue index 9a41e950..47e4f15e 100644 --- a/frontend/src/views/admin/ProxiesView.vue +++ b/frontend/src/views/admin/ProxiesView.vue @@ -887,6 +887,18 @@ const handleBatchCreate = async () => { } const handleCreateProxy = async () => { + if (!createForm.name.trim()) { + appStore.showError(t('admin.proxies.nameRequired')) + return + } + if (!createForm.host.trim()) { + appStore.showError(t('admin.proxies.hostRequired')) + return + } + if (createForm.port < 1 || createForm.port > 65535) { + appStore.showError(t('admin.proxies.portInvalid')) + return + } submitting.value = true try { await adminAPI.proxies.create({ @@ -927,6 +939,18 @@ const closeEditModal = () => { const handleUpdateProxy = async () => { if (!editingProxy.value) return + if (!editForm.name.trim()) { + appStore.showError(t('admin.proxies.nameRequired')) + return + } + if (!editForm.host.trim()) { + appStore.showError(t('admin.proxies.hostRequired')) + return + } + if (editForm.port < 1 || editForm.port > 65535) { + appStore.showError(t('admin.proxies.portInvalid')) + return + } submitting.value = true try { diff --git a/frontend/src/views/user/RedeemView.vue b/frontend/src/views/user/RedeemView.vue index 78650aac..e87720d1 100644 --- a/frontend/src/views/user/RedeemView.vue +++ b/frontend/src/views/user/RedeemView.vue @@ -531,6 +531,7 @@ const fetchHistory = async () => { const handleRedeem = async () => { if (!redeemCode.value.trim()) { + appStore.showError(t('redeem.pleaseEnterCode')) return } From ee29b9428b4484a28fd27e4c7d1b627256b399e2 Mon Sep 17 00:00:00 2001 From: ianshaw Date: Sun, 4 Jan 2026 20:51:37 -0800 Subject: [PATCH 04/28] =?UTF-8?q?fix(frontend):=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E9=87=8D=E6=9E=84=E9=A1=B5=E9=9D=A2=E7=9A=84=E9=81=97=E6=BC=8F?= =?UTF-8?q?=E9=97=AE=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' From e67dbbdb8a6c05a3933209c61d6b39262866e476 Mon Sep 17 00:00:00 2001 From: ianshaw Date: Sun, 4 Jan 2026 21:10:52 -0800 Subject: [PATCH 05/28] =?UTF-8?q?fix(frontend):=20=E6=81=A2=E5=A4=8D=20Usa?= =?UTF-8?q?geTable=20=E7=BC=BA=E5=A4=B1=E7=9A=84=E5=88=97=E5=92=8C?= =?UTF-8?q?=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 恢复 API Key、账号、分组、类型、计费类型等列 - 恢复 Token 详情显示(含缓存读写) - 恢复首Token时间、耗时列 - 恢复请求ID列及复制功能 --- .../src/components/admin/usage/UsageTable.vue | 163 ++++++++++++++++-- 1 file changed, 147 insertions(+), 16 deletions(-) diff --git a/frontend/src/components/admin/usage/UsageTable.vue b/frontend/src/components/admin/usage/UsageTable.vue index 91e71e42..63694925 100644 --- a/frontend/src/components/admin/usage/UsageTable.vue +++ b/frontend/src/components/admin/usage/UsageTable.vue @@ -1,22 +1,153 @@
- - - - - - - - -
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
\ No newline at end of file + +const formatCacheTokens = (tokens: number): string => { + if (tokens >= 1000000) return `${(tokens / 1000000).toFixed(1)}M` + if (tokens >= 1000) return `${(tokens / 1000).toFixed(1)}K` + return tokens.toString() +} + +const formatDuration = (ms: number | null | undefined): string => { + if (ms == null) return '-' + if (ms < 1000) return `${ms}ms` + return `${(ms / 1000).toFixed(2)}s` +} + +const copyRequestId = async (requestId: string) => { + try { + await navigator.clipboard.writeText(requestId) + copiedRequestId.value = requestId + appStore.showSuccess(t('admin.usage.requestIdCopied')) + setTimeout(() => { copiedRequestId.value = null }, 2000) + } catch { + appStore.showError(t('common.copyFailed')) + } +} + From c52c47e1223d557fca1e0c6774b7c7198db8eb67 Mon Sep 17 00:00:00 2001 From: ianshaw Date: Sun, 4 Jan 2026 21:46:23 -0800 Subject: [PATCH 06/28] =?UTF-8?q?fix(frontend):=20=E4=BC=98=E5=8C=96?= =?UTF-8?q?=E8=B4=A6=E5=8F=B7=E7=AD=9B=E9=80=89=E5=B7=A5=E5=85=B7=E6=9D=A1?= =?UTF-8?q?=E5=B8=83=E5=B1=80=E5=B9=B6=E4=BF=AE=E5=A4=8DIP=E7=AE=A1?= =?UTF-8?q?=E7=90=86=E8=A1=A8=E5=A4=B4=E7=BF=BB=E8=AF=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 筛选组件保持固定宽度,不再自动拉伸填充 - 左右分布布局,中间自然留空 - 修复 IP 管理页面表头缺失的中文翻译 --- .../admin/account/AccountTableActions.vue | 8 +++--- .../admin/account/AccountTableFilters.vue | 25 ++++++++--------- frontend/src/i18n/locales/zh.ts | 5 ++++ frontend/src/views/admin/AccountsView.vue | 28 ++++++++----------- 4 files changed, 32 insertions(+), 34 deletions(-) diff --git a/frontend/src/components/admin/account/AccountTableActions.vue b/frontend/src/components/admin/account/AccountTableActions.vue index 035c9f83..ceb7fe9d 100644 --- a/frontend/src/components/admin/account/AccountTableActions.vue +++ b/frontend/src/components/admin/account/AccountTableActions.vue @@ -1,8 +1,8 @@ diff --git a/frontend/src/components/admin/account/AccountTableFilters.vue b/frontend/src/components/admin/account/AccountTableFilters.vue index dfa816f8..4bd6c40f 100644 --- a/frontend/src/components/admin/account/AccountTableFilters.vue +++ b/frontend/src/components/admin/account/AccountTableFilters.vue @@ -1,18 +1,15 @@ diff --git a/frontend/src/i18n/locales/zh.ts b/frontend/src/i18n/locales/zh.ts index f401d9a0..67ea6e5c 100644 --- a/frontend/src/i18n/locales/zh.ts +++ b/frontend/src/i18n/locales/zh.ts @@ -1625,6 +1625,11 @@ export default { deleteConfirmMessage: "确定要删除代理 '{name}' 吗?", testProxy: '测试代理', columns: { + name: '名称', + protocol: '协议', + address: '地址', + status: '状态', + actions: '操作', nameLabel: '名称', namePlaceholder: '请输入代理名称', protocolLabel: '协议', diff --git a/frontend/src/views/admin/AccountsView.vue b/frontend/src/views/admin/AccountsView.vue index 31468165..616a86d0 100644 --- a/frontend/src/views/admin/AccountsView.vue +++ b/frontend/src/views/admin/AccountsView.vue @@ -3,22 +3,18 @@