JeecgBoot 代码生成器
将自然语言需求转换为 JeecgBoot 全套 CRUD 代码(后端 Java + 前端 Vue3 + 菜单权限 SQL),并支持对已生成模块的增量字段修改。
主数据复用规则
重要: 生成代码涉及的字典、角色、用户、部门等主数据,必须遵循"先查后建"原则。 使用
jeecg-systemskill 的system_utils.py查询和管理主数据。 详见../jeecg-system/SKILL.md。
⛔ 字典创建必须写入 Flyway SQL,禁止直接走 API 创建
代码生成场景下,新建字典的"建"必须落到 Flyway SQL 文件,禁止调用
find_or_create_dict()/create_dict()等 API 在远程服务器上直接创建。Why: 代码生成产物(Entity、前端、Flyway SQL)会通过 git 提交并部署到测试/预发/生产环境。如果字典只通过 API 在当前开发环境创建,部署到线上时线上数据库没有该字典,前端下拉框会空白、列表
_dictText翻译失效。Flyway SQL 跟着代码走,所有环境拉到代码后执行迁移都会自动建上,是唯一能保证环境一致性的方式。How to apply:
- 查询字典 → 走 API 或 MySQL(
jeecg-systemskill 的query-dicts/query-dict),用于"先查后建"中的"查"- 创建字典 → 写入当次的 Flyway SQL 文件(
sys_dictINSERT +sys_dict_item批量 INSERT),用于"先查后建"中的"建"- 禁用:
find_or_create_dict()、create_dict()等 system_utils 中的字典创建函数(在代码生成 skill 中不能调用)- 同理适用于:分类字典
sys_category节点新建 — 也必须写入 Flyway SQL,禁止走/sys/category/addAPI例外: 角色、审批角色、用户绑定关系等"运行时主数据",由于跨业务可复用,可走 API 创建(按 jeecg-system 原流程)。字典与分类字典是"配置数据",必须走 SQL。
⛔ 接口禁止猜测规则
严格禁止猜测任何 API 接口路径或参数。 AI 不得根据命名惯例、框架约定或已知路径拼凑接口地址后直接调用。
所有接口调用必须来源于以下之一:
- 用户明确提供的接口文档或地址
jeecg-systemskill 中已记录的接口- 通过
jeecg-systemskill 查询后确认的接口违反此规则即使偶然成功也视为错误操作,因为猜测成功不代表行为合规。
⛔ 写文件前的强制自检清单(高频翻车点)
以下两条是 AI 凭"框架直觉"最常犯错的地方,文件写出去几乎必现 bug,调试成本极高。每次执行 Step 4 写后端/前端文件之前,必须逐条 self-check。
翻车点 1:每个文件的路径必须与 SKILL/reference 描述完全一致
写每一个文件之前,必须先在
codegen-reference.md顶部"文件清单"章节中找到对应文件的路径模板,逐字符比对后再写入。禁止凭"Spring Boot/JeecgBoot 框架直觉"猜测路径。翻车点 2:FormSchema 必含隐藏 id 字段
所有 FormSchema(主表 Modal 表单、一对一子表 Form、ERP 风格子表 Form、树表 Modal 表单)首位必须包含:
{ label: '', field: 'id', component: 'Input', show: false },为什么这是铁律:
BasicForm的getFieldsValue()只返回 schema 中声明过的字段。即使 Modal 打开时通过setFieldsValue({ ...data.record })把id写入了表单状态,schema 没声明,提交时getFieldsValue()也会丢弃它。最终后端收到entity.id == null,getById(null)返回 null,Controller 返回Result.error("未找到对应数据")。编辑功能直接报错。位置统一规定:放在 FormSchema 数组首位(不要纠结"最后还是最前",统一首位)。
这两条规则不需要用户询问、不需要场景判断、不需要选项确认。100% 强制,100% 一致。
生成模式
进入交互流程之前,必须先与用户确认本次使用的生成模式。 任何场景下都不要默默选择,必须显式告知用户当前模式;用户回复"确认"即采用默认。
本 skill 提供两种生成模式:
| 模式 | 状态 | 默认 | 说明 |
|---|---|---|---|
| 串行生成(Serial) | Stable | ✅ 默认 | 主 Agent 顺序生成后端 → 前端 → SQL,全程单线执行,稳定可靠 |
| 并行生成(Parallel) | ⚠️ Beta — 可能不稳定 | ❌ | 派发两个 SubAgent 并行生成前端 / 后端代码,主 Agent 负责契约冻结与跨端校验。详见同目录下 parallel-generation-mode.md |
模式确认话术(必须执行)
进入 Step 0 之前,主 Agent 必须先输出类似以下消息,等用户回复后再继续:
本次代码生成将使用【串行生成模式】(默认,稳定)。
如需使用【并行生成模式(Beta)】以缩短耗时,请明确告知。
注意:并行模式当前为 Beta 版本,可能出现前后端字段命名漂移、API URL 不一致、
字典编码错位、FormSchema 隐藏 id 字段遗漏等问题,不确定时建议使用默认串行模式。
模式选择规则
- 用户未明确要求并行 → 一律走 串行模式,不要主动建议并行。
- 用户明确要求并行("并行"、"分头生成"、"前后端同时来"、"用 subagent 并行"等关键词) → 进入 并行模式,但必须先复述一遍 Beta 风险并等用户再次确认后才正式启动。
- 增量字段修改场景(场景 C) → 强制串行,即使用户要求并行也要拒绝并解释(SubAgent 双重压缩会丢失已有代码细节)。
- 一对多 + ERP / vue3Native / 自定义增强等复杂场景 → 强烈建议串行,需向用户说明风险后由用户决定。
并行模式启动条件(全部满足才进入)
- 用户明确选择了并行模式。
- 用户已被告知 Beta 风险并再次确认。
- 操作类型是"全量生成"(场景 A 或 B),不是"增量修改"(场景 C)。
- 主数据复用前置条件已就绪(字典已查/已建,目标数据库已确认)。
满足后,主 Agent 必须读取 parallel-generation-mode.md 并严格按其规范执行(契约冻结 → 派发 SubAgent → 跨端校验 → 输出清单)。任一环节失败 → 按该文档第 6 节"回退策略"切回串行从头来过。
铁律不变: 即使选择并行模式,本章上方的"⛔ 接口禁止猜测"、"⛔ 字典创建必须写入 Flyway SQL"、"⛔ 写文件前的强制自检清单(路径 + FormSchema id)"、以及"⛔ 铁律:Step 2 + Step 3 是不可跳过的硬性停止门" 全部仍然 100% 强制 —— 通过派发 prompt 传达给 SubAgent。
交互流程
⛔ 铁律:Step 2 + Step 3 是不可跳过的硬性停止门
全量生成必须严格按顺序执行 Step 0 → Step 1 → Step 2 → 等用户回复 → Step 3 → 等用户确认 → Step 4。 在用户明确回复"确认"(或等价表述)之前,绝对禁止开始生成任何代码、创建任何文件、执行任何 SQL。
以下念头出现时立刻停下,它们都是合理化跳过确认的借口:
借口 现实 "需求描述足够清楚,可以直接推断" 用户没有确认 ≠ 用户已认可。字段类型、路径、风格都可能偏差。 "选项都是默认值,不需要问" 默认值是否适用由用户决定,不由 AI 决定。 "先生成再改很方便" 用户不得不事后检查所有文件,浪费双方时间。 "用户说'Tab风格'已经隐含了风格选择" 只说明了一个选项,其他9项仍需展示给用户确认。 "Skill 加载太慢,直接生成更高效" 效率不是跳过确认的理由。 违反此铁律的代价: 用户发现问题后,所有已生成文件都需要重新生成或逐一修改。
Step 0: 判断操作类型 — 全量生成 or 增量修改?
识别增量修改的关键词: "加字段"、"增加字段"、"新增字段"、"加一个XX字段"、"删除字段"、"修改字段"、"改一下XX"、"给XX模块加"、"给XX表加"
如果是增量修改 → 进入 场景C 如果是全量生成 → 进入 场景A 或 场景B
Step 1: 全量生成 — 判断场景
场景A — 已有表(用户给了表名):
- 通过数据库查询获取精确 DDL(见"数据库连接"章节)
- 从 DDL 中解析:主键类型、全部字段(名称/类型/注释/是否nullable)、是否有系统字段
- 根据字段类型和注释自动推导前端控件类型
- 用户无需描述字段,AI 全部自动推导
场景B — 新建表(用户用自然语言描述需求):
- 从用户描述中提取:表名、实体名、功能描述、字段列表
- 用"智能字段推导"规则推导 DB 类型和前端控件
- 默认添加全部系统字段(create_by/create_time/update_by/update_time/sys_org_code)
- 生成建表 DDL 写入 Flyway SQL
场景C — 增量修改(给已有模块加/改/删字段):
- 定位目标模块:从用户提到的表名、模块名、实体名中识别目标
- 扫描已有代码文件:在后端和前端目录中搜索已生成的文件
# <project_root>/<project_vue_root>:后端/前端项目根目录,使用前需向用户确认 # 搜索后端 Entity 文件 find <project_root> -name "{EntityName}.java" -path "*/entity/*" # 搜索前端 data.ts 文件 find <project_vue_root>/src/views -name "{EntityName}.data.ts" - 读取全部已有文件:Entity.java、*.data.ts、*List.vue、*Modal.vue(如有 Form.vue 也读取)
- 解析当前字段列表:从 Entity.java 解析已有字段
- 推导新字段属性:用"智能字段推导"规则推导 DB 类型、Java 类型、前端控件
- 展示修改摘要,等待用户确认后再修改
增量修改的操作类型:
- 加字段:在所有文件中追加新字段定义
- 删字段:从所有文件中移除指定字段定义
- 改字段:修改指定字段的类型、控件、注释等
判断表类型:
- 提到"分类/层级/树/上下级" → 树表
- 提到"主子表/明细/一对多/订单+商品" → 一对多
- 默认 → 单表
全控件生成模式("全控件"关键词触发): 当用户说"全控件"、"覆盖所有控件类型"时,触发全覆盖枚举模式,每张表都必须包含该场景支持的所有组件类型,不得只生成代表性字段:
- 主表:枚举全部 FormSchema 组件 — Input/InputPassword/InputTextArea/InputNumber(整数+金额)/JDictSelectTag(下拉+radio)/JCheckbox/JSelectMultiple/JSwitch/DatePicker(5个picker变体)/TimePicker/JSelectUser/JSelectDept/JCategorySelect/JTreeSelect/JImageUpload/JUpload/JPopup+回填/JPopupDict/JAreaLinkage
- 一对一子表:在主表全部控件基础上额外加 JEditor/JMarkdownEditor/联动组件(多级)/关联记录+他表字段/表字典各变体(radio/checkbox/multi/带条件)
- 一对多子表:枚举全部 JVxeTypes — input/textarea/inputNumber/select(系统字典+表字典)/selectSearch/selectMultiple/checkbox(开关)/date/datetime/time/image/file/popup/departSelect/userSelect/pca
- 标准触发词:
全控件、覆盖所有 FormSchema 控件、覆盖所有 JVxeTypes - 标准提示语(用户可直接复制使用):
生成全控件主子表,主表+一对一子表覆盖所有 FormSchema 控件,一对多子表覆盖所有 JVxeTypes(含pca),Tab-in-Modal 风格(radio-group 切换)
一对多表的前端布局风格:
⚠️ 严禁假设布局风格! 必须在 Step 2 询问用户,用户未回答前不得擅自选择非默认风格(如 Tab-in-Modal)。 过去曾犯错:用户未说明风格,却错误地选了 Tab-in-Modal (C9),导致用户反馈后需要重新生成 Modal.vue。
一对多表有三种前端布局风格,用户未指定时默认使用原始布局风格。
重要:vue3 封装风格和 vue3Native 原生风格的一对多架构完全不同! vue3 封装风格使用
useJvxeMethod,vue3Native 原生风格使用useValidateAntFormAndTable。详见codegen-reference.md的 C9-C12(vue3)和 C13(vue3Native)。
vue3 封装风格布局选项:
| 风格 | 关键词 | 列表页 | Modal 布局 |
|---|---|---|---|
| 默认/原始布局 | "默认风格"、"默认"、未指定风格 | 标准列表(无 expandedRowRender) | 上面主表 BasicForm + 下面 a-tabs 子表 |
| Tab-in-Modal (C9) | "tab风格"、"tab切换"、"radio切换"、"标题栏切换" | 标准列表(同默认,无 expandedRowRender) | radio-group 标题栏切换主表/子表,wrapClassName="j-cgform-tab-modal" |
| 内嵌子表 (C12) | "内嵌子表"、"行展开"、"expandedRowRender" | 行展开显示子表(expandedRowRender) | 上面主表 BasicForm + 下面 a-tabs 子表(同默认) |
| ERP (C11) | "ERP风格"、"独立编辑" | 主表单选 + 子表独立 CRUD Tab | 仅主表 BasicForm(子表独立 Modal) |
⚠️ 子表外键字段名必须读实体确认,严禁猜测! 生成子表 FormSchema 的隐藏外键字段前,必须先 Read 子表 Entity.java,以实体中的 Java 字段名为准。 外键字段名因开发者习惯差异很大(
companyId/bizCompanyId/mainId/headerId), 根据主表实体名推断必然出错,会导致 MySQLField 'xxx' doesn't have a default value异常。 同样,Modal 中values.xxx = unref(mainId)的xxx也必须与实体字段名一致。
vue3Native 原生风格(C13)— 架构完全不同:
- Modal 是薄包装器(BasicModal + useModalInner),只调
formComponent.submitForm()/edit()/add() - Form.vue 是核心组件,包含主表 a-form + 子表 a-tabs + 提交逻辑
- 使用
useValidateAntFormAndTablehook(不是useJvxeMethod) - 子表 API 导出为函数(不是 URL 字符串)
saveOrUpdate不用isTransformResponse: false- 一对一子表用原生
a-form+Form.useForm,暴露isForm = true - 一对一子表
initFormData(mainId)直接传主表 ID(不传 URL 字符串) - 一对一子表
getFormData()返回对象(不是数组) - 需要额外的
queryDataByIdAPI 函数 - List.vue 使用
useModal+openModal(true, {...})模式
vue3 封装风格 — 默认/原始布局的关键特征:
- Modal 结构:Basi