feat(projects): 新增项目、执行、任务等功能
This commit is contained in:
370
CLAUDE.md
Normal file
370
CLAUDE.md
Normal file
@@ -0,0 +1,370 @@
|
||||
# CLAUDE.md
|
||||
|
||||
本文件是我(Claude)在 `cn-rdms-web` 项目中的个人工作笔记,沉淀团队既有规范(来源:`AGENTS.md`)与协作惯例。每次进入仓库前先读这一份,避免重复踩坑。
|
||||
|
||||
> 本文件仅本地保留,已加入 `.gitignore`,请勿提交。
|
||||
|
||||
---
|
||||
|
||||
## 0. 行为基线(最重要,先记住)
|
||||
|
||||
- **描述现状以代码、配置、文档可直接验证的事实为准**;不引入历史实现/过渡方案/猜测。
|
||||
- **默认精简回答**:先给结论 → 改动点 → 验证方式 → 必要风险。**除非用户主动要求详细,否则不要展开**——不复述清单、不列每条改动的小理由、不堆"汇总"段。用户只让分析就停在分析层,不主动跳到实现。
|
||||
- **进入实施阶段前,先说目标、涉及模块、预计改动点、验证方式**。
|
||||
- **最小改动原则**:只改当前任务必需的范围,不顺手重构无关代码。
|
||||
- **不主动执行 git 操作**(status/diff/add/commit/restore/reset/checkout 全部不主动跑),除非用户明确要求。识别用户改动优先用 Read 直接看文件。
|
||||
- 工作树脏的时候,**不要回退与当前任务无关的变更**。
|
||||
- 静态校验默认只跑 `pnpm typecheck`;UI/交互/样式类任务**默认不补也不跑前端测试**,除非用户明确要求。
|
||||
|
||||
---
|
||||
|
||||
## 1. 项目骨架(认知地图)
|
||||
|
||||
| 维度 | 现状 |
|
||||
|---|---|
|
||||
| 应用 | RDMS 系统的 Vue 3 后台前端 |
|
||||
| 包管理 | `pnpm`(>=8.7.0),Node `>=20.19.0` |
|
||||
| 工具链 | Vite 7、TypeScript、Pinia、Element Plus、UnoCSS |
|
||||
| 工作区 | `packages/*`,通过 `@sa/*` 引用 |
|
||||
| 别名 | `@` → `src`;`~` → 仓库根 |
|
||||
| 端口 | dev 9527 / preview 9725 |
|
||||
| 环境文件 | `.env`、`.env.dev`、`.env.prod` |
|
||||
|
||||
**已经形成闭环的五条主线,后续改动顺着做,不平行起新的:**
|
||||
|
||||
1. **路由来源统一**:页面文件 + 自定义路由 → `elegant-router` 生成 → `build/plugins/router.ts` 集中补 `meta`。
|
||||
2. **权限入口统一**:常量路由 / 权限路由分流;`route store` 负责初始化、菜单生成、缓存路由、面包屑。
|
||||
3. **请求入口统一**:所有业务请求走 `src/service/request/index.ts`。
|
||||
4. **页面套路统一**:列表页 = 搜索区 + 表格区 + 操作弹层/抽屉 + `modules/*` 子组件。
|
||||
5. **衍生资产统一**:页面资源白名单从路由结构生成,不手工维护第二份。
|
||||
|
||||
---
|
||||
|
||||
## 2. 关键目录速查
|
||||
|
||||
| 路径 | 职责 |
|
||||
|---|---|
|
||||
| `src/views` | 业务页面(编排层薄) |
|
||||
| `src/components` | 共享组件 |
|
||||
| `src/layouts` | 应用壳、头部、侧栏、菜单、标签页、主题抽屉 |
|
||||
| `src/store/modules` | Pinia 模块:app / auth / route / tab / theme / dict |
|
||||
| `src/service/api` | 接口封装、参数归一化、查询字符串拼装、返回类型对齐 |
|
||||
| `src/service/request` | 统一请求实例、鉴权、加密、错误处理、token 刷新 |
|
||||
| `src/router/routes` | 自定义路由 |
|
||||
| `src/router/elegant` | **生成产物,不要手改** |
|
||||
| `src/theme/settings.ts` | 默认主题与布局设置 |
|
||||
| `build/plugins/router.ts` | elegant-router 配置 + 路由 meta 生成 |
|
||||
| `src/hooks/common/table.ts` | 列表页表格 hook 主入口 |
|
||||
| `src/hooks/common/form.ts` | 表单校验与表单实例 hook |
|
||||
| `src/constants/status-tag.ts` | 业务对象状态颜色(ElTag type)集中配置 |
|
||||
| `src/styles/scss/element-plus.scss` | 表格/弹层/按钮/表单 密度与公共壳样式 |
|
||||
| `packages/*` | 项目内本地共享库 |
|
||||
| `docs/` | 架构/权限/页面规范文档,做相关改动前先查 |
|
||||
|
||||
---
|
||||
|
||||
## 3. 生成文件(不要手改)
|
||||
|
||||
- `src/router/elegant/imports.ts`
|
||||
- `src/router/elegant/routes.ts`
|
||||
- `src/router/elegant/transform.ts`
|
||||
- `src/typings/elegant-router.d.ts`
|
||||
- `src/typings/components.d.ts`
|
||||
- `docs/frontend-page-resource-manifest.json`
|
||||
|
||||
**再生命令:**
|
||||
- 路由产物过期 → `pnpm gen-route`
|
||||
- 页面资源清单需同步 → `pnpm gen:page-resource-manifest`
|
||||
|
||||
---
|
||||
|
||||
## 4. 路由与导航
|
||||
|
||||
- 新增业务页:通过页面文件 + `build/plugins/router.ts` 补齐,**不要在多个位置重复注册**。
|
||||
- `meta.icon` = Iconify 图标;`meta.localIcon` = 本地 SVG。**不要混用字段语义。**
|
||||
- `meta` 中心落点是 `build/plugins/router.ts`,新页的 `icon`/`order`/`roles`/`keepAlive` 在那里集中维护。
|
||||
- `meta.constant = true` → 常量路由;其他默认权限路由。常量路由维护入口是 `build/plugins/router.ts` 和 `src/router/routes/custom-routes.ts`。
|
||||
- `i18nKey` 是兼容字段,不是新页必须补齐项。
|
||||
|
||||
### 4.1 对象上下文业务域(重要陷阱)
|
||||
|
||||
- `product`、`project` 这类业务域,**入口页是设计如此**:先进业务域入口页 → 再选对象建上下文。**不要把"入口页是可点击菜单"误判成 bug。**
|
||||
- 入口页(如 `product_list -> /product/list -> view.product_list`)可作为左侧一级菜单实际命中页。这 ≠ 已进入对象上下文态。
|
||||
- **遇到"点入口页后布局壳消失、只剩内容页"**:先查是否动态权限路由模式 + 后端 `get-user-routes` 是否缺业务域根路由。**不要直接把入口菜单从"菜单"改成"目录"**。
|
||||
- 在 `VITE_AUTH_ROUTE_MODE=dynamic` 下,若后端只返回叶子页(如缺 `product -> layout.base`,只返 `product_list`),前端必须在动态路由归一化阶段**补回本地业务域骨架**,不能让入口裸挂为顶层 `view.*`。
|
||||
- 对象上下文稳定来源仍是本地路由骨架;动态路由兼容只能"补骨架 + 对齐入口",不能反推。
|
||||
- 新增业务域时同步检查:本地静态骨架、`src/constants/object-context.ts` 中的 `domainKey/entryRouteKey/entryRoutePath/fallbackDefaultRouteKey`、动态路由归一化、对象上下文 store、头部菜单切换。
|
||||
|
||||
---
|
||||
|
||||
## 5. 分层职责
|
||||
|
||||
| 层 | 该做 | 不该做 |
|
||||
|---|---|---|
|
||||
| `src/views` | 编排状态、表单行为、组合 store/service | 散落 URL 拼接、token 注入、错误提示、权限路由推导 |
|
||||
| `src/components` | 可复用 UI / 局部业务部件 | 长期堆只服务单页面的复杂流程 |
|
||||
| `src/service/api` | 接口封装、参数归一化、查询拼装、类型对齐 | 在 views/store/components 重复手写接口地址和序列化 |
|
||||
| `src/service/request` | 统一鉴权/加密/成功码/token 刷新/错误处理 | 平行引入新的 axios/fetch 链绕开封装 |
|
||||
| `src/store/modules` | 跨页面共享状态 | 把临时局部状态堆进全局 store |
|
||||
| `src/router` & `build/plugins/router.ts` | 路由/菜单/权限标识/首页/路由 meta | 在页面里临时写条件分支替代正式配置 |
|
||||
| `src/layouts` & `src/theme` | 全局布局壳与主题 | 在业务页面复制平行布局/主题状态 |
|
||||
|
||||
---
|
||||
|
||||
## 6. 业务页面开发风格
|
||||
|
||||
- **页面组件保持"编排层薄"**:页面文件主管搜索参数、表格 hook、列定义、弹层开关、接口编排。
|
||||
- 列表页拆同目录 `modules/*`:搜索组件、操作弹层、详情抽屉、资源面板等。
|
||||
- **参考实现**:系统管理下 `user`/`role`/`menu`/`dict`。
|
||||
- 列表 hook 优先复用:`src/hooks/common/table.ts` 的 `useUIPaginatedTable`、`useTableOperate`、`defaultTransform`。
|
||||
- 表单 hook 优先复用:`src/hooks/common/form.ts` 的 `useForm`、`useFormRules`。
|
||||
- **业务口径是"内网中文优先"**:新页不必强行国际化;但已有大量 `$t(...)` 的页面继续开发时,保持局部一致,不要中文/i18n 混用。
|
||||
|
||||
---
|
||||
|
||||
## 7. 表格、搜索区、操作列
|
||||
|
||||
### 7.1 搜索区(强约束)
|
||||
|
||||
- **必须用** `src/components/custom/table-search-fields.vue` 的 `fields` 声明式配置,不得手写 `ElRow/ElCol/ElFormItem` 骨架。
|
||||
- 仅当字段存在复杂联动、自定义插槽或 `TableSearchFields` 明确无法承载时,才退回 `src/components/custom/table-search-panel.vue`,并在实施说明中写明原因。
|
||||
- **搜索区按钮组固定在第一行最后一格**;存在折叠时按钮顺序固定为 **展开/收起 → 重置 → 查询**。**不允许**因查询条件不足、展开收起或响应式样式把按钮提前或挤到下一行。
|
||||
- `columns` 表示首行总格数,**最后 1 格永远留给按钮**;字段不足 `columns - 1` 由组件补空占位;超过则进入展开区。
|
||||
- 4 个查询条件的场景必须 `:columns="4"`(3 条件 + 按钮)。
|
||||
- 搜索模块只接 `model` 和必要选项,只发 `reset`/`search`,**不直接承载列表请求**。
|
||||
- 详细规范见 `docs/table-search-fields-usage.md`。
|
||||
|
||||
### 7.2 表格
|
||||
|
||||
- 操作列优先复用 `src/components/custom/business-table-action-cell.tsx`。
|
||||
- 操作数 ≤ 2:直出;操作数 > 2:**1 个直出主按钮 + 1 个更多按钮**。
|
||||
- `ElCard` 承载 `ElTable height="100%"` 时,`body-class` 优先用公共类 **`business-table-card-body`**(由 `src/styles/scss/element-plus.scss` 维护)。**不要为每页新建 `xxx-table-card-body` 私有样式**。历史私有类不强制专项回改,触达再收敛。
|
||||
- 表格/按钮/弹层/表单的尺寸与间距标准走 `element-plus.scss` 和公共组件,**不要在业务页散落写局部尺寸作为事实标准**。
|
||||
|
||||
---
|
||||
|
||||
## 8. 表单与弹层(强约束)
|
||||
|
||||
### 8.1 组件选择
|
||||
|
||||
- 标准组合:`ElDialog / ElDrawer / ElForm / ElScrollbar / #footer`。
|
||||
- 轻中量表单:`src/components/custom/business-form-dialog.vue`。
|
||||
- 字段较多 / 需保留列表上下文 / 重型控件:`src/components/custom/business-form-drawer.vue`。
|
||||
- 表单分组:`src/components/custom/business-form-section.vue`。
|
||||
|
||||
### 8.2 Dialog 宽度三档(按纯表单字段数)
|
||||
|
||||
| 字段数 | preset | 默认列数 | 目标宽度 |
|
||||
|---|---|---|---|
|
||||
| ≤ 6 | `sm` | 单列 | 520px |
|
||||
| 7 ~ 14 | `md` | 双列 | 720px |
|
||||
| > 14 | `lg` | 双列为主 | 960px |
|
||||
|
||||
- 实际宽度上限:`calc(100vw - 32px)`。
|
||||
- **不因为单个 textarea 自动升档**,不做列数响应式折叠。
|
||||
- 归到 `sm` 时不能只改 preset,**字段布局也要落到单列**:常规 `ElCol` 用 `span=24`,除非已判定为复合内容特例。
|
||||
|
||||
### 8.3 复合内容特例
|
||||
|
||||
左右分栏 / 表单+表格 / 表单+树 / 关系编辑器 / 时间线 / 大段说明区 → 不强按字段数归类,按内容复杂度评估 `md`/`lg` 或更宽。**只有无法合理归入"纯表单三档"时才允许特例。**
|
||||
|
||||
### 8.4 表单布局
|
||||
|
||||
- 常规 CRUD:`label-position="top"` + `ElRow + ElCol` 双列 + `gutter=16`。
|
||||
- 普通字段 `span=12`;长文本/重量级字段 `span=24`。
|
||||
- 字段 ≤ 6 默认按单列理解。
|
||||
|
||||
### 8.5 其他
|
||||
|
||||
- **禁止**用页面级宽范围样式覆盖整页 `.business-form-dialog` 来统一放大;如需特殊宽度,必须精确作用于目标弹框,不误伤同页其他 dialog。
|
||||
- 底部按钮固定 **取消 → 确认**,右对齐。
|
||||
- 单选组/开关字段优先复用既有钩子:`business-form-radio-group`、`business-form-switch-field`。
|
||||
- **权限按钮默认"无权限不渲染"**;只有业务状态暂时不可操作但仍需让用户感知入口存在时,才允许保留禁用态。
|
||||
|
||||
### 8.6 全局反馈(Toast / Message)
|
||||
|
||||
- **全局反馈通道只有一个**:`window.$message`(`src/components/common/app-provider.vue` 注入的 `ElMessage`),全仓 30+ 处都用它。**不要平行引入 `ElNotification` / 自定义 toast**;要求"全局风格切换"则单独立项,不要在小改动里悄悄启动。
|
||||
- **type 语义**(4 种 type → 3 类视觉语义):
|
||||
- `error` → 错误(红):操作失败、明确异常
|
||||
- `warning` → 告警(橙):用户即将出错、风险确认
|
||||
- `success` → 通知-成功(绿):操作成功
|
||||
- `info` → 通知-信息(蓝):信息告知、默认兜底说明
|
||||
- **type 选错就丑**:`warning` 是"出错警告",不要拿来表达普通信息(用 `info`);`info` 是"信息告知",不要拿来报错(用 `error`)。
|
||||
- **"先做 A 再做 B" 的引导性提示**:用 `ElFormItem :error="msg"` 红字内联(跟校验同款),**不要用 toast**——toast 适合事后反馈、不阻断流程,对引导性提示体验差。
|
||||
- **全局视觉**(实色背景 + 白字 + 阴影 + `$radius` 圆角)由 `src/styles/scss/element-plus.scss` 末尾的 `.el-message` 块统一维护,**业务页面禁止覆盖** `.el-message-*` 样式。要调颜色就改 `element-plus.scss`,不要在业务页 scoped 散落。
|
||||
|
||||
```ts
|
||||
window.$message?.success('保存成功');
|
||||
window.$message?.error('保存失败:xxx');
|
||||
window.$message?.warning('当前修改未保存,确认离开?');
|
||||
window.$message?.info('未选择计划开始日期,已按今日为基准计算');
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 9. 接口、路由、权限
|
||||
|
||||
- 默认走 `src/service/request/index.ts`,不另造鉴权/加密/错误处理/token 刷新。
|
||||
- 接口前缀、服务常量优先复用 `src/constants/service.ts`。
|
||||
- 后端契约变化时同步检查 `src/service/api/*`、`src/typings/api/*`、相关页面、说明文档。
|
||||
- 路由/菜单/权限改动时同步检查 `build/plugins/router.ts`、`src/router/routes/*`、`src/store/modules/route/*`、相关文档。
|
||||
- 路由产物过期:改源配置 + `pnpm gen-route`,**不要把手工修补生成文件当常规方案**。
|
||||
|
||||
---
|
||||
|
||||
## 10. 运行时字典
|
||||
|
||||
- 由 `src/store/modules/dict/index.ts` 管理,登录后通过 `/system/dict-data/frontend-cache` 初始化。**不要在页面重复直调字典接口。**
|
||||
- 字典编码常量收敛在 `src/constants/dict.ts`。**不要散落硬编码 `dictType`。**
|
||||
- **不要猜字典编码**:先从后端接口文档/字段契约/系统字典管理页确认真实 `dictType`,再写入常量。
|
||||
- 常量加中文注释:对应业务字段 + 编码确认来源。
|
||||
- 后端编码带历史命名痕迹(如 `rdms_product_direction`)时,前端常量名按真实业务语义命名,**不扩散历史误导**。
|
||||
|
||||
### 字典使用方式
|
||||
|
||||
| 场景 | 组件/Hook |
|
||||
|---|---|
|
||||
| 表单下拉 | `src/components/custom/dict-select.vue` |
|
||||
| 普通文案回显 | `src/components/custom/dict-text.vue` |
|
||||
| 标签态回显 | `src/components/custom/dict-tag.vue`(标签颜色业务页自决) |
|
||||
| script setup / TSX 列格式化 / 复杂判断 | `src/hooks/business/dict.ts` 的 `useDict(dictCode)` |
|
||||
|
||||
`useDict` 常用能力:`dictOptions`、`getItem`、`getLabel`、`getLabels`、`hasValue`。
|
||||
|
||||
`DictSelect` 默认只展示启用项;需包含禁用项显式 `:only-enabled="false"`。
|
||||
|
||||
```vue
|
||||
<DictSelect v-model="form.directionCode" :dict-code="RDMS_OBJECT_DIRECTION_DICT_CODE" />
|
||||
<DictText :dict-code="RDMS_OBJECT_DIRECTION_DICT_CODE" :value="row.directionCode" />
|
||||
<DictTag :dict-code="SYSTEM_USER_COMPANY_DICT_CODE" :value="row.companyCode" type="info" />
|
||||
```
|
||||
|
||||
```ts
|
||||
const { getLabel, getLabels } = useDict(RDMS_OBJECT_DIRECTION_DICT_CODE);
|
||||
const directionLabel = getLabel(row.directionCode);
|
||||
const directionLabels = getLabels(row.directionCodes, { separator: ',' });
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 11. 页面资源 & 菜单目录(三层不同概念)
|
||||
|
||||
- `component` = 渲染哪个页面组件
|
||||
- 菜单目录 = 挂在哪个业务目录、最终 URL
|
||||
- 页面资源 = 白名单中选择并回填组件信息
|
||||
|
||||
**不要混淆**:组件键 `view.system_dict` ≠ 必须挂 `/system/dict`,同一个组件允许在新业务目录下复用。
|
||||
|
||||
页面资源白名单的标准路径是**参考路径,不应反向覆盖菜单树已确定的最终 URL**。
|
||||
|
||||
菜单编辑器/页面资源选择逻辑改动时,保证"组件可解析、资源合法、最终 URL 由菜单树决定",**不要强绑标准路径与父目录前缀**。
|
||||
|
||||
---
|
||||
|
||||
## 12. ID 类型铁律(强约束,必须严格执行)
|
||||
|
||||
> 后端主键 ID / 用户 ID / 对象 ID / 雪花 ID / Long ID **一律按 `string` 接收和传递**。
|
||||
|
||||
**原因**:JS `number` 无法稳定承载 Long 精度;序列化精度丢失;`number/string` 键不一致 → 回显/筛选/映射/路由参数/对象上下文异常。
|
||||
|
||||
### 落实范围(全部)
|
||||
`typings`、API 返回类型、表单 model、组件 props/emits、`ElSelect` 的 value、路由参数、查询参数、`Map` 键、筛选条件、store 状态 → **全部 `string` / `string[]`**。
|
||||
|
||||
### 禁止写法
|
||||
- ❌ `Number(id)` / `+id` / `parseInt(id)` / `parseFloat(id)` / `Math.floor(id)`
|
||||
- ❌ 任何"为了比较/传参/回填/提交而把 ID 转 number"
|
||||
|
||||
### 比较与映射
|
||||
- ✅ `id === targetId`
|
||||
- ✅ `Map<string, T>` / `Set<string>`
|
||||
- ❌ 不混用 `number/string` 双口径
|
||||
|
||||
### 后端契约风险(关键)
|
||||
- 后端暂返数值型 ID 时,**前端在 `typings` / API 适配层 / 进业务层前转 `string`**,不要按 `number` 扩散。
|
||||
- **但如果后端把超 JS 安全整数的 Long 直接作为 JSON 数字返回,前端再 `String(number)` 只能得到"已经丢精度后的错误字符串"**。这种情况必须明确记为接口契约风险,不能误判为"已安全处理"。
|
||||
- 最稳妥契约:**后端 Long ID 直接按字符串返回**;前端全链路按字符串。后端未改,前端也不得新增 `number` 口径 ID。
|
||||
|
||||
### 历史代码原则
|
||||
不再新增 `number` 口径;当前任务触达相关链路时**顺手矫正**;不要继续复制历史写法。
|
||||
|
||||
---
|
||||
|
||||
## 13. 代码约定
|
||||
|
||||
- 优先用别名导入(`@/...`、`~/...`),避免长相对路径。
|
||||
- 与 TypeScript 严格模式兼容。
|
||||
- 沿用 Vue SFC 风格:`script setup`、类型化 store、职责单一的小型 composable/helper。
|
||||
- UI 沿用 `src/layouts` 和 `src/theme` 现有模式,不平行引入新设计体系。
|
||||
- **注释克制**:只在代码本身不直观时补必要中文说明;不删原有有效注释;不写没信息量的注释。
|
||||
- 中文内容用 UTF-8,自检显示;**不要用改成英文规避编码问题**。
|
||||
- Node ESM 脚本:避免 `__filename`/`__dirname` 这类下划线悬挂命名。
|
||||
- 批量异步并发优先 `Promise.all(...)`,不在循环里默认 `await`。
|
||||
- 手写 `new Promise(...)` 用 block 写法,不要写成隐式返回的单表达式箭头函数。
|
||||
- 函数若同时承担"判断 + 转换 + 组装 + 递归",拆 helper。
|
||||
|
||||
---
|
||||
|
||||
## 14. 校验
|
||||
|
||||
### 14.1 校验口径
|
||||
|
||||
| 任务类型 | 默认校验 |
|
||||
|---|---|
|
||||
| 前端页面/交互/样式 | `pnpm typecheck`,不主动跑测试 |
|
||||
| 需更严格静态检查 | 加 `pnpm lint` |
|
||||
| 涉及路由 | 加 `pnpm gen-route` |
|
||||
| 影响页面资源清单/菜单资源选择/页面白名单 | 加 `pnpm gen:page-resource-manifest` |
|
||||
|
||||
### 14.2 静态校验自查清单
|
||||
- 调用链是否闭环?改动是否在正确分层?
|
||||
- 路由/菜单/权限标识/主题状态/资源注册 是否前后一致?
|
||||
- 改动范围是否控制在最小集合?
|
||||
- 文档/类型/接口封装/生成产物 是否需要同步更新?
|
||||
|
||||
---
|
||||
|
||||
## 15. 提交规范
|
||||
|
||||
- **`pre-commit` 执行 `pnpm typecheck && pnpm lint && git diff --exit-code`**:能跑 ≠ 能提交。
|
||||
- `pnpm lint` 会跑 `eslint . --fix`:提交失败后检查是否有被自动修复但未重新暂存的文件。
|
||||
- 推荐提交方式:`pnpm commit:zh`(交互选 type/scope/description)。
|
||||
- 手动提交:`git commit -m "type(scope): 描述"`,参考 `docs/前端提交规范与示例.md`。
|
||||
- `commit-msg` 钩子校验 Conventional Commits。
|
||||
|
||||
---
|
||||
|
||||
## 16. 协作记忆(与本仓库用户共事)
|
||||
|
||||
- 用户语言:**中文**(始终用中文回复)。
|
||||
- **不主动跑 git 命令**(用户已强调)。
|
||||
- 默认精简、结论先行。
|
||||
- 工作树脏时不要回退无关变更。
|
||||
- 改架构/权限/页面规范前先翻 `docs/`,避免与现有约定冲突。
|
||||
- 改布局/主题时同时检查 `src/layouts/*` 与 `src/store/modules/theme/*`。
|
||||
- 改路由/菜单时同时检查 `build/plugins/router.ts` 与 `src/router/routes/*`。
|
||||
|
||||
---
|
||||
|
||||
## 17. 常用命令速查
|
||||
|
||||
```bash
|
||||
pnpm typecheck # 最小静态校验
|
||||
pnpm lint # eslint . --fix
|
||||
pnpm gen-route # 重新生成路由产物
|
||||
pnpm gen:page-resource-manifest # 同步页面资源清单
|
||||
pnpm commit:zh # 交互式提交(推荐)
|
||||
pnpm dev # dev server (9527)
|
||||
pnpm preview # preview server (9725)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 18. 业务对象状态颜色
|
||||
|
||||
- 集中文件:`src/constants/status-tag.ts`
|
||||
- 各业务域 `statusCode → ElTag type` 在此统一维护,**不要在各页面散落硬编码**。
|
||||
- 已支持域:`projectExecution`、`projectTask`;预留:`project`、`product`、`requirement`、`workOrder`。
|
||||
- helper:`getStatusTagType(domain, statusCode)`,未匹配回退 `'info'`。
|
||||
- 业务模块写薄包装,例如 `getExecutionStatusTagType(code) = getStatusTagType('projectExecution', code)`。
|
||||
- 新增对象域:在 `StatusDomain` 加枚举 + `statusTagTypeRegistry` 加对应 map;调用方写一个 wrapper 即可。
|
||||
- 后端契约:未来若状态字典返颜色字段,调用方优先取后端值,缺失时回退 helper(前端兜底)。
|
||||
Reference in New Issue
Block a user