--- name: crud-by-controller description: 基于现有 Controller 风格快速生成标准 CRUD 代码(Controller/Service/Mapper/Mapper.xml),并强制约束 SQL 只能写在 *Mapper.xml 中。用户提到生成 CRUD、仿照控制器写接口、补全增删改查、统一接口风格或规范 MyBatis SQL 放置位置时使用。 --- # CRUD 生成 Skill(基于 Controller 风格) ## 适用场景 当用户要求“参考某个 Controller 生成 CRUD”时,按此 Skill 执行。 默认参考风格与以下要点一致(以 `GeneralbingController` 为模板): ## 公共 Skill 引用 - 当前 Skill 依赖公共 POM 规范 Skill:`language/java/pom-factory-skill.md`(流程与输出模板);**Maven 必须/禁止项**见 [`rules/java-pom-governance.mdc`](../../../../../rules/java/java-pom-governance.mdc)。 - **Java CRUD 通用规范**(分层、SQL 仅 XML、Mapper、实体、Swagger、注入、自检):[`rules/java-crud-common.mdc`](../../../../../rules/java/java-crud-common.mdc)(原 `java-common.md` 正文)。 - **tf-ylsw 条线**涉及 ResultRespone、ToFlyAppLog、Wrappers/XML 等 MUST/SHOULD 时,叠加 [`rules/java-tf-ylsw-backend.mdc`](../../../../../rules/java/java-tf-ylsw-backend.mdc)。 - 当任务涉及 `pom.xml`、多模块依赖版本治理、`dependencyManagement/pluginManagement`、`systemPath` 清理时,必须同时应用 `pom-factory-skill` 工作流与 **`java-pom-governance`** 规则。 - 当 CRUD 生成与 POM 治理同时出现时,Controller/Service/Mapper 代码规范遵循本文件,Maven 构建与依赖规范遵循 `pom-factory-skill.md` + `java-pom-governance.mdc`。 - 当本文件与 **java-crud-common** 有冲突时:本文件的项目差异规则优先。 ## 模板风格(Generalbing / yx) - `@RestController` + `@RequestMapping("/xxx")` - 返回统一使用 `ResultRespone` - 分页接口:`GET /page`,参数为 `Page` + `@ModelAttribute 查询对象` - 单条查询:`GET /{id}` - 新增:`POST` + `@RequestBody` - 修改:`PUT` + `@RequestBody` - 删除:`DELETE /{id}` - 批量删除:`DELETE /deleteByIds`,`ids` 逗号分隔 - 使用 Swagger 注解(`@Api`、`@ApiOperation`、`@ApiImplicitParam(s)`) - 写操作可加 `@ToFlyAppLog` ## 本项目附加约束(yx,在通用规则之上) 以下与 **`rules/java-crud-common.mdc`** 叠加;冲突时以本节为准。 ### 日志注解 - 查询类接口(分页查询、按 ID 查询、列表查询)**不需要**使用自定义日志注解。 - 新增、修改、删除(含批量删除)接口必须记录操作日志。 - 默认在写操作接口上使用 `@ToFlyAppLog`(或项目等价注解),标题应体现具体动作。 ### 接口契约 - 返回体统一使用 `ResultRespone`,保持 `success/fail` 语义一致。 - CRUD 路径和方法保持统一:`GET /page`、`GET /{id}`、`POST /`、`PUT /`、`DELETE /{id}`、`DELETE /deleteByIds`。 - 参数命名统一:主键参数统一为 `id` 或领域主键名(需在同模块保持一致)。 - 查询接口使用 `@ModelAttribute` 承接查询对象,写接口使用 `@RequestBody`。 - Controller 仅做契约层职责,不返回内部异常堆栈或数据库细节。 ### 简单关联(`@Dict` / `@VoCast`) - 简单字典映射、展示字段转换优先使用 `@Dict` 与 `@VoCast`,避免在 Controller 手写拼装逻辑。 - `@Dict` 用于字典值到字典文本的映射(如状态码、类型码)。 - `@VoCast` 用于实体到 VO 的轻量转换与扩展展示字段封装。 - 注解应放在 VO/展示对象或对应转换链路中,不在 Controller 中堆叠转换细节。 - 复杂跨表聚合仍放在 Service 层处理,Controller 只返回最终 VO 结果。 ### 异常处理 - Controller 不直接 `try-catch` 吞异常,统一交由全局异常处理器处理。 - Service 层对可预期业务错误抛出业务异常(统一异常类型/错误码)。 - 禁止向前端透传数据库错误、SQL 细节、堆栈信息。 - 返回信息使用项目统一失败结构(通过 `ResultRespone` 或全局异常转换)。 - 新增/修改/删除失败时需保留可追踪日志,便于审计与排障。 > **SQL 放置、分层职责、Mapper/XML 细节** 一律以 **`rules/java-crud-common.mdc`** 为准,此处不重复。 ## 生成步骤 1. 识别实体信息 - 确认实体名、主键字段、主键类型、表名。 - 确认是否已有 Mapper/Service,避免重复创建。 2. 生成 Controller - 路由、方法命名、参数风格与 `GeneralbingController` 保持一致。 - 接口最小集合:分页、详情、新增、修改、单删、批删。 - 查询接口不加自定义日志注解;新增/修改/删除必须加日志注解。 - 禁止在 Controller 编写业务处理逻辑,复杂处理下沉到 Service。 - 查询返回涉及字典或展示转换时,优先返回带 `@Dict` / `@VoCast` 处理后的 VO。 - 严格遵循统一接口契约(路径、HTTP 方法、参数绑定、返回结构)。 3. 生成 Service 层 - `Service` 接口继承 MyBatis-Plus `IService`(若项目已有该模式)。 - `ServiceImpl` 继承 `ServiceImpl` 并实现接口。 - 不写任何 SQL。 - 承载全部业务相关代码,Controller 仅做转发与入参出参处理。 - 承担简单关联编排(字典映射、VO 转换触发),统一输出 VO,避免 Controller 参与拼装。 4. 生成 Mapper 层 - `Mapper` 接口继承 `BaseMapper`。 - 如需自定义查询,仅声明方法签名。 5. 生成 `*Mapper.xml` - 创建或补充对应 XML 文件。 - 所有自定义 SQL 都写在 XML 中,包含分页/列表/统计等扩展语句。 - 遵循 **`java-crud-common`** / 项目 XML 规范(`namespace`、显式字段、动态 SQL 标签使用)。 6. 自检 - 按 **`rules/java-crud-common.mdc`** 自检清单执行。 - 检查查询接口未加自定义日志注解;写操作已加日志注解。 - 检查简单关联场景是否优先使用 `@Dict` / `@VoCast`。 - 检查异常是否走统一全局处理,不透传底层异常细节。 ## 输出模板 ```markdown ## CRUD 生成结果 - 实体:`xxx` - 新增文件:`...` - 修改文件:`...` ## 接口清单 - `GET /xxx/page`:分页查询 - `GET /xxx/{id}`:按 ID 查询 - `POST /xxx`:新增 - `PUT /xxx`:修改 - `DELETE /xxx/{id}`:按 ID 删除 - `DELETE /xxx/deleteByIds`:批量删除 ## SQL 约束检查 - [x] 未在 Controller 写 SQL - [x] 未在 Service 写 SQL - [x] 未使用 Mapper 注解 SQL - [x] SQL 全部位于 `*Mapper.xml` ## 分层与日志检查 - [x] Controller 未放置业务代码 - [x] 业务相关代码位于 Service 层 - [x] 查询接口未使用自定义日志注解 - [x] 新增/修改/删除接口已记录日志 - [x] 简单关联优先使用 `@Dict` / `@VoCast` ## 契约与异常检查 - [x] 接口路径/方法/参数绑定符合统一契约 - [x] 返回结构统一为 `ResultRespone` - [x] 异常统一由全局异常处理器转换 - [x] 未透传 SQL/堆栈等底层错误信息 ## MyBatis XML 检查 - [x] 自定义 SQL 全部位于 `*Mapper.xml` - [x] `namespace` 与 Mapper 接口全限定名一致 - [x] 未使用 `select *` - [x] 动态 SQL 使用标准标签(`where/trim/set/foreach`) ``` ## 快速检查命令(可选) 在仓库内检查是否误用了注解 SQL: - 搜索 `@Select\(`、`@Update\(`、`@Delete\(`、`@Insert\(` - 若有结果,判定为不符合本 Skill 约束并要求迁移到 `*Mapper.xml`