Install
openclaw skills install crud-code-generatorUse when generating CRUD code (create, read, update, delete, export) for database table objects across Java/Spring Boot backend and Vue2 frontend projects, based on DDL SQL. Activates when user asks to generate CRUD code, create data management endpoints, or scaffold admin pages from table definitions.
openclaw skills install crud-code-generator根据 DDL 建表语句,一键生成后端 Java 全栈代码(Entity/DTO/QueryParam/Mapper/Service/Controller/Converter/Enum)+ 前端 Vue2 页面 + SQL 文件
当用户提到以下任一内容时激活:
先确认后生成 — 在生成代码前,必须确认以下信息:
生成后验证 — 后端执行 mvn clean package,前端提示用户是否验证 npm run dev。
在生成代码前,必须先探测后端工程目录结构,自动适配不同的项目模块名。
# 找到所有包含 pom.xml 的子模块
find {backend-root} -maxdepth 2 -name "pom.xml" -not -path "*/target/*"
识别模块用途 — 通过以下方式判断各模块的角色:
记录各模块的包路径:
com.infypower.fycev.domain)com.infypower.fycev.service.dto)com.infypower.enums)com.infypower.fycev.service)com.infypower.fycev.service.impl)com.infypower.fycev.service.converter)com.infypower.fycev.service.mapper)ces-core/src/main/resources/mapper/)com.infypower.fycev.rest)探测前端结构:
{frontend-root}/src/components/CRUD/crud.js 是否存在 → 确认使用 CRUD mixinsrc/api/ces/)→ 确认 API 文件存放目录src/pages/ces/)→ 确认页面组件存放目录如果无法自动识别某个模块路径:
需要用户确认:
1. DDL 建表语句(直接粘贴 或 提供 SQL 文件路径)
2. 后端工程主路径(自动探测失败时需确认)
3. 是否生成前端代码?如果是,提供前端工程主路径(自动探测失败时需确认)
4. 表业务中文名称(用于 Controller 注解和页面标题,可从 DDL COMMENT 提取)
从 DDL 中提取以下信息:
| 提取项 | 来源 |
|---|---|
| 表名 | CREATE TABLE xxx |
| 表注释 | COMMENT = 'xxx' |
| 字段列表 | 字段名、类型、注释、是否 NOT NULL、默认值 |
| 主键 | PRIMARY KEY 或 id BIGINT |
| 索引/唯一约束 | INDEX / UNIQUE KEY |
| 逻辑删除字段 | deleted 字段 → 自动添加 @TableLogic |
| SQL 类型 | Java Entity 类型 | DTO 类型 | 说明 |
|---|---|---|---|
| BIGINT / BIGINT UNSIGNED | Long | Long (@JsonSerialize ToStringSerializer) | ID 字段需要 ToStringSerializer 防止 JS 精度丢失 |
| INT / TINYINT (枚举用途) | 自定义 Enum | 自定义 Enum | 需要生成对应枚举类,见字段注释枚举值定义 |
| TINYINT (0/1 二值) | Boolean | Boolean | 如 status=0/1 映射为 Boolean,Excel 导出用 replace = {"启用_true", "禁用_false"} |
| VARCHAR / CHAR | String | String (@NotBlank/@Size) | 需要加校验注解 |
| TEXT | String | String | |
| DATETIME / TIMESTAMP | Date | Date | java.util.Date |
| TIME | java.sql.Time | java.sql.Time | |
| DECIMAL / NUMERIC | BigDecimal | BigDecimal | |
| JSON | String | String | 以 JSON 字符串处理 |
| DOUBLE / FLOAT | Double | Double |
如果 DDL 中包含 deleted 字段(注释含"逻辑删除"或默认值为 0),在 Entity 中添加:
@ApiModelProperty("逻辑删除:0=未删除, 1=已删除")
@TableLogic
private Integer deleted;
仅将以下字段加入 QueryParam:
Ge + _suffix Le,使用 @Query(type = Query.Type.GREATER_THAN_EQ))@Query(type = Query.Type.INNER_LIKE))TINYINT 且注释中包含多个枚举值描述(如 1=xxx, 2=yyy),需要生成对应枚举类TINYINT 且注释仅为 0=禁用, 1=启用 等二值描述,映射为 Boolean,不生成枚举CommonEffectiveStatusEnum),直接复用不生成重要:使用 Step 0-A 探测到的实际路径,而非硬编码路径。
按以下顺序生成文件,每个文件参考模板见 references/java-templates.md:
ces_xxx_yyy_zzz → 类名 XxxYyyZzz(去掉 ces_ 前缀,大写驼峰)ces_ 前缀,直接转换为大写驼峰XxxYyyZzzControllerXxxYyyZzzServiceXxxYyyZzzServiceImplXxxYyyZzzDTOXxxYyyZzzQueryParamXxxYyyZzzConverterXxxYyyZzzMapper/api/ces/xxx-yyy-zzz(中划线分隔,保持表名前缀 ces_ 后面的部分)xxxYyyZzz:list / xxxYyyZzz:add / xxxYyyZzz:edit / xxxYyyZzz:del如果 QueryParam 中引用了枚举类型,必须添加对应 import:
import com.infypower.enums.XxxStatusEnum;
import java.util.List;
import java.util.Set;
在 sql/{year}/{month}/ 目录下创建两个 SQL 文件:
DDL 文件: {日期}-ddl-{表名}.sql — 包含完整建表语句
DML 文件: {日期}-dml-{表名}.sql — 包含菜单权限 SQL,模板见 references/sql-templates.md
如果后端生成了新的枚举类,需要在前端对应字典文件中添加字典配置。
src/store/modules/permission.js 或 src/utils/dict.js 或类似的字典配置文件中// 示例:在权限/字典 store 中添加
{ name: 'ces_xxx_status', items: [
{ label: '禁用', value: '0' },
{ label: '启用', value: '1' }
]}
如果无法自动识别字典配置文件路径,告知用户需要手动添加,并给出具体的字典配置代码片段。
{frontend-root}/src/api/ces/{page-name}.js{frontend-root}/src/pages/ces/{page-name}/index.vue模板参考 references/vue-templates.md。
页面名称转换:
ces_xxx_yyy_zzz → 页面目录 xxx-yyy-zzzxxx-yyy-zzz.jscd {backend-root}
mvn clean package -q
生成前端代码后,询问用户:
前端代码已生成。是否需要验证前端编译?可以执行
npm run dev检查是否有编译错误。
如果用户确认需要验证:
cd {frontend-root}
npm run dev
等待编译完成(Vite/Webpack 显示 "ready in xxx ms" 或类似成功信息),确认无 ERROR 后停止 dev server。
生成完成后,输出文件清单:
已生成以下文件:
后端:
[Enum] {实际路径}/enums/XxxStatusEnum.java(如有)
[Entity] {实际路径}/domain/XxxYyyZzz.java
[DTO] {实际路径}/dto/XxxYyyZzzDTO.java
[QueryParam] {实际路径}/dto/XxxYyyZzzQueryParam.java
[Mapper] {实际路径}/mapper/XxxYyyZzzMapper.java
[MapperXML] {实际路径}/resources/mapper/XxxYyyZzzMapper.xml
[Converter] {实际路径}/converter/XxxYyyZzzConverter.java
[Service] {实际路径}/service/XxxYyyZzzService.java
[ServiceImpl] {实际路径}/impl/XxxYyyZzzServiceImpl.java
[Controller] {实际路径}/rest/XxxYyyZzzController.java
SQL:
[DDL] sql/2026/202605/ddl-日期-表名.sql
[DML] sql/2026/202605/dml-日期-表名.sql
前端:
[Dict] 字典配置代码(如已自动添加 / 提示手动添加)
[Page] src/pages/ces/xxx-yyy-zzz/index.vue
[API] src/api/ces/xxx-yyy-zzz.js
验证:
后端 mvn clean package: ✅ 通过 / ❌ 失败(原因)
前端 npm run dev: 用户未验证 / ✅ 通过 / ❌ 失败(原因)
详见 references/java-templates.md,以下为核心要点:
@ApiModelProperty("字段注释")id: @TableId(type = IdType.ASSIGN_ID) + @TableField(fill = FieldFill.INSERT)createTime / createUser: @TableField(fill = FieldFill.INSERT)updateTime / updateUser: @TableField(fill = FieldFill.UPDATE)deleted: @TableLogic(如果 DDL 有逻辑删除字段)@JsonSerialize(using = ToStringSerializer.class)@NotNull,字符串加 @NotBlank / @Size(max = N)@JsonInclude(JsonInclude.Include.NON_NULL)@Excel(name = "列名", suffix = SUFFIX)@Query(type = Query.Type.INNER_LIKE)@Query@Query(type = Query.Type.GREATER_THAN_EQ) 字段名加 Ge 后缀// @CacheConfig(cacheNames = XxxYyyService.CACHE_KEY) 保留注释import java.util.List;pageByQueryParam, listByQueryParam, countByQueryParam, getById, insert, updateById, removeByIds@UniformAPI、@Log、@ApiOperation、@PreAuthorize 注解download 参考已有 Controller 实现@EnumValue + @JsonValue + @JSONField + @JsonCreator 四注解CommonEffectiveStatusEnum)详见 references/vue-templates.md,以下为核心要点:
| 字段类型 | 搜索栏组件 | 表格列 format |
|---|---|---|
| String | <co-input> | 无 |
| Long (ID关联) | <co-input> | getOperatorName(val) / getUsername(val) |
| Enum | <co-select> with dict.xxx | getDictLabel('dict_key', val) |
| Boolean | <co-toggle toggle-indeterminate> | val ? i18n.t('yes') : i18n.t('no') |
| Date | <co-date-select range> | formatTime(val) |
每个枚举字段在前端需要对应的字典数据支持:
permission.dict 中添加 {name: 'ces_xxx_enum', items: [...]}原因: QueryParam 缺少枚举类型的 import
解决: 添加 import com.infypower.enums.XxxStatusEnum;
原因: ServiceImpl 缺少 java.util.List import
解决: 添加 import java.util.List;
原因: 前端 Vuex permission.store 中未注册对应字典
解决: 在权限字典配置中添加枚举对应的 dict 数据,或使用 getDictLabel('dict_key', val)
生成每个文件后,检查:
@TableName、@TableId(type=ASSIGN_ID)、@TableField(fill=...) 注解@TableLogic 注解(如果 DDL 有逻辑删除字段)@JsonSerialize(using=ToStringSerializer.class)@JsonInclude(NON_NULL) 和字段校验注解@Query 注解,筛选字段合理CommonMapper<Entity>,有 @Repository@Mapper(componentModel="spring")@CacheConfig 注释保留(// 状态)import java.util.List;@Log、@ApiOperation、@PreAuthorize 注解@UniformAPI(enable = false)@EnumValue、@JsonValue、@JsonCreator 注解sql/{year}/{month}/ 目录@RequestMapping 匹配@PreAuthorize 权限一致| 版本 | 日期 | 作者 | 变更 |
|---|---|---|---|
| 1.1.0 | 2026-05-12 | endcy | 自动探测项目结构、自动生成前端字典 SQL、@TableLogic 自动检测、前端验证可选 |
| 1.0.0 | 2026-05-12 | endcy | 初始版本,支持基于 DDL 的全栈 CRUD 代码生成 |