diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/demo02/InfraDemoStudentController.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/demo02/InfraDemoStudentController.java
index 3aca33dbf..ae4d48255 100644
--- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/demo02/InfraDemoStudentController.java
+++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/demo02/InfraDemoStudentController.java
@@ -1,29 +1,34 @@
 package cn.iocoder.yudao.module.infra.controller.admin.demo02;
 
-import cn.iocoder.yudao.framework.common.pojo.CommonResult;
-import cn.iocoder.yudao.framework.common.pojo.PageResult;
-import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
-import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
-import cn.iocoder.yudao.module.infra.controller.admin.demo02.vo.*;
-import cn.iocoder.yudao.module.infra.convert.demo02.InfraDemoStudentConvert;
-import cn.iocoder.yudao.module.infra.dal.dataobject.demo02.InfraDemoStudentDO;
-import cn.iocoder.yudao.module.infra.service.demo02.InfraDemoStudentService;
-import io.swagger.v3.oas.annotations.Operation;
-import io.swagger.v3.oas.annotations.Parameter;
-import io.swagger.v3.oas.annotations.tags.Tag;
-import org.springframework.security.access.prepost.PreAuthorize;
-import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
-
 import javax.annotation.Resource;
-import javax.servlet.http.HttpServletResponse;
-import javax.validation.Valid;
-import java.io.IOException;
-import java.util.Collection;
-import java.util.List;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.security.access.prepost.PreAuthorize;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.Operation;
 
+import javax.validation.constraints.*;
+import javax.validation.*;
+import javax.servlet.http.*;
+import java.util.*;
+import java.io.IOException;
+
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.common.pojo.CommonResult;
 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
-import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
+
+import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
+
+import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
+import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.*;
+
+import cn.iocoder.yudao.module.infra.controller.admin.demo02.vo.*;
+import cn.iocoder.yudao.module.infra.dal.dataobject.demo02.InfraDemoStudentDO;
+import cn.iocoder.yudao.module.infra.dal.dataobject.demo02.InfraDemoStudentContactDO;
+import cn.iocoder.yudao.module.infra.dal.dataobject.demo02.InfraDemoStudentAddressDO;
+import cn.iocoder.yudao.module.infra.convert.demo02.InfraDemoStudentConvert;
+import cn.iocoder.yudao.module.infra.service.demo02.InfraDemoStudentService;
 
 @Tag(name = "管理后台 - 学生")
 @RestController
@@ -87,4 +92,24 @@ public class InfraDemoStudentController {
         ExcelUtils.write(response, "学生.xls", "数据", InfraDemoStudentExcelVO.class, datas);
     }
 
+    // ==================== 子表(学生联系人) ====================
+
+    @GetMapping("/demo-student/list-by-student-id")
+    @Operation(summary = "获得学生联系人列表")
+    @Parameter(name = "studentId", description = "学生编号")
+    @PreAuthorize("@ss.hasPermission('infra:demo-student:query')")
+    public CommonResult<List<InfraDemoStudentContactDO>> getDemoStudentContactListByStudentId(@RequestParam("studentId") Long studentId) {
+        return success(demoStudentService.getDemoStudentContactListByStudentId(studentId));
+    }
+
+    // ==================== 子表(学生地址) ====================
+
+    @GetMapping("/demo-student/get-by-student-id")
+    @Operation(summary = "获得学生地址")
+    @Parameter(name = "studentId", description = "学生编号")
+    @PreAuthorize("@ss.hasPermission('infra:demo-student:query')")
+    public CommonResult<InfraDemoStudentAddressDO> getDemoStudentAddressByStudentId(@RequestParam("studentId") Long studentId) {
+        return success(demoStudentService.getDemoStudentAddressByStudentId(studentId));
+    }
+
 }
\ No newline at end of file
diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/mysql/demo02/InfraDemoStudentContactMapper.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/mysql/demo02/InfraDemoStudentContactMapper.java
index 49f222e55..335245832 100644
--- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/mysql/demo02/InfraDemoStudentContactMapper.java
+++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/mysql/demo02/InfraDemoStudentContactMapper.java
@@ -1,5 +1,6 @@
 package cn.iocoder.yudao.module.infra.dal.mysql.demo02;
 
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
 import cn.iocoder.yudao.module.infra.dal.dataobject.demo02.InfraDemoStudentContactDO;
 import org.apache.ibatis.annotations.Mapper;
diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/enums/codegen/CodegenTemplateTypeEnum.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/enums/codegen/CodegenTemplateTypeEnum.java
index ceb9b9344..d4fb85086 100644
--- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/enums/codegen/CodegenTemplateTypeEnum.java
+++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/enums/codegen/CodegenTemplateTypeEnum.java
@@ -14,8 +14,11 @@ public enum CodegenTemplateTypeEnum {
 
     ONE(1), // 单表(增删改查)
     TREE(2), // 树表(增删改查)
-    MASTER(10), // 主子表 - 主表
-    SUB(11), // 主子表 - 子表
+
+    MASTER_NORMAL(10), // 主子表 - 主表 - 普通模式
+    MASTER_ERP(11), // 主子表 - 主表 - ERP 模式
+    MASTER_INNER(12), // 主子表 - 主表 - 内嵌模式
+    SUB(15), // 主子表 - 子表
     ;
 
     /**
diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/codegen/inner/CodegenEngine.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/codegen/inner/CodegenEngine.java
index 4504cfa40..d6371e06b 100644
--- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/codegen/inner/CodegenEngine.java
+++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/codegen/inner/CodegenEngine.java
@@ -193,6 +193,44 @@ public class CodegenEngine {
      */
     public Map<String, String> execute(CodegenTableDO table, List<CodegenColumnDO> columns,
                                        List<CodegenTableDO> subTables, List<List<CodegenColumnDO>> subColumnsList) {
+        // 1.1 初始化 bindMap 上下文
+        Map<String, Object> bindingMap = initBindingMap(table, columns, subTables, subColumnsList);
+        // 1.2 获得模版
+        Map<String, String> templates = getTemplates(table.getFrontType());
+
+        // 2. 执行生成
+        Map<String, String> result = Maps.newLinkedHashMapWithExpectedSize(templates.size()); // 有序
+        templates.forEach((vmPath, filePath) -> {
+            // 2.1 特殊:主子表专属逻辑
+            if (isSubTemplate(vmPath)) {
+                if (CollUtil.isEmpty(subTables)) {
+                    return;
+                }
+                for (int i = 0; i < subTables.size(); i++) {
+                    bindingMap.put("subIndex", i);
+                    generateCode(result, vmPath, filePath, bindingMap);
+                }
+                bindingMap.remove("subIndex");
+                return;
+            }
+
+            // 2.2 默认生成
+            generateCode(result, vmPath, filePath, bindingMap);
+        });
+        return result;
+    }
+
+    private void generateCode(Map<String, String> result, String vmPath,
+                              String filePath, Map<String, Object> bindingMap) {
+        filePath = formatFilePath(filePath, bindingMap);
+        String content = templateEngine.getTemplate(vmPath).render(bindingMap);
+        // 去除字段后面多余的 , 逗号
+        content = content.replaceAll(",\n}", "\n}").replaceAll(",\n  }", "\n  }");
+        result.put(filePath, content);
+    }
+
+    private Map<String, Object> initBindingMap(CodegenTableDO table, List<CodegenColumnDO> columns,
+                                               List<CodegenTableDO> subTables, List<List<CodegenColumnDO>> subColumnsList) {
         // 创建 bindingMap
         Map<String, Object> bindingMap = new HashMap<>(globalBindingMap);
         bindingMap.put("table", table);
@@ -217,60 +255,40 @@ public class CodegenEngine {
             // 创建 bindingMap
             bindingMap.put("subTables", subTables);
             bindingMap.put("subColumnsList", subColumnsList);
+            List<CodegenColumnDO> subPrimaryColumns = new ArrayList<>();
             List<CodegenColumnDO> subJoinColumns = new ArrayList<>();
+            List<String> subJoinColumnStrikeCases = new ArrayList<>();
             List<String> subSimpleClassNames = new ArrayList<>();
             List<String> subClassNameVars = new ArrayList<>();
+            List<String> subSimpleClassNameStrikeCases = new ArrayList<>();
             for (int i = 0; i < subTables.size(); i++) {
                 CodegenTableDO subTable = subTables.get(i);
                 List<CodegenColumnDO> subColumns = subColumnsList.get(i);
-                subJoinColumns.add(CollectionUtils.findFirst(subColumns, // 关联的字段
-                        column -> Objects.equals(column.getId(), subTable.getSubJoinColumnId())));
+                subPrimaryColumns.add(CollectionUtils.findFirst(subColumns, CodegenColumnDO::getPrimaryKey)); //
+                CodegenColumnDO subColumn = CollectionUtils.findFirst(subColumns, // 关联的字段
+                        column -> Objects.equals(column.getId(), subTable.getSubJoinColumnId()));
+                subJoinColumns.add(subColumn);
+                subJoinColumnStrikeCases.add(toSymbolCase(subColumn.getJavaField(), '-')); // 将 DictType 转换成 dict-type
                 // className 相关
                 String subSimpleClassName = removePrefix(subTable.getClassName(), upperFirst(subTable.getModuleName()));
                 subSimpleClassNames.add(subSimpleClassName);
                 subClassNameVars.add(lowerFirst(subSimpleClassName)); // 将 DictType 转换成 dictType,用于变量
+                subSimpleClassNameStrikeCases.add(toSymbolCase(simpleClassName, '-')); // 将 DictType 转换成 dict-type
             }
+            bindingMap.put("subPrimaryColumns", subPrimaryColumns);
             bindingMap.put("subJoinColumns", subJoinColumns);
+            bindingMap.put("subJoinColumn_strikeCases", subJoinColumnStrikeCases);
             bindingMap.put("subSimpleClassNames", subSimpleClassNames);
             bindingMap.put("subClassNameVars", subClassNameVars);
+            bindingMap.put("subSimpleClassName_strikeCases", subSimpleClassNameStrikeCases);
         }
-
-        // 执行生成
-        Map<String, String> templates = getTemplates(table.getTemplateType(), table.getFrontType());
-        Map<String, String> result = Maps.newLinkedHashMapWithExpectedSize(templates.size()); // 有序
-        templates.forEach((vmPath, filePath) -> {
-            // 特殊:主子表专属逻辑
-            if (isSubTemplate(vmPath)) {
-                for (int i = 0; i < subTables.size(); i++) {
-                    bindingMap.put("subIndex", i);
-                    // TODO 芋艿:这块需要优化下逻辑
-                    String newFilePath = formatFilePath(filePath, bindingMap);
-                    String content = templateEngine.getTemplate(vmPath).render(bindingMap);
-                    // 去除字段后面多余的 , 逗号
-                    content = content.replaceAll(",\n}", "\n}").replaceAll(",\n  }", "\n  }");
-                    result.put(newFilePath, content);
-                    bindingMap.remove("subIndex");
-                }
-            } else {
-                filePath = formatFilePath(filePath, bindingMap);
-                String content = templateEngine.getTemplate(vmPath).render(bindingMap);
-                // 去除字段后面多余的 , 逗号
-                content = content.replaceAll(",\n}", "\n}").replaceAll(",\n  }", "\n  }");
-                result.put(filePath, content);
-            }
-        });
-        return result;
+        return bindingMap;
     }
 
-    private Map<String, String> getTemplates(Integer templateType, Integer frontType) {
+    private Map<String, String> getTemplates(Integer frontType) {
         Map<String, String> templates = new LinkedHashMap<>();
         templates.putAll(SERVER_TEMPLATES);
         templates.putAll(FRONT_TEMPLATES.row(frontType));
-        // 特殊:主子表专属逻辑
-        if (ObjUtil.notEqual(templateType, CodegenTemplateTypeEnum.MASTER.getType())) {
-            templates.remove(javaTemplatePath("dal/do_sub"));
-            templates.remove(javaTemplatePath("dal/mapper_sub"));
-        }
         return templates;
     }
 
diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/demo02/InfraDemoStudentService.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/demo02/InfraDemoStudentService.java
index f79aaaa21..8dc4b981a 100644
--- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/demo02/InfraDemoStudentService.java
+++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/demo02/InfraDemoStudentService.java
@@ -1,15 +1,12 @@
 package cn.iocoder.yudao.module.infra.service.demo02;
 
-import cn.iocoder.yudao.framework.common.pojo.PageResult;
-import cn.iocoder.yudao.module.infra.controller.admin.demo02.vo.InfraDemoStudentCreateReqVO;
-import cn.iocoder.yudao.module.infra.controller.admin.demo02.vo.InfraDemoStudentExportReqVO;
-import cn.iocoder.yudao.module.infra.controller.admin.demo02.vo.InfraDemoStudentPageReqVO;
-import cn.iocoder.yudao.module.infra.controller.admin.demo02.vo.InfraDemoStudentUpdateReqVO;
+import java.util.*;
+import javax.validation.*;
+import cn.iocoder.yudao.module.infra.controller.admin.demo02.vo.*;
 import cn.iocoder.yudao.module.infra.dal.dataobject.demo02.InfraDemoStudentDO;
-
-import javax.validation.Valid;
-import java.util.Collection;
-import java.util.List;
+import cn.iocoder.yudao.module.infra.dal.dataobject.demo02.InfraDemoStudentContactDO;
+import cn.iocoder.yudao.module.infra.dal.dataobject.demo02.InfraDemoStudentAddressDO;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
 
 /**
  * 学生 Service 接口
@@ -65,4 +62,25 @@ public interface InfraDemoStudentService {
     List<InfraDemoStudentDO> getDemoStudentList(InfraDemoStudentExportReqVO exportReqVO);
 
 
+    // ==================== 子表(学生联系人) ====================
+
+    /**
+     * 获得学生联系人列表
+     *
+     * @param studentId 学生编号
+     * @return 学生联系人列表
+     */
+    List<InfraDemoStudentContactDO> getDemoStudentContactListByStudentId(Long studentId);
+
+
+    // ==================== 子表(学生地址) ====================
+
+    /**
+     * 获得学生地址
+     *
+     * @param studentId 学生编号
+     * @return 学生地址
+     */
+    InfraDemoStudentAddressDO getDemoStudentAddressByStudentId(Long studentId);
+
 }
\ No newline at end of file
diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/demo02/InfraDemoStudentServiceImpl.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/demo02/InfraDemoStudentServiceImpl.java
index 4710ac196..94c8739fb 100644
--- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/demo02/InfraDemoStudentServiceImpl.java
+++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/demo02/InfraDemoStudentServiceImpl.java
@@ -8,6 +8,8 @@ import org.springframework.transaction.annotation.Transactional;
 import java.util.*;
 import cn.iocoder.yudao.module.infra.controller.admin.demo02.vo.*;
 import cn.iocoder.yudao.module.infra.dal.dataobject.demo02.InfraDemoStudentDO;
+import cn.iocoder.yudao.module.infra.dal.dataobject.demo02.InfraDemoStudentContactDO;
+import cn.iocoder.yudao.module.infra.dal.dataobject.demo02.InfraDemoStudentAddressDO;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 
 import cn.iocoder.yudao.module.infra.convert.demo02.InfraDemoStudentConvert;
@@ -43,12 +45,10 @@ public class InfraDemoStudentServiceImpl implements InfraDemoStudentService {
         // 插入
         InfraDemoStudentDO demoStudent = InfraDemoStudentConvert.INSTANCE.convert(createReqVO);
         demoStudentMapper.insert(demoStudent);
-        // 插入子表(学生联系人)
-        createReqVO.getDemoStudentContacts().forEach(o -> o.setStudentId(demoStudent.getId()));
-        demoStudentContactMapper.insertBatch(createReqVO.getDemoStudentContacts());
-        // 插入子表(学生地址)
-        createReqVO.getDemoStudentAddress().setStudentId(demoStudent.getId());
-        demoStudentAddressMapper.insert(createReqVO.getDemoStudentAddress());
+
+        // 插入子表($subTable.classComment)
+        createDemoStudentContactList(demoStudent.getId(), createReqVO.getDemoStudentContacts());
+        createDemoStudentAddress(demoStudent.getId(), createReqVO.getDemoStudentAddress());
         // 返回
         return demoStudent.getId();
     }
@@ -61,13 +61,10 @@ public class InfraDemoStudentServiceImpl implements InfraDemoStudentService {
         // 更新
         InfraDemoStudentDO updateObj = InfraDemoStudentConvert.INSTANCE.convert(updateReqVO);
         demoStudentMapper.updateById(updateObj);
-        // 更新子表(学生联系人)
-        demoStudentContactMapper.deleteByStudentId(updateReqVO.getId());
-        updateReqVO.getDemoStudentContacts().forEach(o -> o.setStudentId(updateReqVO.getId()));
-        demoStudentContactMapper.insertBatch(updateReqVO.getDemoStudentContacts());
-        // 更新子表(学生地址)
-        updateReqVO.getDemoStudentAddress().setStudentId(updateReqVO.getId());
-        demoStudentAddressMapper.updateById(updateReqVO.getDemoStudentAddress());
+
+        // 更新子表
+        updateDemoStudentContactList(updateReqVO.getId(), updateReqVO.getDemoStudentContacts());
+        updateDemoStudentAddress(updateReqVO.getId(), updateReqVO.getDemoStudentAddress());
     }
 
     @Override
@@ -77,10 +74,10 @@ public class InfraDemoStudentServiceImpl implements InfraDemoStudentService {
         validateDemoStudentExists(id);
         // 删除
         demoStudentMapper.deleteById(id);
-        // 删除子表(学生联系人)
-        demoStudentContactMapper.deleteByStudentId(id);
-        // 删除子表(学生地址)
-        demoStudentAddressMapper.deleteByStudentId(id);
+
+        // 删除子表
+        deleteDemoStudentContactByStudentId(id);
+        deleteDemoStudentAddressByStudentId(id);
     }
 
     private void validateDemoStudentExists(Long id) {
@@ -104,4 +101,46 @@ public class InfraDemoStudentServiceImpl implements InfraDemoStudentService {
         return demoStudentMapper.selectList(exportReqVO);
     }
 
+    // ==================== 子表(学生联系人) ====================
+
+    @Override
+    public List<InfraDemoStudentContactDO> getDemoStudentContactListByStudentId(Long studentId) {
+        return demoStudentContactMapper.selectListByStudentId(studentId);
+    }
+
+    private void createDemoStudentContactList(Long studentId, List<InfraDemoStudentContactDO> list) {
+        list.forEach(o -> o.setStudentId(studentId));
+        demoStudentContactMapper.insertBatch(list);
+    }
+
+    private void updateDemoStudentContactList(Long studentId, List<InfraDemoStudentContactDO> list) {
+        deleteDemoStudentContactByStudentId(studentId);
+        createDemoStudentContactList(studentId, list);
+    }
+
+    private void deleteDemoStudentContactByStudentId(Long studentId) {
+        demoStudentContactMapper.deleteByStudentId(studentId);
+    }
+
+    // ==================== 子表(学生地址) ====================
+
+    @Override
+    public InfraDemoStudentAddressDO getDemoStudentAddressByStudentId(Long studentId) {
+        return demoStudentAddressMapper.selectByStudentId(studentId);
+    }
+
+    private void createDemoStudentAddress(Long studentId, InfraDemoStudentAddressDO demoStudentAddress) {
+        demoStudentAddress.setStudentId(studentId);
+        demoStudentAddressMapper.insert(demoStudentAddress);
+    }
+
+    private void updateDemoStudentAddress(Long studentId, InfraDemoStudentAddressDO demoStudentAddress) {
+        demoStudentAddress.setStudentId(studentId);
+        demoStudentAddressMapper.updateById(demoStudentAddress);
+    }
+
+    private void deleteDemoStudentAddressByStudentId(Long studentId) {
+        demoStudentAddressMapper.deleteByStudentId(studentId);
+    }
+
 }
\ No newline at end of file
diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/controller/controller.vm b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/controller/controller.vm
index 875c12be3..c864f22be 100644
--- a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/controller/controller.vm
+++ b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/controller/controller.vm
@@ -26,6 +26,10 @@ import static ${OperateTypeEnumClassName}.*;
 
 import ${basePackage}.module.${table.moduleName}.controller.${sceneEnum.basePackage}.${table.businessName}.vo.*;
 import ${basePackage}.module.${table.moduleName}.dal.dataobject.${table.businessName}.${table.className}DO;
+## 特殊:主子表专属逻辑
+#foreach ($subTable in $subTables)
+import ${basePackage}.module.${subTable.moduleName}.dal.dataobject.${subTable.businessName}.${subTable.className}DO;
+#end
 import ${basePackage}.module.${table.moduleName}.convert.${table.businessName}.${table.className}Convert;
 import ${basePackage}.module.${table.moduleName}.service.${table.businessName}.${table.className}Service;
 
@@ -41,16 +45,18 @@ public class ${sceneEnum.prefixClass}${table.className}Controller {
 
     @PostMapping("/create")
     @Operation(summary = "创建${table.classComment}")
-#if ($sceneEnum.scene == 1)    @PreAuthorize("@ss.hasPermission('${permissionPrefix}:create')")#end
-
+#if ($sceneEnum.scene == 1)
+    @PreAuthorize("@ss.hasPermission('${permissionPrefix}:create')")
+#end
     public CommonResult<${primaryColumn.javaType}> create${simpleClassName}(@Valid @RequestBody ${sceneEnum.prefixClass}${table.className}CreateReqVO createReqVO) {
         return success(${classNameVar}Service.create${simpleClassName}(createReqVO));
     }
 
     @PutMapping("/update")
     @Operation(summary = "更新${table.classComment}")
-#if ($sceneEnum.scene == 1)    @PreAuthorize("@ss.hasPermission('${permissionPrefix}:update')")#end
-
+#if ($sceneEnum.scene == 1)
+    @PreAuthorize("@ss.hasPermission('${permissionPrefix}:update')")
+#end
     public CommonResult<Boolean> update${simpleClassName}(@Valid @RequestBody ${sceneEnum.prefixClass}${table.className}UpdateReqVO updateReqVO) {
         ${classNameVar}Service.update${simpleClassName}(updateReqVO);
         return success(true);
@@ -59,8 +65,9 @@ public class ${sceneEnum.prefixClass}${table.className}Controller {
     @DeleteMapping("/delete")
     @Operation(summary = "删除${table.classComment}")
     @Parameter(name = "id", description = "编号", required = true)
-#if ($sceneEnum.scene == 1)    @PreAuthorize("@ss.hasPermission('${permissionPrefix}:delete')")#end
-
+#if ($sceneEnum.scene == 1)
+    @PreAuthorize("@ss.hasPermission('${permissionPrefix}:delete')")
+#end
     public CommonResult<Boolean> delete${simpleClassName}(@RequestParam("id") ${primaryColumn.javaType} id) {
         ${classNameVar}Service.delete${simpleClassName}(id);
         return success(true);
@@ -69,8 +76,9 @@ public class ${sceneEnum.prefixClass}${table.className}Controller {
     @GetMapping("/get")
     @Operation(summary = "获得${table.classComment}")
     @Parameter(name = "id", description = "编号", required = true, example = "1024")
-#if ($sceneEnum.scene == 1)    @PreAuthorize("@ss.hasPermission('${permissionPrefix}:query')")#end
-
+#if ($sceneEnum.scene == 1)
+    @PreAuthorize("@ss.hasPermission('${permissionPrefix}:query')")
+#end
     public CommonResult<${sceneEnum.prefixClass}${table.className}RespVO> get${simpleClassName}(@RequestParam("id") ${primaryColumn.javaType} id) {
         ${table.className}DO ${classNameVar} = ${classNameVar}Service.get${simpleClassName}(id);
         return success(${table.className}Convert.INSTANCE.convert(${classNameVar}));
@@ -78,8 +86,9 @@ public class ${sceneEnum.prefixClass}${table.className}Controller {
 
     @GetMapping("/page")
     @Operation(summary = "获得${table.classComment}分页")
-#if ($sceneEnum.scene == 1)    @PreAuthorize("@ss.hasPermission('${permissionPrefix}:query')")#end
-
+#if ($sceneEnum.scene == 1)
+    @PreAuthorize("@ss.hasPermission('${permissionPrefix}:query')")
+#end
     public CommonResult<PageResult<${sceneEnum.prefixClass}${table.className}RespVO>> get${simpleClassName}Page(@Valid ${sceneEnum.prefixClass}${table.className}PageReqVO pageVO) {
         PageResult<${table.className}DO> pageResult = ${classNameVar}Service.get${simpleClassName}Page(pageVO);
         return success(${table.className}Convert.INSTANCE.convertPage(pageResult));
@@ -87,8 +96,9 @@ public class ${sceneEnum.prefixClass}${table.className}Controller {
 
     @GetMapping("/export-excel")
     @Operation(summary = "导出${table.classComment} Excel")
-#if ($sceneEnum.scene == 1)    @PreAuthorize("@ss.hasPermission('${permissionPrefix}:export')")#end
-
+#if ($sceneEnum.scene == 1)
+    @PreAuthorize("@ss.hasPermission('${permissionPrefix}:export')")
+#end
     @OperateLog(type = EXPORT)
     public void export${simpleClassName}Excel(@Valid ${sceneEnum.prefixClass}${table.className}ExportReqVO exportReqVO,
               HttpServletResponse response) throws IOException {
@@ -98,4 +108,89 @@ public class ${sceneEnum.prefixClass}${table.className}Controller {
         ExcelUtils.write(response, "${table.classComment}.xls", "数据", ${sceneEnum.prefixClass}${table.className}ExcelVO.class, datas);
     }
 
+## 特殊:主子表专属逻辑
+#foreach ($subTable in $subTables)
+#set ($index = $foreach.count - 1)
+#set ($subSimpleClassName = $subSimpleClassNames.get($index))
+#set ($subPrimaryColumn = $subPrimaryColumns.get($index))##当前 primary 字段
+#set ($subJoinColumn = $subJoinColumns.get($index))##当前 join 字段
+#set ($SubJoinColumnName = $subJoinColumn.javaField.substring(0,1).toUpperCase() + ${subJoinColumn.javaField.substring(1)})##首字母大写
+#set ($subSimpleClassName_strikeCase = $subSimpleClassName_strikeCases.get($index))
+#set ($subJoinColumn_strikeCase = $subJoinColumn_strikeCases.get($index))
+#set ($subClassNameVar = $subClassNameVars.get($index))
+    // ==================== 子表($subTable.classComment) ====================
+
+## 情况一:MASTER_ERP 时,需要分查询页子表
+#if ( $table.templateType == 11 )
+    @GetMapping("/${subSimpleClassName_strikeCase}/page")
+    @Operation(summary = "获得${subTable.classComment}分页")
+    @Parameter(name = "${subJoinColumn.javaField}", description = "${subJoinColumn.columnComment}")
+#if ($sceneEnum.scene == 1)
+    @PreAuthorize("@ss.hasPermission('${permissionPrefix}:query')")
+#end
+    public CommonResult<PageResult<${subTable.className}DO>> get${subSimpleClassName}Page(PageParam pageReqVO,
+                                                                                        @RequestParam("${subJoinColumn.javaField}") ${subJoinColumn.javaType} ${subJoinColumn.javaField}) {
+        return success(${classNameVar}Service.get${subSimpleClassName}Page(pageReqVO, ${subJoinColumn.javaField}));
+    }
+
+## 情况二:非 MASTER_ERP 时,需要列表查询子表
+#else
+    #if ( $subTable.subJoinMany )
+    @GetMapping("/${subSimpleClassName_strikeCase}/list-by-${subJoinColumn_strikeCase}")
+    @Operation(summary = "获得${subTable.classComment}列表")
+    @Parameter(name = "${subJoinColumn.javaField}", description = "${subJoinColumn.columnComment}")
+#if ($sceneEnum.scene == 1)
+    @PreAuthorize("@ss.hasPermission('${permissionPrefix}:query')")
+#end
+    public CommonResult<List<${subTable.className}DO>> get${subSimpleClassName}ListBy${SubJoinColumnName}(@RequestParam("${subJoinColumn.javaField}") ${subJoinColumn.javaType} ${subJoinColumn.javaField}) {
+        return success(${classNameVar}Service.get${subSimpleClassName}ListBy${SubJoinColumnName}(${subJoinColumn.javaField}));
+    }
+
+    #else
+    @GetMapping("/${subSimpleClassName_strikeCase}/get-by-${subJoinColumn_strikeCase}")
+    @Operation(summary = "获得${subTable.classComment}")
+    @Parameter(name = "${subJoinColumn.javaField}", description = "${subJoinColumn.columnComment}")
+#if ($sceneEnum.scene == 1)
+    @PreAuthorize("@ss.hasPermission('${permissionPrefix}:query')")
+#end
+    public CommonResult<${subTable.className}DO> get${subSimpleClassName}By${SubJoinColumnName}(@RequestParam("${subJoinColumn.javaField}") ${subJoinColumn.javaType} ${subJoinColumn.javaField}) {
+        return success(${classNameVar}Service.get${subSimpleClassName}By${SubJoinColumnName}(${subJoinColumn.javaField}));
+    }
+
+    #end
+#end
+## 特殊:MASTER_ERP 时,支持单个的新增、修改、删除操作
+#if ( $table.templateType == 11 )
+    @PostMapping("/${subSimpleClassName_strikeCase}/create")
+    @Operation(summary = "创建${subTable.classComment}")
+#if ($sceneEnum.scene == 1)
+    @PreAuthorize("@ss.hasPermission('${permissionPrefix}:create')")
+#end
+    public CommonResult<${subPrimaryColumn.javaType}> create${subSimpleClassName}(@Valid @RequestBody ${subTable.className}DO ${subClassNameVar}) {
+        return success(${classNameVar}Service.create${subSimpleClassName}(${subClassNameVar}));
+    }
+
+    @PutMapping("/${subSimpleClassName_strikeCase}/update")
+    @Operation(summary = "更新${subTable.classComment}")
+#if ($sceneEnum.scene == 1)
+    @PreAuthorize("@ss.hasPermission('${permissionPrefix}:update')")
+#end
+    public CommonResult<Booealn> update${subSimpleClassName}(@Valid @RequestBody ${subTable.className}DO ${subClassNameVar}) {
+        ${classNameVar}Service.update${subSimpleClassName}(${subClassNameVar});
+        return success(true);
+    }
+
+    @DeleteMapping("/${subSimpleClassName_strikeCase}/delete")
+    @Parameter(name = "id", description = "编号", required = true)
+    @Operation(summary = "删除${subTable.classComment}")
+#if ($sceneEnum.scene == 1)
+    @PreAuthorize("@ss.hasPermission('${permissionPrefix}:delete')")
+#end
+    public CommonResult<Booealn> delete${subSimpleClassName}(@RequestParam("id") ${subPrimaryColumn.javaType} id) {
+        ${classNameVar}Service.delete${subSimpleClassName}(${subClassNameVar});
+        return success(true);
+    }
+
+#end
+#end
 }
\ No newline at end of file
diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/dal/mapper_sub.vm b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/dal/mapper_sub.vm
index eb158ea49..e5589e99d 100644
--- a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/dal/mapper_sub.vm
+++ b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/dal/mapper_sub.vm
@@ -6,6 +6,9 @@ package ${basePackage}.module.${subTable.moduleName}.dal.mysql.${subTable.busine
 
 import java.util.*;
 
+import ${PageResultClassName};
+import ${PageParamClassName};
+import ${QueryWrapperClassName};
 import ${BaseMapperClassName};
 import ${basePackage}.module.${subTable.moduleName}.dal.dataobject.${subTable.businessName}.${subTable.className}DO;
 import org.apache.ibatis.annotations.Mapper;
@@ -18,21 +21,29 @@ import org.apache.ibatis.annotations.Mapper;
 @Mapper
 public interface ${subTable.className}Mapper extends BaseMapperX<${subTable.className}DO> {
 
-#if ( $subTable.subJoinMany)
+## 情况一:MASTER_ERP 时,需要分查询页子表
+#if ( $table.templateType == 11 )
+    default PageResult<${subTable.className}DO> selectPage(PageParam reqVO, ${subJoinColumn.javaType} ${subJoinColumn.javaField}) {
+        return selectPage(reqVO, new LambdaQueryWrapperX<${subTable.className}DO>()
+            .eq(${subTable.className}DO::get${SubJoinColumnName}, ${subJoinColumn.javaField})
+            .orderByDesc(${subTable.className}DO::getId));## 大多数情况下,id 倒序
+
+    }
+
+## 情况二:非 MASTER_ERP 时,需要列表查询子表
+#else
+    #if ( $subTable.subJoinMany)
     default List<${subTable.className}DO> selectListBy${SubJoinColumnName}(${subJoinColumn.javaType} ${subJoinColumn.javaField}) {
         return selectList(${subTable.className}DO::get${SubJoinColumnName}, ${subJoinColumn.javaField});
     }
 
-#else
+    #else
     default ${subTable.className}DO selectBy${SubJoinColumnName}(${subJoinColumn.javaType} ${subJoinColumn.javaField}) {
         return selectOne(${subTable.className}DO::get${SubJoinColumnName}, ${subJoinColumn.javaField});
     }
 
-#end
-    default List<${subTable.className}DO> selectListBy${SubJoinColumnName}(List<${subJoinColumn.javaType}> ${subJoinColumn.javaField}s) {
-        return selectList(${subTable.className}DO::get${SubJoinColumnName}, ${subJoinColumn.javaField}s);
-    }
-
+    #end
+    #end
     default int deleteBy${SubJoinColumnName}(${subJoinColumn.javaType} ${subJoinColumn.javaField}) {
         return delete(${subTable.className}DO::get${SubJoinColumnName}, ${subJoinColumn.javaField});
     }
diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/service/service.vm b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/service/service.vm
index 3ff2193f3..6f95ac164 100644
--- a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/service/service.vm
+++ b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/service/service.vm
@@ -4,6 +4,10 @@ import java.util.*;
 import javax.validation.*;
 import ${basePackage}.module.${table.moduleName}.controller.${sceneEnum.basePackage}.${table.businessName}.vo.*;
 import ${basePackage}.module.${table.moduleName}.dal.dataobject.${table.businessName}.${table.className}DO;
+## 特殊:主子表专属逻辑
+#foreach ($subTable in $subTables)
+import ${basePackage}.module.${subTable.moduleName}.dal.dataobject.${subTable.businessName}.${subTable.className}DO;
+#end
 import ${PageResultClassName};
 
 /**
@@ -63,8 +67,26 @@ public interface ${table.className}Service {
 #foreach ($subTable in $subTables)
 #set ($index = $foreach.count - 1)
 #set ($subSimpleClassName = $subSimpleClassNames.get($index))
+#set ($subPrimaryColumn = $subPrimaryColumns.get($index))##当前 primary 字段
 #set ($subJoinColumn = $subJoinColumns.get($index))##当前 join 字段
 #set ($SubJoinColumnName = $subJoinColumn.javaField.substring(0,1).toUpperCase() + ${subJoinColumn.javaField.substring(1)})##首字母大写
+#set ($subClassNameVar = $subClassNameVars.get($index))
+
+    // ==================== 子表($subTable.classComment) ====================
+
+## 情况一:MASTER_ERP 时,需要分查询页子表
+#if ( $table.templateType == 11 )
+    /**
+     * 获得${subTable.classComment}分页
+     *
+     * @param pageReqVO 分页查询
+     * @param ${subJoinColumn.javaField} ${subJoinColumn.columnComment}
+     * @return ${subTable.classComment}分页
+     */
+    PageResult<${subTable.className}DO> get${subSimpleClassName}Page(PageParam pageReqVO, ${subJoinColumn.javaType} ${subJoinColumn.javaField})
+
+## 情况二:非 MASTER_ERP 时,需要列表查询子表
+#else
     #if ( $subTable.subJoinMany )
     /**
      * 获得${subTable.classComment}列表
@@ -85,4 +107,30 @@ public interface ${table.className}Service {
 
     #end
 #end
+## 特殊:MASTER_ERP 时,支持单个的新增、修改、删除操作
+#if ( $table.templateType == 11 )
+    /**
+     * 创建${subTable.classComment}
+     *
+     * @param ${subClassNameVar} 创建信息
+     * @return 编号
+     */
+    ${subPrimaryColumn.javaType} create${subSimpleClassName}(@Valid ${subTable.className}DO ${subClassNameVar});
+
+    /**
+     * 更新${subTable.classComment}
+     *
+     * @param ${subClassNameVar} 更新信息
+     */
+    void update${subSimpleClassName}(@Valid ${subTable.className}DO ${subClassNameVar});
+
+    /**
+     * 删除${subTable.classComment}
+     *
+     * @param id 编号
+     */
+    void delete${subSimpleClassName}(${subPrimaryColumn.javaType} id);
+
+#end
+#end
 }
\ No newline at end of file
diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/service/serviceImpl.vm b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/service/serviceImpl.vm
index d85e21b3b..a2a4fc4f1 100644
--- a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/service/serviceImpl.vm
+++ b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/service/serviceImpl.vm
@@ -9,7 +9,7 @@ import java.util.*;
 import ${basePackage}.module.${table.moduleName}.controller.${sceneEnum.basePackage}.${table.businessName}.vo.*;
 import ${basePackage}.module.${table.moduleName}.dal.dataobject.${table.businessName}.${table.className}DO;
 ## 特殊:主子表专属逻辑
-#if( $subTable )
+#foreach ($subTable in $subTables)
 import ${basePackage}.module.${subTable.moduleName}.dal.dataobject.${subTable.businessName}.${subTable.className}DO;
 #end
 import ${PageResultClassName};
@@ -56,18 +56,20 @@ public class ${table.className}ServiceImpl implements ${table.className}Service
         ${table.className}DO ${classNameVar} = ${table.className}Convert.INSTANCE.convert(createReqVO);
         ${classNameVar}Mapper.insert(${classNameVar});
 ## 特殊:主子表专属逻辑
+#if ( $subTables.size() > 0)
+
+        // 插入子表($subTable.classComment)
 #foreach ($subTable in $subTables)
 #set ($index = $foreach.count - 1)
+#set ($subSimpleClassName = $subSimpleClassNames.get($index))
 #set ($subJoinColumn = $subJoinColumns.get($index))##当前 join 字段
 #set ($SubJoinColumnName = $subJoinColumn.javaField.substring(0,1).toUpperCase() + ${subJoinColumn.javaField.substring(1)})##首字母大写
-        // 插入子表($subTable.classComment)
     #if ( $subTable.subJoinMany)
-        createReqVO.get${subSimpleClassNames.get($index)}s().forEach(o -> o.set$SubJoinColumnName(${classNameVar}.getId()));
-        ${subClassNameVars.get($index)}Mapper.insertBatch(createReqVO.get${subSimpleClassNames.get($index)}s());
+        create${subSimpleClassName}List(${classNameVar}.getId(), createReqVO.get${subSimpleClassNames.get($index)}s());
     #else
-        createReqVO.get${subSimpleClassNames.get($index)}().set$SubJoinColumnName(${classNameVar}.getId());
-        ${subClassNameVars.get($index)}Mapper.insert(createReqVO.get${subSimpleClassNames.get($index)}());
+        create${subSimpleClassName}(${classNameVar}.getId(), createReqVO.get${subSimpleClassNames.get($index)}());
     #end
+#end
 #end
         // 返回
         return ${classNameVar}.getId();
@@ -85,19 +87,20 @@ public class ${table.className}ServiceImpl implements ${table.className}Service
         ${table.className}DO updateObj = ${table.className}Convert.INSTANCE.convert(updateReqVO);
         ${classNameVar}Mapper.updateById(updateObj);
 ## 特殊:主子表专属逻辑
+#if ( $subTables.size() > 0)
+
+        // 更新子表
 #foreach ($subTable in $subTables)
 #set ($index = $foreach.count - 1)
+#set ($subSimpleClassName = $subSimpleClassNames.get($index))
 #set ($subJoinColumn = $subJoinColumns.get($index))##当前 join 字段
 #set ($SubJoinColumnName = $subJoinColumn.javaField.substring(0,1).toUpperCase() + ${subJoinColumn.javaField.substring(1)})##首字母大写
-        // 更新子表($subTable.classComment)
     #if ( $subTable.subJoinMany)
-        ${subClassNameVars.get($index)}Mapper.deleteBy${SubJoinColumnName}(updateReqVO.getId());
-        updateReqVO.get${subSimpleClassNames.get($index)}s().forEach(o -> o.set$SubJoinColumnName(updateReqVO.getId()));
-        ${subClassNameVars.get($index)}Mapper.insertBatch(updateReqVO.get${subSimpleClassNames.get($index)}s());
+        update${subSimpleClassName}List(updateReqVO.getId(), updateReqVO.get${subSimpleClassNames.get($index)}s());
     #else
-        updateReqVO.get${subSimpleClassNames.get($index)}().set$SubJoinColumnName(updateReqVO.getId());
-        ${subClassNameVars.get($index)}Mapper.updateById(updateReqVO.get${subSimpleClassNames.get($index)}());
+        update${subSimpleClassName}(updateReqVO.getId(), updateReqVO.get${subSimpleClassNames.get($index)}());
     #end
+#end
 #end
     }
 
@@ -112,12 +115,16 @@ public class ${table.className}ServiceImpl implements ${table.className}Service
         // 删除
         ${classNameVar}Mapper.deleteById(id);
 ## 特殊:主子表专属逻辑
+#if ( $subTables.size() > 0)
+
+        // 删除子表
 #foreach ($subTable in $subTables)
 #set ($index = $foreach.count - 1)
+#set ($subSimpleClassName = $subSimpleClassNames.get($index))
 #set ($subJoinColumn = $subJoinColumns.get($index))##当前 join 字段
 #set ($SubJoinColumnName = $subJoinColumn.javaField.substring(0,1).toUpperCase() + ${subJoinColumn.javaField.substring(1)})##首字母大写
-        // 删除子表($subTable.classComment)
-        ${subClassNameVars.get($index)}Mapper.deleteBy${SubJoinColumnName}(id);
+        delete${subSimpleClassName}By${SubJoinColumnName}(id);
+#end
 #end
     }
 
@@ -142,4 +149,86 @@ public class ${table.className}ServiceImpl implements ${table.className}Service
         return ${classNameVar}Mapper.selectList(exportReqVO);
     }
 
+## 特殊:主子表专属逻辑
+#foreach ($subTable in $subTables)
+#set ($index = $foreach.count - 1)
+#set ($subSimpleClassName = $subSimpleClassNames.get($index))
+#set ($subPrimaryColumn = $subPrimaryColumns.get($index))##当前 primary 字段
+#set ($subJoinColumn = $subJoinColumns.get($index))##当前 join 字段
+#set ($SubJoinColumnName = $subJoinColumn.javaField.substring(0,1).toUpperCase() + ${subJoinColumn.javaField.substring(1)})##首字母大写
+#set ($subClassNameVar = $subClassNameVars.get($index))
+    // ==================== 子表($subTable.classComment) ====================
+
+## 情况一:MASTER_ERP 时,需要分查询页子表
+#if ( $table.templateType == 11 )
+    @Override
+    public PageResult<${subTable.className}DO> get${subSimpleClassName}Page(PageParam pageReqVO, ${subJoinColumn.javaType} ${subJoinColumn.javaField}) {
+        return ${subClassNameVars.get($index)}Mapper.selectPage(pageReqVO, ${subJoinColumn.javaField});
+    }
+
+## 情况二:非 MASTER_ERP 时,需要列表查询子表
+#else
+    #if ( $subTable.subJoinMany )
+    @Override
+    public List<${subTable.className}DO> get${subSimpleClassName}ListBy${SubJoinColumnName}(${subJoinColumn.javaType} ${subJoinColumn.javaField}) {
+        return ${subClassNameVars.get($index)}Mapper.selectListBy${SubJoinColumnName}(${subJoinColumn.javaField});
+    }
+
+    #else
+    @Override
+    public ${subTable.className}DO get${subSimpleClassName}By${SubJoinColumnName}(${subJoinColumn.javaType} ${subJoinColumn.javaField}) {
+        return ${subClassNameVars.get($index)}Mapper.selectBy${SubJoinColumnName}(${subJoinColumn.javaField});
+    }
+
+    #end
+#end
+## 情况一:MASTER_ERP 时,支持单个的新增、修改、删除操作
+#if ( $table.templateType == 11 )
+    @Override
+    public ${subPrimaryColumn.javaType} create${subSimpleClassName}(@Valid ${subTable.className}DO ${subClassNameVar}) {
+        ${subClassNameVars.get($index)}Mapper.insert(${subClassNameVar});
+        return ${subClassNameVar}.getId();
+    }
+
+    @Override
+    public void update${subSimpleClassName}(@Valid ${subTable.className}DO ${subClassNameVar}) {
+        ${subClassNameVars.get($index)}Mapper.updateById(${subClassNameVar});
+    }
+
+    @Override
+    public void delete${subSimpleClassName}(${subPrimaryColumn.javaType} id) {
+        ${subClassNameVars.get($index)}Mapper.deleteById(id);
+    }
+
+## 情况二:非 MASTER_ERP 时,支持批量的新增、修改操作
+#else
+    #if ( $subTable.subJoinMany)
+    private void create${subSimpleClassName}List(${primaryColumn.javaType} ${subJoinColumn.javaField}, List<${subTable.className}DO> list) {
+        list.forEach(o -> o.set$SubJoinColumnName(${subJoinColumn.javaField}));
+        ${subClassNameVars.get($index)}Mapper.insertBatch(list);
+    }
+
+    private void update${subSimpleClassName}List(${primaryColumn.javaType} ${subJoinColumn.javaField}, List<${subTable.className}DO> list) {
+        delete${subSimpleClassName}By${SubJoinColumnName}(${subJoinColumn.javaField});
+        create${subSimpleClassName}List(${subJoinColumn.javaField}, list);
+    }
+
+    #else
+    private void create${subSimpleClassName}(${primaryColumn.javaType} ${subJoinColumn.javaField}, ${subTable.className}DO ${subClassNameVar}) {
+        ${subClassNameVar}.set$SubJoinColumnName(${subJoinColumn.javaField});
+        ${subClassNameVars.get($index)}Mapper.insert(${subClassNameVar});
+    }
+
+    private void update${subSimpleClassName}(${primaryColumn.javaType} ${subJoinColumn.javaField}, ${subTable.className}DO ${subClassNameVar}) {
+        ${subClassNameVar}.set$SubJoinColumnName(${subJoinColumn.javaField});
+        ${subClassNameVars.get($index)}Mapper.updateById(${subClassNameVar});
+    }
+
+    #end
+    private void delete${subSimpleClassName}By${SubJoinColumnName}(${primaryColumn.javaType} ${subJoinColumn.javaField}) {
+        ${subClassNameVars.get($index)}Mapper.deleteBy${SubJoinColumnName}(${subJoinColumn.javaField});
+    }
+
+#end
+#end
 }
\ No newline at end of file
diff --git a/yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/service/codegen/inner/CodegenEngineTest.java b/yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/service/codegen/inner/CodegenEngineTest.java
index 319bc0d26..2bbe3309b 100644
--- a/yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/service/codegen/inner/CodegenEngineTest.java
+++ b/yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/service/codegen/inner/CodegenEngineTest.java
@@ -173,7 +173,8 @@ public class CodegenEngineTest extends BaseMockitoUnitTest {
                 .setTableName("infra_demo_student").setTableComment("学生表")
                 .setModuleName("infra").setBusinessName("demo02").setClassName("InfraDemoStudent")
                 .setClassComment("学生").setAuthor("芋道源码")
-                .setTemplateType(CodegenTemplateTypeEnum.MASTER.getType())
+                .setTemplateType(CodegenTemplateTypeEnum.MASTER_NORMAL.getType())
+//                .setTemplateType(CodegenTemplateTypeEnum.MASTER_ERP.getType())
                 .setFrontType(CodegenFrontTypeEnum.VUE3.getType());
         CodegenColumnDO idColumn = new CodegenColumnDO().setColumnName("id").setDataType(JdbcType.BIGINT.name())
                 .setColumnComment("编号").setNullable(false).setPrimaryKey(true).setAutoIncrement(true)