diff --git a/.claude/agents/backend-cloud.md b/.claude/agents/backend-cloud.md new file mode 100644 index 000000000..c5244300d --- /dev/null +++ b/.claude/agents/backend-cloud.md @@ -0,0 +1,41 @@ +--- +name: backend-cloud +description: Cloud 后端专家。用于当前 RuoYi-Cloud-Plus 项目中的 Dubbo 远程调用、ruoyi-api 契约、服务拆分、Gateway/Auth、Nacos、Seata 分布式事务、服务间数据权限透传和 mock/stub 降级。 +--- + +你负责 Cloud 架构相关的增量修改。 + +## 核心原则 + +1. 先读 `.codex/skills/ruoyi-plus-ai-coding/references/cloud.md`。 +2. 再读目标远程接口、provider 实现、consumer 调用点、mock/stub 和 pom 依赖。 +3. 服务间能力优先通过 `ruoyi-api-*` 的 `RemoteXxxService` 契约暴露,不跨模块直接注入对方 mapper/service/entity。 +4. 修改远程接口签名时同步检查所有 `@DubboReference`、`@DubboService`、mock/stub、转换器和调用点。 +5. 跨服务写入检查 `@GlobalTransactional`,弱依赖副作用检查 Dubbo mock/stub 降级。 + +## Dubbo 规则 + +- Provider 放在业务模块 `dubbo` 包,命名 `RemoteXxxServiceImpl`,通常使用 `@RequiredArgsConstructor`、`@Service`、`@DubboService`。 +- Consumer 使用 `@DubboReference` 注入 `ruoyi-api-*` 中的 `RemoteXxxService`。 +- 可选能力按已有模式使用 `@DubboReference(mock = "true")` 或 `@DubboReference(stub = "true")`。 +- 批量查询、翻译、流程候选人、消息推送等场景不要在循环中逐条远程调用。 +- 远程 DTO 使用 `RemoteXxxBo`、`RemoteXxxVo`、`RemoteXxx`,不要泄露内部 Entity。 + +## Gateway / Auth / Nacos + +- Auth 相关逻辑优先查 `ruoyi-auth` 和 `ruoyi-gateway`,不要把 token 签发、客户端校验、网关白名单散落到业务模块。 +- Gateway 的 Sa-Token 校验、客户端 ID 匹配、访问路径/IP 白名单、same-token、`X-Forwarded-Prefix` 透传要保持原有 filter order。 +- 配置优先走 Nacos:`application-common.yml` 和 `${spring.application.name}.yml`,不要把环境差异硬编码到代码。 + +## Seata / 数据权限 + +- 同请求跨服务写入时判断是否需要 `@GlobalTransactional(rollbackFor = Exception.class)`。 +- Dubbo 消费端通过 `DubboDataPermissionFilter` 透传 `DataPermissionHelper` 上下文,不要绕过或删除。 +- 确实需要忽略数据权限时按现有模式用 `DataPermissionHelper.ignore(...)` 包裹最小范围。 + +## 自检 + +- 是否保持服务边界和远程契约稳定。 +- 是否同步 provider、consumer、mock/stub、转换器、pom 和配置。 +- 是否避免 N+1 Dubbo 调用。 +- 是否保留 Gateway/Auth、Nacos、Seata、数据权限透传和异常降级语义。 diff --git a/.claude/agents/backend-common-infrastructure.md b/.claude/agents/backend-common-infrastructure.md index 3e5a77fc7..18d18a377 100644 --- a/.claude/agents/backend-common-infrastructure.md +++ b/.claude/agents/backend-common-infrastructure.md @@ -1,6 +1,6 @@ --- name: backend-common-infrastructure -description: 公共基础模块专家。用于修改 ruoyi-common 下的 mybatis、translation、json enhance、excel、oss、redis、web、encrypt 等公共能力,强调 API 兼容、调用点检查和同包风格一致。 +description: 公共基础模块专家。用于修改 ruoyi-common 下的 mybatis、translation、json enhance、excel、oss、redis、web、encrypt、dubbo、seata 等公共能力,强调 API 兼容、调用点检查和同包风格一致。 --- 你负责 `ruoyi-common` 公共基础模块的增量修改。 @@ -14,8 +14,8 @@ description: 公共基础模块专家。用于修改 ruoyi-common 下的 mybatis ## common-mybatis -- 链式查询能力沿用 `BaseMapperPlus#lambda()`、`LambdaCrudChainWrapper`、`LambdaQueryBuilder`、`LambdaQueryCondition`。 -- 条件辅助方法命名沿用 `eqIfPresent`、`eqIfText`、`likeIfText`、`betweenIfPresent`、`inIfNotEmpty`、`findInSetIfPresent`。 +- 链式查询能力沿用 `QueryBuilder.lambda(...)`、`QueryBuilder.lambdaJoin(...)`、`BaseMapperPlus#lambda()`、`LambdaCrudChainWrapper`、`LambdaQueryBuilder`、`LambdaJoinQueryBuilder`、`LambdaQueryCondition`。 +- 条件辅助方法命名沿用 `eqIfPresent`、`eqIfText`、`neIfPresent`、`likeIfText`、`betweenIfPresent`、`betweenParams`、`inIfNotEmpty`、`findInSetIfPresent`。 - `LambdaCrudChainWrapper` 同时维护查询字段和更新 set 片段;新增状态时必须检查 `instance()` 与 `clear()`。 - 返回链式对象时保持 `this` / `typedThis`,不要暴露底层 wrapper 破坏调用链。 @@ -34,6 +34,13 @@ description: 公共基础模块专家。用于修改 ruoyi-common 下的 mybatis - JSON 响应增强处理器优先实现 `JsonFieldProcessor`,并按字段上下文读取注解。 - Web、Redis、Encrypt、Sa-Token 自动配置类新增 bean 时检查条件注解、配置属性和已有命名。 +## dubbo / seata + +- `common-dubbo` 修改前检查 `DubboRequestFilter`、`DubboCustomProperties`、`common-dubbo.yml`、Dubbo SPI 文件和 provider/consumer 调用点。 +- Dubbo filter 要区分 provider/consumer 端,保持 `@Activate` group、order、异常记录和降级语义。 +- `common-mybatis` 中的 `DubboDataPermissionFilter` 负责消费端数据权限上下文透传,不要随意移除。 +- `common-seata` 和跨服务写入相关修改要检查 `@GlobalTransactional` 调用点,不要把本地事务规则直接套到分布式事务。 + ## 自检 - 是否破坏已有调用点。 diff --git a/.claude/agents/backend-crud.md b/.claude/agents/backend-crud.md index 6da0b453d..8d4dd08aa 100644 --- a/.claude/agents/backend-crud.md +++ b/.claude/agents/backend-crud.md @@ -33,8 +33,8 @@ description: 标准后端 CRUD 专家。用于当前项目中的新增单表 CRU ## 查询规则 -- 单表查询优先用 `LambdaQueryWrapper` -- 项目公共链式查询可使用 `BaseMapperPlus#lambda()`、`LambdaCrudChainWrapper`、`LambdaQueryCondition` 的 `IfPresent` / `IfText` / `IfNotEmpty` 风格 +- 单表查询优先返回 `LambdaQueryWrapper`,新增 generator 风格代码优先用 `QueryBuilder.lambda(Entity.class).build()` +- 项目公共链式查询可使用 `QueryBuilder.lambda(...)`、`BaseMapperPlus#lambda()`、`LambdaCrudChainWrapper`、`LambdaQueryCondition` 的 `IfPresent` / `IfText` / `IfNotEmpty` 风格 - 日期范围默认从 `bo.getParams()` 中读取 begin/end - 分页优先返回 `PageResult` - BO 转实体使用 `MapstructUtils.convert(bo, Entity.class)` diff --git a/.claude/agents/backend-engineering.md b/.claude/agents/backend-engineering.md index 59efb4daf..eef0adb9b 100644 --- a/.claude/agents/backend-engineering.md +++ b/.claude/agents/backend-engineering.md @@ -1,6 +1,6 @@ --- name: backend-engineering -description: 后端工程总入口。用于在当前 RuoYi-Vue-Plus 项目中识别任务属于标准 CRUD、复杂模块增强、联表与数据权限、公共 common 模块、JavaDoc 注释、或前后端联动,并选择合适的后端子 agent。 +description: 后端工程总入口。用于在当前 RuoYi-Cloud-Plus 项目中识别任务属于标准 CRUD、复杂模块增强、联表与数据权限、公共 common 模块、JavaDoc 注释、或前后端联动,并选择合适的后端子 agent。 --- 你是当前后端工程的总入口 agent。 @@ -9,10 +9,20 @@ description: 后端工程总入口。用于在当前 RuoYi-Vue-Plus 项目中识 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-common` 公共基础能力,例如 `common-mybatis`、`common-translation`、`common-json`、`common-excel`、`common-oss`,优先使用 `backend-common-infrastructure.md` 的规则。 -5. 如果只要求补充或修正 JavaDoc 注释,优先使用 `backend-javadoc.md` 的规则。 -6. 如果同时要求同步前端接口或前端页面骨架,保持后端路由与 generator 风格稳定,便于前端 agent 对接。 +3. 如果涉及 Cloud 专属能力,例如 Dubbo、`ruoyi-api` 远程契约、Gateway、Nacos、Seata、服务间调用或服务边界,优先使用 `backend-cloud.md` 的规则。 +4. 如果重点在 MPJ 联表、`@DataPermission`、复杂查询、数据范围控制,优先使用 `backend-query-permission.md` 的规则。 +5. 如果是修改 `ruoyi-common` 公共基础能力,例如 `common-mybatis`、`common-translation`、`common-json`、`common-excel`、`common-oss`、`common-dubbo`、`common-seata`,优先使用 `backend-common-infrastructure.md` 的规则。 +6. 如果只要求补充或修正 JavaDoc 注释,优先使用 `backend-javadoc.md` 的规则。 +7. 如果同时要求同步前端接口或前端页面骨架,保持后端路由与 generator 风格稳定,便于前端 agent 对接。 + +文档读取顺序: + +- 后端 Java、Mapper、Service、Controller、BO、VO、Entity、权限、查询、公共模块或 JavaDoc 任务,先读 `.codex/skills/ruoyi-plus-ai-coding/references/backend.md`。 +- Dubbo 远程调用、`ruoyi-api` 契约、服务拆分、Gateway、Nacos、Seata、服务间数据权限透传任务,先读 `.codex/skills/ruoyi-plus-ai-coding/references/cloud.md`。 +- 同步前端 Vue、TypeScript、api、types 或页面骨架时,再读 `.codex/skills/ruoyi-plus-ai-coding/references/frontend.md`。 +- 任务边界不清晰或需要标准场景示例时,再读 `.codex/skills/ruoyi-plus-ai-coding/references/examples.md`。 +- 只读取当前任务相关的 reference,不一次性展开全部文档。 +- reference 用来约束实现方式和检查范围;如果 reference、generator 模板和真实代码冲突,优先相信当前模块真实代码和实际调用点。 通用要求: diff --git a/.claude/agents/backend-query-permission.md b/.claude/agents/backend-query-permission.md index c801d598c..adcc168d8 100644 --- a/.claude/agents/backend-query-permission.md +++ b/.claude/agents/backend-query-permission.md @@ -16,18 +16,20 @@ description: 后端查询、联表与数据权限专家。用于当前项目中 ## 重点关注 - `BaseMapperPlus` +- `QueryBuilder` - `LambdaCrudChainWrapper` - `LambdaQueryBuilder` +- `LambdaJoinQueryBuilder` - `LambdaQueryCondition` - `@DataPermission` - `DataColumn` - `MPJBaseMapper` -- `JoinWrappers.lambda(...)` +- `QueryBuilder.lambdaJoin(...)` - 复杂分页与列表查询 ## 项目写法 -- MPJ 联表查询沿用别名风格,例如 `JoinWrappers.lambda("u", SysUser.class)`。 +- MPJ 联表查询沿用别名风格,例如 `QueryBuilder.lambdaJoin("u", SysUser.class)`。 - 带别名字段条件使用 `.eq("u", Entity::getField, value)`、`.orderByAsc("m", SysMenu::getOrderNum)`。 - 数据权限列名要和真实 SQL 别名一致,例如 `d.dept_id`、`u.create_by`。 - `ruoyi-system` 的用户、角色、菜单、部门查询常带角色状态、删除标识、部门权限过滤,修改前先读对应 mapper/service。 diff --git a/.codex/skills/ruoyi-plus-ai-coding/SKILL.md b/.codex/skills/ruoyi-plus-ai-coding/SKILL.md index 3cfbc2940..2f7743ea8 100644 --- a/.codex/skills/ruoyi-plus-ai-coding/SKILL.md +++ b/.codex/skills/ruoyi-plus-ai-coding/SKILL.md @@ -1,6 +1,6 @@ --- name: ruoyi-plus-ai-coding -description: 在仓库内按代码生成器模板和项目既有约定生成或修改代码。用于新增或修改 CRUD 模块、controller/service/mapper/BO/VO/entity、MyBatis-Plus/MPJ 查询、数据权限、缓存、翻译/JSON 增强、公共 common 模块能力、JavaDoc 注释,以及与后端接口配套的 Vue 3 + TypeScript 页面、types 和 api 文件。 +description: 在仓库内按代码生成器模板、项目 reference 文档和既有约定生成或修改代码。用于新增或修改 CRUD 模块、controller/service/mapper/BO/VO/entity、MyBatis-Plus/MPJ 查询、数据权限、缓存、翻译/JSON 增强、公共 common 模块能力、JavaDoc 注释,以及与后端接口配套的 Vue 3 + TypeScript 页面、types 和 api 文件;触发后应先按任务类型读取对应 references,再阅读目标模块真实代码和 generator 模板。 --- # RuoYi Plus AI 编码规范 @@ -15,6 +15,7 @@ description: 在仓库内按代码生成器模板和项目既有约定生成或 - 根据新表结构补齐 entity、bo、vo、mapper、service、controller。 - 修改已有模块的查询、校验、导入导出、数据权限、事务逻辑。 - 修改 `ruoyi-common` 公共能力,例如 mybatis 查询构造器、translation、json enhance、excel、oss、redis、web 配置。 +- 修改 Cloud 专属能力,例如 `ruoyi-api` 远程契约、Dubbo provider/consumer、Gateway/Auth、Nacos 配置约定、Seata 分布式事务、服务间数据权限透传。 - 补充或修正 JavaDoc 注释,尤其是公共 API、接口、BO/VO/Entity 字段、Mapper 默认方法、Service/Controller 方法。 - 在系统、监控、工作流、demo 等模块内按现有约定扩展业务代码。 - 为后端新增接口同步补前端 `api/types/index.vue` 骨架。 @@ -30,14 +31,26 @@ description: 在仓库内按代码生成器模板和项目既有约定生成或 ## 执行流程 -1. 先确认目标模块,优先复用同模块中最近似功能的写法。 -2. 新增标准 CRUD 代码前,先读取 `ruoyi-modules/ruoyi-gen/src/main/resources/vm/` 下的模板。 -3. 命名和分层保持与仓库一致: +1. 先判断任务类型,并按“文档读取规则”读取当前任务需要的 reference。 +2. 确认目标模块,优先复用同模块中最近似功能的写法。 +3. 新增标准 CRUD 代码前,先读取 `ruoyi-modules/ruoyi-gen/src/main/resources/vm/` 下的模板。 +4. 命名和分层保持与仓库一致: `domain` entity、`domain.bo`、`domain.vo`、`mapper`、`service`、`service.impl`、`controller`。 -4. 优先在生成器结构上扩展,不要自行发明新的分层。 -5. 修改 `ruoyi-system` 这类复杂模块前,先阅读同类现有实现,因为这些模块通常比生成器默认产物多出数据权限、联表、缓存、安全校验等逻辑。 -6. 修改 `ruoyi-common` 公共模块前,先阅读同包接口、实现类和调用点,优先保持已有 API 语义与兼容性。 -7. 只补注释或文档时,不运行无关格式化,不重排 import,不改代码逻辑。 +5. 优先在生成器结构上扩展,不要自行发明新的分层。 +6. 修改 `ruoyi-system` 这类复杂模块前,先阅读同类现有实现,因为这些模块通常比生成器默认产物多出数据权限、联表、缓存、安全校验等逻辑。 +7. 修改 `ruoyi-common` 公共模块前,先阅读同包接口、实现类和调用点,优先保持已有 API 语义与兼容性。 +8. 只补注释或文档时,不运行无关格式化,不重排 import,不改代码逻辑。 + +## 文档读取规则 + +使用本 skill 时,先按任务类型读取适用 reference,不一次性展开所有文档: + +- 后端 Java、Mapper、Service、Controller、BO、VO、Entity、权限、查询、公共模块或 JavaDoc 任务,先读 [references/backend.md](references/backend.md)。 +- Cloud 专属能力,例如 Dubbo 远程调用、`ruoyi-api` 契约、服务拆分、Gateway、Nacos、Seata 分布式事务、服务间数据权限透传,先读 [references/cloud.md](references/cloud.md)。 +- 前端 Vue、TypeScript、api、types 或页面任务,先读 [references/frontend.md](references/frontend.md)。 +- 不确定任务边界、需要标准调用方式或需要对照典型场景时,再读 [references/examples.md](references/examples.md)。 + +reference 用来约束实现方式和自检范围;发生冲突时,仍以当前模块真实代码和实际调用点为准。 ## 优先级规则 @@ -58,6 +71,10 @@ description: 在仓库内按代码生成器模板和项目既有约定生成或 Java、MyBatis-Plus、BO/VO/entity、controller、mapper、service 的具体规则见 [references/backend.md](references/backend.md)。 +## Cloud 规则 + +Dubbo、`ruoyi-api`、Gateway/Auth、Nacos、Seata、服务间数据权限透传的具体规则见 [references/cloud.md](references/cloud.md)。 + ## 前端规则 Vue 3、TypeScript API 文件、生成式列表页、表单状态、字典和日期范围约定见 [references/frontend.md](references/frontend.md)。 @@ -145,14 +162,16 @@ Vue 3、TypeScript API 文件、生成式列表页、表单状态、字典和日 - Mapper 继承 `BaseMapperPlus`。 - 手写 Service 注入 Mapper 时使用具体业务短名;代码生成器模板按类名首字母小写命名,例如 `SysRoleMapper` 生成 `sysRoleMapper`。 - Service 按场景返回 `PageResult` 或 `List`。 -- 查询代码优先使用 `LambdaQueryWrapper`,复杂模块沿用既有 MPJ 联表风格。 -- 公共 Mapper 链式能力优先沿用 `LambdaCrudChainWrapper`、`LambdaQueryBuilder`、`LambdaQueryCondition` 的 `IfPresent` / `IfText` / `IfNotEmpty` 风格。 +- 查询代码优先使用 `QueryBuilder.lambda(...)` 构造 `LambdaQueryWrapper`,复杂模块沿用 `QueryBuilder.lambdaJoin(...)` 的 MPJ 联表风格。 +- 公共 Mapper 链式能力优先沿用 `QueryBuilder.lambda(...)`、`QueryBuilder.lambdaJoin(...)`、`LambdaCrudChainWrapper`、`LambdaQueryBuilder`、`LambdaJoinQueryBuilder`、`LambdaQueryCondition` 的 `IfPresent` / `IfText` / `IfNotEmpty` 风格。 - 翻译能力优先沿用 `TranslationInterface` + `@TranslationType` + `@Translation`,批量翻译实现 `translationBatch`,避免退化成逐条查询。 - JSON 响应增强优先沿用 `JsonFieldProcessor` 的 `collect` / `prepare` / `process` 三阶段模型。 +- Cloud 服务间调用优先通过 `ruoyi-api-*` 的 `RemoteXxxService` 契约和 `@DubboReference` / `@DubboService`,不要跨模块直接注入对方 mapper/service。 +- 涉及跨服务写入、文件上传、消息推送、工作流联动时检查是否需要 `@GlobalTransactional`、Dubbo 降级 `mock/stub`、数据权限上下文透传和 Nacos/Gateway 配置。 - BO 使用 `@AutoMapper(target = Entity.class, reverseConvertGenerate = false)`。 - VO 使用 `@AutoMapper(target = Entity.class)`。 - 前端 API 路径与后端路由完全对应。 -- 前端列表页继续使用仓库里的 `proxy?.addDateRange`、`proxy?.$modal`、`proxy?.download`、`useDict`、`pagination` 等工具。 +- 前端列表页优先沿用 generator 模板里的 `useLoading`、`useSearchReset`、`useTableSelection`、`useFormDialog`、`useDateRangeQuery`、`modal.confirm`、`requestDownload`、`useDict`、`pagination` 等工具。 ## 推荐提问方式 diff --git a/.codex/skills/ruoyi-plus-ai-coding/agents/openai.yaml b/.codex/skills/ruoyi-plus-ai-coding/agents/openai.yaml index d5977d1a9..b476025e6 100644 --- a/.codex/skills/ruoyi-plus-ai-coding/agents/openai.yaml +++ b/.codex/skills/ruoyi-plus-ai-coding/agents/openai.yaml @@ -1,7 +1,7 @@ interface: display_name: "RuoYi Plus 编码" - short_description: "按生成器、common 与仓库约定编写代码" - default_prompt: "使用 $ruoyi-plus-ai-coding 在这个仓库里按现有约定实现代码修改,保持生成器、公共模块和业务模块风格一致。" + short_description: "先读适用 reference,再按 Cloud、生成器与仓库约定编码" + default_prompt: "使用 $ruoyi-plus-ai-coding 在这个仓库里先读取适用 reference;涉及 Dubbo、ruoyi-api、Gateway、Nacos、Seata 时读取 cloud reference,再按生成器、公共模块和业务模块风格实现代码修改。" 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 index 3a86cc759..e472db191 100644 --- a/.codex/skills/ruoyi-plus-ai-coding/references/backend.md +++ b/.codex/skills/ruoyi-plus-ai-coding/references/backend.md @@ -5,6 +5,10 @@ - `ruoyi-modules/ruoyi-gen/src/main/resources/vm/java/*.vm` - `ruoyi-modules/ruoyi-demo/...` - `ruoyi-modules/ruoyi-system/...` +- `ruoyi-modules/ruoyi-workflow/...` +- `ruoyi-api/...` +- `ruoyi-auth/...` +- `ruoyi-gateway/...` - `ruoyi-common/ruoyi-common-mybatis/...` ## 决策顺序 @@ -62,7 +66,7 @@ - 默认形式是 `interface XxxMapper extends BaseMapperPlus`。 - 不要为简单的 entity 转 vo 手写重复代码,优先依赖 `BaseMapperPlus`。 - 模块已经使用 `@DataPermission` 时,在重写方法和自定义查询上继续保留。 -- 复杂模块里 mapper 可能同时继承 `MPJBaseMapper` 并使用 `JoinWrappers.lambda(...)`,遇到这种风格要延续,不要换一种写法。 +- 复杂模块里 mapper 可能同时继承 `MPJBaseMapper` 并使用 `QueryBuilder.lambdaJoin(...)` 构造 MPJ 查询,遇到这种风格要延续,不要换一种写法。 - 只有在 `selectVoList/selectVoPage` 不够用时,才补 XML 或自定义 mapper 方法。 - Mapper 默认方法可以承载短小的 wrapper 查询;涉及复杂业务编排、缓存、事务或跨 mapper 写入时放到 service。 - `ruoyi-system` 的用户、角色、菜单、部门等模块常带数据权限、MPJ 联表、角色状态过滤,修改前先读对应 mapper/service。 @@ -93,8 +97,8 @@ - 如果去掉前缀会产生歧义或命名冲突,保留必要前缀。 - 读操作通常返回 `Vo`、`List` 或 `PageResult`。 - BO 转实体用 `MapstructUtils.convert(bo, Entity.class)`。 -- 查询条件优先用 `LambdaQueryWrapper` 和 `Wrappers.lambdaQuery()`。 -- 在 wrapper 条件里直接写 `StringUtils.isNotBlank(...)` 和 null 判断。 +- 查询条件优先返回 `LambdaQueryWrapper`;新增 generator 风格代码优先用 `QueryBuilder.lambda(Entity.class)`,老模块已有 `Wrappers.lambdaQuery()` 时可继续保持。 +- 字符串和空值条件优先用 `eqIfText`、`likeIfText`、`eqIfPresent`、`inIfNotEmpty`、`betweenParams` 等项目扩展;老代码已有直接 `StringUtils.isNotBlank(...)` 和 null 判断时可增量保持。 - 分页查询优先采用: `Page result = entityMapper.selectVoPage(pageQuery.build(), lqw);` `return PageResult.build(result.getRecords(), result.getTotal());` @@ -119,10 +123,10 @@ ### 查询逻辑建议 -- 单表查询优先使用 `LambdaQueryWrapper`。 -- 条件判断直接放在 wrapper 上,不要额外写大量 if 套壳。 -- 日期范围统一从 `bo.getParams()` 取 begin/end。 -- 复杂联表查询优先查同模块是否已有 MPJ 风格可复用。 +- 单表查询优先返回 `LambdaQueryWrapper`,生成器风格优先通过 `QueryBuilder.lambda(Entity.class).build()` 构造。 +- 条件判断直接放在 wrapper 链式条件上,不要额外写大量 if 套壳。 +- 日期范围统一从 `bo.getParams()` 取 begin/end;生成器默认使用 `betweenParams(Entity::getField, params, "beginField", "endField")`。 +- 复杂联表查询优先查同模块是否已有 MPJ 风格可复用;新写法优先用 `QueryBuilder.lambdaJoin("u", Entity.class)`。 ### 写入逻辑建议 @@ -136,6 +140,7 @@ - 类上通常带 `@Validated`、`@RestController`、`@RequiredArgsConstructor`、`@RequestMapping`。 - 返回值使用 `R` 或 `R`。 - 标准 CRUD 接口通常是:`GET /list`、`POST /export`、`GET /{id}`、`POST`、`PUT`、`DELETE /{ids}`。 +- 树表接口通常不分页,`list` 返回 `R>`;导出路由以目标模块或 generator 模板为准,旧 demo 树表存在 `GET /export`,新版生成器通常是 `POST /export`。 - `@SaCheckPermission` 权限格式遵循 `${module}:${business}:${action}`。 - 写操作、导入导出接口通常加 `@Log(title = "...", businessType = BusinessType.X)`。 - 附近接口已有防重时,写接口继续使用 `@RepeatSubmit`。 @@ -166,14 +171,22 @@ - 优先使用项目工具类:`MapstructUtils`、`StringUtils`、`StreamUtils`、`ValidatorUtils`、`SpringUtils`、`RedisUtils`。 - 数组转列表按附近代码习惯使用 `List.of(ids)` 或 `Arrays.asList(ids)`。 - 日期范围查询通常从 `bo.getParams()` 中读取 `beginTime`、`endTime` 或 `beginFieldName`、`endFieldName`。 +- 构建查询优先识别 `QueryBuilder.lambda(...)`、`QueryBuilder.lambdaJoin(...)`、`BaseMapperPlus#lambda()` 三类入口,不要退回临时手写 SQL 或自造 wrapper。 + +## Cloud 服务规则 + +- 涉及 Dubbo、`ruoyi-api` 远程契约、Gateway、Nacos、Seata 或服务间调用时,同时读取 [cloud.md](cloud.md)。 +- Cloud 服务间调用优先通过 `RemoteXxxService` + `@DubboReference` / `@DubboService`,不要跨模块直接注入其他服务的 mapper/service。 +- 远程接口、远程 BO/VO/domain、mock/stub 放在 `ruoyi-api-*`;业务实现放在对应业务模块 `dubbo` 包。 +- 跨服务写入检查 `@GlobalTransactional(rollbackFor = Exception.class)`;弱依赖远程调用检查是否需要 `mock = "true"` 或 `stub = "true"` 降级。 ## common-mybatis 规则 -- 链式查询能力优先沿用 `BaseMapperPlus#lambda()`、`LambdaCrudChainWrapper`、`LambdaQueryBuilder`、`LambdaQueryCondition`。 -- 条件辅助方法使用项目已有命名:`eqIfPresent`、`eqIfText`、`likeIfText`、`betweenIfPresent`、`inIfNotEmpty`、`findInSetIfPresent`。 +- 链式查询能力优先沿用 `QueryBuilder.lambda(...)`、`QueryBuilder.lambdaJoin(...)`、`BaseMapperPlus#lambda()`、`LambdaCrudChainWrapper`、`LambdaQueryBuilder`、`LambdaJoinQueryBuilder`、`LambdaQueryCondition`。 +- 条件辅助方法使用项目已有命名:`eqIfPresent`、`eqIfText`、`neIfPresent`、`likeIfText`、`betweenIfPresent`、`betweenParams`、`inIfNotEmpty`、`findInSetIfPresent`。 - 新增 wrapper 方法时保持链式返回 `this` / `typedThis`,不要返回底层 `LambdaQueryWrapper` 破坏调用链。 - `LambdaCrudChainWrapper` 既承担查询又承担更新 set 片段,新增能力时要同时考虑 `getSqlSelect`、`getSqlSet`、`clear`、`instance` 的状态复制和清理。 -- MPJ 联表查询沿用别名风格,例如 `JoinWrappers.lambda("u", SysUser.class)`、`.leftJoin(..., "d", ...)`、`.eq("u", Entity::getField, value)`。 +- MPJ 联表查询沿用别名风格,例如 `QueryBuilder.lambdaJoin("u", SysUser.class)`、`.leftJoin(..., "d", ...)`、`.eq("u", Entity::getField, value)`。 - 数据权限注解使用 `@DataPermission` + `@DataColumn`,列名需和实际 SQL 别名一致,例如 `d.dept_id`、`u.create_by`。 ## translation / JSON 增强规则 @@ -187,8 +200,8 @@ ## 缓存与异步/监听规则 -- 已有 service 使用 `@Cacheable`、`@CacheEvict`、`@Caching` 时,新增写操作要同步考虑缓存失效。 -- 部门、字典、OSS 配置等模块已有缓存初始化或失效逻辑,不要只改数据库不处理缓存。 +- 已有 service 使用 `@Cacheable`、`@CachePut`、`@CacheEvict`、`@Caching` 或 `CacheUtils.evict/clear` 时,新增写操作要同步考虑缓存失效。 +- 部门、字典、OSS 配置等模块已有缓存初始化或失效逻辑,不要只改数据库不处理缓存;字典这类模块常同时维护 `CacheNames.SYS_DICT` 与 `CacheNames.SYS_DICT_TYPE`。 - Excel 导入监听器实现 `ExcelListener` 时,保留 `getExcelResult()` 的回执语义和错误聚合方式。 - 定时任务、MQTT、SSE、异步回调等框架方法一般按接口覆写语义实现,除非业务不直观,不要添加冗长注释。 diff --git a/.codex/skills/ruoyi-plus-ai-coding/references/cloud.md b/.codex/skills/ruoyi-plus-ai-coding/references/cloud.md new file mode 100644 index 000000000..9197e24dc --- /dev/null +++ b/.codex/skills/ruoyi-plus-ai-coding/references/cloud.md @@ -0,0 +1,72 @@ +# Cloud 约定 + +## 优先参考的代码来源 + +- `ruoyi-api/ruoyi-api-*/src/main/java/.../api/Remote*Service.java` +- `ruoyi-api/ruoyi-api-*/src/main/java/.../api/domain/**` +- `ruoyi-modules/*/src/main/java/.../dubbo/Remote*ServiceImpl.java` +- `ruoyi-auth/src/main/java/...` +- `ruoyi-gateway/src/main/java/.../filter/**` +- `ruoyi-common/ruoyi-common-dubbo/**` +- `ruoyi-common/ruoyi-common-seata/**` +- `script/config/nacos/*.yml` + +## 服务边界 + +- 当前项目是 Cloud 拆分结构,服务间能力优先通过 `ruoyi-api-*` 暴露契约,不要跨模块直接注入对方 mapper、service 或 entity。 +- `ruoyi-api-*` 只放远程接口、远程 BO/VO/domain、model、event、mock、stub 等契约对象;不要放业务实现、mapper、controller 或依赖具体业务模块。 +- 远程接口命名沿用 `RemoteXxxService`,提供方实现命名沿用 `RemoteXxxServiceImpl` 并放在业务模块的 `dubbo` 包。 +- 远程对象命名沿用 `RemoteXxxBo`、`RemoteXxxVo`、`RemoteXxx`,避免直接把内部 Entity 或内部管理端 VO 暴露成跨服务契约。 +- 修改远程接口签名时必须同时检查所有 `@DubboReference` 调用点、`@DubboService` 实现、mock/stub、MapStruct 转换器和编译影响。 + +## Dubbo Provider + +- 提供方类通常同时标注 `@RequiredArgsConstructor`、`@Service`、`@DubboService`,并实现 `ruoyi-api-*` 中的 `RemoteXxxService`。 +- Provider 内部复用本模块 service/mapper,不绕过本模块已有权限、缓存、校验、事务和转换规则。 +- 返回远程 VO/BO 时优先使用已有 convert 接口或 `MapstructUtils.convert(...)`,不要手写重复字段拷贝。 +- 批量查询接口遇到空集合时优先返回 `List.of()`、`Map.of()` 或空字符串,避免无意义远程调用和 SQL。 +- 登录、权限、字典、用户、部门、资源、消息、工作流等远程接口要保持稳定,因为它们常被 `auth`、`gateway`、`workflow`、公共 translation/log/service-impl 模块消费。 + +## Dubbo Consumer + +- 消费方注入远程服务使用 `@DubboReference`,字段类型使用 `ruoyi-api-*` 的 `RemoteXxxService`。 +- 可选或弱依赖调用按已有写法使用 `@DubboReference(mock = "true")` 或 `@DubboReference(stub = "true")`,并在 `ruoyi-api-*` 中提供 `RemoteXxxServiceMock` / `RemoteXxxServiceStub`。 +- mock 用于服务调用异常后的降级返回,例如返回 `null`、`List.of()`、`StringUtils.EMPTY`;stub 用于本地包裹远程调用并吞掉非关键异常,例如消息推送未开启。 +- 列表、翻译、流程候选人、消息推送等场景优先调用批量远程接口,避免在循环中逐条 Dubbo 调用。 +- 远程调用失败是否抛出异常要按业务语义决定:登录、权限、注册等关键路径应失败;通知、推送、OSS URL 翻译等弱依赖可降级。 + +## 应用与依赖 + +- 需要 Dubbo provider 或 consumer 的应用启动类保持 `@EnableDubbo`,模块 pom 检查是否依赖 `ruoyi-common-dubbo`。 +- 跨服务写入需要分布式事务时检查是否依赖 `ruoyi-common-seata`,并使用 `@GlobalTransactional(rollbackFor = Exception.class)`;单服务本地写入继续使用 `@Transactional`。 +- `common-dubbo.yml` 是内置配置,注册中心走 Nacos,元数据中心走 Redis;不要直接改内置配置做业务定制,业务环境差异优先通过 Nacos 同名配置覆盖。 +- 各应用 `application.yml` 通常导入 `optional:nacos:application-common.yml` 和 `optional:nacos:${spring.application.name}.yml`,新增应用或配置时保持这个结构。 + +## 数据权限与上下文 + +- Dubbo 消费端存在 `DubboDataPermissionFilter`,会透传 `DataPermissionHelper` 上下文;不要随意删除或绕过数据权限上下文。 +- 远程 provider 内部查询仍按本模块 mapper/service 的数据权限规则执行。 +- 确实需要系统级写入或登录记录更新时,按现有代码使用 `DataPermissionHelper.ignore(...)` 包裹最小范围。 +- 涉及登录用户、租户、客户端、same-token、请求头透传时先查 `LoginHelper`、Gateway 过滤器和 common-satoken 现有实现。 + +## Gateway 与 Auth + +- 认证中心位于 `ruoyi-auth`,网关位于 `ruoyi-gateway`;不要把 token 签发、客户端校验、网关白名单逻辑散落到普通业务模块。 +- Gateway 的 `AuthFilter` 负责 Sa-Token 登录校验、客户端 ID 匹配、客户端访问路径/IP 白名单和 actuator Basic Auth。 +- `ForwardAuthFilter` 负责透传 `X-Forwarded-Prefix` 和内部 same-token;新增网关过滤逻辑时注意 filter order 和 actuator 排除。 +- 网关白名单、路由、鉴权、Nacos metadata 等配置优先放 Nacos 配置文件或已有 properties,不硬编码到业务 controller。 +- 业务 controller 仍保留 `@SaCheckPermission`、`@SaCheckRole` 等权限注解,网关认证不替代业务权限。 + +## Seata 与跨服务副作用 + +- 同一个请求里同时修改本服务数据库并调用远程服务写入时,优先判断是否需要 `@GlobalTransactional`。 +- 文件上传、头像更新、消息推送、工作流启动/完成等跨服务副作用要区分强一致与可降级副作用。 +- 非关键消息推送可采用 stub/mock 降级;关键数据一致性不要用吞异常替代事务或补偿。 + +## 自检 + +- 是否误把内部 Entity/VO 暴露到 `ruoyi-api-*`。 +- 是否同步修改了远程接口、provider、consumer、mock/stub、转换器和 pom 依赖。 +- 是否避免了循环中的逐条 Dubbo 调用。 +- 是否检查了 `@EnableDubbo`、`ruoyi-common-dubbo`、`ruoyi-common-seata`、Nacos 配置和 Gateway 白名单。 +- 是否保留数据权限上下文透传、缓存失效、事务边界和异常语义。 diff --git a/.codex/skills/ruoyi-plus-ai-coding/references/frontend.md b/.codex/skills/ruoyi-plus-ai-coding/references/frontend.md index f77a22653..a4340306d 100644 --- a/.codex/skills/ruoyi-plus-ai-coding/references/frontend.md +++ b/.codex/skills/ruoyi-plus-ai-coding/references/frontend.md @@ -6,12 +6,13 @@ - `ruoyi-modules/ruoyi-gen/src/main/resources/vm/vue/*.vm` - 前端工程中与目标模块最接近的现有页面 -如果任务涉及前端,先看仓库里实际使用的前端目录和同类页面,不要直接套通用 Vue 习惯。 +当前 boot4 仓库通常只含后端与 generator 前端模板;如果前端工程不在当前 root,先以 generator 模板约定为准,再对照用户提供的前端目录或相邻仓库。 ## API 文件规则 - 从 `@/utils/request` 引入 `request`。 -- 从 `axios` 引入 `AxiosPromise`。 +- 从 `@/utils/api-types` 引入 `AxiosPromise`。 +- 从 `@/api/types` 引入 `PageResult`。 - 从 `@/api///types` 引入本模块类型。 - 列表接口通常返回 `AxiosPromise>`。 - 常规接口命名和路由保持: @@ -36,24 +37,24 @@ - 使用 `