feat: 统一品牌标识、关于页面三卡片布局与版本诊断功能
- 统一品牌为 Nex:侧边栏、托盘 tooltip、HTML 标题、favicon (PNG 替代 SVG) - 重构关于页面为三卡片布局(品牌/版本/链接),版本状态 Tag 绝对定位右上角 - 新增 GET /api/version 后端接口,返回 version/commit/build_time - 新增前端版本一致性诊断:匹配/不匹配/不可判断三种状态 - 同步 delta specs 到主 specs 并归档变更
This commit is contained in:
@@ -2,25 +2,83 @@
|
||||
|
||||
## Purpose
|
||||
|
||||
TBD - 提供关于页面展示项目品牌信息
|
||||
TBD - 提供关于页面展示项目品牌信息、版本信息和外部链接
|
||||
|
||||
## Requirements
|
||||
|
||||
### Requirement: 关于页面
|
||||
|
||||
前端 SHALL 提供关于页面,使用 TDesign Card 组件居中展示项目品牌信息(应用名称、描述、项目链接)。
|
||||
前端 SHALL 提供现代化关于页面,使用 TDesign 组件展示项目品牌信息、项目链接、前端版本、后端版本和版本匹配状态。
|
||||
|
||||
#### Scenario: 显示关于页面
|
||||
|
||||
- **WHEN** 用户访问 `/about` 路径
|
||||
- **THEN** 前端 SHALL 显示关于页面
|
||||
- **THEN** 页面 SHALL 展示应用名称"Nex"
|
||||
- **THEN** 页面 SHALL 展示应用描述"AI Gateway - 统一的大模型 API 网关"
|
||||
- **THEN** 页面 SHALL 展示项目链接"https://github.com/nex/gateway"
|
||||
- **THEN** 页面 SHALL 展示应用名称 `Nex`
|
||||
- **THEN** 页面 SHALL 展示应用描述 `AI Gateway - 统一的大模型 API 网关`
|
||||
- **THEN** 页面 SHALL 展示项目链接 `https://github.com/nex/gateway`
|
||||
|
||||
#### Scenario: 页面布局
|
||||
|
||||
- **WHEN** 渲染关于页面
|
||||
- **THEN** 页面 SHALL 使用 TDesign Card 组件作为容器
|
||||
- **THEN** Card SHALL 设置 `bordered={false}`
|
||||
- **THEN** 内容 SHALL 居中展示
|
||||
- **THEN** 页面 SHALL 使用三个独立 TDesign Card 组件分别承载品牌区、版本信息区和链接区
|
||||
- **THEN** 三个 Card SHALL 使用 grid 布局垂直排列
|
||||
- **THEN** 每个 Card SHALL 设置 `bordered={false}` 和 `hoverShadow`
|
||||
- **THEN** Card SHALL 使用 TDesign 组件 props 和 tokens 完成主要视觉效果
|
||||
|
||||
#### Scenario: 品牌卡片
|
||||
|
||||
- **WHEN** 渲染品牌卡片
|
||||
- **THEN** 卡片 SHALL 展示应用图标、应用名称 `Nex` 和产品描述
|
||||
|
||||
#### Scenario: 版本信息卡片
|
||||
|
||||
- **WHEN** 渲染版本信息卡片
|
||||
- **THEN** 版本状态 Tag SHALL 以绝对定位浮动在卡片右上角,不占据内容布局空间
|
||||
- **THEN** 版本状态 Tag SHALL 使用 TDesign Tag 的 `theme`、`variant`、`shape` props
|
||||
- **THEN** 卡片 SHALL 展示前端版本、后端版本、后端提交和后端构建时间
|
||||
|
||||
#### Scenario: 链接卡片
|
||||
|
||||
- **WHEN** 渲染链接卡片
|
||||
- **THEN** 卡片 SHALL 展示项目外部链接
|
||||
|
||||
#### Scenario: 展示前端版本
|
||||
|
||||
- **WHEN** 渲染关于页面
|
||||
- **THEN** 页面 SHALL 显示前端版本号
|
||||
- **THEN** 前端版本号 SHALL 来源于构建注入的 `VITE_APP_VERSION`
|
||||
- **THEN** 当前端版本号缺失时页面 SHALL 显示开发或未知版本状态
|
||||
|
||||
#### Scenario: 展示后端版本
|
||||
|
||||
- **WHEN** 渲染关于页面且后端版本接口请求成功
|
||||
- **THEN** 页面 SHALL 显示后端 `version`
|
||||
- **THEN** 页面 SHALL 显示后端 `commit`
|
||||
- **THEN** 页面 SHALL 显示后端 `build_time`
|
||||
|
||||
#### Scenario: 判断版本一致
|
||||
|
||||
- **WHEN** 前端版本号与后端版本号相同
|
||||
- **THEN** 页面 SHALL 显示版本一致状态
|
||||
- **THEN** 版本状态 SHALL 使用 TDesign Tag 展示成功语义
|
||||
|
||||
#### Scenario: 判断版本不一致
|
||||
|
||||
- **WHEN** 前端版本号与后端版本号不同且两者均为可判断的发布版本
|
||||
- **THEN** 页面 SHALL 显示版本不一致状态
|
||||
- **THEN** 页面 SHALL 展示提示信息说明该状态用于部署诊断
|
||||
- **THEN** 页面 SHALL NOT 阻断用户使用其他功能
|
||||
|
||||
#### Scenario: 后端版本无法判断
|
||||
|
||||
- **WHEN** 后端版本号为 `dev`、`unknown` 或空值
|
||||
- **THEN** 页面 SHALL 显示开发构建或无法判断状态
|
||||
- **THEN** 页面 SHALL NOT 将该状态显示为版本错误
|
||||
|
||||
#### Scenario: 后端版本获取失败
|
||||
|
||||
- **WHEN** 请求后端版本接口失败
|
||||
- **THEN** 页面 SHALL 显示无法获取后端版本的状态
|
||||
- **THEN** 页面 SHALL 保留前端版本信息
|
||||
- **THEN** 页面 SHALL NOT 因版本接口失败而崩溃
|
||||
|
||||
@@ -42,7 +42,7 @@ TBD - 提供跨平台桌面应用支持,将后端服务与前端静态资源
|
||||
- **THEN** 系统根据平台加载正确的图标格式
|
||||
- **AND** 在 Windows 上加载 ICO 格式图标(`assets/icon.ico`)
|
||||
- **AND** 在 macOS 和 Linux 上加载 PNG 格式图标(`assets/icon.png`)
|
||||
- **AND** 托盘图标 tooltip 显示"AI Gateway"
|
||||
- **AND** 托盘图标 tooltip 显示 `Nex`
|
||||
|
||||
#### Scenario: 托盘菜单显示
|
||||
|
||||
@@ -80,6 +80,13 @@ TBD - 提供跨平台桌面应用支持,将后端服务与前端静态资源
|
||||
- **WHEN** 请求路径以 `/api/` 或 `/health` 开头
|
||||
- **THEN** 请求由现有业务 handler 处理或返回 API 风格 404
|
||||
|
||||
#### Scenario: 版本接口路由
|
||||
|
||||
- **WHEN** desktop 模式收到 `GET /api/version` 请求
|
||||
- **THEN** 请求 SHALL 由版本信息 handler 处理
|
||||
- **THEN** 响应 SHALL 为 API JSON 响应
|
||||
- **THEN** 请求 SHALL NOT 返回前端 `index.html`
|
||||
|
||||
#### Scenario: 协议代理请求路由
|
||||
|
||||
- **WHEN** 请求路径以 `/openai/` 或 `/anthropic/` 开头
|
||||
@@ -104,10 +111,10 @@ TBD - 提供跨平台桌面应用支持,将后端服务与前端静态资源
|
||||
- **THEN** 返回嵌入的前端静态资源文件
|
||||
- **THEN** 请求 SHALL NOT 被协议代理路由处理
|
||||
|
||||
#### Scenario: Favicon 路由
|
||||
#### Scenario: PNG Favicon 路由
|
||||
|
||||
- **WHEN** 请求路径为 `/favicon.svg`
|
||||
- **THEN** 返回嵌入的前端 favicon 资源
|
||||
- **WHEN** 请求路径为 `/icon.png`
|
||||
- **THEN** 返回来源于统一应用图标的 PNG favicon 资源
|
||||
- **THEN** 请求 SHALL NOT 被协议代理路由处理
|
||||
|
||||
#### Scenario: SPA 路由回退
|
||||
|
||||
@@ -8,31 +8,31 @@ TBD - 提供供应商、模型配置和用量统计的前端管理界面
|
||||
|
||||
### Requirement: 样式体系
|
||||
|
||||
前端样式 SHALL 优先使用 TDesign 样式体系,SCSS 作为补充工具。
|
||||
前端样式 SHALL 优先使用 TDesign 组件 props,其次使用 TDesign tokens,最后在前两者无法表达所需效果时使用 SCSS 作为补充工具。
|
||||
|
||||
#### Scenario: TDesign 组件 Props 优先
|
||||
|
||||
- **WHEN** 实现组件视觉效果
|
||||
- **THEN** 前端 SHALL 优先使用 TDesign 组件的视觉增强 Props(如 color、trend、hoverShadow、stripe、variant、shape 等)
|
||||
- **THEN** 前端 SHALL 优先使用 TDesign 组件的视觉增强 Props(如 color、trend、hoverShadow、stripe、variant、shape、headerBordered、gutter 等)
|
||||
- **THEN** 前端 SHALL NOT 通过 CSS 类名覆盖组件内部样式
|
||||
|
||||
#### Scenario: TDesign Tokens 作为第二优先级
|
||||
|
||||
- **WHEN** 组件 props 无法完整表达颜色、边框、背景、间距等视觉细节
|
||||
- **THEN** 前端 SHALL 使用 TDesign CSS Token 引用(`var(--td-*)`)表达样式
|
||||
- **THEN** 前端 SHALL NOT 在布局样式中硬编码 `#fff`、`#e7e7e7`、`#999` 等颜色值
|
||||
|
||||
#### Scenario: CSS Variables 主题微调
|
||||
|
||||
- **WHEN** 需要调整全局视觉风格
|
||||
- **THEN** 前端 SHALL 通过 \`:root\` 中声明 TDesign CSS Variables(\`--td-*\`)进行覆盖
|
||||
- **THEN** 前端 SHALL NOT 使用 \`!important\` 或高优先级选择器覆盖组件样式
|
||||
- **THEN** 前端 SHALL 通过 `:root` 中声明 TDesign CSS Variables(`--td-*`)进行覆盖
|
||||
- **THEN** 前端 SHALL NOT 使用 `!important` 或高优先级选择器覆盖组件样式
|
||||
|
||||
#### Scenario: 布局样式 Token 化
|
||||
#### Scenario: SCSS 兜底使用
|
||||
|
||||
- **WHEN** 编写布局级 inline style
|
||||
- **THEN** 前端 SHALL 使用 TDesign CSS Token 引用(\`var(--td-*)\`)替代硬编码颜色值
|
||||
- **THEN** 前端 SHALL NOT 在布局样式中硬编码 \`#fff\`、\`#e7e7e7\`、\`#999\` 等颜色值
|
||||
|
||||
#### Scenario: SCSS 补充使用
|
||||
|
||||
- **WHEN** TDesign 样式体系无法满足需求
|
||||
- **WHEN** TDesign 组件 props 和 TDesign tokens 均无法满足布局、响应式或品牌视觉需求
|
||||
- **THEN** 前端 MAY 使用 SCSS 作为补充
|
||||
- **THEN** SCSS 文件 SHALL 仅用于 \`:root\` 级别的 CSS Variables 声明和全局 reset
|
||||
- **THEN** SCSS SHALL 只承载必要的补充样式
|
||||
- **THEN** 前端 SHALL NOT 使用纯 CSS 文件(*.css)
|
||||
|
||||
|
||||
@@ -231,12 +231,20 @@ TBD - 提供供应商、模型配置和用量统计的前端管理界面
|
||||
#### Scenario: 桌面布局
|
||||
|
||||
- **WHEN** 在桌面屏幕上查看前端
|
||||
- **THEN** 布局 SHALL 使用 TDesign \`Layout.Aside\` + \`Menu\`
|
||||
- **THEN** 布局 SHALL 使用 TDesign `Layout.Aside` + `Menu`
|
||||
- **THEN** 侧边栏 SHALL 显示导航菜单,包含图标和文字标签
|
||||
- **THEN** 侧边栏 SHALL 使用固定宽度 232px
|
||||
- **THEN** Menu 组件 SHALL 使用 \`logo\` prop 显示品牌标识
|
||||
- **THEN** Menu 组件 SHALL 使用 \`operations\` prop 在底部显示操作区域
|
||||
- **THEN** Menu 组件 SHALL 支持 \`collapsed\` 折叠功能
|
||||
- **THEN** Menu 组件 SHALL 使用 `logo` prop 显示品牌标识
|
||||
- **THEN** Menu 组件 SHALL 使用 `operations` prop 在底部显示操作区域
|
||||
- **THEN** Menu 组件 SHALL 支持 `collapsed` 折叠功能
|
||||
|
||||
#### Scenario: 侧边栏折叠布局
|
||||
|
||||
- **WHEN** 用户折叠侧边栏
|
||||
- **THEN** 侧边栏 SHALL 使用折叠宽度 64px
|
||||
- **THEN** Menu logo 区域 SHALL 保留应用图标
|
||||
- **THEN** Menu logo 区域 SHALL 隐藏应用名称文字
|
||||
- **THEN** Menu logo 区域 SHALL NOT 显示为空白
|
||||
|
||||
#### Scenario: 页面内容区域
|
||||
|
||||
@@ -402,21 +410,29 @@ TBD - 提供供应商、模型配置和用量统计的前端管理界面
|
||||
|
||||
### Requirement: 提供侧边栏导航
|
||||
|
||||
前端 SHALL 使用 TDesign \`Layout.Aside\` 提供侧边栏导航。
|
||||
前端 SHALL 使用 TDesign `Layout.Aside` 提供侧边栏导航。
|
||||
|
||||
#### Scenario: 侧边栏内容
|
||||
|
||||
- **WHEN** 渲染侧边栏
|
||||
- **THEN** 侧边栏顶部 SHALL 显示应用名称/Logo
|
||||
- **THEN** 侧边栏顶部 SHALL 显示统一应用图标和应用名称 `Nex`
|
||||
- **THEN** 侧边栏 SHALL NOT 显示旧品牌文字 `AI Gateway` 作为应用名称
|
||||
- **THEN** 侧边栏 SHALL 包含导航菜单
|
||||
- **THEN** 导航菜单项 SHALL 包含:供应商管理(ServerIcon 图标)、用量统计(ChartLineIcon 图标)、设置(SettingIcon 图标)、关于(InfoCircleIcon 图标)
|
||||
|
||||
#### Scenario: 侧边栏折叠品牌显示
|
||||
|
||||
- **WHEN** 侧边栏处于折叠状态
|
||||
- **THEN** 侧边栏顶部 SHALL 显示统一应用图标
|
||||
- **THEN** 侧边栏顶部 SHALL 隐藏 `Nex` 文案
|
||||
- **THEN** 侧边栏顶部 SHALL NOT 为空白
|
||||
|
||||
#### Scenario: 导航菜单交互
|
||||
|
||||
- **WHEN** 用户点击导航中的"供应商管理"
|
||||
- **THEN** 前端 SHALL 导航到 \`/providers\` 并高亮当前菜单项
|
||||
- **THEN** 前端 SHALL 导航到 `/providers` 并高亮当前菜单项
|
||||
- **WHEN** 用户点击导航中的"用量统计"
|
||||
- **THEN** 前端 SHALL 导航到 \`/stats\` 并高亮当前菜单项
|
||||
- **THEN** 前端 SHALL 导航到 `/stats` 并高亮当前菜单项
|
||||
- **WHEN** 用户点击导航中的"设置"
|
||||
- **THEN** 前端 SHALL 导航到 `/settings` 并高亮当前菜单项
|
||||
- **WHEN** 用户点击导航中的"关于"
|
||||
@@ -583,3 +599,26 @@ TBD - 提供供应商、模型配置和用量统计的前端管理界面
|
||||
- **THEN** 前端 SHALL 显示全局错误提示
|
||||
- **THEN** 错误消息 SHALL 具有描述性
|
||||
|
||||
### Requirement: 统一 public 图标资源
|
||||
|
||||
前端 SHALL 使用仓库统一应用图标作为 public favicon 和品牌图标来源。
|
||||
|
||||
#### Scenario: 使用 PNG favicon
|
||||
|
||||
- **WHEN** 前端页面加载 HTML 入口
|
||||
- **THEN** 页面 SHALL 使用 `/icon.png` 作为 PNG favicon 路径
|
||||
- **THEN** `frontend/public/icon.png` SHALL 来源于仓库根目录 `assets/icon.png`
|
||||
- **THEN** 页面 SHALL NOT 引用独立维护的 SVG favicon
|
||||
|
||||
#### Scenario: HTML 标题使用统一应用名称
|
||||
|
||||
- **WHEN** 前端页面加载 HTML 入口
|
||||
- **THEN** 页面标题 SHALL 使用 `Nex` 作为应用名称
|
||||
- **THEN** 页面标题 SHALL NOT 使用旧应用名称 `AI Gateway`
|
||||
|
||||
#### Scenario: 清理未使用 public SVG 图标
|
||||
|
||||
- **WHEN** public 目录中的 SVG 图标资源没有被前端代码、HTML 或 desktop 静态服务引用
|
||||
- **THEN** 前端 SHALL 删除该未使用 SVG 图标资源
|
||||
- **THEN** 前端 SHALL NOT 保留未使用的 `frontend/public/icons.svg`
|
||||
|
||||
|
||||
@@ -66,3 +66,56 @@
|
||||
- **WHEN** 执行前端生产构建
|
||||
- **THEN** 构建流程 SHALL 注入 `VITE_APP_VERSION`
|
||||
- **AND** 该值 SHALL 等于 `VERSION` 中的版本号
|
||||
|
||||
### Requirement: 后端运行时版本查询
|
||||
|
||||
系统 SHALL 通过管理接口暴露后端运行时构建版本信息,供前端和用户诊断前后端版本一致性。
|
||||
|
||||
#### Scenario: 查询后端版本信息
|
||||
|
||||
- **WHEN** 客户端请求 `GET /api/version`
|
||||
- **THEN** 后端 SHALL 返回 HTTP 200
|
||||
- **THEN** 响应 JSON SHALL 包含 `version` 字段
|
||||
- **THEN** 响应 JSON SHALL 包含 `commit` 字段
|
||||
- **THEN** 响应 JSON SHALL 包含 `build_time` 字段
|
||||
|
||||
#### Scenario: 版本信息来源于构建注入
|
||||
|
||||
- **WHEN** 后端返回版本信息
|
||||
- **THEN** `version` SHALL 来源于 `buildinfo.Version()`
|
||||
- **THEN** `commit` SHALL 来源于 `buildinfo.Commit()`
|
||||
- **THEN** `build_time` SHALL 来源于 `buildinfo.BuildTime()`
|
||||
- **THEN** 后端 SHALL NOT 在运行时读取仓库 `VERSION` 文件作为接口响应来源
|
||||
|
||||
#### Scenario: 本地开发构建降级值
|
||||
|
||||
- **WHEN** 后端未通过构建参数注入版本元数据
|
||||
- **THEN** 后端版本接口 SHALL 返回 buildinfo 的默认降级值
|
||||
- **THEN** 前端 SHALL 能够展示该降级值而不崩溃
|
||||
|
||||
### Requirement: 前后端版本一致性诊断
|
||||
|
||||
系统 SHALL 支持前端使用自身构建版本和后端运行时版本进行一致性诊断。
|
||||
|
||||
#### Scenario: 前端读取构建版本
|
||||
|
||||
- **WHEN** 前端渲染版本信息
|
||||
- **THEN** 前端 SHALL 使用 `VITE_APP_VERSION` 作为前端版本号
|
||||
- **THEN** `VITE_APP_VERSION` SHALL 继续由版本同步流程保持与 `VERSION` 一致
|
||||
|
||||
#### Scenario: 诊断版本匹配
|
||||
|
||||
- **WHEN** 前端版本号和后端版本号均可判断且完全相同
|
||||
- **THEN** 前端 SHALL 将版本状态判定为一致
|
||||
|
||||
#### Scenario: 诊断版本不匹配
|
||||
|
||||
- **WHEN** 前端版本号和后端版本号均可判断且不相同
|
||||
- **THEN** 前端 SHALL 将版本状态判定为不一致
|
||||
- **THEN** 前端 SHALL 将该状态作为诊断提示展示
|
||||
|
||||
#### Scenario: 诊断版本不可判断
|
||||
|
||||
- **WHEN** 任一版本号为空、`dev` 或 `unknown`
|
||||
- **THEN** 前端 SHALL 将版本状态判定为无法判断
|
||||
- **THEN** 前端 SHALL NOT 将该状态判定为版本不一致
|
||||
|
||||
Reference in New Issue
Block a user