1
0
Files
nex/frontend/openspec/changes/archive/2026-04-17-migrate-to-tdesign/design.md
lanyuanxiaoyao 2b1c5e96c3 refactor: 迁移 UI 组件库从 Ant Design 至 TDesign
- 替换 antd 为 tdesign-react 作为主要 UI 组件库
- 引入 Recharts 替代 @ant-design/charts 实现图表功能
- 移除主题系统相关代码(ThemeContext、themes 目录)
- 更新所有组件以适配 TDesign 组件 API
- 更新测试用例以匹配新的组件实现
- 新增 TDesign 和 Recharts 集成规范文档
2026-04-17 18:22:13 +08:00

10 KiB
Raw Blame History

Context

当前状态

  • 前端使用Ant Design 6.3.5作为UI框架
  • 实现了6套自定义主题系统default、dark、mui、shadcn、bootstrap、glass
  • 使用@ant-design/charts进行数据可视化
  • 使用antd-style进行动态样式管理
  • 完整的供应商管理和统计功能

约束条件

  • 必须保持所有业务功能不变
  • 图表功能必须保留
  • Settings页面路由必须保留即使暂时为空
  • 使用bun作为唯一包管理器
  • 遵循项目现有代码规范(中文注释、测试覆盖)

利益相关者

  • 前端开发团队:维护成本降低
  • 产品用户UI风格变化功能保持不变

Goals / Non-Goals

Goals:

  • 完全迁移到TDesign React组件库统一设计系统
  • 移除复杂的多主题系统,简化代码架构
  • 使用Recharts替代@ant-design/charts实现数据可视化
  • 保持所有业务功能完整可用
  • 确保测试覆盖率不降低
  • 优化bundle体积移除未使用的主题系统

Non-Goals:

  • 不实现新的业务功能
  • 不保留Ant Design相关代码或依赖
  • 不实现侧边栏折叠功能(接受简化)
  • 不实现主题切换功能使用TDesign默认主题
  • 不优化后端API或数据结构

Decisions

1. 图表库选择Recharts

决策使用Recharts替代@ant-design/charts

理由

  • React原生JSX语法与TDesign风格一致
  • TypeScript支持优秀类型定义完整
  • 文档清晰社区活跃1.8M周下载量)
  • Bundle体积适中~370KB vs ECharts ~1MB
  • shadcn/ui生态默认选择现代化设计
  • 声明式组件,易于维护和测试

替代方案

  • ECharts功能强大但体积大1MB需要wrapper非React原生
  • Chart.js最流行但非React原生需要react-chartjs-2 wrapper
  • Visx:最灵活但学习曲线陡峭,适合高度定制场景

实现

// UsageChart.tsx
import { LineChart, Line, XAxis, YAxis, CartesianGrid, ResponsiveContainer, Tooltip } from 'recharts';

<ResponsiveContainer width="100%" height={300}>
  <LineChart data={chartData}>
    <CartesianGrid strokeDasharray="3 3" />
    <XAxis dataKey="date" />
    <YAxis />
    <Tooltip />
    <Line type="monotone" dataKey="requestCount" stroke="#0052D9" strokeWidth={2} />
  </LineChart>
</ResponsiveContainer>

2. 主题系统:完全移除

决策删除所有主题相关代码使用TDesign默认主题

理由

  • 多主题系统增加维护成本和代码复杂度
  • TDesign默认主题已满足企业级应用需求
  • 简化迁移过程,降低风险
  • 减少bundle体积移除antd-style和主题配置

实现

  • 删除src/contexts/ThemeContext.tsx
  • 删除src/themes/整个目录
  • App.tsx移除ThemeProvider直接使用TDesign ConfigProvider
  • Settings页面简化为空页面

3. 布局组件:简化侧边栏

决策:移除侧边栏折叠功能,使用固定宽度侧边栏

理由

  • TDesign Menu组件没有内置折叠功能
  • 自定义实现增加复杂度和维护成本
  • 固定宽度侧边栏满足当前业务需求
  • 简化迁移过程,降低风险

实现

// AppLayout.tsx
<Layout.Aside width="232px">
  <div style={{ height: 64 }}>AI Gateway</div>
  <Menu value={location.pathname} items={menuItems} onChange={({ value }) => navigate(value)} />
</Layout.Aside>

4. 图标系统TDesign Icons

决策使用tdesign-icons-react图标库

理由

  • 与TDesign组件库配套风格一致
  • 支持按需导入优化bundle体积
  • 提供完整的图标集合

映射方案

// Ant Design → TDesign
CloudServerOutlined  CloudServerIcon (ServerIcon)
BarChartOutlined     ChartLineIcon (ChartIcon)
SettingOutlined      SettingIcon

注意具体图标名称需要在安装tdesign-icons-react后确认根据实际可用图标选择最接近的。

5. 栅格系统:保持不变

决策继续使用Row/Col栅格系统

理由

  • TDesign提供完整的Row/Col组件
  • API与Ant Design完全兼容
  • 无需修改现有栅格代码
  • 保持响应式布局能力

实现直接替换import路径即可

// import { Row, Col } from 'antd';
import { Row, Col } from 'tdesign-react';

6. 表单组件Dialog替代Modal

决策使用TDesign Dialog组件替代Ant Design Modal

理由

  • Dialog是TDesign的标准弹窗组件
  • API相似迁移成本低
  • 支持所有必要功能(确认、取消、加载状态)

API映射

// Ant Design Modal → TDesign Dialog
title        header
open         visible
onOk         onConfirm
onCancel     onClose (注意:语义略有不同)
okText       confirmBtn
cancelText   cancelBtn
destroyOnHidden  destroyOnClose
Form.Item    Form.FormItem

7. 迁移策略:渐进式文件替换

决策:按模块逐个替换,保持项目可运行

理由

  • 降低风险,便于调试
  • 可以逐步验证每个模块的功能
  • 出现问题容易定位和回滚

顺序

  1. 依赖安装与配置(基础)
  2. App.tsx主题移除入口
  3. AppLayout布局迁移导航
  4. 表单组件迁移ProviderForm、ModelForm
  5. 表格组件迁移ProviderTable、ModelTable、StatsTable
  6. 统计组件迁移StatCards、UsageChart
  7. Settings页面简化
  8. 测试文件更新

Risks / Trade-offs

风险1图标名称不匹配

风险TDesign可能没有与Ant Design完全对应的图标名称

缓解

  • 安装tdesign-icons-react后立即确认可用图标
  • 选择语义最接近的图标
  • 必要时使用通用图标如CloudIcon、ChartIcon、SettingIcon
  • 在design.md中记录最终选择的图标映射

风险2组件API差异导致功能缺失

风险TDesign组件API与Ant Design不完全一致可能影响功能

缓解

  • 逐个组件对比API文档
  • 编写详细的迁移映射表
  • 每个模块迁移后立即测试验证
  • 保留原有业务逻辑只替换UI组件

风险3样式差异影响用户体验

风险TDesign默认样式与Ant Design不同用户可能不适应

缓解

  • 迁移后进行完整UI验收测试
  • 必要时通过ConfigProvider调整主题配置
  • 记录样式差异点,统一调整

风险4测试覆盖率下降

风险:迁移过程中测试可能失败或被跳过

缓解

  • 迁移前确保所有测试通过
  • 每个模块迁移后立即更新对应测试
  • 删除主题相关测试,其他测试必须保留
  • 迁移后运行完整测试套件,确保覆盖率不降低

风险5DatePicker日期格式处理

风险TDesign DatePicker的日期格式处理可能与Ant Design不同

缓解

  • 对比两个组件的日期格式API
  • 测试日期范围选择功能
  • 确保与后端API的日期格式兼容

Migration Plan

阶段1依赖准备0.5小时)

  1. 安装新依赖:
    cd frontend
    bun add tdesign-react tdesign-icons-react recharts
    
  2. 移除旧依赖:
    bun remove antd @ant-design/icons @ant-design/charts antd-style
    
  3. 引入TDesign全局样式
    // src/main.tsx
    import 'tdesign-react/es/style/index.css';
    

阶段2主题系统移除0.5小时)

  1. 删除src/contexts/ThemeContext.tsx
  2. 删除src/themes/整个目录
  3. 修改src/App.tsx
    • 移除ThemeProvider导入和使用
    • 替换为TDesign ConfigProvider
  4. 删除主题相关测试文件

阶段3布局与导航迁移1小时

  1. 修改src/components/AppLayout/index.tsx
    • 替换Layout组件Sider→Aside
    • 替换Menu组件
    • 替换图标(@ant-design/icons→tdesign-icons-react
    • 移除折叠功能相关代码
    • 移除主题相关逻辑
  2. 更新AppLayout测试

阶段4表单组件迁移1.5小时)

  1. 修改src/pages/Providers/ProviderForm.tsx
    • Modal→Dialog
    • Form.Item→Form.FormItem
    • Input、Switch组件替换
  2. 修改src/pages/Providers/ModelForm.tsx
    • 同上处理
  3. 更新表单测试

阶段5表格组件迁移1小时

  1. 修改src/pages/Providers/ProviderTable.tsx
    • Table、Card、Button、Tag、Popconfirm、Space替换
  2. 修改src/pages/Providers/ModelTable.tsx
    • 同上处理
  3. 修改src/pages/Stats/StatsTable.tsx
    • Table、Card、Select、Input、DatePicker替换
  4. 更新表格测试

阶段6统计组件迁移1小时

  1. 修改src/pages/Stats/StatCards.tsx
    • Row、Col、Card、Statistic替换
  2. 修改src/pages/Stats/UsageChart.tsx
    • Card保持
    • @ant-design/charts→recharts重写
  3. 更新统计测试

阶段7Settings页面简化0.5小时)

  1. 修改src/pages/Settings/index.tsx
    • 移除主题设置相关代码
    • 简化为空页面提示
  2. 更新Settings测试

阶段8测试与修复2小时

  1. 运行完整测试套件:bun test
  2. 修复失败的测试
  3. 运行E2E测试bun test:e2e
  4. 手动验收测试:
    • 供应商管理完整流程
    • 统计数据展示
    • 图表交互
    • 响应式布局

阶段9样式微调1小时

  1. 检查UI一致性
  2. 调整间距、颜色等细节
  3. 确认图标显示正确
  4. 最终验收

回滚策略

如果迁移过程中出现严重问题:

  1. 恢复package.json到迁移前状态
  2. 恢复所有源代码文件
  3. 重新安装依赖:bun install
  4. 运行测试确认回滚成功

注意建议在迁移前创建Git分支便于回滚。

Open Questions

  1. TDesign图标名称确认

    • 需要安装tdesign-icons-react后确认具体图标名称
    • 如果没有CloudServer/ChartLine/Setting图标选择哪个替代
    • 是否需要自定义SVG图标
  2. DatePicker日期格式兼容性

    • TDesign DatePicker的日期格式是否与后端API兼容
    • RangePicker的API是否完全兼容
    • 是否需要额外的日期处理逻辑?
  3. ConfigProvider全局配置

    • 是否需要配置TDesign的全局属性
    • 是否需要自定义主题token
    • 国际化配置是否需要调整?
  4. 性能影响评估

    • 新bundle体积是否可接受
    • Recharts渲染性能是否满足需求
    • 是否需要代码分割优化?
  5. 用户验收标准

    • UI风格变化的接受度如何
    • 是否需要用户参与验收测试?
    • 是否需要提供UI变更说明文档