Files
cn-rdms-web/AGENTS.md

225 lines
14 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.

# AGENTS.md
本文件为后续编码代理提供 `cn-rdms-web` 的稳定仓库上下文。
在修改代码前请先阅读。
## 适用范围
本说明适用于以 `C:\code\gitea\rdms\cn-rdms-web` 为根目录的整个仓库。
描述仓库现状时,以当前代码、当前配置、当前文档中可直接验证的事实为准;除非用户明确要求,不引入历史实现、过渡方案或猜测来解释当前行为。
默认回答保持精简,优先给结论、改动点、验证方式和必要风险;如果用户只要求分析、审阅或方案,就停留在分析层,不主动扩展到实现层。
## 交互与执行原则
- 进入实施阶段前,先说明目标、涉及模块、预计改动点和验证方式。
- 先定义验证方式,再执行修改和校验;如果没有实际运行命令,需要明确说明只做了静态检查。
- 只在当前任务需要的最小范围内改动,避免把无关重构混入同一次修改。
## 项目概览
- 应用类型RDMS 系统的 Vue 3 后台前端
- 包管理器:`pnpm`
- 运行时与工具链Vite 7、TypeScript、Pinia、Element Plus、UnoCSS
- 工作区包位于 `packages/*`,通过 `@sa/*` 引用
- Node 版本要求:`>=20.19.0`
- pnpm 版本要求:`>=8.7.0`
## 项目骨架主线
当前项目不是边写边拼的页面集合,而是已经形成闭环的后台前端骨架。后续改动优先顺着这几条主线做,而不是平行再起一套:
- 路由来源统一:页面文件与自定义路由作为源头,经 `elegant-router` 生成路由产物,再由 `build/plugins/router.ts` 集中补齐 `meta`
- 权限入口统一:常量路由和权限路由明确分流,`route store` 负责初始化、菜单生成、缓存路由和面包屑
- 请求入口统一:所有业务请求默认走 `src/service/request/index.ts`
- 页面套路统一:列表页通常拆为搜索区、表格区、操作弹层/抽屉和 `modules/*` 子组件
- 衍生资产统一:页面资源白名单从路由结构生成,不手工维护第二份页面清单
## 环境与构建说明
- Vite 路径别名:`@` -> `src`
- Vite 路径别名:`~` -> 仓库根目录
- 开发服务器默认端口:`9527`
- 预览服务器默认端口:`9725`
- 环境文件包括 `.env``.env.dev``.env.prod`
## 关键目录与文件
- `src/views`:业务页面
- `src/components`:共享组件
- `src/layouts`:应用壳、头部、侧栏、菜单、标签页、主题抽屉
- `src/store/modules`Pinia 模块,包含 app、auth、route、tab、theme
- `src/service/api`:接口封装与请求参数拼装
- `src/service/request`统一请求实例、鉴权头、加密、错误处理、token 刷新
- `src/router/routes`:自定义路由定义
- `src/router/elegant`:自动生成的路由产物
- `src/theme/settings.ts`:默认主题与布局设置
- `build/plugins/router.ts`elegant-router 配置与路由元信息生成逻辑
- `src/hooks/common/table.ts`:列表页表格 hook 主入口
- `src/hooks/common/form.ts`:表单校验与表单实例 hook
- `src/styles/scss/element-plus.scss`:当前项目表格、弹层、按钮、表单密度与公共壳样式标准
- `packages/*`:项目内本地共享库
- `docs/`:当前工作上下文的一部分,做架构级、权限级、页面规范级改动前优先查阅
## 生成文件
除非有非常明确的理由并且同步维护生成流程,否则不要手工修改生成文件。
- `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`
## 路由与导航开发口径
- 新增业务页面时,优先通过页面文件与 `build/plugins/router.ts` 补齐路由,不要手工在多个位置重复注册同一页面。
- 路由 `meta` 的中心落点是 `build/plugins/router.ts`;新增业务页的 `icon``order``roles``keepAlive` 优先在那里集中维护。
- 当前代码链路仍保留 `i18nKey` 兼容字段,但它是兼容保留项,不是新增业务页面必须补齐的默认要求。
- `meta.constant = true` 的路由属于常量路由;其余默认属于权限路由。
- 常量路由维护入口优先是 `build/plugins/router.ts``src/router/routes/custom-routes.ts`,不要把常量路由散落到业务页面逻辑里。
- 菜单图标约定属于路由契约的一部分:`meta.icon` 表示 Iconify 图标,`meta.localIcon` 表示本地 SVG 图标;不要混用字段语义。
## 分层职责约束
### `src/views`
- 页面层负责页面编排、交互状态、表单行为和对 store/service 的组合调用。
- 不要在页面组件里散落 URL 拼接、token 注入、统一错误提示或权限路由推导逻辑。
### `src/components`
- 共享组件负责可复用 UI 或局部业务部件。
- 不要把只服务于单个页面的复杂流程长期堆在公共组件目录中。
### `src/service/api`
- API 层负责接口封装、请求参数归一化、查询字符串拼装和返回类型对齐。
- 不要在 `views``store``components` 中重复手写同一接口地址和参数序列化逻辑。
### `src/service/request`
- 请求层负责统一请求实例、鉴权头、接口加密、成功码判定、token 刷新和通用错误处理。
- 除非任务明确需要,不要平行引入新的 `axios`/`fetch` 调用链绕开现有封装。
### `src/store/modules`
- Store 负责跨页面共享状态,例如认证、路由、标签页、主题、布局和全局 UI 状态。
- 临时性的页面局部状态优先留在页面组件或 composable 中,不要无边界堆进全局 store。
### `src/router` 与 `build/plugins/router.ts`
- 路由、菜单、权限标识、首页配置和路由元信息优先沿用当前 elegant-router 与 route store 链路。
- 不要只在页面里临时写条件分支来替代正式的路由、菜单或权限配置。
### `src/layouts` 与 `src/theme`
- 布局壳和主题设置是全局行为源头相关改动要同时检查布局组件、theme store 和默认设置。
- 不要在业务页面里复制一套平行的布局状态或主题状态。
## 业务页面开发风格
- 页面组件保持“编排层薄”。页面文件主要负责搜索参数、表格 hook、列定义、弹层开关、接口调用编排不把大量表单细节和重复交互直接堆在页面根组件里。
- 列表页优先拆出同目录下的 `modules/*` 子组件,例如搜索组件、操作弹层、详情抽屉、资源面板等。
- 系统管理下现有 `user``role``menu``dict` 页面可以作为参考实现,新增同类页面优先沿用它们的拆分方式。
- 搜索组件优先复用 `src/components/custom/table-search-panel.vue` 作为外壳。搜索模块本身应尽量只接收 `model`,只向外发出 `reset` / `search`,不直接承载列表请求逻辑。
- 列表能力优先复用 `src/hooks/common/table.ts` 中的 `useUIPaginatedTable``useTableOperate``defaultTransform`
- 表单能力优先复用 `src/hooks/common/form.ts` 中的 `useForm``useFormRules`
- 当前项目的真实业务口径是“内网中文优先”。新增业务页不必为了形式强行补全国际化键;但如果是在已有大量 `$t(...)` 的页面或模块内继续开发,优先保持该局部代码风格一致,不要半页中文直写、半页国际化混用。
## 表格、搜索区与操作列约束
- 搜索区按钮组保持在最右侧;存在折叠项时,按钮顺序保持为“展开/收起 -> 重置 -> 查询”。
- 不要在每个页面重新拼一套搜索区骨架,优先延续 `TableSearchPanel` 的结构和交互。
- 表格操作列优先复用 `src/components/custom/business-table-action-cell.tsx`
- 操作数 `<= 2` 时默认直出;操作数 `> 2` 时优先收敛为 `1 个直出主按钮 + 1 个更多按钮`
- 表格、按钮、弹层、表单的尺寸和间距标准优先由 `src/styles/scss/element-plus.scss` 和公共组件承接,不在业务页面散落写新的局部尺寸作为事实标准。
## 表单与弹层约束
- 新增、编辑能力优先沿用 `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`
- 现有公共壳组件已内置尺寸预设:`dialog``sm/md/lg` 对应 `520px/640px/720px``drawer``md/lg/xl` 对应 `480px/720px/960px`;优先使用预设值而不是页面内重复硬编码宽度。
- 常规 CRUD 表单优先使用 `label-position="top"``ElRow + ElCol` 双列布局、`gutter=16`;普通字段优先 `span=12`,长文本或重量级字段优先 `span=24`
- 底部按钮顺序固定为“取消 -> 确认”,并保持右对齐。
- 单选组和开关类字段优先复用仓库既有样式钩子,例如 `business-form-radio-group``business-form-switch-field`
## 接口、路由与权限约束
- 默认沿用 `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`,不要把手工修补生成文件当成常规方案。
## 页面资源与菜单目录约束
- 页面组件键、页面资源、菜单目录是三层不同概念,不要把它们当成同一个值。
- `component` 决定“渲染哪个页面组件”;菜单目录决定“挂在哪个业务目录下”和最终 URL页面资源主要用于从白名单中选择并回填组件信息。
- 不要因为组件键是 `view.system_dict`,就推导它只能挂在 `/system/dict`;同一个页面组件允许挂在新的业务目录下复用。
- 页面资源白名单中的标准路径是参考路径,不应反向覆盖当前菜单树已经确定的最终 URL。
- 涉及菜单编辑器或页面资源选择逻辑时,优先保证“组件可解析、资源合法、最终 URL 由菜单树决定”,不要强绑页面资源标准路径和父级目录前缀。
## 代码约定
- 优先使用现有别名导入(`@/...``~/...`),避免过长的相对路径。
- 保持与 TypeScript 严格模式兼容。
- 遵循仓库现有的 Vue SFC 风格:`script setup`、类型化 store、职责单一的小型 composable/helper。
- 修改界面时优先延续 `src/layouts``src/theme` 中已有的 UI 模式,不要平行引入另一套设计体系。
- 注释保持克制,只在代码本身不够直观时补充必要说明。
## 注释与编码
- 新增或修改代码时,关键分支、关键约束和非直观实现可以补充简洁中文注释。
- 不要为了省事删除原有有效注释,也不要添加没有信息量的注释。
- 写入中文内容时保持 UTF-8 编码,并自行确认显示正常;不要用改成英文来规避编码问题。
## 校验建议
对有实际影响的代码改动,优先执行:
- `pnpm typecheck`
- `pnpm lint`
如果改动涉及路由,额外执行:
- `pnpm gen-route`
如果改动影响页面资源清单、菜单资源选择或页面白名单,额外执行:
- `pnpm gen:page-resource-manifest`
静态校验时,至少自查以下几点:
- 调用链是否闭环,改动是否落在正确的分层位置
- 路由、菜单、权限标识、主题状态或资源注册是否前后一致
- 改动范围是否控制在当前任务所需的最小集合内
- 文档、类型定义、接口封装或生成产物是否需要同步更新
## 提交与脚本约束
- `pre-commit` 会执行 `pnpm typecheck && pnpm lint && git diff --exit-code`,因此“代码能跑”不等于“可以提交”。
- `pnpm lint` 实际会执行 `eslint . --fix`;提交失败后要检查是否有被自动修复但尚未重新暂存的文件。
- 提交规范说明以 `docs/前端提交规范与示例.md` 为准;最稳妥的提交方式是执行 `pnpm commit:zh`,按交互选择 `type``scope``description`
- `commit-msg` 钩子会校验 Conventional Commits推荐使用 `pnpm commit:zh` 生成提交信息。
- 如果手动提交,执行 `git commit -m "type(scope): 描述"`,并确保 `type``scope`、描述写法与 `docs/前端提交规范与示例.md` 保持一致。
- 提交信息基础格式遵循 `type(scope): 描述`
- 写 Node ESM 脚本时,避免沿用 `__filename``__dirname` 这类下划线悬挂命名。
- 能并发的批量异步任务优先 `Promise.all(...)`,不要默认在循环体里直接 `await`
- 手写 `new Promise(...)` 时优先使用 block 写法,不要把 executor 写成隐式返回值的单表达式箭头函数。
- 一个函数如果开始同时承担“判断 + 转换 + 组装 + 递归”,优先拆 helper避免把复杂度堆到单个函数里。
## 代理工作说明
- 编辑前先检查当前 `git diff`,仓库中可能已经存在用户进行中的修改。
- 在工作树不干净时,不要回退与当前任务无关的变更。
- 修改布局或主题行为时,同时检查 `src/layouts/*``src/store/modules/theme/*`,因为相关逻辑分散在界面层和状态层。
- 修改路由或菜单时,同时检查 `build/plugins/router.ts``src/router/routes/*`
- 做架构级、权限级或页面规范级修改前,优先查阅 `docs/` 中现有说明,避免与当前文档约定冲突。