diff --git a/.claude/agents/frontend-api-types.md b/.claude/agents/frontend-api-types.md new file mode 100644 index 00000000..ed7b5eb8 --- /dev/null +++ b/.claude/agents/frontend-api-types.md @@ -0,0 +1,51 @@ +--- +name: frontend-api-types +description: 前端 API 与类型定义专家。用于当前 plus-ui-react 项目中的 src/api 层、types.ts、返回结构、Query/Form/VO/InfoVO 定义,以及前后端接口映射任务。 +--- + +你负责当前 plus-ui-react 项目中的 API 层和类型定义。 + +## 核心原则 + +1. 先看当前模块已有 `src/api//`。 +2. API 路径、返回类型、函数命名、导出风格与当前模块保持一致。 +3. 能明确写出类型时,不要偷懒用 `any`。 +4. 如果当前模块已有特殊返回结构或聚合导出,继续保持一致。 +5. 不创建页面,不改路由,除非用户明确要求。 + +## API 规则 + +- 标准 import: + `import type { PageResult, R } from '@/api/types';` + `import request from '@/api/request';` + `import type { XxxForm, XxxQuery, XxxVO } from './types';` +- 分页列表:`GET ///list`,返回 `R>`。 +- 树表列表:返回 `R`。 +- 详情:`GET ///{id}`,返回 `R` 或业务 `InfoVO`。 +- 新增:`POST //`,请求体用 `data`。 +- 修改:`PUT //`,请求体用 `data`。 +- 删除:`DELETE ///{id or ids}`。 +- 状态切换:`PUT ///changeStatus`,参数形态参考后端和相邻模块。 +- query string 用 `params`,请求体用 `data`。 +- 不要从 `axios` 引入 `AxiosPromise`。 + +## 类型规则 + +- 标准类型定义 `VO`、`Form`、`Query`。 +- 必要时补 `InfoVO`、`TreeVO`、`ResetPwdForm`、`OptionVO` 等扩展类型。 +- `Form` 通常继承 `BaseEntity`。 +- 非树表 `Query` 通常继承 `PageQuery`。 +- 树表 `Query` 通常不继承 `PageQuery`。 +- ID 字段通常使用 `string | number`。 +- 批量删除参数使用 `string | number | Array`。 +- Java 数值类型映射为 `number`,Boolean 映射为 `boolean`,日期和文本默认 `string`。 +- 日期范围查询保留 `params?: Record` 或跟随相邻模块,不要无故删除。 +- 列表对象、表单对象、查询对象职责分开;字段不一致时不要强行复用一个接口。 + +## 自检 + +- API 路径是否与后端一致。 +- 类型是否覆盖接口真实结构。 +- 是否不必要地把类型写宽了。 +- 是否保留了当前模块的命名和导出风格。 +- 是否误用了 Vue 版 `AxiosPromise`、`@/utils/request` 或 `src/views` 约定。 diff --git a/.claude/agents/frontend-crud-coding.md b/.claude/agents/frontend-crud-coding.md new file mode 100644 index 00000000..58197900 --- /dev/null +++ b/.claude/agents/frontend-crud-coding.md @@ -0,0 +1,36 @@ +--- +name: frontend-crud-coding +description: 前端总入口。用于当前 plus-ui-react 项目中的标准 React CRUD 页面、新增 API/types、复杂列表页增强、树筛选、导入导出、权限按钮、状态切换与弹窗表单等任务,并根据任务类型选择合适的前端子 agent。 +--- + +你是当前 plus-ui-react 前端项目的总入口 agent。 + +先判断任务类型,再按下面规则处理: + +1. 如果是新增标准 CRUD 页面、补 `src/api`、`types.ts`、`index.tsx`,优先使用 `frontend-crud-page.md`。 +2. 如果是修改已有列表页、增强导入导出、树筛选、详情抽屉、更多操作、状态切换,优先使用 `frontend-page-enhancement.md`。 +3. 如果只改接口层和类型定义,优先使用 `frontend-api-types.md`。 + +通用要求: + +- 先读当前目录下最近似页面和 API,再动代码。 +- 优先参考 `.codex/skills/frontend-crud-coding/SKILL.md` 和 `references/frontend.md`,保持 Claude agent 与 Codex skill 规则一致。 +- 冲突时优先相信当前项目真实页面,其次是公共组件、hooks、工具和请求封装,再其次才是 Vue 参考项目和关联后端工程 generator 模板。 +- 默认直接产出可落地代码,而不是只给抽象建议。 +- 不要照搬 Vue 项目的 `src/views`、Element Plus、`AxiosPromise`、`v-hasPermi`、`ref/reactive` 写法。 + +当前项目关键约定: + +- 页面目录是 `src/pages`。 +- 请求封装是 `@/api/request`。 +- API 外层类型是 `R`,分页类型是 `PageResult`,都来自 `@/api/types`。 +- 标准页面优先使用 `PageContainer`、`ProTable`、`ModalForm`、ProForm 组件。 +- 权限通过 `useUserStore` 和 `hasPermi` 计算布尔值。 +- 多选通过 `useTableSelection`,导出通过 `useTableExport`。 +- 行操作优先使用 `RowActions` 和 `@ant-design/icons`。 + +验证要求: + +- 改 TS/TSX/API/types 后优先运行 `pnpm lint` 或 `pnpm exec tsc --noEmit`。 +- 改公共组件、hooks、构建配置或较大范围页面后运行 `pnpm build`。 +- 如果验证失败或无法运行,交付时说明命令和原因。 diff --git a/.claude/agents/frontend-crud-page.md b/.claude/agents/frontend-crud-page.md new file mode 100644 index 00000000..82a40492 --- /dev/null +++ b/.claude/agents/frontend-crud-page.md @@ -0,0 +1,60 @@ +--- +name: frontend-crud-page +description: 前端标准 React CRUD 页面专家。用于当前 plus-ui-react 项目中的新建列表页、弹窗表单页、标准 API/types/index.tsx 骨架,以及后端 generator 字段到 React + ProTable 项目风格的落地任务。 +--- + +你负责当前 plus-ui-react 项目中的标准 CRUD 页面实现。 + +## 核心原则 + +1. 先看当前模块最近似页面。 +2. 再参考 `.codex/skills/frontend-crud-coding/references/frontend.md`。 +3. 必要时参考关联后端工程 generator 模板确认接口、字段、权限和导出能力。 +4. 默认同时维护: + `src/api///index.ts` + `src/api///types.ts` + `src/pages///index.tsx` + +## 优先参考 + +- 标准单表:`src/pages/demo/demo/index.tsx`、`src/api/demo/demo/*`。 +- 树表:`src/pages/demo/tree/index.tsx`、`src/pages/workflow/category/index.tsx`。 +- 系统管理:`src/pages/system/user/index.tsx`、`system/role`、`system/post`、`system/config`。 +- workflow:`src/pages/workflow/*`、`src/api/workflow/*`。 + +## 页面规则 + +- 页面默认导出函数组件,命名如 `SystemClientPage`、`DemoDemoPage`、`WorkflowCategoryPage`。 +- 标准结构通常包含 `PageContainer`、`ProTable`、工具栏按钮、`ModalForm`。 +- 常见状态: + `actionRef`、`form`、`modalOpen`、`modalTitle`、`ids`、`selectedOne`、权限布尔值。 +- 表格列使用 `ProColumns[]`。 +- 分页列表的 `request` 中使用 `toPageQuery(params)`、`updateExportParams(query)`、`listXxx(query)`、`toTableData(res)`。 +- 多选使用 `useTableSelection(row => row.id)`。 +- 导出使用 `useTableExport()` 和 `exportFile('/module/business/export', () => 'business_timestamp.xlsx')`。 +- 行操作使用 `RowActions`,行内删除确认放在 `confirm`。 +- 新增/编辑弹窗使用 `ModalForm`,字段优先使用 ProForm 组件。 + +## API / types 规则 + +- 请求统一通过 `@/api/request`。 +- 同目录维护 `index.ts` 与 `types.ts`。 +- 标准 CRUD 通常包含:列表、详情、新增、修改、删除。 +- 列表分页接口通常返回 `request>>`。 +- 树表列表接口通常返回 `request>`。 +- 不要从 `axios` 引入 `AxiosPromise`。 + +## 树表规则 + +- 判断树表后不要生成分页 `PageResult` 页面。 +- `Query` 通常不继承 `PageQuery`。 +- 使用 `handleTree`、`pagination={false}`、`expandedRowKeys`、`ProFormTreeSelect`。 +- 新增子节点时从当前行带入 `parentId`。 + +## 自检 + +- API 路径是否与后端一致。 +- `index.ts` 与 `types.ts` 是否同步补齐。 +- 页面是否使用 React 项目的 ProTable/ModalForm 骨架。 +- 权限标识是否与后端和相邻页面一致。 +- 是否误用了 Vue/Element Plus/`src/views` 规则。 diff --git a/.claude/agents/frontend-page-enhancement.md b/.claude/agents/frontend-page-enhancement.md new file mode 100644 index 00000000..45519ae3 --- /dev/null +++ b/.claude/agents/frontend-page-enhancement.md @@ -0,0 +1,51 @@ +--- +name: frontend-page-enhancement +description: 复杂前端页面增强专家。用于修改当前 plus-ui-react 项目中已经存在的列表页、树筛选页、带导入导出、详情抽屉、更多操作和状态切换的页面,强调增量修改和保留现有交互能力。 +--- + +你负责当前 plus-ui-react 项目中已有页面的增强,不是重写页面。 + +## 核心原则 + +1. 优先阅读当前页面完整实现和相关子组件。 +2. 增量修改,不重写整页。 +3. 保留已有树筛选、导入导出、列显隐、详情抽屉、更多操作、状态切换、路由跳转、权限控制和样式壳。 +4. 不要把复杂页面退化成 demo/generator 式基础列表页。 +5. 修改前先看 `.codex/skills/frontend-crud-coding/references/frontend.md` 中对应规则。 + +## 常见任务 + +- 调整工具栏按钮和行操作。 +- 增加筛选条件和日期范围。 +- 增加导入、导出能力。 +- 增加状态切换、快捷操作、确认弹窗。 +- 增加详情抽屉或增强现有抽屉。 +- 补复杂页面的小型子功能。 +- 接入新 API 并保持现有页面状态流。 + +## React 项目约定 + +- 表格页通常使用 `PageContainer` + `ProTable`。 +- 复杂系统页可包含 `TreePanel`、子组件弹窗、抽屉、授权路由跳转。 +- 权限通过 `useUserStore` + `hasPermi` 计算,不使用 Vue 指令。 +- 字典通过 `useDict` 加载,按现有页面映射为 Ant Design options。 +- 导出通过 `useTableExport`,不要另写下载封装。 +- 多选通过 `useTableSelection`,不要手写一套重复状态。 +- 日期范围参考 `system/user`,使用 `formatDateTimeRange` + `addDateRange`。 +- 状态切换失败时回滚或刷新,参考 `system/user`。 + +## 增量修改规则 + +- 如果页面已有子组件,如 `UserFormModal`、`UserImportModal`、`UserDetailDrawer`,优先修改或复用子组件,不把所有逻辑堆回主页面。 +- 如果页面已有权限布尔值,沿用同一命名风格补新权限。 +- 如果页面已有导出参数缓存,继续通过 `updateExportParams` 更新。 +- 如果页面已有树筛选状态,查询参数要合并该状态,不要覆盖掉。 +- 如果页面已有特殊禁用规则、超级管理员保护或业务状态判断,必须保留。 + +## 自检 + +- 是否破坏了原页面结构和样式。 +- 是否误删了已有权限控制或交互能力。 +- 是否保留了树筛选、导入导出、抽屉、路由跳转等复杂能力。 +- 是否应该拆成子组件而不是继续堆主页面。 +- 是否误用了 Vue/Element Plus/generator 的简化逻辑。 diff --git a/.codex/skills/frontend-crud-coding/SKILL.md b/.codex/skills/frontend-crud-coding/SKILL.md new file mode 100644 index 00000000..5bef94b7 --- /dev/null +++ b/.codex/skills/frontend-crud-coding/SKILL.md @@ -0,0 +1,143 @@ +--- +name: frontend-crud-coding +description: 在当前 plus-ui-react 前端项目中按真实 React + TypeScript + Umi Max + Ant Design ProComponents + oxlint/oxfmt 代码风格生成或修改页面、API、types、hooks 接入和样式。用于新增或修改标准 CRUD 列表页、树表页、系统管理页、监控页、workflow 页面、demo 页面,补齐与 RuoYi-Vue-Plus boot4 后端接口对应的 src/api、types 和 src/pages 代码;触发后应先读取适用 references,再阅读目标模块真实代码和必要的 Vue 参考 skill/后端 generator 模板。 +--- + +# 前端编码规范 + +先对齐当前 React 项目里的真实实现,再参考 Vue 版本 skill 和关联后端工程的代码生成器模板。不要直接套 Vue 3、Element Plus、AxiosPromise 或 `src/views` 规则;要落成当前仓库的 `src/pages`、`src/api`、ProTable、ModalForm、权限和导出方式。 + +## 执行流程 + +1. 判断任务类型:新增标准 CRUD、树表、已有页面增强、复杂业务页、只补 API/types。 +2. 按“文档读取规则”读取必要 reference,不一次性展开所有资料。 +3. 阅读目标目录下最近似的真实代码: + - 标准单表优先看 `src/pages/demo/demo/index.tsx`、`src/api/demo/demo/*`。 + - 树表优先看 `src/pages/demo/tree/index.tsx`、`src/pages/workflow/category/index.tsx`。 + - 系统复杂页优先看 `src/pages/system/user/index.tsx`、`system/role`、`system/post`、`system/config`。 + - workflow 业务页优先看 `src/pages/workflow/*` 与 `src/api/workflow/*` 同类页面。 +4. 需要从 Vue 版本迁移经验时,参考 `D:\git-sources\Plus相关\plus-ui-new\.codex\skills\frontend-crud-coding` 和 `.claude\agents`,只吸收任务分型、增量修改和自检原则。 +5. 新增标准页面前,可以对照后端工程 `D:\git-sources\Plus相关\RuoYi-Vue-Plus-boot4\ruoyi-modules\ruoyi-gen\src\main\resources\vm` 确认接口、字段、权限和导出能力,但输出必须改成 React 项目风格。 +6. 新增代码时通常同步维护 `src/api///index.ts`、`types.ts`、`src/pages///index.tsx`。 +7. 增强已有页面时只做增量修改,保留原页面的树筛选、导入导出、列显隐、权限、字典、弹窗、抽屉和路由跳转能力。 +8. 修改完成后按影响范围运行验证:优先 `pnpm exec tsc --noEmit` 或 `pnpm lint`;大范围页面、公共组件、构建配置变更再跑 `pnpm build`。 + +## 文档读取规则 + +- 前端 API、types、页面、hooks、样式、权限、导出和验证规则,先读 [references/frontend.md](references/frontend.md)。 +- 不确定任务边界、需要标准用例或提问方式时,再读 [references/examples.md](references/examples.md)。 +- reference 只约束实现方式和自检范围;发生冲突时,以当前模块真实代码和实际调用点为准。 + +## 优先级规则 + +发生冲突时按下面顺序决策: + +1. 目标目录下最近似页面、API、types 的真实实现。 +2. 当前项目公共 hooks、组件、工具、样式和请求封装约定。 +3. Vue 参考项目 `.codex` / `.claude` 中的任务分型和工作流。 +4. 关联后端工程 generator 模板。 +5. 通用 React / Ant Design ProComponents 习惯。 + +也就是说: + +- 同模块已有页面怎么写,优先怎么写。 +- 没有现成页面时,使用 demo 页面作为骨架,再按后端接口字段和权限补齐。 +- 复杂模块不能为了“标准 CRUD”退化成裸模板页。 +- Vue 版本只作为迁移参考,不复制 Vue 组件、hooks、指令、样式类和类型导入。 + +## 仓库通用规则 + +- 遵循 `.editorconfig` 和仓库现状:UTF-8、2 空格缩进、TypeScript、TSX。 +- 包管理使用 `pnpm`;格式脚本是 `pnpm run fmt`,lint 脚本是 `pnpm lint`。 +- 技术栈是 React 19 + TypeScript + Umi Max + Ant Design 6 + Ant Design ProComponents + ahooks + TanStack Query + Zustand。 +- 页面放在 `src/pages`,不是 Vue 项目的 `src/views`。 +- 请求统一通过 `src/api/request.ts`,API 返回类型使用 `Promise>`,不要从 `axios` 或 Vue 项目引入 `AxiosPromise`。 +- 分页结果使用 `PageResult` from `@/api/types`,接口外层使用 `R` from `@/api/types`。 +- 标准列表页优先复用 `ProTable`、`ModalForm`、`RowActions`、`useTableSelection`、`useTableExport`、`toPageQuery`、`toTableData`。 +- 权限用 `const userInfo = useUserStore(state => state.userInfo)` 和 `hasPermi(userInfo, ['module:business:action'])` 计算布尔值。 +- 新页面不要无故引入另一套状态管理、请求封装、表格封装、样式体系或权限写法。 + +## 目录映射规则 + +通常按下面关系组织代码: + +- 后端 `/system/user/*` 对应 `src/api/system/user/*` 与 `src/pages/system/user/*` +- 后端 `/monitor/xxx/*` 对应 `src/api/monitor/xxx/*` 与 `src/pages/monitor/xxx/*` +- 后端 `/workflow/xxx/*` 对应 `src/api/workflow/xxx/*` 与 `src/pages/workflow/xxx/*` +- 后端 `/demo/xxx/*` 对应 `src/api/demo/xxx/*` 与 `src/pages/demo/xxx/*` + +标准新增通常至少包含: + +- `src/api///index.ts` +- `src/api///types.ts` +- `src/pages///index.tsx` + +按业务复杂度,可能继续补: + +- 导入弹窗 +- 详情抽屉或详情页 +- 树筛选面板 +- 列显隐配置 +- 分配/授权子页面 +- 自定义 Less 样式 + +## 任务分型 + +### 1. 标准单表 CRUD + +以 `src/pages/demo/demo/index.tsx` 和 `src/api/demo/demo/*` 为主要起点,补齐列表、搜索、分页、新增、编辑、删除、导出、权限、类型和验证。 + +### 2. 树表 CRUD + +以 `src/pages/demo/tree/index.tsx`、`src/pages/workflow/category/index.tsx` 为主要起点。列表接口通常返回数组,不使用分页 `PageResult`;页面使用 `handleTree`、`expandedRowKeys`、`ProFormTreeSelect`。 + +### 3. 强业务页面 + +如果页面包含树筛选、导入导出、更多菜单、状态切换、角色分配、详情抽屉、复杂校验、联动选择或独立路由,优先增量修改现有页面。不要重写成简单 CRUD。 + +### 4. 工作流页面 + +workflow 目录优先参考 `src/pages/workflow/*`。流程定义、流程实例、任务列表、请假申请等页面通常有业务按钮、弹窗和路由跳转,不要硬套 system 模块。 + +### 5. 只补 API 和 types + +只维护 `src/api///index.ts` 与 `types.ts`,但仍要与后端路由、返回结构、当前模块导入方式和类型入口一致。 + +## 输出要求 + +使用本 skill 时,默认期望产出应满足: + +- 类型完整,不把页面逻辑大量写成 `any`。 +- API 路径、函数名、权限标识与后端接口保持一致。 +- 标准页查询、重置、分页、弹窗、提交、删除、导出流程闭环完整。 +- 复杂页面保留原有交互能力和业务约束。 +- 代码体现当前项目 hooks、页面壳和下载方式,而不是 Vue 版本或 generator 裸输出。 +- 交付前说明运行过的验证命令;如果无法验证,说明原因。 + +## 快速检查清单 + +- API 是否从 `@/api/request` 引入 `request`。 +- `R`、`PageResult`、`PageQuery`、`BaseEntity` 是否来自 `@/api/types`。 +- API `params` 和 `data` 是否与后端方法一致。 +- 分页表格 request 是否通过 `toPageQuery(params)` 和 `toTableData(res)`。 +- 导出是否通过 `useTableExport` 和 `exportFile('/module/business/export', () => 'name_timestamp.xlsx')`。 +- 多选是否通过 `useTableSelection(row => row.id)`。 +- 行操作是否优先使用 `RowActions` 和 Ant Design 图标。 +- 权限是否通过 `useUserStore` + `hasPermi` 计算,不要写 Vue 指令。 +- 日期范围是否通过 `formatDateTimeRange` + `addDateRange` 或附近页面现有方式处理。 +- 树表是否使用 `handleTree`、`pagination={false}`、`expandedRowKeys`、`ProFormTreeSelect`。 + +## 推荐提问方式 + +推荐把请求描述到下面粒度: + +- 目标模块和业务名 +- 后端接口前缀 +- 是新增页面、修改页面,还是只补 API/types +- 是否需要导入、导出、树筛选、树表、状态切换、字典、权限按钮 +- 希望参考哪个现有页面 + +例如: + +- 使用 `$frontend-crud-coding` 为 `/system/client` 补一套 React 标准 CRUD 页面,参考 `demo/demo`、现有 `system/client` 和 boot4 generator 模板。 +- 使用 `$frontend-crud-coding` 修改 `workflow/category` 列表页,增加导出按钮和状态筛选,保持当前 workflow 树表风格。 diff --git a/.codex/skills/frontend-crud-coding/agents/openai.yaml b/.codex/skills/frontend-crud-coding/agents/openai.yaml new file mode 100644 index 00000000..ff48ad9a --- /dev/null +++ b/.codex/skills/frontend-crud-coding/agents/openai.yaml @@ -0,0 +1,7 @@ +interface: + display_name: "前端编码" + short_description: "按 plus-ui-react 真实代码编写 React CRUD" + default_prompt: "使用 $frontend-crud-coding 先读取适用 reference,再按 plus-ui-react 真实页面、API/types、ProTable、ModalForm、权限和导出约定实现前端修改。" + +policy: + allow_implicit_invocation: true diff --git a/.codex/skills/frontend-crud-coding/references/examples.md b/.codex/skills/frontend-crud-coding/references/examples.md new file mode 100644 index 00000000..edb2fb2f --- /dev/null +++ b/.codex/skills/frontend-crud-coding/references/examples.md @@ -0,0 +1,126 @@ +# 使用案例 + +## 案例 1:新增标准 CRUD 页面 + +### 用户提问示例 + +```text +使用 $frontend-crud-coding 为 system/client 补一套 React 前端 CRUD 页面。 +后端接口已经有 /system/client/list、/system/client/{id}、POST /system/client、PUT /system/client、DELETE /system/client/{ids}。 +请参考 src/pages/demo/demo/index.tsx 和现有 system/client 风格实现。 +``` + +### 期望执行方式 + +- 先看 `src/api/system/client/*` 和 `src/pages/system/client/index.tsx` 是否已存在。 +- 再看 `src/pages/demo/demo/index.tsx` 的标准 React CRUD 骨架。 +- 必要时对照 boot4 generator 模板确认字段、权限和接口。 +- 生成或修改 `api/index.ts`、`types.ts`、`pages/.../index.tsx`。 +- 使用 `request>>`、`ProTable`、`ModalForm`、`RowActions`、`useTableSelection`、`useTableExport`。 + +## 案例 2:新增树表页面 + +### 用户提问示例 + +```text +使用 $frontend-crud-coding 为 demo/tree2 新增树表 CRUD,接口返回数组,字段包含 id、parentId、name、orderNum。 +参考 src/pages/demo/tree/index.tsx 和 workflow/category。 +``` + +### 期望执行方式 + +- 判断这是树表,不生成分页 `PageResult` 页面。 +- API 列表返回 `R`。 +- `Query` 不继承 `PageQuery`。 +- 页面使用 `handleTree`、`pagination={false}`、`expandedRowKeys`、`ProFormTreeSelect`。 +- 新增子节点时从当前行带入 `parentId`。 + +## 案例 3:修改已有复杂列表页 + +### 用户提问示例 + +```text +使用 $frontend-crud-coding 修改 system/user 页面: +1. 新增一个创建时间快捷筛选 +2. 导出按钮保留在工具栏中 +3. 保持现有树筛选、导入、详情抽屉和角色分配不变 +``` + +### 期望执行方式 + +- 判断这是“已有复杂页面增强”,不是重新生成 CRUD。 +- 优先阅读 `src/pages/system/user/index.tsx` 和相关子组件。 +- 保留 `TreePanel`、导入弹窗、`UserDetailDrawer`、角色分配路由、权限控制。 +- 只增量修改搜索和查询参数处理。 + +## 案例 4:修改 workflow 页面 + +### 用户提问示例 + +```text +使用 $frontend-crud-coding 为 workflow/category 增加状态筛选和导出按钮,保持 workflow 模块自己的树表风格。 +``` + +### 期望执行方式 + +- 优先看 `src/pages/workflow/category/index.tsx` 和 `src/api/workflow/category/*`。 +- 判断是否需要后端新增导出接口;前端导出路径保持 `/workflow/category/export`。 +- 不迁移 system/user 的用户专属逻辑。 +- 保留树表、`expandedRowKeys`、`handleTree` 和分类弹窗逻辑。 + +## 案例 5:只补 API 和 types + +### 用户提问示例 + +```text +使用 $frontend-crud-coding 为 monitor/cache 补全前端 API 和 types,页面先不改。 +``` + +### 期望执行方式 + +- 只维护 `src/api/monitor/cache/index.ts` 和 `src/api/monitor/cache/types.ts`。 +- 仍然检查同目录 monitor API 的命名、返回结构和导出风格。 +- 返回类型使用 `R` 和 `PageResult` from `@/api/types`。 +- 不创建页面,不改路由。 + +## 案例 6:接入后端新增状态切换接口 + +### 用户提问示例 + +```text +使用 $frontend-crud-coding 给 system/client 页面接入 PUT /system/client/changeStatus,状态字段 status,参考 system/user。 +``` + +### 期望执行方式 + +- API 增加 `changeClientStatus(id, status)`。 +- types 确认 `status` 类型是 string、number 还是 boolean。 +- 表格列用 Ant Design `Switch`,checked 值跟后端字段类型一致。 +- 切换失败时回滚原状态或刷新列表。 +- 权限使用 `system:client:edit` 或后端实际权限。 + +## 推荐的高质量任务描述 + +```text +使用 $frontend-crud-coding 在当前 React 前端项目中增强 `/system/notice` 列表页: +1. 保留现有页面 +2. 新增状态筛选和导出 +3. API 路径沿用后端接口 +4. 参考 system/config 的工具栏与导出交互 +5. 参考 boot4 generator 模板补齐缺失 types +``` + +## 不推荐的任务描述 + +```text +帮我写个后台页面 +``` + +更好的写法至少补充: + +- 模块名 +- 业务名 +- 后端接口前缀 +- 是新增还是修改 +- 是否需要分页、导出、树表、字典、权限 +- 想参考哪个现有页面 diff --git a/.codex/skills/frontend-crud-coding/references/frontend.md b/.codex/skills/frontend-crud-coding/references/frontend.md new file mode 100644 index 00000000..a506a068 --- /dev/null +++ b/.codex/skills/frontend-crud-coding/references/frontend.md @@ -0,0 +1,144 @@ +# 前端约定 + +## 优先参考的代码来源 + +- 当前目标目录下最近似页面、API、types。 +- 标准单表:`src/pages/demo/demo/index.tsx`、`src/api/demo/demo/index.ts`、`src/api/demo/demo/types.ts`。 +- 树表:`src/pages/demo/tree/index.tsx`、`src/pages/workflow/category/index.tsx`。 +- 复杂系统页:`src/pages/system/user/index.tsx`、`src/pages/system/role/index.tsx`、`src/pages/system/post/index.tsx`、`src/pages/system/config/index.tsx`。 +- workflow 页:`src/pages/workflow/*`、`src/api/workflow/*`。 +- 监控页:`src/pages/monitor/*`、`src/api/monitor/*`。 +- 公共 hooks:`src/hooks/useTableSelection.ts`、`src/hooks/useTableExport.ts`、`src/hooks/useDict.ts`。 +- 公共组件:`src/components/common/RowActions.tsx`、`TreePanel.tsx`、`RightToolbar.tsx`、`DictTag.tsx`、上传/预览组件。 +- 工具函数:`src/utils/ruoyi.ts`、`src/utils/permission.ts`、`src/utils/download.ts`。 + +## 基础栈与格式 + +- 技术栈是 React + TypeScript + Umi Max + Ant Design + ProComponents + ahooks + Zustand + TanStack Query。 +- 包管理按仓库现状使用 pnpm。 +- `.editorconfig` 要求 UTF-8、2 空格缩进。 +- 当前仓库没有 Prettier;格式化使用 `pnpm run fmt`,lint 使用 `pnpm lint`。 +- 不要在一个页面里混入与仓库不一致的格式和写法。 + +## API 文件规则 + +- 标准 API 文件放在 `src/api///index.ts`,同目录维护 `types.ts`。 +- import 顺序优先跟随附近文件,标准形式: + `import type { PageResult, R } from '@/api/types';` + `import request from '@/api/request';` + `import type { XxxForm, XxxQuery, XxxVO } from './types';` +- 不要从 `axios` 引入 `AxiosPromise`;当前 `request()` 返回 `Promise`,接口函数通常返回 `Promise>`。 +- 列表分页接口通常返回 `request>>({ url, method: 'get', params: query })`。 +- 树表列表接口通常返回 `request>({ url, method: 'get', params: query })`。 +- 详情接口返回 `R`;复杂详情返回单独的 `InfoVO`。 +- 标准函数命名: + `listXxx` -> `GET ///list` + `getXxx` -> `GET ///{id}` + `addXxx` -> `POST //` + `updateXxx` -> `PUT //` + `delXxx` -> `DELETE ///{id or ids}` + `changeXxxStatus` -> `PUT ///changeStatus` +- query string 用 `params`,请求体用 `data`。 +- 加密、防重复提交等 headers 直接写在请求配置里,例如用户重置密码中的 `isEncrypt`、`repeatSubmit`。 +- 当前仓库多数 API 使用 `export function`;新增标准 CRUD 优先跟随相邻模块。 +- 只有相邻模块已有聚合对象时才新增默认导出。 + +## 类型文件规则 + +- 标准类型定义 `VO`、`Form`、`Query`,必要时补 `InfoVO`、`TreeVO`、`ResetPwdForm` 等扩展类型。 +- `Form` 通常继承 `BaseEntity`。 +- 非树表 `Query` 通常继承 `PageQuery`。 +- 树表 `Query` 通常不继承 `PageQuery`。 +- ID 字段通常使用 `string | number`,批量删除参数使用 `string | number | Array`。 +- Java 数值类型映射为 `number`,Boolean 映射为 `boolean`,日期/文本默认 `string`。 +- 日期范围查询保留 `params?: Record` 或跟随相邻页面现有类型,不要因为它看起来宽松就删掉。 +- 列表对象、表单对象、查询对象职责分开;字段不一致时不要强行复用一个接口。 +- 能明确写出类型时不要用 `any`;组件库、字典或历史接口确实无法收窄时再保留。 + +## React 页面结构规则 + +- 页面默认导出函数组件,命名如 `SystemUserPage`、`DemoDemoPage`、`WorkflowCategoryPage`。 +- 标准页使用 `PageContainer` 包裹 `ProTable` 和 `ModalForm`。 +- 标准列表页常见状态: + `actionRef`、`form`、`modalOpen`、`modalTitle`、`ids`、`selectedOne`、权限布尔值。 +- 弹窗状态优先使用 `useBoolean(false)`,表单用 `Form.useForm()`。 +- ProTable 使用: + `rowKey` + `columns` + `search={{ labelWidth: 90 }}` + `pagination={{ defaultPageSize: 10, showSizeChanger: true }}` + `request={async params => { ... }}` + `toolBarRender={() => [...]}` +- 分页查询使用 `toPageQuery(params)`,然后 `updateExportParams(query)`,最后 `return toTableData(res)`。 +- 表格列类型使用 `ProColumns[]`。 +- 新增/编辑弹窗使用 `ModalForm`,字段优先使用 `ProFormText`、`ProFormDigit`、`ProFormSelect`、`ProFormTreeSelect`、`ProFormDateTimeRangePicker` 等 ProForm 组件。 +- ModalForm 成功提交后返回 `true`,并刷新 `actionRef.current?.reload()`。 + +## 页面行为规则 + +- `openAdd` 负责 `form.resetFields()`、设置默认值、设置标题、打开弹窗。 +- `openEdit` 先按行或 `selectedOne` 找目标,再查详情,`form.resetFields()`,`form.setFieldsValue(res.data)`,最后打开弹窗。 +- `submitForm` 根据主键判断新增或修改,成功后 `message.success('操作成功')`、重置表单、刷新列表。 +- `remove` 或 `handleDelete` 支持行删除和批量删除,成功后 `message.success('删除成功')`、`clearSelection()`、`reloadAndRest` 或 `reload`。 +- 批量按钮通常用 `Popconfirm`,行操作确认优先放在 `RowActions` 的 `confirm`。 +- 状态切换失败时要回滚或刷新,参考 `src/pages/system/user/index.tsx`。 +- 日期范围查询使用 `formatDateTimeRange` 和 `addDateRange`,参考 `system/user`。 +- 导入上传参考 `system/user/components/UserImportModal.tsx` 或流程定义导入弹窗,保留 `globalHeaders()` 和 `appEnv.baseApi` 相关方式。 + +## 字典、权限与公共工具 + +- 字典使用 `const dicts = useDict('sys_normal_disable', 'sys_user_gender')`。 +- 字典 options 可按 `system/user` 中的 `dictOptions` 函数映射为 `{ label, value }`。 +- 权限使用: + `const userInfo = useUserStore(state => state.userInfo);` + `const canAdd = hasPermi(userInfo, ['system:user:add']);` +- 不要使用 Vue 权限指令 `v-hasPermi`。 +- 常用工具: + `hasPermi` from `@/utils/permission` + `handleTree`、`parseStrEmpty`、`toPageQuery`、`toTableData`、`addDateRange`、`formatDateTimeRange` from `@/utils/ruoyi` + `download` via `useTableExport` + +## 组件与样式规则 + +- 行操作优先复用 `RowActions`,并使用 `@ant-design/icons` 图标。 +- 树筛选优先复用 `TreePanel`,参考 `system/user`。 +- 导出优先复用 `useTableExport`。 +- 多选优先复用 `useTableSelection`。 +- 标准页面尽量使用 `PageContainer`、`ProTable`、ProComponents 页面壳,不堆大量内联样式。 +- 需要自定义布局时先查 `src/assets/styles` 是否已有 `.tree-table-page`、`.table-panel`、`.page-surface` 等类。 +- 不要为了单页需求修改全局组件样式。 + +## 树表规则 + +- 树表列表接口通常返回数组,页面通过 `handleTree(res.data || [], 'id', 'parentId')` 组树。 +- `ProTable` 使用 `pagination={false}`。 +- 使用 `expandedRowKeys` 和 `onExpandedRowsChange` 控制展开。 +- 展开/折叠按钮参考 `demo/tree` 和 `workflow/category`,用 `SortAscendingOutlined`。 +- 表单中上级节点使用 `ProFormTreeSelect`。 +- 新增子节点时从当前行回填 `parentId`。 +- 删除确认文案优先使用业务名称,而不是批量 ID 文案。 + +## 与 Vue 参考项目和生成器模板的关系 + +- Vue skill 和 `.claude/agents` 提供的是任务分型、优先级、增量修改、自检方式,不是 React 实现模板。 +- generator 模板可用于确认字段、权限、导出、状态切换、排序、日期范围等,但不是最终答案。 +- 当前 React 项目的核心骨架是 `ProTable`、`ModalForm`、`RowActions`、`useTableSelection`、`useTableExport`。 +- 修改已有页面时,不要把现有强业务逻辑替换回 generator 的简化逻辑。 + +## 验证规则 + +- 只改文档或 skill:运行 skill 基础校验。 +- 改前端 TS/TSX/API/types:优先运行 `pnpm exec tsc --noEmit` 或 `pnpm lint`。 +- 改页面、import、权限或较多文件:运行 `pnpm lint`。 +- 改公共 hooks、组件、构建相关或大范围页面:再运行 `pnpm build`。 +- 如果验证因为环境、依赖或权限失败,交付时说明失败命令和原因。 + +## 避免事项 + +- 不要从 `axios` 引入 `AxiosPromise`。 +- 不要绕开 `@/api/request` 或 `useTableExport` 自造请求/下载封装。 +- 不要跳过 `types.ts`,把类型全写在页面里。 +- 不要把 `src/pages` 写成 Vue 项目的 `src/views`。 +- 不要使用 Vue 的 `ref`、`reactive`、`toRefs`、`v-hasPermi`、Element Plus 组件或 SCSS 页面壳。 +- 不要删除日期范围 `params`、权限判断、导出、导入、树筛选、列显隐等现有能力。 +- 不要为了“更整洁”重写复杂页面的大块业务逻辑。