diff --git a/web/admin-spa/src/components/apikeys/LimitBadge.vue b/web/admin-spa/src/components/apikeys/LimitBadge.vue
new file mode 100644
index 00000000..afe28e1e
--- /dev/null
+++ b/web/admin-spa/src/components/apikeys/LimitBadge.vue
@@ -0,0 +1,94 @@
+
+
+
+
+ {{ label }}
+
+
+ ${{ current.toFixed(2) }}
+ /
+ ${{ limit.toFixed(2) }}
+
+
+
+
+
+
+
diff --git a/web/admin-spa/src/components/apikeys/LimitProgressBar.vue b/web/admin-spa/src/components/apikeys/LimitProgressBar.vue
new file mode 100644
index 00000000..7a3eb789
--- /dev/null
+++ b/web/admin-spa/src/components/apikeys/LimitProgressBar.vue
@@ -0,0 +1,213 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ label }}
+
+
+ ${{ current.toFixed(2) }}
+ / ${{ limit.toFixed(2) }}
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/web/admin-spa/src/components/apikeys/WindowLimitBar.vue b/web/admin-spa/src/components/apikeys/WindowLimitBar.vue
new file mode 100644
index 00000000..54c647c3
--- /dev/null
+++ b/web/admin-spa/src/components/apikeys/WindowLimitBar.vue
@@ -0,0 +1,241 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ rateLimitWindow }}分钟窗口
+
+
+
+ {{ remainingSeconds > 0 ? formatTime(remainingSeconds) : '未激活' }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 费用
+
+ ${{ currentCost.toFixed(1) }}/${{ costLimit.toFixed(0) }}
+
+
+
+
+
+
+
+
+
+
+
+ 请求
+
+ {{ currentRequests }}/{{ requestLimit }}
+
+
+
+
+
+
+
+
+
+
diff --git a/web/admin-spa/src/views/ApiKeysView.vue b/web/admin-spa/src/views/ApiKeysView.vue
index b3845b7f..14c33171 100644
--- a/web/admin-spa/src/views/ApiKeysView.vue
+++ b/web/admin-spa/src/views/ApiKeysView.vue
@@ -293,7 +293,7 @@
费用
@@ -308,7 +308,12 @@
|
+ 限制
+ |
+
Token
@@ -323,7 +328,7 @@
|
请求数
@@ -338,7 +343,7 @@
|
最后使用
@@ -353,7 +358,7 @@
|
创建时间
@@ -368,7 +373,7 @@
|
过期时间
@@ -383,7 +388,7 @@
|
操作
|
@@ -530,68 +535,63 @@
-
-
- ${{ getPeriodCost(key).toFixed(2) }}
-
-
+
+ ${{ getPeriodCost(key).toFixed(2) }}
+
+ |
+
+
+
-
-
- 每日费用
-
- ${{ (key.dailyCost || 0).toFixed(2) }} / ${{
- key.dailyCostLimit.toFixed(2)
- }}
-
-
-
-
+
-
-
- Opus周费用
-
- ${{ (key.weeklyOpusCost || 0).toFixed(2) }} / ${{
- key.weeklyOpusCostLimit.toFixed(2)
- }}
-
-
-
-
+
-
+
+
+
|
@@ -767,7 +767,7 @@
- |
+ |
-
-
-
- 每日费用限额
-
- ${{ (key.dailyCost || 0).toFixed(2) }} / ${{ key.dailyCostLimit.toFixed(2) }}
-
-
-
@@ -1760,7 +1770,8 @@ import BatchApiKeyModal from '@/components/apikeys/BatchApiKeyModal.vue'
import BatchEditApiKeyModal from '@/components/apikeys/BatchEditApiKeyModal.vue'
import ExpiryEditModal from '@/components/apikeys/ExpiryEditModal.vue'
import UsageDetailModal from '@/components/apikeys/UsageDetailModal.vue'
-import WindowCountdown from '@/components/apikeys/WindowCountdown.vue'
+import LimitProgressBar from '@/components/apikeys/LimitProgressBar.vue'
+import WindowLimitBar from '@/components/apikeys/WindowLimitBar.vue'
import CustomDropdown from '@/components/common/CustomDropdown.vue'
// 响应式数据
@@ -2058,7 +2069,7 @@ const loadAccounts = async () => {
accounts.value.openaiGroups = allGroups.filter((g) => g.platform === 'openai')
}
} catch (error) {
- console.error('加载账户列表失败:', error)
+ // console.error('加载账户列表失败:', error)
}
}
@@ -3104,9 +3115,9 @@ const clearAllDeletedApiKeys = async () => {
// 如果有失败的,显示详细信息
if (data.details && data.details.failedCount > 0) {
- const errors = data.details.errors
- console.error('部分API Keys清空失败:', errors)
- showToast(`${data.details.failedCount} 个清空失败,请查看控制台`, 'warning')
+ // const errors = data.details.errors
+ // console.error('部分API Keys清空失败:', errors)
+ showToast(`${data.details.failedCount} 个清空失败`, 'warning')
}
// 刷新已删除列表
@@ -3169,7 +3180,7 @@ const batchDeleteApiKeys = async () => {
}
} catch (error) {
showToast('批量删除失败', 'error')
- console.error('批量删除 API Keys 失败:', error)
+ // console.error('批量删除 API Keys 失败:', error)
}
}
@@ -3276,35 +3287,35 @@ const formatDate = (dateString) => {
.replace(/\//g, '-')
}
-// 获取每日费用进度
-const getDailyCostProgress = (key) => {
- if (!key.dailyCostLimit || key.dailyCostLimit === 0) return 0
- const percentage = ((key.dailyCost || 0) / key.dailyCostLimit) * 100
- return Math.min(percentage, 100)
-}
+// 获取每日费用进度 - 已移到 LimitProgressBar 组件中
+// const getDailyCostProgress = (key) => {
+// if (!key.dailyCostLimit || key.dailyCostLimit === 0) return 0
+// const percentage = ((key.dailyCost || 0) / key.dailyCostLimit) * 100
+// return Math.min(percentage, 100)
+// }
-// 获取每日费用进度条颜色
-const getDailyCostProgressColor = (key) => {
- const progress = getDailyCostProgress(key)
- if (progress >= 100) return 'bg-red-500'
- if (progress >= 80) return 'bg-yellow-500'
- return 'bg-green-500'
-}
+// 获取每日费用进度条颜色 - 已移到 LimitProgressBar 组件中
+// const getDailyCostProgressColor = (key) => {
+// const progress = getDailyCostProgress(key)
+// if (progress >= 100) return 'bg-red-500'
+// if (progress >= 80) return 'bg-yellow-500'
+// return 'bg-green-500'
+// }
-// 获取 Opus 周费用进度
-const getWeeklyOpusCostProgress = (key) => {
- if (!key.weeklyOpusCostLimit || key.weeklyOpusCostLimit === 0) return 0
- const percentage = ((key.weeklyOpusCost || 0) / key.weeklyOpusCostLimit) * 100
- return Math.min(percentage, 100)
-}
+// 获取 Opus 周费用进度 - 已移到 LimitBadge 组件中
+// const getWeeklyOpusCostProgress = (key) => {
+// if (!key.weeklyOpusCostLimit || key.weeklyOpusCostLimit === 0) return 0
+// const percentage = ((key.weeklyOpusCost || 0) / key.weeklyOpusCostLimit) * 100
+// return Math.min(percentage, 100)
+// }
-// 获取 Opus 周费用进度条颜色
-const getWeeklyOpusCostProgressColor = (key) => {
- const progress = getWeeklyOpusCostProgress(key)
- if (progress >= 100) return 'bg-red-500'
- if (progress >= 80) return 'bg-yellow-500'
- return 'bg-green-500'
-}
+// 获取 Opus 周费用进度条颜色 - 已移到 LimitBadge 组件中
+// const getWeeklyOpusCostProgressColor = (key) => {
+// const progress = getWeeklyOpusCostProgress(key)
+// if (progress >= 100) return 'bg-red-500'
+// if (progress >= 80) return 'bg-yellow-500'
+// return 'bg-green-500'
+// }
// 获取总费用进度 - 暂时不用
// const getTotalCostProgress = (key) => {
@@ -3319,6 +3330,23 @@ const showUsageDetails = (apiKey) => {
showUsageDetailModal.value = true
}
+// 格式化时间(秒转换为可读格式) - 已移到 WindowLimitBar 组件中
+// const formatTime = (seconds) => {
+// if (seconds === null || seconds === undefined) return '--:--'
+//
+// const hours = Math.floor(seconds / 3600)
+// const minutes = Math.floor((seconds % 3600) / 60)
+// const secs = seconds % 60
+//
+// if (hours > 0) {
+// return `${hours}h ${minutes}m`
+// } else if (minutes > 0) {
+// return `${minutes}m ${secs}s`
+// } else {
+// return `${secs}s`
+// }
+// }
+
// 格式化最后使用时间
const formatLastUsed = (dateString) => {
if (!dateString) return '从未使用'
@@ -3531,7 +3559,7 @@ const exportToExcel = () => {
showToast(`成功导出 ${exportData.length} 条API Key用量数据`, 'success')
} catch (error) {
- console.error('导出失败:', error)
+ // console.error('导出失败:', error)
showToast('导出失败,请重试', 'error')
}
}
|