feat(openai): 显示订阅到期时间

从 /backend-api/accounts/check 的 entitlement.expires_at 提取订阅
到期日期,每次 token 刷新时更新并存入 credentials,前端账号列表
的订阅类型和隐私下方以灰色小字显示(仅非 Free 账号)。

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
QTom
2026-04-02 20:44:28 +08:00
parent cf70fb1b4e
commit 00947d6492
6 changed files with 100 additions and 51 deletions

View File

@@ -45,6 +45,10 @@
<span>{{ privacyBadge.label }}</span>
</span>
</div>
<!-- Row 3: Subscription expiration (non-free paid accounts only) -->
<div v-if="expiresLabel" class="text-[10px] leading-tight text-gray-400 dark:text-gray-500 pl-0.5" :title="subscriptionExpiresAt">
{{ expiresLabel }}
</div>
</div>
</template>
@@ -62,6 +66,7 @@ interface Props {
type: AccountType
planType?: string
privacyMode?: string
subscriptionExpiresAt?: string
}
const props = defineProps<Props>()
@@ -148,6 +153,22 @@ const planBadgeClass = computed(() => {
return typeClass.value
})
// Subscription expiration label (non-free only)
const expiresLabel = computed(() => {
if (!props.subscriptionExpiresAt || !props.planType) return ''
if (props.planType.toLowerCase() === 'free') return ''
try {
const d = new Date(props.subscriptionExpiresAt)
if (isNaN(d.getTime())) return ''
const yyyy = d.getFullYear()
const mm = String(d.getMonth() + 1).padStart(2, '0')
const dd = String(d.getDate()).padStart(2, '0')
return `${t('admin.accounts.subscriptionExpires')} ${yyyy}-${mm}-${dd}`
} catch {
return ''
}
})
// Privacy badge — shows different states for OpenAI/Antigravity OAuth privacy setting
const privacyBadge = computed(() => {
if (props.type !== 'oauth' || !props.privacyMode) return null

View File

@@ -1988,6 +1988,7 @@ export default {
privacyAntigravityFailed: 'Privacy setting failed',
setPrivacy: 'Set Privacy',
subscriptionAbnormal: 'Abnormal',
subscriptionExpires: 'Expires',
// Capacity status tooltips
capacity: {
windowCost: {

View File

@@ -2026,6 +2026,7 @@ export default {
privacyAntigravityFailed: '隐私设置失败',
setPrivacy: '设置隐私',
subscriptionAbnormal: '异常',
subscriptionExpires: '到期',
// 容量状态提示
capacity: {
windowCost: {

View File

@@ -182,7 +182,7 @@
</template>
<template #cell-platform_type="{ row }">
<div class="flex flex-wrap items-center gap-1">
<PlatformTypeBadge :platform="row.platform" :type="row.type" :plan-type="row.credentials?.plan_type" :privacy-mode="row.extra?.privacy_mode" />
<PlatformTypeBadge :platform="row.platform" :type="row.type" :plan-type="row.credentials?.plan_type" :privacy-mode="row.extra?.privacy_mode" :subscription-expires-at="row.credentials?.subscription_expires_at" />
<span
v-if="getAntigravityTierLabel(row)"
:class="['inline-block rounded px-1.5 py-0.5 text-[10px] font-medium', getAntigravityTierClass(row)]"