feat:Rock刷新去UID拦截,新增绑定错误自动刷新与使用/绑定超时预警

This commit is contained in:
2026-11-08 18:03:48 +08:00
parent 1dba8e4c2e
commit 51dcb9de5a
22 changed files with 768 additions and 182 deletions
@@ -18,15 +18,20 @@ const { Text } = Typography
const MS_PER_DAY = 24 * 60 * 60 * 1000
// 满 72 小时算 1 天:超时预警按实际时长计算,不按自然日跨天。
function usingElapsedDays(usingAt?: string): number | null {
if (!usingAt) return null
const startedAt = new Date(usingAt).getTime()
// 满 24 小时算 1 天:超时预警按实际时长计算,不按自然日跨天。
function elapsedDaysSince(value?: string): number | null {
if (!value) return null
const startedAt = new Date(value).getTime()
if (Number.isNaN(startedAt)) return null
const diff = Date.now() - startedAt
return diff > 0 ? diff / MS_PER_DAY : 0
}
// 使用中超时起点:using_at。
function usingElapsedDays(usingAt?: string): number | null {
return elapsedDaysSince(usingAt)
}
// Token 主信息:编号/兑换码 与 包ID/提取码 上下两行展示,
// 两个复制按钮各自只复制兑换码 / 提取码,编号与包 ID 不参与复制。
export function TokenInfoCell({ record }: { record: RockTokenItem }) {
@@ -73,6 +78,7 @@ export interface TokenColumnHandlers {
copyingVoucherId: number | null
usingWarnDays: number
usingDangerDays: number
boundWarnDays: number
refreshingTokenId: number | null
onRefreshBinding: (id: number) => void
openingUpstreamId: number | null
@@ -91,6 +97,7 @@ export function buildTokenColumns({
copyingVoucherId,
usingWarnDays,
usingDangerDays,
boundWarnDays,
refreshingTokenId,
onRefreshBinding,
openingUpstreamId,
@@ -166,12 +173,24 @@ export function buildTokenColumns({
</Tag>
)
}
case 'bound':
case 'bound': {
const boundDays = elapsedDaysSince(record.bound_at)
if (boundDays !== null && boundDays >= boundWarnDays) {
return (
<Tag
color="volcano"
style={{ fontWeight: 600, padding: '2px 8px', border: '1px solid #ff7a45' }}
>
⏱ 绑定超时 {boundDays.toFixed(1)} 天
</Tag>
)
}
return (
<Tag color="cyan" style={{ fontWeight: 600, padding: '2px 8px' }}>
● 已授权绑定
</Tag>
)
}
case 'redeemed':
return (
<Tag color="purple" style={{ fontWeight: 600, padding: '2px 8px' }}>
@@ -209,6 +228,7 @@ export function buildTokenColumns({
width: 180,
render: (_, record) => {
const usingDays = record.status === 'using' ? usingElapsedDays(record.using_at) : null
const boundDays = record.status === 'bound' ? elapsedDaysSince(record.bound_at) : null
const usingColor =
usingDays === null
? '#64748b'
@@ -243,9 +263,10 @@ export function buildTokenColumns({
</div>
)}
{!record.redeemed_at && record.bound_at && (
<div style={{ fontSize: 11, color: '#0284c7' }}>
<div style={{ fontSize: 11, color: boundDays !== null && boundDays >= boundWarnDays ? '#ea580c' : '#0284c7' }}>
<span>🔗 绑定: </span>
{formatDateTime(record.bound_at)}
{boundDays !== null ? `(${boundDays.toFixed(1)} 天)` : ''}
</div>
)}
{!record.bound_at && !record.mismatch_at && record.claimed_at && (