feat(provider-ops): 新增 Sub2API 架构支持并优化余额分项显示

- 新增 Sub2ApiArchitecture 和 Sub2ApiBalanceAction,支持 Sub2API 风格中转站
- 前端 provider 列表支持 balance + points 分项显示
- 验证弹窗适配 Sub2API 余额和积分的分开展示
This commit is contained in:
fawney19
2026-02-13 21:03:21 +08:00
parent d6b39babf5
commit 941e599d36
7 changed files with 280 additions and 5 deletions

View File

@@ -493,7 +493,12 @@ async function handleVerify() {
verifyStatus.value = 'success'
formChanged.value = false
const displayName = result.data?.display_name || result.data?.username
showSuccess(`用户: ${displayName} | 余额: ${formatQuota(quota)}`, '验证成功')
const extra = result.data?.extra
let balanceText = `余额: ${formatQuota(quota)}`
if (extra && extra.balance !== undefined && extra.points !== undefined) {
balanceText = `余额: ${formatQuota(extra.balance)} | 积分: ${formatQuota(extra.points)}`
}
showSuccess(`用户: ${displayName} | ${balanceText}`, '验证成功')
}
} else {
verifyStatus.value = 'error'

View File

@@ -216,10 +216,26 @@
v-else-if="provider.ops_configured && getProviderBalance(provider.id)"
class="flex items-center gap-2 text-xs"
>
<!-- 余额文字 -->
<span class="font-semibold text-foreground/90 min-w-[4.5rem] tabular-nums">
{{ formatBalanceDisplay(getProviderBalance(provider.id)) }}
</span>
<!-- 余额文字balance + points 分开显示或普通余额 -->
<template v-for="bd in [getProviderBalanceBreakdown(provider.id)]" :key="'bd'">
<div
v-if="bd"
class="min-w-[4.5rem] tabular-nums leading-tight"
>
<div class="font-semibold text-foreground/90">
${{ bd.balance.toFixed(2) }}
</div>
<div class="text-muted-foreground/70 text-[10px]">
${{ bd.points.toFixed(2) }}
</div>
</div>
<span
v-else
class="font-semibold text-foreground/90 min-w-[4.5rem] tabular-nums"
>
{{ formatBalanceDisplay(getProviderBalance(provider.id)) }}
</span>
</template>
<!-- 窗口限额 + 签到状态 + Cookie 失效警告 -->
<div
v-if="getProviderBalanceExtra(provider.id, provider.ops_architecture_id).length > 0 || getProviderCheckin(provider.id) || getProviderCookieExpired(provider.id)"
@@ -1016,6 +1032,24 @@ function getProviderBalance(providerId: string): { available: number | null; cur
}
}
// 获取 provider 余额明细balance + points 分开显示)
function getProviderBalanceBreakdown(providerId: string): { balance: number; points: number; currency: string } | null {
const result = balanceCache.value[providerId]
if (!result || (result.status !== 'success' && result.status !== 'auth_expired') || !result.data) {
return null
}
const data = result.data as Record<string, any>
const extra = data.extra
if (!extra || extra.balance === undefined || extra.points === undefined) {
return null
}
return {
balance: extra.balance,
points: extra.points,
currency: data.currency || 'USD',
}
}
// 获取 provider 余额查询的错误状态
function getProviderBalanceError(providerId: string): { status: string; message: string } | null {
const result = balanceCache.value[providerId]