fix(frontend): 合并 OAuth 状态展示并移除 Codex 积分信息

- providerKeyStatus: 合并 snapshot 与 legacy OAuth 状态,按严重程度取优并补全失效原因
- ProviderDetailDrawer: 移除 Codex 积分摘要与相关字段显示
This commit is contained in:
fawney19
2026-04-20 14:26:05 +08:00
parent b2ff7d2c28
commit 9b48a008dc
3 changed files with 65 additions and 39 deletions

View File

@@ -62,6 +62,37 @@ describe('providerKeyStatus', () => {
})
})
it('prefers legacy oauth invalidation over a stale valid snapshot', () => {
const future = Math.floor(Date.now() / 1000) + 2 * 24 * 3600
const status = getOAuthStatusDisplay(
{
auth_type: 'oauth',
oauth_expires_at: future,
oauth_invalid_reason: '[REFRESH_FAILED] Token 续期失败 (401): refresh_token_reused',
status_snapshot: {
oauth: {
code: 'valid',
expires_at: future,
},
account: {
code: 'ok',
blocked: false,
},
quota: { code: 'ok', exhausted: false },
},
},
0,
)
expect(status).toEqual({
text: '已失效',
isExpired: false,
isExpiringSoon: false,
isInvalid: true,
invalidReason: '[REFRESH_FAILED] Token 续期失败 (401): refresh_token_reused',
})
})
it('falls back to countdown for account block without oauth invalidation', () => {
const status = getOAuthStatusDisplay(
{

View File

@@ -127,11 +127,44 @@ function getLegacyOAuthState(
)
}
function getOAuthStatusSeverity(status: OAuthStatusInfo | null): number {
if (!status) return 0
if (status.isInvalid) return 3
if (status.isExpired) return 2
return 1
}
function mergeOAuthStatusDisplay(
snapshotStatus: OAuthStatusInfo | null,
legacyStatus: OAuthStatusInfo | null,
): OAuthStatusInfo | null {
if (getOAuthStatusSeverity(legacyStatus) > getOAuthStatusSeverity(snapshotStatus)) {
return legacyStatus
}
if (
snapshotStatus?.isInvalid
&& !snapshotStatus.invalidReason
&& legacyStatus?.isInvalid
&& legacyStatus.invalidReason
) {
return {
...snapshotStatus,
invalidReason: legacyStatus.invalidReason,
}
}
return snapshotStatus ?? legacyStatus
}
export function getOAuthStatusDisplay(
input: ProviderKeyStatusCarrier,
tick: number,
): OAuthStatusInfo | null {
return getSnapshotOAuthState(input, tick) ?? getLegacyOAuthState(input, tick)
return mergeOAuthStatusDisplay(
getSnapshotOAuthState(input, tick),
getLegacyOAuthState(input, tick),
)
}
export function getOAuthStatusTitle(