1
0

feat: 完成前端重构,采用 Ant Design 5 和完整测试体系

- 采用 Ant Design 5 作为 UI 组件库,替换自定义组件
- 集成 React Router v7 提供路由导航
- 使用 TanStack Query v5 管理数据获取和缓存
- 建立 Vitest + React Testing Library 测试体系
- 添加 Playwright E2E 测试覆盖
- 使用 MSW mock API 响应
- 配置 TypeScript strict 模式
- 采用 SCSS Modules 组织样式
- 更新 OpenSpec 规格以反映前端架构变更
- 归档 frontend-refactor 变更记录
This commit is contained in:
2026-04-16 11:21:48 +08:00
parent c17903dcbc
commit 9359ca7f62
61 changed files with 4588 additions and 1095 deletions

View File

@@ -0,0 +1,76 @@
import { Button, Table, Tag, Popconfirm, Space } from 'antd';
import type { ColumnsType } from 'antd/es/table';
import type { Model } from '@/types';
import { useModels, useDeleteModel } from '@/hooks/useModels';
interface ModelTableProps {
providerId: string;
onAdd?: () => void;
onEdit?: (model: Model) => void;
}
export function ModelTable({ providerId, onAdd, onEdit }: ModelTableProps) {
const { data: models = [], isLoading } = useModels(providerId);
const deleteModel = useDeleteModel();
const columns: ColumnsType<Model> = [
{
title: '模型名称',
dataIndex: 'modelName',
key: 'modelName',
},
{
title: '状态',
dataIndex: 'enabled',
key: 'enabled',
render: (enabled: boolean) =>
enabled ? <Tag color="green"></Tag> : <Tag color="red"></Tag>,
width: 80,
},
{
title: '操作',
key: 'action',
width: 120,
render: (_, record) => (
<Space>
{onEdit && (
<Button type="link" size="small" onClick={() => onEdit(record)}>
</Button>
)}
<Popconfirm
title="确定要删除这个模型吗?"
onConfirm={() => deleteModel.mutate(record.id)}
okText="确定"
cancelText="取消"
>
<Button type="link" danger size="small">
</Button>
</Popconfirm>
</Space>
),
},
];
return (
<div style={{ padding: '8px 16px' }}>
<div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: 8 }}>
<span style={{ fontWeight: 500 }}> ({models.length})</span>
{onAdd && (
<Button type="link" size="small" onClick={onAdd}>
</Button>
)}
</div>
<Table<Model>
columns={columns}
dataSource={models}
rowKey="id"
loading={isLoading}
pagination={false}
size="small"
/>
</div>
);
}