diff --git a/.claude/agents/backend-crud.md b/.claude/agents/backend-crud.md new file mode 100644 index 000000000..5292c937b --- /dev/null +++ b/.claude/agents/backend-crud.md @@ -0,0 +1,62 @@ +--- +name: backend-crud +description: 标准后端 CRUD 专家。用于当前项目中的新增单表 CRUD、补 entity/bo/vo/mapper/service/controller、分页查询、导出、删除前校验等任务。适用于单个微服务内部开发;如果需求跨服务复用、Dubbo 远程调用、gateway 或 Seata,请先升级为微服务任务处理。 +--- + +你负责当前项目中的标准后端 CRUD 实现。 + +## 核心原则 + +1. 先参考 `ruoyi-modules/ruoyi-gen/src/main/resources/vm/` 下的模板。 +2. 再参考当前模块内最近似的标准管理模块。 +3. 分层保持稳定: + `domain`、`domain.bo`、`domain.vo`、`mapper`、`service`、`service.impl`、`controller` +4. 默认这是单个微服务内部的 CRUD;不要顺手扩成 `ruoyi-api` 远程契约,除非明确有跨服务复用需求。 + +## 结构约定 + +- entity 默认继承 `BaseEntity` +- mapper 默认继承 `BaseMapperPlus` +- BO 使用 `@AutoMapper(target = Entity.class, reverseConvertGenerate = false)` +- VO 使用 `@AutoMapper(target = Entity.class)` +- service 使用 `baseMapper` +- controller 暴露 HTTP 接口,跨服务复用另走 `ruoyi-api + Dubbo` + +## 默认方法集合 + +- `queryById` +- `queryPageList` +- `queryList` +- `insertByBo` +- `updateByBo` +- `deleteWithValidByIds` + +## 查询规则 + +- 单表查询优先用 `LambdaQueryWrapper` +- 日期范围默认从 `bo.getParams()` 中读取 begin/end +- 分页优先返回 `PageResult` +- 日期范围与查询参数风格要保持前端与 gateway 入口路由稳定,不因微服务拆分改变 HTTP 接口习惯 + +## 接口规则 + +- controller 继承 `BaseController` +- 返回值使用 `R` 或 `R` +- 标准 CRUD 路由通常是: + `GET /list` + `POST /export` + `GET /{id}` + `POST` + `PUT` + `DELETE /{ids}` +- 默认检查是否需要 `@SaCheckPermission`、`@Log`、`@RepeatSubmit` +- 如果只是服务内 CRUD,不要新增 `@DubboReference` +- 如果别的服务也需要这块能力,先停止裸 CRUD 思路,改为补 `ruoyi-api` 契约再继续 + +## 自检 + +- CRUD 链路是否完整 +- BO / VO / Entity 是否职责分离 +- 导出、分页、删除前校验是否齐全 +- 是否只是 generator 裸产物,如果是要继续补齐项目约定 +- 是否错误把单服务 CRUD 做成了跨服务实现 diff --git a/.claude/agents/backend-engineering.md b/.claude/agents/backend-engineering.md new file mode 100644 index 000000000..c1470705b --- /dev/null +++ b/.claude/agents/backend-engineering.md @@ -0,0 +1,23 @@ +--- +name: backend-engineering +description: 后端工程总入口。用于在当前项目中识别任务属于标准 CRUD、复杂模块增强、联表与数据权限、微服务契约与 Dubbo 协作、或前后端联动,并选择合适的后端子 agent。 +--- + +你是当前后端工程的总入口 agent。 + +先判断任务类型,再按下面规则处理: + +1. 如果是新增标准单表 CRUD、从表结构补 entity/bo/vo/mapper/service/controller,优先使用 `backend-crud.md` 的规则。 +2. 如果是修改 `system`、`workflow` 等已经很复杂的模块,优先使用 `backend-module-enhancement.md` 的规则。 +3. 如果重点在 MPJ 联表、`@DataPermission`、复杂查询、数据范围控制,优先使用 `backend-query-permission.md` 的规则。 +4. 如果任务涉及 `ruoyi-api`、`Remote*Service`、`@DubboReference`、`@DubboService`、gateway、Nacos 配置、Seata 边界,先按微服务任务处理,不要误判成普通 CRUD。 +5. 如果同时要求同步前端接口或前端页面骨架,保持后端路由与 generator 风格稳定,便于前端 agent 对接。 + +通用要求: + +- 先读同模块最近似实现,再动代码。 +- 发生冲突时优先相信当前模块真实代码,其次是公共基础设施,再其次才是 generator 模板。 +- 默认直接产出可落地代码,而不是只给抽象建议。 +- 当前仓库服务间协作默认是 Dubbo,不要按 Feign 习惯生成跨服务代码。 +- 需要跨服务复用能力时,优先判断是否应修改 `ruoyi-api` 契约层。 +- gateway 负责统一入口与横切能力,不承载业务 CRUD。 diff --git a/.claude/agents/backend-module-enhancement.md b/.claude/agents/backend-module-enhancement.md new file mode 100644 index 000000000..a8e6aba1f --- /dev/null +++ b/.claude/agents/backend-module-enhancement.md @@ -0,0 +1,38 @@ +--- +name: backend-module-enhancement +description: 复杂后端模块增强专家。用于修改当前项目中已经存在较重业务逻辑的模块,例如 system、workflow 等,强调增量修改、保留现有权限、事务、缓存、导入导出、Dubbo 协作和业务校验。 +--- + +你负责复杂后端模块的增量增强,不是从零生成裸 CRUD。 + +## 核心原则 + +1. 优先阅读当前模块最近似实现。 +2. 增量修改,不重写整块 service/controller。 +3. 保留已有的数据权限、事务、缓存、导入导出、唯一性校验、删除前校验。 +4. 不能为了“简洁”把复杂模块退化成模板式单表 CRUD。 +5. 如果模块已经通过 `@DubboReference` 调其他服务,或在 `dubbo/` 下提供远程能力,新增逻辑默认保持同样的微服务边界。 + +## 常见任务 + +- 修改 `system`、`workflow` 模块的查询与导出逻辑 +- 新增或调整写入前校验 +- 维护角色、岗位、用户等关联数据 +- 增加复杂页面所需的特殊接口 +- 扩展已有 `Remote*Service` provider 或消费其他服务远程能力 + +## 约束 + +- controller 不堆重业务逻辑 +- service 里的旧逻辑要先理解再改 +- 如果附近已有 `ServiceException`、缓存注解、事务注解、数据权限判断,新增逻辑默认保持一致 +- 如果存在联动前端页面,接口路径与返回结构尽量稳定 +- 不要把已有 Dubbo 调用改回 controller 互调或其他 HTTP 临时方案 +- 只有明确跨服务写一致性要求时,才扩大到 `@GlobalTransactional` + +## 自检 + +- 是否破坏了原模块的权限边界 +- 是否误删了旧逻辑中的事务或校验 +- 是否错误简化了复杂关系维护 +- 是否破坏了原有微服务边界或远程契约 diff --git a/.claude/agents/backend-query-permission.md b/.claude/agents/backend-query-permission.md new file mode 100644 index 000000000..bba2bfe85 --- /dev/null +++ b/.claude/agents/backend-query-permission.md @@ -0,0 +1,31 @@ +--- +name: backend-query-permission +description: 后端查询、联表与数据权限专家。用于当前项目中的 MPJ 联表、DataPermission、复杂分页查询、范围控制、查询增强,以及需要兼顾微服务边界的查询类任务。 +--- + +你负责当前项目中的复杂查询和数据权限类任务。 + +## 核心原则 + +1. 优先看当前模块已有的 mapper 查询实现。 +2. 涉及数据权限时优先复用 `@DataPermission` 与已有字段映射方式。 +3. 复杂联表优先参考 MPJ 风格,不轻易改回手写零散 SQL。 +4. 如果 `BaseMapperPlus + wrapper` 足够,不要额外补 XML。 +5. 如果查询能力需要跨服务复用,先判断应该暴露为 `ruoyi-api` 远程查询接口,还是只保留在当前服务内。 + +## 重点关注 + +- `BaseMapperPlus` +- `@DataPermission` +- `DataColumn` +- `MPJBaseMapper` +- `JoinWrappers.lambda(...)` +- 复杂分页与列表查询 +- 跨服务查询 DTO 与远程返回对象边界 + +## 输出要求 + +- 明确说明查询是单表、联表还是带权限控制 +- 保持与当前模块 mapper 风格一致 +- 不要让查询参数风格和前端现有调用脱节 +- 不要为了跨服务查询去直接依赖对方 controller 路由 diff --git a/.codex/skills/ruoyi-plus-ai-coding/SKILL.md b/.codex/skills/ruoyi-plus-ai-coding/SKILL.md new file mode 100644 index 000000000..a1b25fdfb --- /dev/null +++ b/.codex/skills/ruoyi-plus-ai-coding/SKILL.md @@ -0,0 +1,181 @@ +--- +name: ruoyi-plus-ai-coding +description: 在仓库内按代码生成器模板和项目既有约定生成或修改代码。用于新增 CRUD 模块、补全 controller/service/mapper/BO/VO/entity、编写 MyBatis-Plus 查询,以及新增与后端接口配套的 Vue 3 + TypeScript 页面、types 和 api 文件。 +--- + +# RuoYi Plus AI 编码规范 + +先对齐代码生成器产物,再叠加仓库里真实业务代码已经形成的更强约定。 + +## 适用场景 + +在下面这些任务里优先使用此 skill: + +- 新增标准 CRUD 模块。 +- 根据新表结构补齐 entity、bo、vo、mapper、service、controller。 +- 修改已有模块的查询、校验、导入导出、数据权限、事务逻辑。 +- 在系统、监控、工作流、demo 等模块内按现有约定扩展业务代码。 +- 为后端新增接口同步补前端 `api/types/index.vue` 骨架。 + +## 不适用场景 + +下面这些任务不要机械套用本 skill 的 CRUD 规则: + +- 基础框架升级、Spring Boot 主版本迁移。 +- 与当前分层明显不同的实验性模块。 +- 第三方中间件深度接入、基础设施改造。 +- 完全脱离 generator 体系的独立子系统。 + +## 执行流程 + +1. 先确认目标模块,优先复用同模块中最近似功能的写法。 +2. 新增标准 CRUD 代码前,先读取 `ruoyi-modules/ruoyi-gen/src/main/resources/vm/` 下的模板。 +3. 命名和分层保持与仓库一致: + `domain` entity、`domain.bo`、`domain.vo`、`mapper`、`service`、`service.impl`、`controller`。 +4. 先判断任务只发生在单个微服务内,还是同时涉及 `ruoyi-api`、Dubbo 远程调用、gateway 路由、跨服务事务。 +5. 优先在生成器结构上扩展,不要自行发明新的分层。 +6. 修改 `ruoyi-system` 这类复杂模块前,先阅读同类现有实现,因为这些模块通常比生成器默认产物多出数据权限、联表、缓存、安全校验等逻辑。 + +## 优先级规则 + +发生冲突时按下面顺序决策: + +1. 当前模块内最近似业务代码。 +2. 当前仓库公共基础模块约定,例如 `common-mybatis`、`common-core`、`common-web`。 +3. 代码生成器模板。 +4. 通用 Spring Boot / MyBatis-Plus 习惯。 + +也就是说: + +- 同模块已有成熟实现时,优先复用该实现。 +- 同模块没有现成代码时,再参考 generator 模板。 +- 不要因为“更通用”就覆盖掉项目已形成的强约定。 + +## 后端规则 + +Java、MyBatis-Plus、BO/VO/entity、controller、mapper、service 的具体规则见 [references/backend.md](references/backend.md)。 + +如果任务涉及微服务边界、`ruoyi-api` 契约、Dubbo 调用、Seata、Nacos 配置或 gateway 路由,也优先参考 [references/backend.md](references/backend.md) 中的微服务章节。 + +## 前端规则 + +Vue 3、TypeScript API 文件、生成式列表页、表单状态、字典和日期范围约定见 [references/frontend.md](references/frontend.md)。 + +## 使用案例 + +具体调用方式见 [references/examples.md](references/examples.md)。 + +## 仓库通用规则 + +- 遵循 [`.editorconfig`](../../../.editorconfig):UTF-8、LF,默认 4 空格,JSON/YAML 为 2 空格。 +- 不要把 `BaseMapperPlus`、`PageQuery`、`PageResult`、`R`、`MapstructUtils` 或项目工具类替换成临时自造方案。 +- 仓库已使用 `List.of(...)` 的地方,数组转列表优先继续沿用。 +- import、注解顺序、文件结构以附近代码为准,不要顺手重排整个文件。 +- 只有在业务逻辑不直观时才加简短注释。 + +## 决策规则 + +- 如果任务是围绕单表的标准 CRUD,尽量贴近生成器默认产物。 +- 如果目标模块已经存在自定义校验、数据权限、事务、缓存、Excel 导入导出、联表查询等逻辑,应在此基础上扩展,不要为了“简洁”把它们削平。 +- 如果附近 controller 接口已经带有权限、日志、防重、加密、分组校验等注解,新接口默认同步保持一致,除非有明确理由不这样做。 +- 如果 BO 或 VO 需要字段校验、翻译、Excel 注解,应优先参考同模块同用途对象,不要机械套通用注解。 +- 如果需求跨服务复用能力,优先新增或扩展 `ruoyi-api` 下的 `Remote*Service` 契约,再在服务提供方用 `@DubboService` 实现,在消费方用 `@DubboReference` 注入。 +- 如果只是服务内 controller/service/mapper 调整,不要顺手把它拔高成远程接口。 +- 如果需求只影响前端访问入口但不改变服务内部逻辑,先检查是否只需要调整 gateway 或 Nacos 中的路由配置;不要把路由问题误改成业务代码问题。 + +## 目录映射规则 + +标准后端模块通常按下面结构组织: + +- `src/main/java/.../domain/Entity.java` +- `src/main/java/.../domain/bo/EntityBo.java` +- `src/main/java/.../domain/vo/EntityVo.java` +- `src/main/java/.../mapper/EntityMapper.java` +- `src/main/java/.../service/IEntityService.java` +- `src/main/java/.../service/impl/EntityServiceImpl.java` +- `src/main/java/.../controller/EntityController.java` + +标准生成器模板通常对应: + +- `vm/java/domain.java.vm` -> entity +- `vm/java/bo.java.vm` -> bo +- `vm/java/vo.java.vm` -> vo +- `vm/java/mapper.java.vm` -> mapper +- `vm/java/service.java.vm` -> service interface +- `vm/java/serviceImpl.java.vm` -> service impl +- `vm/java/controller.java.vm` -> controller +- `vm/xml/mapper.xml.vm` -> 自定义 XML mapper 起点 + +微服务相关目录通常按下面结构组织: + +- `ruoyi-auth`、`ruoyi-gateway`、`ruoyi-modules/*`:具体服务实现与服务内 controller/service/mapper。 +- `ruoyi-api/ruoyi-api-system|resource|workflow`:跨服务契约层,放 `Remote*Service`、远程 BO/VO/model、mock/stub。 +- `ruoyi-modules/*/src/main/java/.../dubbo/`:`@DubboService` 提供者实现。 +- `ruoyi-*/src/main/resources/application.yml`:服务自身端口、应用名、Nacos 配置导入入口。 + +## 任务分型 + +### 1. 标准单表 CRUD + +优先按 generator 模板落骨架,再补校验、权限、导出、翻译等项目约定。 + +### 2. 强业务模块扩展 + +如果目标模块像 `system`、`workflow` 一样已经有复杂逻辑,优先增量修改,不要回退成模板式简化代码。 + +### 3. 微服务协作扩展 + +如果需求横跨两个及以上服务,先明确服务提供方、消费方与契约归属: + +- 对外给其他服务复用的能力,放到 `ruoyi-api`。 +- provider 在归属服务内实现 `dubbo/Remote*ServiceImpl`。 +- consumer 通过 `@DubboReference` 调用,不在 controller 里手写 HTTP 互调。 +- 需要容错时复用现有 `Mock` / `Stub` 风格,不自造另一套降级约定。 + +### 4. 基础能力复用 + +如果涉及数据权限、缓存、事务、导入导出、字典、翻译、加密、分组校验,优先查项目已有做法并复用公共能力。 + +## 输出要求 + +使用本 skill 时,默认期望产出应满足: + +- 后端分层完整,不直接在 controller 里堆业务逻辑。 +- `BO/VO/Entity` 职责分明。 +- 查询、分页、删除校验、写入校验逻辑闭环完整。 +- 权限、日志、防重、事务、数据权限尽量贴近同模块现有实现。 +- 如果同步改前端,前端 API 路径和后端接口保持一致。 +- 如果跨服务,`ruoyi-api` 契约、provider 实现、consumer 调用三处保持一致。 +- 如果涉及跨服务写操作,明确本地事务与分布式事务边界,不要无故扩大 `@GlobalTransactional` 范围。 + +## 快速检查清单 + +- 包路径和 `@RequestMapping` 与模块保持一致。 +- 权限标识遵循 `${module}:${business}:${action}`。 +- Mapper 继承 `BaseMapperPlus`。 +- Service 使用 `baseMapper`,并按场景返回 `PageResult` 或 `List`。 +- 查询代码优先使用 `LambdaQueryWrapper`,复杂模块沿用既有 MPJ 联表风格。 +- BO 使用 `@AutoMapper(target = Entity.class, reverseConvertGenerate = false)`。 +- VO 使用 `@AutoMapper(target = Entity.class)`。 +- 前端 API 路径与后端路由完全对应。 +- 前端列表页继续使用仓库里的 `proxy?.addDateRange`、`proxy?.$modal`、`proxy?.download`、`useDict`、`pagination` 等工具。 +- 不要把当前仓库的 Dubbo 远程调用误写成 Feign。 +- 新增远程能力时,先看是否应落在 `ruoyi-api-system`、`ruoyi-api-resource`、`ruoyi-api-workflow`。 +- `@DubboReference` 只有在确实跨服务时才新增;服务内调用继续直接走本地 service。 +- gateway 负责入口、鉴权、过滤、跨域、日志等,不承载具体业务 service 逻辑。 +- 服务 `application.yml` 继续沿用当前的 `spring.config.import` + `optional:nacos:*` 结构,不要擅自改成另一套配置加载方式。 + +## 推荐提问方式 + +推荐把任务描述到下面这个粒度: + +- 目标模块和业务名 +- 是新建模块还是修改已有模块 +- 表名或接口前缀 +- 是否需要分页、导出、导入、数据权限、字典、翻译、联表 +- 希望参考哪个现有模块 + +例如: + +- 使用 `$ruoyi-plus-ai-coding` 在 `system` 模块新增一个标准单表 CRUD,参考 `SysConfig` 与 generator 模板。 +- 使用 `$ruoyi-plus-ai-coding` 修改 `workflow/category` 的查询和导出逻辑,保持现有模块风格。 diff --git a/.codex/skills/ruoyi-plus-ai-coding/agents/openai.yaml b/.codex/skills/ruoyi-plus-ai-coding/agents/openai.yaml new file mode 100644 index 000000000..de6cbc2d0 --- /dev/null +++ b/.codex/skills/ruoyi-plus-ai-coding/agents/openai.yaml @@ -0,0 +1,7 @@ +interface: + display_name: "RuoYi Plus 编码" + short_description: "按生成器与仓库约定编写代码" + default_prompt: "使用 $ruoyi-plus-ai-coding 在这个仓库里按现有约定实现代码修改。" + +policy: + allow_implicit_invocation: true diff --git a/.codex/skills/ruoyi-plus-ai-coding/references/backend.md b/.codex/skills/ruoyi-plus-ai-coding/references/backend.md new file mode 100644 index 000000000..fc2e2009f --- /dev/null +++ b/.codex/skills/ruoyi-plus-ai-coding/references/backend.md @@ -0,0 +1,318 @@ +# 后端约定 + +## 优先参考的代码来源 + +- `ruoyi-modules/ruoyi-gen/src/main/resources/vm/java/*.vm` +- `ruoyi-modules/ruoyi-demo/...` +- `ruoyi-modules/ruoyi-system/...` +- `ruoyi-common/ruoyi-common-mybatis/...` + +## 决策顺序 + +写代码时按下面顺序取样: + +1. 当前业务模块下最近似实现。 +2. 当前仓库公共能力模块中的统一约定。 +3. generator 模板。 +4. 通用 Spring / MyBatis-Plus 默认习惯。 + +如果规则冲突,优先相信当前仓库真实代码。 + +## 微服务总览 + +当前仓库的微服务相关真实约定不是 Feign 风格,而是: + +- 服务注册与配置中心使用 Nacos。 +- 对外入口使用 `ruoyi-gateway`。 +- 服务间 RPC 默认使用 Dubbo。 +- 跨服务契约放在 `ruoyi-api/*`。 +- 跨服务写操作按需使用 Seata,不是所有写接口都默认上全局事务。 + +写代码前先判断任务属于下面哪类: + +1. 纯服务内 CRUD 或模块增强。 +2. 需要给其他服务复用能力,必须新增或修改 `ruoyi-api` 契约。 +3. 只是网关入口、跨域、过滤、日志、鉴权相关,应该改 `ruoyi-gateway` 或配置。 +4. 涉及跨服务写入一致性,才评估 `@GlobalTransactional`。 + +## 微服务模块边界 + +- `ruoyi-auth`:认证授权中心,本身也通过 `@DubboReference` 依赖 system/resource 等远程能力。 +- `ruoyi-gateway`:统一入口,负责过滤器、异常处理、跨域、日志、语言解析等,不写业务 CRUD。 +- `ruoyi-modules/ruoyi-system|resource|workflow|job|gen`:具体微服务业务实现。 +- `ruoyi-api/ruoyi-api-system|resource|workflow`:服务间共享契约,放 `Remote*Service`、远程 BO/VO/model、mock/stub。 +- `ruoyi-common/*`:跨服务都会复用的基础能力,不要在业务模块里重复造轮子。 + +## 应用入口与基础配置规则 + +- 每个微服务应用入口默认使用 `@EnableDubbo` + `@SpringBootApplication`。 +- 每个服务的 `application.yml` 只保留本服务端口、服务名、激活环境、Nacos 导入入口。 +- 配置导入继续沿用 `spring.config.import` + `optional:nacos:*` 结构。 +- 业务服务通常额外导入 `datasource.yml`;像 `ruoyi-auth`、`ruoyi-gateway` 这类服务不一定导入数据源配置,先以当前模块现状为准。 +- 不要因为新增一个接口就改动服务名、端口、Nacos group/namespace、配置加载方式。 + +## 跨服务契约规则 + +需要被其他服务调用的能力,按下面顺序落代码: + +1. 在 `ruoyi-api` 下新增或扩展 `Remote*Service` 接口。 +2. 如需跨服务传参或返回展示字段,在 `ruoyi-api` 下补充专用 `domain.bo`、`domain.vo` 或 `model`。 +3. 在服务提供方模块的 `dubbo/` 包下新增 `@DubboService` 实现。 +4. 在服务消费方用 `@DubboReference` 注入。 + +### 契约放置原则 + +- `Remote*Service` 放到能力归属服务对应的 `ruoyi-api-*` 模块。 +- 远程 DTO 只放跨服务真正需要的字段,不直接暴露服务内 Entity。 +- 不要把 controller 的 BO/VO 直接搬去做远程 DTO,除非该对象本身已经是跨服务语义。 +- 远程接口命名延续当前仓库风格:`RemoteUserService`、`RemoteFileService`、`RemoteWorkflowService`。 + +### provider 实现规则 + +- provider 一般放在 `src/main/java/.../dubbo/RemoteXxxServiceImpl.java`。 +- 类上保留 `@DubboService`,通常同时保留 Spring `@Service` 或使用构造注入风格与当前模块一致。 +- provider 内优先复用本服务已有 `service`、`mapper`、`convert`、工具类,不重新实现一套业务。 +- provider 返回远程 VO / model,不把本服务内部实体直接外泄。 + +### consumer 调用规则 + +- 跨服务调用使用 `@DubboReference`,不要新写服务间 HTTP/Feign 调用。 +- 只有真正跨服务时才新增 `@DubboReference`;同服务内调用继续直接注入本地 service。 +- controller 中允许少量直接 `@DubboReference`,但仅限当前模块已有这种写法的场景;新逻辑优先看附近代码风格保持一致。 +- 消费方如果附近已有 `stub = "true"`、`mock = "true"` 等容错写法,继续沿用。 + +### mock / stub 规则 + +- 可选能力或允许降级的远程服务,优先复用 `ruoyi-api` 中现有 `Mock` / `Stub` 风格。 +- `Mock` 适合返回空对象、空列表、空字符串等兜底值。 +- `Stub` 适合包一层 try/catch 做调用保护和告警日志。 +- 不要在业务代码里散落重复的远程降级逻辑,优先收敛到 API 契约侧。 + +## 分层结构 + +标准 CRUD 代码应优先遵循下面这套结构: + +- `domain/Entity.java` +- `domain/bo/EntityBo.java` +- `domain/vo/EntityVo.java` +- `mapper/EntityMapper.java` +- `service/IEntityService.java` +- `service/impl/EntityServiceImpl.java` +- `controller/EntityController.java` + +## Entity 规则 + +- 除非所在模块明显另有约定,否则实体类继承 `org.dromara.common.mybatis.core.domain.BaseEntity`。 +- 使用 Lombok `@Data` 和 `@EqualsAndHashCode(callSuper = true)`。 +- 使用 `@TableName("table_name")`。 +- 主键使用 `@TableId`。 +- 存在 `delFlag` 时保留 `@TableLogic`,存在乐观锁字段时保留 `@Version`。 +- 如果附近实体已经使用 `@OrderBy` 等额外注解,应继续保持。 + +## BO 规则 + +- 实现 `Serializable`。 +- 添加 `@AutoMapper(target = Entity.class, reverseConvertGenerate = false)`。 +- 请求专用字段、查询专用字段放在 BO 中,包括 `params`。 +- 在生成器或附近代码已有分组校验时,继续使用:`AddGroup`、`EditGroup`、`QueryGroup`。 +- `@Xss`、`@Email`、`@Size`、`@NotBlank`、`@NotNull` 要按真实业务语义添加,不要一股脑全套上。 +- 查询存在日期范围或扩展条件时,保留 `params = new HashMap<>()`。 + +## VO 规则 + +- 实现 `Serializable`。 +- 添加 `@AutoMapper(target = Entity.class)`。 +- 生成器风格的导出对象通常带 `@ExcelIgnoreUnannotated`。 +- `@ExcelProperty`、`@ExcelDictFormat`、`ExcelDictConvert`、`@ExcelRequired`、`@ExcelNotation`、`@DateTimeFormat` 只在导入导出场景下使用。 +- 如果附近代码会把 ID 翻译成展示字段,沿用 `@Translation(type = TransConstant.USER_ID_TO_NAME, mapper = "createBy")` 这类写法。 +- 展示型派生字段放在 VO,不放在 Entity。 + +## Mapper 规则 + +- 默认形式是 `interface XxxMapper extends BaseMapperPlus`。 +- 不要为简单的 entity 转 vo 手写重复代码,优先依赖 `BaseMapperPlus`。 +- 模块已经使用 `@DataPermission` 时,在重写方法和自定义查询上继续保留。 +- 复杂模块里 mapper 可能同时继承 `MPJBaseMapper` 并使用 `JoinWrappers.lambda(...)`,遇到这种风格要延续,不要换一种写法。 +- 只有在 `selectVoList/selectVoPage` 不够用时,才补 XML 或自定义 mapper 方法。 + +### Mapper 建议结构 + +标准 mapper 一般按这个顺序组织: + +1. 接口声明 +2. 默认查询方法 +3. 自定义分页或列表方法 +4. 特殊数据权限重写 +5. 辅助构造方法 + +### 什么时候需要 XML + +- 复杂联表 SQL 无法仅靠 wrapper 清晰表达时。 +- 需要手写查询列和结果映射时。 +- 项目当前模块已经大量使用 XML 时。 + +如果 `BaseMapperPlus + wrapper` 已足够,优先不要补 XML。 + +## Service 规则 + +- 类声明通常是 `@RequiredArgsConstructor`、`@Service`,按需补 `@Slf4j`。 +- mapper 注入字段命名为 `private final XxxMapper baseMapper;`。 +- 读操作通常返回 `Vo`、`List` 或 `PageResult`。 +- BO 转实体用 `MapstructUtils.convert(bo, Entity.class)`。 +- 查询条件优先用 `LambdaQueryWrapper` 和 `Wrappers.lambdaQuery()`。 +- 在 wrapper 条件里直接写 `StringUtils.isNotBlank(...)` 和 null 判断。 +- 分页查询优先采用: + `Page result = baseMapper.selectVoPage(pageQuery.build(), lqw);` + `return PageResult.build(result.getRecords(), result.getTotal());` +- 生成器风格模块保留 `validEntityBeforeSave(...)` 这种扩展点。 +- 多表写操作使用 `@Transactional(rollbackFor = Exception.class)`。 +- 明确的业务失败,尤其是权限、数据完整性、删除校验,使用 `ServiceException`。 +- 不要绕过模块现有的数据权限、角色校验、删除前校验。 +- 如果写操作只发生在单服务内,优先本地 `@Transactional`,不要无故提升成分布式事务。 +- 如果像 `SysProfileController` 这类场景同时写本服务数据并调用远程文件服务,再参考附近代码决定是否使用 `@GlobalTransactional`。 + +### Service 建议结构 + +标准 service impl 一般按下面顺序组织: + +1. 查询单条 +2. 分页查询 +3. 列表查询 +4. 构建查询条件 +5. 新增 +6. 修改 +7. 保存前校验 +8. 删除前校验与删除 +9. 其他扩展业务方法 + +### 查询逻辑建议 + +- 单表查询优先使用 `LambdaQueryWrapper`。 +- 条件判断直接放在 wrapper 上,不要额外写大量 if 套壳。 +- 日期范围统一从 `bo.getParams()` 取 begin/end。 +- 复杂联表查询优先查同模块是否已有 MPJ 风格可复用。 + +### 写入逻辑建议 + +- BO 转实体统一走 `MapstructUtils.convert`。 +- 批量关系维护时优先拆成私有方法,例如角色、岗位、用户关联。 +- 修改前优先保留已有防误删、防越权、防并发覆盖逻辑。 + +## Controller 规则 + +- 继承 `BaseController`。 +- 类上通常带 `@Validated`、`@RestController`、`@RequiredArgsConstructor`、`@RequestMapping`。 +- 返回值使用 `R` 或 `R`。 +- 标准 CRUD 接口通常是:`GET /list`、`POST /export`、`GET /{id}`、`POST`、`PUT`、`DELETE /{ids}`。 +- `@SaCheckPermission` 权限格式遵循 `${module}:${business}:${action}`。 +- 写操作、导入导出接口通常加 `@Log(title = "...", businessType = BusinessType.X)`。 +- 附近接口已有防重时,写接口继续使用 `@RepeatSubmit`。 +- 适合分组校验时,使用 `@Validated(AddGroup.class)` 和 `@Validated(EditGroup.class)`。 +- 特殊接口直接复用模块内现成做法,例如导入导出、`@ApiEncrypt`、multipart 上传、数据权限检查、写入前唯一性校验。 +- controller 默认是对前端开放的 HTTP 接口,不要把跨服务契约直接建在 controller 上。 +- 新增给其他服务复用的能力时,优先补 `Remote*Service`,不是补一个“内部专用 controller”。 + +### Controller 建议结构 + +标准 controller 一般按下面顺序组织: + +1. 列表 +2. 导出 +3. 详情 +4. 新增 +5. 修改 +6. 删除 +7. 特殊接口 + +### Controller 边界 + +- controller 负责接参、校验、权限、日志、返回值转换。 +- 重业务逻辑尽量放 service,不要在 controller 里堆长逻辑。 +- 但前置权限检查、唯一性提示、显式业务失败提示可以留在 controller,前提是同模块已有这种习惯。 + +## 查询与工具规则 + +- 分页统一使用 `PageQuery` 和 `PageResult`,不要无故引入新的分页 DTO。 +- 优先使用项目工具类:`MapstructUtils`、`StringUtils`、`StreamUtils`、`ValidatorUtils`、`SpringUtils`、`RedisUtils`。 +- 数组转列表按附近代码习惯使用 `List.of(ids)` 或 `Arrays.asList(ids)`。 +- 日期范围查询通常从 `bo.getParams()` 中读取 `beginTime`、`endTime` 或 `beginFieldName`、`endFieldName`。 + +## 前后端联动规则 + +- 新增后端接口时,路径和权限前缀尽量保持 generator 约定,方便前端目录和 API 命名同步。 +- 新增日期范围查询时,记得保留 `bo.params` 结构,避免前端 `addDateRange` 无法对接。 +- 导出接口通常保持 `POST /export` 风格,便于前端直接复用现有下载逻辑。 +- 批量删除接口通常使用 `DELETE /{ids}`,便于前端直接传数组或逗号串。 +- 前端访问路径保持面向 gateway 的稳定 HTTP 路由,不把 Dubbo 远程接口暴露给前端设计。 + +## Gateway 规则 + +- `ruoyi-gateway` 主要承载入口、过滤器、异常处理、跨域、日志、国际化等横切能力。 +- 不在 gateway 中新增业务 service、mapper、领域对象 CRUD。 +- 如果问题只与请求头、跨域、过滤链、日志、安全入口有关,优先检查 gateway。 +- 如果问题属于业务数据查询、写入、校验,优先改对应业务服务,不要误改 gateway。 + +## Seata 与事务边界规则 + +- 本地单服务写操作优先 `@Transactional(rollbackFor = Exception.class)`。 +- 只有一个业务动作明确跨越多个微服务资源写入时,才考虑 `@GlobalTransactional(rollbackFor = Exception.class)`。 +- 不要把纯查询接口、纯远程读取接口或可容忍最终一致的场景都包进全局事务。 +- 是否需要 Seata,以当前模块已有实现和业务一致性要求为准,不做想当然扩张。 + +## 生成器优先模式 + +从零新增 CRUD 时,优先对齐生成器默认方法集合: + +- `queryById` +- `queryPageList` +- `queryList` +- `insertByBo` +- `updateByBo` +- `deleteWithValidByIds` + +然后再叠加模块内已有增强,例如: + +- 唯一性校验 +- 数据权限注解 +- MPJ 联表查询 +- 缓存注解 +- Excel 导入导出监听器 +- 关联表维护逻辑 + +## 什么时候优先看 generator + +- 新增一个标准单表 CRUD 时。 +- 只有表结构和基本接口需求,没有现成业务模块可参考时。 +- 需要快速补齐整套骨架代码时。 + +## 什么时候优先看现有模块 + +- 目标模块已经有类似业务。 +- 涉及数据权限、联表、缓存、角色岗位关系、导入导出、工作流扩展时。 +- 任务是“修改已有模块”而不是“新建模块”时。 + +## 避免事项 + +- 不要在 controller 里直接暴露 entity 代替 BO/VO。 +- 不要给新的管理接口漏掉权限注解。 +- 没有明确必要时,不要从 `BaseMapperPlus` 风格退回手工映射。 +- 前端查询页用了日期范围时,不要删掉后端 `params` 相关处理。 +- 不要把 `ruoyi-system` 这类复杂逻辑强行简化成生成器式单表 CRUD。 +- 不要把当前仓库默认的 Dubbo 远程协作改写成 Feign 风格。 +- 不要把 `ruoyi-api` 变成业务实现模块;它只承载契约、远程 DTO、mock/stub。 +- 不要为跨服务复用去直接依赖对方 controller 路由。 +- 不要在 gateway 里堆业务逻辑。 +- 不要无故扩大全局事务边界。 + +## 交付前自检 + +交付前至少检查这些点: + +- CRUD 主链路是否完整。 +- BO / VO / Entity 职责是否清晰。 +- 分页、查询、删除校验是否与前端对得上。 +- 权限、日志、防重、事务是否遗漏。 +- 是否只是 generator 裸产物,如果是,需要继续补齐同模块已有增强。 +- 如果改了跨服务能力,`ruoyi-api`、provider、consumer 三处是否同步。 +- 如果改了微服务入口或配置,是否仍保持当前 Nacos 导入结构。 +- 如果改了事务,是否能说明为什么需要本地事务或全局事务。 diff --git a/.codex/skills/ruoyi-plus-ai-coding/references/examples.md b/.codex/skills/ruoyi-plus-ai-coding/references/examples.md new file mode 100644 index 000000000..b1bc0d22f --- /dev/null +++ b/.codex/skills/ruoyi-plus-ai-coding/references/examples.md @@ -0,0 +1,101 @@ +# 使用案例 + +## 案例 1:新增标准单表 CRUD + +### 用户提问示例 + +```text +使用 $ruoyi-plus-ai-coding 在 system 模块新增一个 client 管理的标准 CRUD。 +请参考 generator 模板和现有 system 模块写法,补齐 entity、bo、vo、mapper、service、controller。 +``` + +### 期望执行方式 + +- 先读 generator 的 `domain/bo/vo/service/serviceImpl/controller` 模板。 +- 再读 `system` 模块里最接近的现有管理模块。 +- 先生成骨架,再补权限、日志、校验、导出等细节。 + +## 案例 2:修改已有复杂模块 + +### 用户提问示例 + +```text +使用 $ruoyi-plus-ai-coding 修改 workflow/category 的查询和导出逻辑,保持现有模块风格,不要简化成模板式单表 CRUD。 +``` + +### 期望执行方式 + +- 先读当前 workflow 模块同类代码。 +- 判断这是“复杂模块增强”,不是“从零生成”。 +- 增量修改原逻辑,不要重写整个 service/controller。 + +## 案例 3:补唯一性校验与删除前校验 + +### 用户提问示例 + +```text +使用 $ruoyi-plus-ai-coding 为 demo/demo 模块补充新增和修改时的唯一性校验,并补充删除前校验。 +``` + +### 期望执行方式 + +- 优先修改 `validEntityBeforeSave(...)`。 +- 根据模块现有风格补 `ServiceException` 或显式失败返回。 +- 删除逻辑只补必要校验,不重构整套 CRUD。 + +## 案例 4:补数据权限与联表查询 + +### 用户提问示例 + +```text +使用 $ruoyi-plus-ai-coding 为 system 模块某个列表查询增加部门数据权限和联表字段返回,参考现有 user mapper 的 MPJ 与 DataPermission 写法。 +``` + +### 期望执行方式 + +- 先看 `SysUserMapper` 和相关 service。 +- 判断需要 `BaseMapperPlus` 重写还是 MPJ 联表。 +- 保持权限注解和联表风格一致。 + +## 案例 5:新增后端接口并同步前端骨架 + +### 用户提问示例 + +```text +使用 $ruoyi-plus-ai-coding 为 monitor/cache 新增一个导出接口,并同步补齐前端 api/types 调用骨架。 +``` + +### 期望执行方式 + +- 先补后端 `controller/service`。 +- 再根据后端路由补前端 `src/api` 或 generator 风格的前端骨架。 +- 保证导出接口路径和前端下载调用一致。 + +## 案例 6:推荐的高质量任务描述 + +下面这种描述最容易得到稳定结果: + +```text +使用 $ruoyi-plus-ai-coding 在 workflow 模块新增一个标准列表管理功能: +1. 需要分页、导出、详情、增删改 +2. 查询包含状态和创建时间范围 +3. 保持现有 workflow 模块风格 +4. 参考 generator 模板生成基础骨架 +5. 删除前需要做业务校验 +``` + +## 不推荐的任务描述 + +下面这种描述太模糊,容易导致产物偏离项目: + +```text +帮我加个后端接口 +``` + +更好的写法至少要补充: + +- 模块名 +- 表或业务名 +- 是新增还是修改 +- 是否需要分页、导出、权限、数据范围、联表 +- 想参考哪个现有模块 diff --git a/.codex/skills/ruoyi-plus-ai-coding/references/frontend.md b/.codex/skills/ruoyi-plus-ai-coding/references/frontend.md new file mode 100644 index 000000000..f77a22653 --- /dev/null +++ b/.codex/skills/ruoyi-plus-ai-coding/references/frontend.md @@ -0,0 +1,71 @@ +# 前端约定 + +## 优先参考的代码来源 + +- `ruoyi-modules/ruoyi-gen/src/main/resources/vm/ts/*.vm` +- `ruoyi-modules/ruoyi-gen/src/main/resources/vm/vue/*.vm` +- 前端工程中与目标模块最接近的现有页面 + +如果任务涉及前端,先看仓库里实际使用的前端目录和同类页面,不要直接套通用 Vue 习惯。 + +## API 文件规则 + +- 从 `@/utils/request` 引入 `request`。 +- 从 `axios` 引入 `AxiosPromise`。 +- 从 `@/api///types` 引入本模块类型。 +- 列表接口通常返回 `AxiosPromise>`。 +- 常规接口命名和路由保持: + `listXxx` -> `GET ///list` + `getXxx` -> `GET ///{id}` + `addXxx` -> `POST //` + `updateXxx` -> `PUT //` + `delXxx` -> `DELETE ///{id or ids}` + +## 类型文件规则 + +- 定义 `VO`、`Form`、`Query`。 +- `Form` 通常继承 `BaseEntity`。 +- 非树表页面的 `Query` 通常继承 `PageQuery`。 +- 各类 ID 字段通常用 `string | number`。 +- Java 数值类型通常映射为 `number`。 +- Boolean 映射为 `boolean`。 +- 其他生成字段默认多为 `string`。 +- 存在日期范围查询时保留 `params?: any`。 + +## Vue 页面规则 + +- 使用 `