/Users/lengleng/Downloads/CGTM当前仓库已提供三组模板:
本次需要新增第四组模板,用于生成“左树右表”业务页面。页面形态为:
该场景与现有主子表最接近,但关系方向不同。这里不是“主表聚合子表列表”,而是“主表记录持有树节点外键”。
新增一组独立模板 左树右表增删改查,满足以下目标:
本次设计不包含以下内容:
saveDeep/updateDeep 聚合模型采用“新增独立模板组,但仍使用同一业务模块命名空间”的方案。
核心思路:
左树右表增删改查/${functionName} 下不采用“完全拆成两套资源”的原因:
config.json 和模板目录的组织方式不采用“直接改造主子表模板”的原因:
saveDeep/updateDeep 会让前后端职责边界变得混乱关系采用以下形式:
即:
右侧主表继续使用现有主表变量:
fieldListformListgridListqueryListpkClassNameclassName左侧树继续复用现有主子表变量:
childFieldListchildTableNameChildClassNamechildClassName树专用额外约定:
parentField:左树子表中的父节点字段nameField:左树子表中的树节点名称字段这一组模板中,跨表关联采用以下固定规则:
mainField 表示主表中的树节点外键字段mainField 关联到左树子表主键childFieldList 中 primaryPk = true 的字段推导说明:
childField 定义来自主子表聚合场景childField 作为跨表删除或聚合写入的核心字段childField 兼容生成器配置,可保留变量,但生成逻辑以“主表外键 -> 子表主键”为准该约定必须在实现中明确,否则实现者可能误把当前场景继续按“子表保存主表外键”处理。
| 字段 | 来源 | 是否新增输入 | 本模板组中的含义 |
|---|---|---|---|
mainField |
复用现有主子表配置 | 否 | 主表中的树节点外键字段 |
childFieldList |
复用现有主子表配置 | 否 | 左树子表字段列表 |
ChildClassName / childClassName |
复用现有主子表配置 | 否 | 左树子表实体命名 |
childTableName |
复用现有主子表配置 | 否 | 左树子表表名 |
parentField |
新增模板配置 | 是 | 左树子表父节点字段 |
nameField |
新增模板配置 | 是 | 左树节点显示名称字段 |
| 左树子表主键 | 从 childFieldList 推导 |
否 | 通过 primaryPk = true 的字段识别 |
结论:
parentField、nameFieldmainField 沿用现有主子表配置,但语义固定为“主表引用树节点的外键”新增模板组名称:
左树右表增删改查建议生成产物如下。
ControllerServiceServiceImpl实体MapperMapper.xml子实体子Mapperapi.tsindex.vuetree-form.vueform.vue权限菜单.sqlindex.vue:左右布局、树节点选中状态、右表查询、双弹窗联动tree-form.vue:左树节点新增/编辑form.vue:右表主记录新增/编辑api.ts:同时暴露主表和树接口不建议将左右两种编辑能力继续合并到一个表单文件中,否则页面职责会过于拥挤。
config.json 注册要求该仓库是 registry-driven,新增模板组后必须同步更新 config.json,否则模板无法出现在代码生成器里。
建议新增一组根配置:
左树右表增删改查建议的文件映射如下:
| templateName | generatorPath | templateFile |
|---|---|---|
Controller |
${backendPath}/src/main/java/${packagePath}/${moduleName}/controller/${ClassName}Controller.java |
treeTable/Controller.java |
Service |
${backendPath}/src/main/java/${packagePath}/${moduleName}/service/${ClassName}Service.java |
treeTable/Service.java |
ServiceImpl |
${backendPath}/src/main/java/${packagePath}/${moduleName}/service/impl/${ClassName}ServiceImpl.java |
treeTable/ServiceImpl.java |
实体 |
${backendPath}/src/main/java/${packagePath}/${moduleName}/entity/${ClassName}Entity.java |
single/实体.java |
Mapper |
${backendPath}/src/main/java/${packagePath}/${moduleName}/mapper/${ClassName}Mapper.java |
single/Mapper.java |
Mapper.xml |
${backendPath}/src/main/resources/mapper/${ClassName}Mapper.xml |
single/Mapper.xml |
子实体 |
${backendPath}/src/main/java/${packagePath}/${moduleName}/entity/${ChildClassName}Entity.java |
multiple/子实体.java |
子Mapper |
${backendPath}/src/main/java/${packagePath}/${moduleName}/mapper/${ChildClassName}Mapper.java |
multiple/子Mapper.java |
权限菜单 |
${backendPath}/menu/${functionName}_menu.sql |
common/权限菜单.sql |
api.ts |
${frontendPath}/src/api/${moduleName}/${functionName}.ts |
treeTable/api.ts |
表格 |
${frontendPath}/src/views/${moduleName}/${functionName}/index.vue |
treeTable/index.vue |
树表单 |
${frontendPath}/src/views/${moduleName}/${functionName}/tree-form.vue |
treeTable/tree-form.vue |
主表单 |
${frontendPath}/src/views/${moduleName}/${functionName}/form.vue |
treeTable/form.vue |
说明:
treeTable/Controller / Service / ServiceImpl / api.ts / index.vue / tree-form.vue / form.vue主表接口沿用现有单表风格:
GET /${functionName}/pageGET /${functionName}/detailsPOST /${functionName}PUT /${functionName}DELETE /${functionName}GET /${functionName}/exportPOST /${functionName}/import在同一控制器下新增树节点子路由:
GET /${functionName}/treeGET /${functionName}/tree/detailsPOST /${functionName}/treePUT /${functionName}/treeDELETE /${functionName}/tree/tree 子路由区分树节点操作和主表操作Service 和 ServiceImpl 不采用主子表 saveDeep/updateDeep/removeDeep 风格,而是明确承担三类职责:
ServiceImpl 需要注入:
MapperChildMapper建议至少存在以下方法类别:
这里的重点不是方法名,而是职责边界要明确,避免把左树和右表重新做成一个聚合保存模型。
页面初始化时:
当用户选中左树节点后:
mainField当用户取消选中或删除了当前选中节点后:
mainField左树支持:
tree-form.vue 的字段来源为 childFieldList,但需要:
parentField 作为父级节点选择器nameField 作为默认树节点显示名称来源0,与现有树模板的根节点构建方式保持一致右表支持:
form.vue 的字段来源为主表 formList。
对于主表中的树节点外键字段 mainField:
该字段在前端表现可以是:
实现阶段二选一即可,但必须保证不会生成缺少树节点归属的主表记录。
删除左树节点时,必须同时校验:
parentField = 当前节点 IDmainField = 当前节点 ID仅当两者都不存在时才允许删除。
用户确认采用:
后端返回明确业务提示,例如:
前端保持与现有模板一致的错误提示方式:
不在本次模板设计中扩展统一异常体系。
index.vue负责:
tree-form.vue负责:
参考方向接近当前 tree/树形表单.vue,但实体来源切换为左树子表。
form.vue负责:
api.ts应同时暴露两组接口:
fetchList/getObj/addObj/putObj/delObjsfetchTreeList/getTreeObj/addTreeObj/putTreeObj/delTreeObjs实现完成后,至少应验证以下行为。
parentField/nameField当前仓库的主子表语义是“子表持有主表外键”,而本次场景是“主表持有树节点外键”。
如果实现阶段没有显式区分,会导致:
saveDeep/updateDeepchildField因此 implementation planning 阶段必须首先确认:
本次设计只覆盖“标准左树右表 CRUD 模板”,不额外承诺:
本设计确认新增一组独立模板 左树右表增删改查,其实现原则为:
该设计已经满足进入 implementation planning 的条件。