1
0
Files
nex/openspec/specs/frontend-config-ui/spec.md
lanyuanxiaoyao 9359ca7f62 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 变更记录
2026-04-16 11:21:48 +08:00

272 lines
9.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 前端配置界面
## Purpose
TBD - 提供供应商、模型配置和用量统计的前端管理界面
## Requirements
### Requirement: 提供供应商管理页面
前端 SHALL 使用 Ant Design 组件提供供应商管理页面。
#### Scenario: 显示供应商列表
- **WHEN** 加载供应商管理页面
- **THEN** 前端 SHALL 使用 Ant Design Table 显示所有已配置供应商
- **THEN** 每个供应商 SHALL 显示 name、base_url 和 enabled 状态(使用 Tag 组件)
- **THEN** API Key SHALL 被脱敏显示(掩码处理)
- **THEN** 表格 SHALL 支持展开行以显示关联模型
#### Scenario: 添加新供应商
- **WHEN** 用户点击"添加供应商"按钮
- **THEN** 前端 SHALL 使用 Ant Design Modal + Form 显示输入表单
- **THEN** 表单 SHALL 包含 id、name、api_key、base_url 字段,带校验规则
- **WHEN** 用户提交包含有效数据的表单
- **THEN** 前端 SHALL 通过 useMutation 调用创建 API
- **THEN** 成功后 SHALL 关闭 Modal 并刷新供应商列表
- **THEN** 失败 SHALL 使用 message.error() 提示
#### Scenario: 编辑现有供应商
- **WHEN** 用户点击供应商的"编辑"按钮
- **THEN** 前端 SHALL 使用 Ant Design Modal + Form 显示预填充数据的表单
- **WHEN** 用户提交包含更新数据的表单
- **THEN** 前端 SHALL 通过 useMutation 调用更新 API
- **THEN** 成功后 SHALL 关闭 Modal 并刷新供应商列表
#### Scenario: 删除供应商
- **WHEN** 用户点击供应商的"删除"按钮
- **THEN** 前端 SHALL 使用 Ant Design Popconfirm 弹出确认
- **WHEN** 用户确认删除
- **THEN** 前端 SHALL 通过 useMutation 调用删除 API
- **THEN** 成功后 SHALL 刷新供应商列表
### Requirement: 提供模型管理界面
前端 SHALL 在供应商页面展开行中提供模型管理。
#### Scenario: 显示供应商的模型
- **WHEN** 展开供应商行
- **THEN** 前端 SHALL 显示该供应商的模型列表
- **THEN** 每个模型 SHALL 显示 model_name 和 enabled 状态
#### Scenario: 为供应商添加模型
- **WHEN** 用户在展开行中点击"添加模型"
- **THEN** 前端 SHALL 显示 Ant Design Modal + Form
- **THEN** provider_id SHALL 自动关联当前供应商
- **WHEN** 用户提交表单
- **THEN** 前端 SHALL 通过 useMutation 调用创建 API
- **THEN** 成功后 SHALL 刷新模型列表
#### Scenario: 编辑模型
- **WHEN** 用户点击模型的"编辑"
- **THEN** 前端 SHALL 显示编辑表单
- **WHEN** 用户提交表单
- **THEN** 前端 SHALL 通过 useMutation 调用更新 API
- **THEN** 成功后 SHALL 刷新模型列表
#### Scenario: 删除模型
- **WHEN** 用户点击模型的"删除"
- **THEN** 前端 SHALL 使用 Popconfirm 弹出确认
- **WHEN** 用户确认删除
- **THEN** 前端 SHALL 通过 useMutation 调用删除 API
- **THEN** 成功后 SHALL 刷新模型列表
### Requirement: 提供统计查看页面
前端 SHALL 使用 Ant Design 组件提供统计查看页面。
#### Scenario: 显示统计概览
- **WHEN** 加载统计页面
- **THEN** 前端 SHALL 使用 Ant Design Table 显示统计数据
- **THEN** 统计数据 SHALL 按供应商和模型显示请求计数
#### Scenario: 按供应商过滤统计
- **WHEN** 用户从 Ant Design Select 选择供应商
- **THEN** 前端 SHALL 自动查询并过滤统计
#### Scenario: 按日期范围过滤统计
- **WHEN** 用户使用 Ant Design DatePicker.RangePicker 选择日期范围
- **THEN** 前端 SHALL 自动查询并过滤统计
### Requirement: 优雅处理 API 错误
前端 SHALL 处理 API 错误并显示用户友好的消息。
#### Scenario: API 请求失败
- **WHEN** API 请求失败网络错误、4xx、5xx
- **THEN** 前端 SHALL 使用 Ant Design 的 message.error() 显示全局错误提示
- **THEN** 错误消息 SHALL 具有描述性
#### Scenario: 验证错误
- **WHEN** 用户提交包含无效数据的表单
- **THEN** 前端 SHALL 在相关字段旁显示验证错误
- **THEN** 前端 SHALL 阻止表单提交
### Requirement: 提供响应式布局
前端 SHALL 使用 Ant Design Layout 提供顶部导航布局。
#### Scenario: 桌面布局
- **WHEN** 在桌面屏幕上查看前端
- **THEN** 布局 SHALL 使用 Ant Design Layout.Header + Menuhorizontal 模式)
- **THEN** 导航菜单 SHALL 在顶部水平排列
#### Scenario: 页面内容区域
- **WHEN** 显示页面内容
- **THEN** 内容区域 SHALL 有合理的最大宽度和内边距
- **THEN** 页面之间 SHALL 通过 React Router Outlet 渲染
### Requirement: 使用无组件库的最小 UI
前端 SHALL 使用 Ant Design 5 作为 UI 组件库。
#### Scenario: Ant Design 组件使用
- **WHEN** 实现前端
- **THEN** 它 SHALL 使用 Ant Design 5 组件Table、Form、Modal、Menu、Tag、Popconfirm、DatePicker、Button、Select 等)
- **THEN** 它 SHALL 使用 @ant-design/icons 提供图标
- **THEN** 图标 SHALL 优先使用图标库中已有的图标
#### Scenario: Ant Design 默认主题
- **WHEN** 配置 Ant Design 主题
- **THEN** 前端 SHALL 使用 Ant Design 默认主题,不进行自定义主题色配置
- **THEN** 前端 SHALL NOT 支持暗色模式切换
### Requirement: SCSS 样式
前端样式 SHALL 全部使用 SCSS禁止使用纯 CSS 文件。
#### Scenario: 样式文件规范
- **WHEN** 编写样式
- **THEN** 前端 SHALL 使用 SCSS*.scss 文件)
- **THEN** 前端 SHALL NOT 使用纯 CSS 文件(*.css
- **THEN** 前端 SHALL NOT 使用 CSS-in-JS 方案
#### Scenario: SCSS Modules 使用
- **WHEN** 编写组件级样式
- **THEN** 前端 SHALL 使用 SCSS Modules*.module.scss
- **THEN** 全局样式仅保留 index.scss 做 reset 和 CSS variables
### Requirement: 提供导航
前端 SHALL 使用 React Router v7 提供导航。
#### Scenario: 路由配置
- **WHEN** 应用启动
- **THEN** 前端 SHALL 使用 React Router v7 Library 模式BrowserRouter
- **THEN** `/providers` 路径 SHALL 显示供应商管理页面
- **THEN** `/stats` 路径 SHALL 显示用量统计页面
- **THEN** `/` 路径 SHALL 重定向到 `/providers`
- **THEN** 不存在的路径 SHALL 显示 404 页面
#### Scenario: 导航菜单
- **WHEN** 用户点击导航中的"供应商管理"
- **THEN** 前端 SHALL 导航到 `/providers` 并高亮当前菜单项
- **WHEN** 用户点击导航中的"用量统计"
- **THEN** 前端 SHALL 导航到 `/stats` 并高亮当前菜单项
#### Scenario: URL 同步
- **WHEN** 用户在供应商页面刷新浏览器
- **THEN** 前端 SHALL 保持在供应商页面URL 持久化)
- **WHEN** 用户使用浏览器后退按钮
- **THEN** 前端 SHALL 正确导航到上一个页面
### Requirement: 使用 React 和 TypeScript
前端 SHALL 使用 React 和 TypeScript 实现,遵循 strict 模式。
#### Scenario: TypeScript strict 模式
- **WHEN** 编写前端代码
- **THEN** TypeScript 配置 SHALL 开启 strict: true
- **THEN** TypeScript 配置 SHALL 开启 noUncheckedIndexedAccess
- **THEN** 所有代码 SHALL NOT 使用 any 类型
- **THEN** tsconfig SHALL 合并为单文件(不使用 project references
#### Scenario: React 函数组件
- **WHEN** 实现 UI
- **THEN** 它 SHALL 使用 React 函数组件
- **THEN** 它 SHALL 使用自定义 Hooks 封装业务逻辑
### Requirement: 使用 Vite 构建
前端 SHALL 使用 Vite 作为构建工具。
#### Scenario: 开发服务器
- **WHEN** 在开发模式下启动前端
- **THEN** Vite SHALL 使用热模块替换服务应用
#### Scenario: 生产构建
- **WHEN** 为生产构建前端
- **THEN** Vite SHALL 生成优化的静态文件
### Requirement: 与后端 API 通信
前端 SHALL 使用 TanStack Query v5 和统一 API 客户端与后端通信。
#### Scenario: API 基础 URL 配置
- **WHEN** 前端发起 API 请求
- **THEN** 开发环境 SHALL 通过 Vite proxy 转发 /api 请求到后端
- **THEN** 生产环境 SHALL 使用环境变量 VITE_API_BASE 配置基础 URL
- **THEN** 前端 SHALL NOT 硬编码 API 基础 URL
#### Scenario: 统一 API 客户端
- **WHEN** 进行 API 调用
- **THEN** 所有调用 SHALL 通过 api/client.ts 的 request<T>() 方法
- **THEN** 错误处理 SHALL 统一抛出 ApiError包含 status 和 message
- **THEN** 开发环境 SHALL 使用 Vite proxy 转发 API 请求
#### Scenario: 字段名转换
- **WHEN** 接收后端 API 响应
- **THEN** API 层 SHALL 将 snake_case 字段转换为 camelCase
- **WHEN** 发送请求到后端 API
- **THEN** API 层 SHALL 将 camelCase 字段转换为 snake_case
- **THEN** hooks 和组件 SHALL 仅使用 camelCase 字段
#### Scenario: TanStack Query 数据管理
- **WHEN** 页面加载数据
- **THEN** 前端 SHALL 使用 TanStack Query 的 useQuery hook
- **THEN** 前端 SHALL 自动缓存请求结果
- **THEN** 前端 SHALL 自动处理加载和错误状态
#### Scenario: TanStack Query 写操作
- **WHEN** 用户执行创建、更新或删除操作
- **THEN** 前端 SHALL 使用 TanStack Query 的 useMutation hook
- **THEN** 操作成功后 SHALL 自动失效相关查询缓存
- **THEN** 操作失败 SHALL 使用 Ant Design message.error() 显示错误提示
#### Scenario: 错误提示
- **WHEN** API 请求失败网络错误、4xx、5xx
- **THEN** 前端 SHALL 使用 Ant Design 的 message.error() 显示全局错误提示
- **THEN** 错误消息 SHALL 具有描述性