mirror of
https://github.com/Wei-Shaw/sub2api.git
synced 2026-09-24 16:05:44 +08:00
feat(frontend): move API Key quota bars from capacity to usage window column
Move daily/weekly/total quota progress bars for API Key accounts from the capacity column (QuotaBadge) to the usage window column (UsageProgressBar), providing a consistent visual experience with other usage displays.
This commit is contained in:
@@ -1 +1 @@
|
||||
0.1.93.23
|
||||
0.1.93.24
|
||||
|
||||
@@ -30,11 +30,6 @@
|
||||
|
||||
<!-- 客户端亲和 -->
|
||||
<AffinityBadge v-if="showAffinity" :account-id="account.id" :count="affinityClientCount" :base="affinityBase" :buffer="affinityBuffer" />
|
||||
|
||||
<!-- 配额限制 -->
|
||||
<QuotaBadge v-if="showDailyQuota" label="D" :used="account.quota_daily_used ?? 0" :limit="account.quota_daily_limit!" />
|
||||
<QuotaBadge v-if="showWeeklyQuota" label="W" :used="account.quota_weekly_used ?? 0" :limit="account.quota_weekly_limit!" />
|
||||
<QuotaBadge v-if="showTotalQuota" :used="account.quota_used ?? 0" :limit="account.quota_limit!" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -44,7 +39,6 @@ import { useI18n } from 'vue-i18n'
|
||||
import type { Account } from '@/types'
|
||||
import CapacityBadge from '@/components/account/CapacityBadge.vue'
|
||||
import AffinityBadge from '@/components/account/AffinityBadge.vue'
|
||||
import QuotaBadge from '@/components/account/QuotaBadge.vue'
|
||||
|
||||
const props = defineProps<{
|
||||
account: Account
|
||||
@@ -197,17 +191,6 @@ const affinityBuffer = computed((): number | null => {
|
||||
return null
|
||||
})
|
||||
|
||||
// ====== 配额 ======
|
||||
const showDailyQuota = computed(() =>
|
||||
props.account.type === 'apikey' && props.account.quota_daily_limit != null && props.account.quota_daily_limit > 0
|
||||
)
|
||||
const showWeeklyQuota = computed(() =>
|
||||
props.account.type === 'apikey' && props.account.quota_weekly_limit != null && props.account.quota_weekly_limit > 0
|
||||
)
|
||||
const showTotalQuota = computed(() =>
|
||||
props.account.type === 'apikey' && props.account.quota_limit != null && props.account.quota_limit > 0
|
||||
)
|
||||
|
||||
const formatCost = (value: number | null | undefined) => {
|
||||
if (value === null || value === undefined) return '0'
|
||||
return value.toFixed(2)
|
||||
|
||||
@@ -334,6 +334,32 @@
|
||||
<div v-else>
|
||||
<!-- Gemini API Key accounts: show quota info -->
|
||||
<AccountQuotaInfo v-if="account.platform === 'gemini'" :account="account" />
|
||||
<!-- API Key accounts with quota limits: show progress bars -->
|
||||
<div v-else-if="hasApiKeyQuota" class="space-y-1">
|
||||
<UsageProgressBar
|
||||
v-if="quotaDailyBar"
|
||||
label="1d"
|
||||
:utilization="quotaDailyBar.utilization"
|
||||
:resets-at="quotaDailyBar.resetsAt"
|
||||
:display-value="quotaDailyBar.displayValue"
|
||||
color="indigo"
|
||||
/>
|
||||
<UsageProgressBar
|
||||
v-if="quotaWeeklyBar"
|
||||
label="7d"
|
||||
:utilization="quotaWeeklyBar.utilization"
|
||||
:resets-at="quotaWeeklyBar.resetsAt"
|
||||
:display-value="quotaWeeklyBar.displayValue"
|
||||
color="emerald"
|
||||
/>
|
||||
<UsageProgressBar
|
||||
v-if="quotaTotalBar"
|
||||
label="$"
|
||||
:utilization="quotaTotalBar.utilization"
|
||||
:display-value="quotaTotalBar.displayValue"
|
||||
color="purple"
|
||||
/>
|
||||
</div>
|
||||
<div v-else class="text-xs text-gray-400">-</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -822,6 +848,63 @@ const loadUsage = async () => {
|
||||
}
|
||||
}
|
||||
|
||||
// ===== API Key quota progress bars =====
|
||||
|
||||
interface QuotaBarInfo {
|
||||
utilization: number
|
||||
displayValue: string
|
||||
resetsAt: string | null
|
||||
}
|
||||
|
||||
const fmtCost = (v: number) => v.toFixed(2)
|
||||
|
||||
const makeQuotaBar = (
|
||||
used: number,
|
||||
limit: number,
|
||||
startKey?: string
|
||||
): QuotaBarInfo => {
|
||||
const utilization = limit > 0 ? (used / limit) * 100 : 0
|
||||
const displayValue = `${fmtCost(used)}/${fmtCost(limit)}`
|
||||
let resetsAt: string | null = null
|
||||
if (startKey) {
|
||||
const extra = props.account.extra as Record<string, unknown> | undefined
|
||||
const startStr = extra?.[startKey] as string | undefined
|
||||
if (startStr) {
|
||||
const startDate = new Date(startStr)
|
||||
const periodMs = startKey.includes('daily') ? 24 * 60 * 60 * 1000 : 7 * 24 * 60 * 60 * 1000
|
||||
resetsAt = new Date(startDate.getTime() + periodMs).toISOString()
|
||||
}
|
||||
}
|
||||
return { utilization, displayValue, resetsAt }
|
||||
}
|
||||
|
||||
const hasApiKeyQuota = computed(() => {
|
||||
if (props.account.type !== 'apikey') return false
|
||||
return (
|
||||
(props.account.quota_daily_limit ?? 0) > 0 ||
|
||||
(props.account.quota_weekly_limit ?? 0) > 0 ||
|
||||
(props.account.quota_limit ?? 0) > 0
|
||||
)
|
||||
})
|
||||
|
||||
const quotaDailyBar = computed((): QuotaBarInfo | null => {
|
||||
const limit = props.account.quota_daily_limit ?? 0
|
||||
if (limit <= 0) return null
|
||||
return makeQuotaBar(props.account.quota_daily_used ?? 0, limit, 'quota_daily_start')
|
||||
})
|
||||
|
||||
const quotaWeeklyBar = computed((): QuotaBarInfo | null => {
|
||||
const limit = props.account.quota_weekly_limit ?? 0
|
||||
if (limit <= 0) return null
|
||||
return makeQuotaBar(props.account.quota_weekly_used ?? 0, limit, 'quota_weekly_start')
|
||||
})
|
||||
|
||||
const quotaTotalBar = computed((): QuotaBarInfo | null => {
|
||||
const limit = props.account.quota_limit ?? 0
|
||||
if (limit <= 0) return null
|
||||
return makeQuotaBar(props.account.quota_used ?? 0, limit)
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
loadUsage()
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user