Files
cn-rdms-web/AGENTS.md

14 KiB
Raw Blame History

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/modulesPinia 模块,包含 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.tselegant-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;新增业务页的 iconorderroleskeepAlive 优先在那里集中维护。
  • 当前代码链路仍保留 i18nKey 兼容字段,但它是兼容保留项,不是新增业务页面必须补齐的默认要求。
  • meta.constant = true 的路由属于常量路由;其余默认属于权限路由。
  • 常量路由维护入口优先是 build/plugins/router.tssrc/router/routes/custom-routes.ts,不要把常量路由散落到业务页面逻辑里。
  • 菜单图标约定属于路由契约的一部分:meta.icon 表示 Iconify 图标,meta.localIcon 表示本地 SVG 图标;不要混用字段语义。

分层职责约束

src/views

  • 页面层负责页面编排、交互状态、表单行为和对 store/service 的组合调用。
  • 不要在页面组件里散落 URL 拼接、token 注入、统一错误提示或权限路由推导逻辑。

src/components

  • 共享组件负责可复用 UI 或局部业务部件。
  • 不要把只服务于单个页面的复杂流程长期堆在公共组件目录中。

src/service/api

  • API 层负责接口封装、请求参数归一化、查询字符串拼装和返回类型对齐。
  • 不要在 viewsstorecomponents 中重复手写同一接口地址和参数序列化逻辑。

src/service/request

  • 请求层负责统一请求实例、鉴权头、接口加密、成功码判定、token 刷新和通用错误处理。
  • 除非任务明确需要,不要平行引入新的 axios/fetch 调用链绕开现有封装。

src/store/modules

  • Store 负责跨页面共享状态,例如认证、路由、标签页、主题、布局和全局 UI 状态。
  • 临时性的页面局部状态优先留在页面组件或 composable 中,不要无边界堆进全局 store。

src/routerbuild/plugins/router.ts

  • 路由、菜单、权限标识、首页配置和路由元信息优先沿用当前 elegant-router 与 route store 链路。
  • 不要只在页面里临时写条件分支来替代正式的路由、菜单或权限配置。

src/layoutssrc/theme

  • 布局壳和主题设置是全局行为源头相关改动要同时检查布局组件、theme store 和默认设置。
  • 不要在业务页面里复制一套平行的布局状态或主题状态。

业务页面开发风格

  • 页面组件保持“编排层薄”。页面文件主要负责搜索参数、表格 hook、列定义、弹层开关、接口调用编排不把大量表单细节和重复交互直接堆在页面根组件里。
  • 列表页优先拆出同目录下的 modules/* 子组件,例如搜索组件、操作弹层、详情抽屉、资源面板等。
  • 系统管理下现有 userrolemenudict 页面可以作为参考实现,新增同类页面优先沿用它们的拆分方式。
  • 搜索组件优先复用 src/components/custom/table-search-panel.vue 作为外壳。搜索模块本身应尽量只接收 model,只向外发出 reset / search,不直接承载列表请求逻辑。
  • 列表能力优先复用 src/hooks/common/table.ts 中的 useUIPaginatedTableuseTableOperatedefaultTransform
  • 表单能力优先复用 src/hooks/common/form.ts 中的 useFormuseFormRules
  • 当前项目的真实业务口径是“内网中文优先”。新增业务页不必为了形式强行补全国际化键;但如果是在已有大量 $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
  • 现有公共壳组件已内置尺寸预设:dialogsm/md/lg 对应 520px/640px/720pxdrawermd/lg/xl 对应 480px/720px/960px;优先使用预设值而不是页面内重复硬编码宽度。
  • 常规 CRUD 表单优先使用 label-position="top"ElRow + ElCol 双列布局、gutter=16;普通字段优先 span=12,长文本或重量级字段优先 span=24
  • 底部按钮顺序固定为“取消 -> 确认”,并保持右对齐。
  • 单选组和开关类字段优先复用仓库既有样式钩子,例如 business-form-radio-groupbusiness-form-switch-field

接口、路由与权限约束

  • 默认沿用 src/service/request/index.ts 中现有请求链路,不要另造一套鉴权、加密、错误处理或 token 刷新机制。
  • 接口前缀、服务常量优先复用现有常量定义,例如 src/constants/service.ts
  • 后端契约变化时,至少同步检查 src/service/api/*src/typings/api/*、相关页面调用和说明文档是否一致。
  • 涉及路由、菜单、权限的改动时,同时检查 build/plugins/router.tssrc/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/layoutssrc/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,按交互选择 typescopedescription
  • commit-msg 钩子会校验 Conventional Commits推荐使用 pnpm commit:zh 生成提交信息。
  • 如果手动提交,执行 git commit -m "type(scope): 描述",并确保 typescope、描述写法与 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.tssrc/router/routes/*
  • 做架构级、权限级或页面规范级修改前,优先查阅 docs/ 中现有说明,避免与当前文档约定冲突。