修复开发者密钥时间显示
复用个人中心时间解析逻辑格式化秒级小数时间戳 统一展示密钥创建时间和最近使用时间 补充弹窗回归测试与接入文档约束
This commit is contained in:
@@ -123,7 +123,7 @@ POST /api/profile/api-keys
|
||||
DELETE /api/profile/api-keys/{keyId}
|
||||
```
|
||||
|
||||
前端入口位于登录后个人中心的 `我的 → 开发者 API Key`,用于查看当前 Key、创建新 Key、复制一次性明文和撤销已创建 Key。外部 OpenAPI 只描述 `/api/external/v1` 下可由 API Key 调用的接口,不混入登录态 API Key 管理接口。
|
||||
前端入口位于登录后个人中心的 `我的 → 开发者 API Key`,用于查看当前 Key、创建新 Key、复制一次性明文和撤销已创建 Key。Key 卡片中的创建时间和最近使用时间必须格式化为 `YYYY-MM-DD`,不得直接展示后端时间戳。外部 OpenAPI 只描述 `/api/external/v1` 下可由 API Key 调用的接口,不混入登录态 API Key 管理接口。
|
||||
|
||||
## 版本与兼容策略
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ import { PlatformStatusMessage } from '../common/PlatformStatusMessage';
|
||||
import { PlatformTextField } from '../common/PlatformTextField';
|
||||
import { useCopyFeedback } from '../common/useCopyFeedback';
|
||||
import { PlatformProfileSecondaryModalShell } from './PlatformProfileModalShell';
|
||||
import { formatPlatformProfileTime } from './platformProfileFundsModel';
|
||||
|
||||
type PlatformProfileApiKeysModalProps = {
|
||||
onClose: () => void;
|
||||
@@ -34,14 +35,7 @@ function buildApiKeyTimeLabel(value: string | null) {
|
||||
if (!value) {
|
||||
return '尚未使用';
|
||||
}
|
||||
const date = new Date(value);
|
||||
if (Number.isNaN(date.getTime())) {
|
||||
return value;
|
||||
}
|
||||
const year = date.getUTCFullYear();
|
||||
const month = String(date.getUTCMonth() + 1).padStart(2, '0');
|
||||
const day = String(date.getUTCDate()).padStart(2, '0');
|
||||
return `${year}-${month}-${day}`;
|
||||
return formatPlatformProfileTime(value);
|
||||
}
|
||||
|
||||
function buildApiKeyScopeLabel(scopes: string[]) {
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
/* @vitest-environment jsdom */
|
||||
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import { createElement } from 'react';
|
||||
import { beforeEach, describe, expect, test, vi } from 'vitest';
|
||||
|
||||
import { PlatformProfileApiKeysModal } from './PlatformProfileApiKeysModal';
|
||||
|
||||
const listExternalApiKeysMock = vi.hoisted(() => vi.fn());
|
||||
|
||||
vi.mock('../../services/platform-entry/platformProfileClient', () => ({
|
||||
createPlatformProfileExternalApiKey: vi.fn(),
|
||||
listPlatformProfileExternalApiKeys: listExternalApiKeysMock,
|
||||
revokePlatformProfileExternalApiKey: vi.fn(),
|
||||
}));
|
||||
|
||||
describe('PlatformProfileApiKeysModal', () => {
|
||||
beforeEach(() => {
|
||||
listExternalApiKeysMock.mockReset();
|
||||
});
|
||||
|
||||
test('将 API Key 时间戳格式化为日期', async () => {
|
||||
listExternalApiKeysMock.mockResolvedValueOnce({
|
||||
keys: [
|
||||
{
|
||||
keyId: 'api-key-1',
|
||||
name: '外部 API Key',
|
||||
keyPrefix: 'tnr_sk_example',
|
||||
scopes: ['editor:project'],
|
||||
createdAt: '1785913407.182731Z',
|
||||
lastUsedAt: null,
|
||||
revokedAt: null,
|
||||
updatedAt: '1785913407.182731Z',
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
render(createElement(PlatformProfileApiKeysModal, { onClose: vi.fn() }));
|
||||
|
||||
expect(
|
||||
await screen.findByText('创建 2026-08-05 · 最近使用 尚未使用'),
|
||||
).toBeTruthy();
|
||||
expect(screen.queryByText(/1785913407\.182731Z/u)).toBeNull();
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user