This commit is contained in:
zlwu committed 2026-05-23 21:27:10 +08:00
1 parent 05684ba2a4
commit 7fbf71b6e1
150 files changed
+19834 -12611

No files matched your search

@@ -58,3 +58,38 @@
- **WHEN** 创建合并请求
- **THEN** 描述 SHALL 使评审者无需阅读聊天历史即可理解动机与风险
### Requirement: 前端 API 返回值消费约定
`web-admin` 的 axios 拦截器(`src/utils/http/index.ts`)已对响应做两层解包:`res.data.data` → 返回值即为后端 `data` 字段的内容。因此页面组件中消费 API 函数返回值时,SHALL NOT 再做 `{ data }` 解构或 `.data` 取值,SHALL 直接从返回值中读取业务字段。
#### Scenario: 调用列表 API
- **GIVEN** 后端返回 `{"code": 200, "data": {"list": [...], "total": 12}}`
- **WHEN** 页面调用 `const result = await fetchXxxList(params)`
- **THEN** `result` 已经是 `{"list": [...], "total": 12}`,SHALL 使用 `result.list`、`result.total`,SHALL NOT 写 `const { data } = await fetchXxxList()` 再从 `data.list` 取值
#### Scenario: 调用单条 API
- **GIVEN** 后端返回 `{"code": 200, "data": {"smsContent": "..."}}`
- **WHEN** 页面调用 `const result = await fetchGenerateSms(id)`
- **THEN** `result` 已经是 `{"smsContent": "..."}`,SHALL 使用 `result.smsContent`,SHALL NOT 写 `const { data } = await fetchGenerateSms()` 再从 `data.smsContent` 取值
#### Scenario: 新增 API 调用前确认返回值层级
- **WHEN** 编写新的页面消费 API 函数
- **THEN** 开发者 SHALL 先查看 `src/utils/http/index.ts` 第 420 行的 `return res.data.data as T`,确认拦截器已剥离 `{code, data}` 外层包装,消费端直接拿返回值即可
### Requirement: 前后端 HTTP 方法一致性
前端 API 函数的 HTTP 方法(GET / POST / PUT / DELETE)SHALL 与后端路由装饰器(`@router.get` / `@router.post` / `@router.put` / `@router.delete`)严格一致。有副作用的操作(创建、更新、状态变更、内容生成)SHALL 使用 POST 或 PUT。
#### Scenario: 新增 API 接口
- **WHEN** 后端定义 `@router.post("/generate-sms")`
- **THEN** 前端对应的 `fetchGenerateSms` SHALL 使用 `request.post()`,SHALL NOT 使用 `request.get()`
#### Scenario: 代码评审检查项
- **WHEN** 评审涉及前后端联调的变更
- **THEN** 评审者 SHALL 校验前端 `request.get/post/put/delete` 与后端 `@router.get/post/put/delete` 的方法一一匹配
@@ -137,18 +137,44 @@ Web 管理端弹窗 SHALL 遵循规范:表单 `label-position="top"`;遮罩
### Requirement: 表格操作列固定在右侧
`web-admin` 中所有业务列表页(系统管理、业务模块等,不含 Demo 参考页)的 `el-table` 操作列 SHALL 使用 `fixed="right"` 固定在表格右侧。宽度规则:2 个按钮时 `width="260"`,3 个按钮时 `width="320"`,4 个及以上按钮时 `width="400"`。全局 CSS 通过 `.el-table-fixed-column--right` 选择器(注意:Element Plus 使用单短横线,非双下划线)提供固定列样式。
`web-admin` 中所有业务列表页(系统管理、业务模块等,不含 Demo 参考页)的 `el-table` 操作列 SHALL 使用 `fixed="right"` 固定在表格右侧。宽度规则:2 个按钮时 `min-width="260"`,3 个按钮时 `min-width="320"`,4 个及以上按钮时 `min-width="400"`。全局 CSS 通过 `.el-table-fixed-column--right` 选择器(注意:Element Plus 使用单短横线,非双下划线)提供固定列样式。
#### Scenario: 新增系统管理列表页
- **WHEN** 在系统管理模块下新增列表页面(如用户管理、角色管理等)
- **THEN** 表格操作列 SHALL 设置 `fixed="right"`,宽度按按钮数设置:≤ 2 按钮用 `width="260"`,3 按钮用 `width="320"`,≥ 4 按钮用 `width="400"`
- **THEN** 表格操作列 SHALL 设置 `fixed="right"`,宽度按按钮数设置:≤ 2 按钮用 `min-width="260"`,3 按钮用 `min-width="320"`,≥ 4 按钮用 `min-width="400"`
#### Scenario: Code review 表格列
- **WHEN** PR 包含新增或修改的 `el-table-column` 且 `label="操作"`
- **THEN** 审查者 SHALL 确认该列包含 `fixed="right"` 属性,且宽度与按钮数量匹配(2 按钮 260px,3+ 按钮 320px)
### Requirement: 表格列宽使用 min-width 实现等比缩放
`web-admin` 中所有 `el-table` 的列宽属性 SHALL 使用 `min-width` 替代 `width`,使浏览器视口宽度变化时各列按基础比例等比伸缩。
**原理**:Element Plus 的布局逻辑是,所有 `min-width` 列按各自 `min-width` 值的比例分配容器可用宽度;当容器宽度小于所有 `min-width` 之和时,触发横向滚动。若部分列使用 `width`(固定宽度),则多余空间全部由 `min-width` 列吸收,导致视口加宽时只有 `min-width` 列变宽而 `width` 列不变。
**规则**:
1. 所有 `el-table-column`(包括序号列、数据列、操作列)SHALL 使用 `min-width` 设定基础宽度,SHALL NOT 使用 `width`。
2. `min-width` 值即为该列的最小可读宽度,也是等比分配的权重基数。
3. `el-table` 本身的 `width` 属性(如弹窗内嵌表格的固定总宽)不受此规则约束。
#### Scenario: 新增列表页
- **WHEN** 新增列表页包含 `el-table`
- **THEN** 所有 `el-table-column` 的宽度属性 SHALL 使用 `min-width`,SHALL NOT 使用 `width`
#### Scenario: 浏览器窗口宽度变化
- **WHEN** 用户调整浏览器窗口宽度
- **THEN** 各列宽度 SHALL 按 `min-width` 设定的基础比例等比伸缩
#### Scenario: Code review 表格列宽
- **WHEN** PR 包含新增或修改的 `el-table-column` 且使用 `width` 属性
- **THEN** 审查者 SHALL 要求改为 `min-width`
### Requirement: 侧边栏菜单图标层级规则
`web-admin` 左侧菜单区域的图标展示 SHALL 遵循以下层级规则:
@@ -202,10 +228,11 @@ Web 管理端弹窗 SHALL 遵循规范:表单 `label-position="top"`;遮罩
### Requirement: 列表行查看弹窗(按钮 + 双击)
`web-admin` 中所有系统管理与业务列表页(含标准列表、树形列表)的 `el-table` SHALL 提供只读「查看」弹窗能力,实现规则如下:
`web-admin` 中**所有** `el-table` 组件——包括主列表页(标准列表、树形列表)、弹窗内嵌列表(如编辑弹窗/查看弹窗/选择弹窗中的子表格)、侧栏面板内的列表——若操作列包含「查看」「查看详情」「查看确认信息」等只读查看类按钮,SHALL 同时提供行双击触发查看的能力,实现规则如下:
1. **操作列「查看」按钮**:操作列 SHALL 在首位包含一个「查看」按钮(`<el-icon><View /></el-icon>查看`),点击后弹出只读查看弹窗。
2. **行双击触发**:`el-table` SHALL 监听 `@row-dblclick` 事件,双击任意行时触发与「查看」按钮相同的弹窗(即调用同一 `handleView(row)` 函数)。
3. **条件按钮场景**:当操作列按钮随状态/Tab 变化(如待确认 Tab 显示「确认收款」,已确认 Tab 显示「查看确认信息」),`@row-dblclick` handler SHALL 仅在「查看」类按钮可见时触发对应查看函数,其余状态下可忽略或调用对应主操作函数。
3. **弹窗样式**:查看弹窗 SHALL 使用 `SystemViewDialog` 共享组件(`src/components/business/system-view-dialog/index.vue`),样式对齐待办中心「查看详情」弹窗(无标题栏、hero 渐变头图 + 图标、KV grid 字段展示、关闭按钮)。
4. **字段内容**:查看弹窗 SHALL 展示该行记录的所有业务字段(含状态映射、字典翻译),不展示 `id`、`del_flag` 等技术字段。长文本/备注字段 SHALL 使用 `span: true` 跨两列展示。
5. **区块标题样式**:查看弹窗中各区块标题(`SystemViewDialog` 的 section title,渲染为 `h3`)SHALL 与字段标签(`dt`)形成明显视觉区分。区块标题 SHALL 使用深色文字(`#1e293b`)配合左侧主色竖条装饰(`border-left: 3px solid #10b981`),字号 14px、`font-weight: 600`;字段标签 SHALL 保持为辅助灰色(`#64748b`)、`font-weight: 500`。区块标题样式 SHALL NOT 与字段标签使用相同颜色或相近字重。
@@ -566,7 +593,7 @@ import { Plus, Close, Check, Search, RefreshLeft, Edit, Delete, View } from '@el
**标准写法:**
```html
<el-table-column prop="status" label="状态" width="90" align="center">
<el-table-column prop="status" label="状态" min-width="90" align="center">
<template #default="{ row }">
<el-tag :type="row.status === '1' ? 'success' : 'info'" size="small">
{{ row.status === '1' ? '正常' : '停用' }}
@@ -578,7 +605,7 @@ import { Plus, Close, Check, Search, RefreshLeft, Edit, Delete, View } from '@el
**多状态映射标准写法(使用状态标签注册表):**
```html
<el-table-column prop="workOrderStatus" label="状态" width="100" align="center">
<el-table-column prop="workOrderStatus" label="状态" min-width="100" align="center">
<template #default="{ row }">
<el-tag :type="workOrderStatusTagType(row.workOrderStatus)" size="small">
{{ workOrderStatusLabel(row.workOrderStatus) }}