Commit 2f6456e2b0a3c9d5e4726e1493c3b66391d4eab7

Authored by zhijiantianya@gmail.com
1 parent 2afc2caf

代码生成器:主子表,支持多个从字段 50%

Showing 48 changed files with 916 additions and 147 deletions
yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/mapper/BaseMapperX.java
... ... @@ -136,4 +136,8 @@ public interface BaseMapperX<T> extends MPJBaseMapper<T> {
136 136 return delete(new QueryWrapper<T>().eq(field, value));
137 137 }
138 138  
  139 + default int delete(SFunction<T, ?> field, Object value) {
  140 + return delete(new LambdaQueryWrapper<T>().eq(field, value));
  141 + }
  142 +
139 143 }
... ...
yudao-module-infra/yudao-module-infra-api/src/main/java/cn/iocoder/yudao/module/infra/enums/ErrorCodeConstants.java
... ... @@ -54,4 +54,7 @@ public interface ErrorCodeConstants {
54 54 ErrorCode DATA_SOURCE_CONFIG_NOT_EXISTS = new ErrorCode(1_001_007_000, "数据源配置不存在");
55 55 ErrorCode DATA_SOURCE_CONFIG_NOT_OK = new ErrorCode(1_001_007_001, "数据源配置不正确,无法进行连接");
56 56  
  57 + // ========== 数据源配置 1-001-107-000 ==========
  58 + ErrorCode DEMO_STUDENT_NOT_EXISTS = new ErrorCode(1_001_107_000, "学生不存在");
  59 +
57 60 }
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/codegen/vo/CodegenUpdateReqVO.java
... ... @@ -44,9 +44,10 @@ public class CodegenUpdateReqVO {
44 44 || getParentMenuId() != null;
45 45 }
46 46  
  47 + // TODO 芋艿:这里有问题哈;
47 48 @AssertTrue(message = "关联的子表与字段不能为空")
48 49 public boolean isSubValid() {
49   - return ObjectUtil.notEqual(getTemplateType(), CodegenTemplateTypeEnum.MASTER_SUB)
  50 + return ObjectUtil.notEqual(getTemplateType(), CodegenTemplateTypeEnum.SUB)
50 51 || (getSubTableId() != null && getSubColumnId() != null);
51 52 }
52 53  
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/demo02/InfraDemoStudentController.java 0 → 100644
  1 +package cn.iocoder.yudao.module.infra.controller.admin.demo02;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  4 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  5 +import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
  6 +import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
  7 +import cn.iocoder.yudao.module.infra.controller.admin.demo02.vo.*;
  8 +import cn.iocoder.yudao.module.infra.convert.demo02.InfraDemoStudentConvert;
  9 +import cn.iocoder.yudao.module.infra.dal.dataobject.demo02.InfraDemoStudentDO;
  10 +import cn.iocoder.yudao.module.infra.service.demo02.InfraDemoStudentService;
  11 +import io.swagger.v3.oas.annotations.Operation;
  12 +import io.swagger.v3.oas.annotations.Parameter;
  13 +import io.swagger.v3.oas.annotations.tags.Tag;
  14 +import org.springframework.security.access.prepost.PreAuthorize;
  15 +import org.springframework.validation.annotation.Validated;
  16 +import org.springframework.web.bind.annotation.*;
  17 +
  18 +import javax.annotation.Resource;
  19 +import javax.servlet.http.HttpServletResponse;
  20 +import javax.validation.Valid;
  21 +import java.io.IOException;
  22 +import java.util.Collection;
  23 +import java.util.List;
  24 +
  25 +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  26 +import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
  27 +
  28 +@Tag(name = "管理后台 - 学生")
  29 +@RestController
  30 +@RequestMapping("/infra/demo-student")
  31 +@Validated
  32 +public class InfraDemoStudentController {
  33 +
  34 + @Resource
  35 + private InfraDemoStudentService demoStudentService;
  36 +
  37 + @PostMapping("/create")
  38 + @Operation(summary = "创建学生")
  39 + @PreAuthorize("@ss.hasPermission('infra:demo-student:create')")
  40 + public CommonResult<Long> createDemoStudent(@Valid @RequestBody InfraDemoStudentCreateReqVO createReqVO) {
  41 + return success(demoStudentService.createDemoStudent(createReqVO));
  42 + }
  43 +
  44 + @PutMapping("/update")
  45 + @Operation(summary = "更新学生")
  46 + @PreAuthorize("@ss.hasPermission('infra:demo-student:update')")
  47 + public CommonResult<Boolean> updateDemoStudent(@Valid @RequestBody InfraDemoStudentUpdateReqVO updateReqVO) {
  48 + demoStudentService.updateDemoStudent(updateReqVO);
  49 + return success(true);
  50 + }
  51 +
  52 + @DeleteMapping("/delete")
  53 + @Operation(summary = "删除学生")
  54 + @Parameter(name = "id", description = "编号", required = true)
  55 + @PreAuthorize("@ss.hasPermission('infra:demo-student:delete')")
  56 + public CommonResult<Boolean> deleteDemoStudent(@RequestParam("id") Long id) {
  57 + demoStudentService.deleteDemoStudent(id);
  58 + return success(true);
  59 + }
  60 +
  61 + @GetMapping("/get")
  62 + @Operation(summary = "获得学生")
  63 + @Parameter(name = "id", description = "编号", required = true, example = "1024")
  64 + @PreAuthorize("@ss.hasPermission('infra:demo-student:query')")
  65 + public CommonResult<InfraDemoStudentRespVO> getDemoStudent(@RequestParam("id") Long id) {
  66 + InfraDemoStudentDO demoStudent = demoStudentService.getDemoStudent(id);
  67 + return success(InfraDemoStudentConvert.INSTANCE.convert(demoStudent));
  68 + }
  69 +
  70 + @GetMapping("/page")
  71 + @Operation(summary = "获得学生分页")
  72 + @PreAuthorize("@ss.hasPermission('infra:demo-student:query')")
  73 + public CommonResult<PageResult<InfraDemoStudentRespVO>> getDemoStudentPage(@Valid InfraDemoStudentPageReqVO pageVO) {
  74 + PageResult<InfraDemoStudentDO> pageResult = demoStudentService.getDemoStudentPage(pageVO);
  75 + return success(InfraDemoStudentConvert.INSTANCE.convertPage(pageResult));
  76 + }
  77 +
  78 + @GetMapping("/export-excel")
  79 + @Operation(summary = "导出学生 Excel")
  80 + @PreAuthorize("@ss.hasPermission('infra:demo-student:export')")
  81 + @OperateLog(type = EXPORT)
  82 + public void exportDemoStudentExcel(@Valid InfraDemoStudentExportReqVO exportReqVO,
  83 + HttpServletResponse response) throws IOException {
  84 + List<InfraDemoStudentDO> list = demoStudentService.getDemoStudentList(exportReqVO);
  85 + // 导出 Excel
  86 + List<InfraDemoStudentExcelVO> datas = InfraDemoStudentConvert.INSTANCE.convertList02(list);
  87 + ExcelUtils.write(response, "学生.xls", "数据", InfraDemoStudentExcelVO.class, datas);
  88 + }
  89 +
  90 +}
0 91 \ No newline at end of file
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/demo02/package-info.java 0 → 100644
  1 +package cn.iocoder.yudao.module.infra.controller.admin.demo02;
0 2 \ No newline at end of file
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/demo02/vo/InfraDemoStudentBaseVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.infra.controller.admin.demo02.vo;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.*;
  5 +import java.util.*;
  6 +import javax.validation.constraints.*;
  7 +import cn.iocoder.yudao.module.infra.dal.dataobject.demo02.InfraDemoStudentContactDO;
  8 +import cn.iocoder.yudao.module.infra.dal.dataobject.demo02.InfraDemoStudentAddressDO;
  9 +
  10 +/**
  11 + * 学生 Base VO,提供给添加、修改、详细的子 VO 使用
  12 + * 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
  13 + */
  14 +@Data
  15 +public class InfraDemoStudentBaseVO {
  16 +
  17 + private List<InfraDemoStudentContactDO> demoStudentContacts;
  18 +
  19 + private InfraDemoStudentAddressDO demoStudentAddress;
  20 +
  21 +}
0 22 \ No newline at end of file
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/demo02/vo/InfraDemoStudentCreateReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.infra.controller.admin.demo02.vo;
  2 +
  3 +import lombok.*;
  4 +import java.util.*;
  5 +import io.swagger.v3.oas.annotations.media.Schema;
  6 +import javax.validation.constraints.*;
  7 +
  8 +@Schema(description = "管理后台 - 学生创建 Request VO")
  9 +@Data
  10 +@EqualsAndHashCode(callSuper = true)
  11 +@ToString(callSuper = true)
  12 +public class InfraDemoStudentCreateReqVO extends InfraDemoStudentBaseVO {
  13 +
  14 +}
0 15 \ No newline at end of file
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/demo02/vo/InfraDemoStudentExcelVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.infra.controller.admin.demo02.vo;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.*;
  5 +import java.util.*;
  6 +
  7 +import com.alibaba.excel.annotation.ExcelProperty;
  8 +
  9 +/**
  10 + * 学生 Excel VO
  11 + *
  12 + * @author 芋道源码
  13 + */
  14 +@Data
  15 +public class InfraDemoStudentExcelVO {
  16 +
  17 + @ExcelProperty("编号")
  18 + private Long id;
  19 +
  20 +}
0 21 \ No newline at end of file
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/demo02/vo/InfraDemoStudentExportReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.infra.controller.admin.demo02.vo;
  2 +
  3 +import lombok.*;
  4 +import java.util.*;
  5 +import io.swagger.v3.oas.annotations.media.Schema;
  6 +import cn.iocoder.yudao.framework.common.pojo.PageParam;
  7 +
  8 +@Schema(description = "管理后台 - 学生 Excel 导出 Request VO,参数和 InfraDemoStudentPageReqVO 是一致的")
  9 +@Data
  10 +public class InfraDemoStudentExportReqVO {
  11 +
  12 +}
0 13 \ No newline at end of file
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/demo02/vo/InfraDemoStudentPageReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.infra.controller.admin.demo02.vo;
  2 +
  3 +import lombok.*;
  4 +import java.util.*;
  5 +import io.swagger.v3.oas.annotations.media.Schema;
  6 +import cn.iocoder.yudao.framework.common.pojo.PageParam;
  7 +
  8 +@Schema(description = "管理后台 - 学生分页 Request VO")
  9 +@Data
  10 +@EqualsAndHashCode(callSuper = true)
  11 +@ToString(callSuper = true)
  12 +public class InfraDemoStudentPageReqVO extends PageParam {
  13 +
  14 +}
0 15 \ No newline at end of file
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/demo02/vo/InfraDemoStudentRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.infra.controller.admin.demo02.vo;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.*;
  5 +
  6 +@Schema(description = "管理后台 - 学生 Response VO")
  7 +@Data
  8 +@EqualsAndHashCode(callSuper = true)
  9 +@ToString(callSuper = true)
  10 +public class InfraDemoStudentRespVO extends InfraDemoStudentBaseVO {
  11 +
  12 + @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
  13 + private Long id;
  14 +
  15 +}
0 16 \ No newline at end of file
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/demo02/vo/InfraDemoStudentUpdateReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.infra.controller.admin.demo02.vo;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.*;
  5 +import java.util.*;
  6 +import javax.validation.constraints.*;
  7 +
  8 +@Schema(description = "管理后台 - 学生更新 Request VO")
  9 +@Data
  10 +@EqualsAndHashCode(callSuper = true)
  11 +@ToString(callSuper = true)
  12 +public class InfraDemoStudentUpdateReqVO extends InfraDemoStudentBaseVO {
  13 +
  14 + @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
  15 + @NotNull(message = "编号不能为空")
  16 + private Long id;
  17 +
  18 +}
0 19 \ No newline at end of file
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/convert/demo02/InfraDemoStudentConvert.java 0 → 100644
  1 +package cn.iocoder.yudao.module.infra.convert.demo02;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  4 +import cn.iocoder.yudao.module.infra.controller.admin.demo02.vo.InfraDemoStudentCreateReqVO;
  5 +import cn.iocoder.yudao.module.infra.controller.admin.demo02.vo.InfraDemoStudentExcelVO;
  6 +import cn.iocoder.yudao.module.infra.controller.admin.demo02.vo.InfraDemoStudentRespVO;
  7 +import cn.iocoder.yudao.module.infra.controller.admin.demo02.vo.InfraDemoStudentUpdateReqVO;
  8 +import cn.iocoder.yudao.module.infra.dal.dataobject.demo02.InfraDemoStudentDO;
  9 +import org.mapstruct.Mapper;
  10 +import org.mapstruct.factory.Mappers;
  11 +
  12 +import java.util.List;
  13 +
  14 +/**
  15 + * 学生 Convert
  16 + *
  17 + * @author 芋道源码
  18 + */
  19 +@Mapper
  20 +public interface InfraDemoStudentConvert {
  21 +
  22 + InfraDemoStudentConvert INSTANCE = Mappers.getMapper(InfraDemoStudentConvert.class);
  23 +
  24 + InfraDemoStudentDO convert(InfraDemoStudentCreateReqVO bean);
  25 +
  26 + InfraDemoStudentDO convert(InfraDemoStudentUpdateReqVO bean);
  27 +
  28 + InfraDemoStudentRespVO convert(InfraDemoStudentDO bean);
  29 +
  30 + List<InfraDemoStudentRespVO> convertList(List<InfraDemoStudentDO> list);
  31 +
  32 + PageResult<InfraDemoStudentRespVO> convertPage(PageResult<InfraDemoStudentDO> page);
  33 +
  34 + List<InfraDemoStudentExcelVO> convertList02(List<InfraDemoStudentDO> list);
  35 +
  36 +}
0 37 \ No newline at end of file
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/dataobject/codegen/CodegenTableDO.java
... ... @@ -119,16 +119,23 @@ public class CodegenTableDO extends BaseDO {
119 119 // ========== 主子表相关字段 ==========
120 120  
121 121 /**
122   - * 子表的表编号
  122 + * 主表的编号
123 123 *
124 124 * 关联 {@link CodegenTableDO#getId()}
125 125 */
126   - private Long subTableId;
  126 + private Long masterTableId;
127 127 /**
128   - * 子表的关联字段编号
  128 + * 【自己】子表关联主表的字段编号
129 129 *
130 130 * 关联 {@link CodegenColumnDO#getId()}
131 131 */
132   - private Long subColumnId;
  132 + private Long subJoinColumnId;
  133 + /**
  134 + * 主表与子表是否一对多
  135 + *
  136 + * true:一对多
  137 + * false:一对一
  138 + */
  139 + private Boolean subJoinMany;
133 140  
134 141 }
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/dataobject/demo02/InfraDemoStudentAddressDO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.infra.dal.dataobject.demo02;
  2 +
  3 +import lombok.*;
  4 +import java.util.*;
  5 +import com.baomidou.mybatisplus.annotation.*;
  6 +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
  7 +
  8 +/**
  9 + * 学生地址 DO
  10 + *
  11 + * @author 芋道源码
  12 + */
  13 +@TableName("infra_demo_student_address")
  14 +@KeySequence("infra_demo_student_address_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
  15 +@Data
  16 +@EqualsAndHashCode(callSuper = true)
  17 +@ToString(callSuper = true)
  18 +@Builder
  19 +@NoArgsConstructor
  20 +@AllArgsConstructor
  21 +public class InfraDemoStudentAddressDO extends BaseDO {
  22 +
  23 + /**
  24 + * 编号
  25 + */
  26 + @TableId
  27 + private Long id;
  28 + /**
  29 + * 学生编号
  30 + */
  31 + private Long studentId;
  32 + /**
  33 + * 明细
  34 + */
  35 + private String detail;
  36 +
  37 +}
0 38 \ No newline at end of file
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/dataobject/demo02/InfraDemoStudentContactDO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.infra.dal.dataobject.demo02;
  2 +
  3 +import lombok.*;
  4 +import java.util.*;
  5 +import com.baomidou.mybatisplus.annotation.*;
  6 +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
  7 +
  8 +/**
  9 + * 学生联系人 DO
  10 + *
  11 + * @author 芋道源码
  12 + */
  13 +@TableName("infra_demo_student_contact")
  14 +@KeySequence("infra_demo_student_contact_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
  15 +@Data
  16 +@EqualsAndHashCode(callSuper = true)
  17 +@ToString(callSuper = true)
  18 +@Builder
  19 +@NoArgsConstructor
  20 +@AllArgsConstructor
  21 +public class InfraDemoStudentContactDO extends BaseDO {
  22 +
  23 + /**
  24 + * 编号
  25 + */
  26 + @TableId
  27 + private Long id;
  28 + /**
  29 + * 学生编号
  30 + */
  31 + private Long studentId;
  32 + /**
  33 + * 名字
  34 + */
  35 + private String name;
  36 +
  37 +}
0 38 \ No newline at end of file
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/dataobject/demo02/InfraDemoStudentDO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.infra.dal.dataobject.demo02;
  2 +
  3 +import lombok.*;
  4 +import java.util.*;
  5 +import com.baomidou.mybatisplus.annotation.*;
  6 +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
  7 +
  8 +/**
  9 + * 学生 DO
  10 + *
  11 + * @author 芋道源码
  12 + */
  13 +@TableName("infra_demo_student")
  14 +@KeySequence("infra_demo_student_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
  15 +@Data
  16 +@EqualsAndHashCode(callSuper = true)
  17 +@ToString(callSuper = true)
  18 +@Builder
  19 +@NoArgsConstructor
  20 +@AllArgsConstructor
  21 +public class InfraDemoStudentDO extends BaseDO {
  22 +
  23 + /**
  24 + * 编号
  25 + */
  26 + @TableId
  27 + private Long id;
  28 +
  29 +}
0 30 \ No newline at end of file
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/mysql/demo02/InfraDemoStudentAddressMapper.java 0 → 100644
  1 +package cn.iocoder.yudao.module.infra.dal.mysql.demo02;
  2 +
  3 +import java.util.*;
  4 +
  5 +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
  6 +import cn.iocoder.yudao.module.infra.dal.dataobject.demo02.InfraDemoStudentAddressDO;
  7 +import org.apache.ibatis.annotations.Mapper;
  8 +
  9 +/**
  10 + * 学生地址 Mapper
  11 + *
  12 + * @author 芋道源码
  13 + */
  14 +@Mapper
  15 +public interface InfraDemoStudentAddressMapper extends BaseMapperX<InfraDemoStudentAddressDO> {
  16 +
  17 + default InfraDemoStudentAddressDO selectByStudentId(Long studentId) {
  18 + return selectOne(InfraDemoStudentAddressDO::getStudentId, studentId);
  19 + }
  20 +
  21 + default List<InfraDemoStudentAddressDO> selectListByStudentId(List<Long> studentIds) {
  22 + return selectList(InfraDemoStudentAddressDO::getStudentId, studentIds);
  23 + }
  24 +
  25 + default int deleteByStudentId(Long studentId) {
  26 + return delete(InfraDemoStudentAddressDO::getStudentId, studentId);
  27 + }
  28 +
  29 +}
0 30 \ No newline at end of file
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/mysql/demo02/InfraDemoStudentContactMapper.java 0 → 100644
  1 +package cn.iocoder.yudao.module.infra.dal.mysql.demo02;
  2 +
  3 +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
  4 +import cn.iocoder.yudao.module.infra.dal.dataobject.demo02.InfraDemoStudentContactDO;
  5 +import org.apache.ibatis.annotations.Mapper;
  6 +
  7 +import java.util.List;
  8 +
  9 +/**
  10 + * 学生联系人 Mapper
  11 + *
  12 + * @author 芋道源码
  13 + */
  14 +@Mapper
  15 +public interface InfraDemoStudentContactMapper extends BaseMapperX<InfraDemoStudentContactDO> {
  16 +
  17 + default List<InfraDemoStudentContactDO> selectListByStudentId(Long studentId) {
  18 + return selectList(InfraDemoStudentContactDO::getStudentId, studentId);
  19 + }
  20 +
  21 + default List<InfraDemoStudentContactDO> selectListByStudentId(List<Long> studentIds) {
  22 + return selectList(InfraDemoStudentContactDO::getStudentId, studentIds);
  23 + }
  24 +
  25 + default int deleteByStudentId(Long studentId) {
  26 + return delete(InfraDemoStudentContactDO::getStudentId, studentId);
  27 + }
  28 +
  29 +}
0 30 \ No newline at end of file
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/mysql/demo02/InfraDemoStudentMapper.java 0 → 100644
  1 +package cn.iocoder.yudao.module.infra.dal.mysql.demo02;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  4 +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
  5 +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
  6 +import cn.iocoder.yudao.module.infra.controller.admin.demo02.vo.InfraDemoStudentExportReqVO;
  7 +import cn.iocoder.yudao.module.infra.controller.admin.demo02.vo.InfraDemoStudentPageReqVO;
  8 +import cn.iocoder.yudao.module.infra.dal.dataobject.demo02.InfraDemoStudentDO;
  9 +import org.apache.ibatis.annotations.Mapper;
  10 +
  11 +import java.util.List;
  12 +
  13 +/**
  14 + * 学生 Mapper
  15 + *
  16 + * @author 芋道源码
  17 + */
  18 +@Mapper
  19 +public interface InfraDemoStudentMapper extends BaseMapperX<InfraDemoStudentDO> {
  20 +
  21 + default PageResult<InfraDemoStudentDO> selectPage(InfraDemoStudentPageReqVO reqVO) {
  22 + return selectPage(reqVO, new LambdaQueryWrapperX<InfraDemoStudentDO>()
  23 + .orderByDesc(InfraDemoStudentDO::getId));
  24 + }
  25 +
  26 + default List<InfraDemoStudentDO> selectList(InfraDemoStudentExportReqVO reqVO) {
  27 + return selectList(new LambdaQueryWrapperX<InfraDemoStudentDO>()
  28 + .orderByDesc(InfraDemoStudentDO::getId));
  29 + }
  30 +
  31 +}
0 32 \ No newline at end of file
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/enums/codegen/CodegenTemplateTypeEnum.java
... ... @@ -12,9 +12,10 @@ import lombok.Getter;
12 12 @Getter
13 13 public enum CodegenTemplateTypeEnum {
14 14  
15   - CRUD(1), // 单表(增删改查)
  15 + ONE(1), // 单表(增删改查)
16 16 TREE(2), // 树表(增删改查)
17   - MASTER_SUB(3), // 主子表
  17 + MASTER(10), // 主子表 - 主表
  18 + SUB(11), // 主子表 - 子表
18 19 ;
19 20  
20 21 /**
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/codegen/CodegenServiceImpl.java
... ... @@ -238,13 +238,14 @@ public class CodegenServiceImpl implements CodegenService {
238 238 // 校验子表是否已经存在
239 239 CodegenTableDO subTable = null;
240 240 List<CodegenColumnDO> subColumns = null;
241   - if (table.getSubTableId() != null) {
242   - subTable = codegenTableMapper.selectById(table.getSubTableId());
243   - subColumns = codegenColumnMapper.selectListByTableId(table.getSubTableId());
  241 + if (table.getMasterTableId() != null) {
  242 + subTable = codegenTableMapper.selectById(table.getMasterTableId());
  243 + subColumns = codegenColumnMapper.selectListByTableId(table.getMasterTableId());
244 244 }
245 245  
246 246 // 执行生成
247   - return codegenEngine.execute(table, columns, subTable, subColumns);
  247 +// return codegenEngine.execute(table, columns, subTable, subColumns);
  248 + return codegenEngine.execute(table, columns, null, null);
248 249 }
249 250  
250 251 @Override
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/codegen/inner/CodegenBuilder.java
... ... @@ -118,7 +118,7 @@ public class CodegenBuilder {
118 118 table.setClassName(upperFirst(toCamelCase(subAfter(tableName, '_', false))));
119 119 // 去除结尾的表,作为类描述
120 120 table.setClassComment(StrUtil.removeSuffixIgnoreCase(table.getTableComment(), "表"));
121   - table.setTemplateType(CodegenTemplateTypeEnum.CRUD.getType());
  121 + table.setTemplateType(CodegenTemplateTypeEnum.ONE.getType());
122 122 }
123 123  
124 124 public List<CodegenColumnDO> buildColumns(Long tableId, List<TableField> tableFields) {
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/codegen/inner/CodegenEngine.java
1 1 package cn.iocoder.yudao.module.infra.service.codegen.inner;
2 2  
  3 +import cn.hutool.core.collection.CollUtil;
3 4 import cn.hutool.core.map.MapUtil;
4 5 import cn.hutool.core.util.ObjUtil;
5 6 import cn.hutool.core.util.StrUtil;
... ... @@ -186,12 +187,12 @@ public class CodegenEngine {
186 187 *
187 188 * @param table 表定义
188 189 * @param columns table 的字段定义数组
189   - * @param subTable 子表定义,当且仅当主子表时使用
190   - * @param subColumns subTable 的字段定义数组
  190 + * @param subTables 子表数组,当且仅当主子表时使用
  191 + * @param subColumnsList subTables 的字段定义数组
191 192 * @return 生成的代码,key 是路径,value 是对应代码
192 193 */
193 194 public Map<String, String> execute(CodegenTableDO table, List<CodegenColumnDO> columns,
194   - CodegenTableDO subTable, List<CodegenColumnDO> subColumns) {
  195 + List<CodegenTableDO> subTables, List<List<CodegenColumnDO>> subColumnsList) {
195 196 // 创建 bindingMap
196 197 Map<String, Object> bindingMap = new HashMap<>(globalBindingMap);
197 198 bindingMap.put("table", table);
... ... @@ -212,27 +213,51 @@ public class CodegenEngine {
212 213 bindingMap.put("permissionPrefix", table.getModuleName() + ":" + simpleClassNameStrikeCase);
213 214  
214 215 // 特殊:主子表专属逻辑
215   - if (subTable != null) {
  216 + if (CollUtil.isNotEmpty(subTables)) {
216 217 // 创建 bindingMap
217   - bindingMap.put("subTable", subTable);
218   - bindingMap.put("subColumns", subColumns);
219   - bindingMap.put("subColumn", CollectionUtils.findFirst(subColumns, // 关联的字段
220   - column -> Objects.equals(column.getId(), table.getSubColumnId())));
221   - // className 相关
222   - String subSimpleClassName = removePrefix(subTable.getClassName(), upperFirst(subTable.getModuleName()));
223   - bindingMap.put("subSimpleClassName", subSimpleClassName);
224   - bindingMap.put("subClassNameVar", lowerFirst(subSimpleClassName)); // 将 DictType 转换成 dictType,用于变量
  218 + bindingMap.put("subTables", subTables);
  219 + bindingMap.put("subColumnsList", subColumnsList);
  220 + List<CodegenColumnDO> subJoinColumns = new ArrayList<>();
  221 + List<String> subSimpleClassNames = new ArrayList<>();
  222 + List<String> subClassNameVars = new ArrayList<>();
  223 + for (int i = 0; i < subTables.size(); i++) {
  224 + CodegenTableDO subTable = subTables.get(i);
  225 + List<CodegenColumnDO> subColumns = subColumnsList.get(i);
  226 + subJoinColumns.add(CollectionUtils.findFirst(subColumns, // 关联的字段
  227 + column -> Objects.equals(column.getId(), subTable.getSubJoinColumnId())));
  228 + // className 相关
  229 + String subSimpleClassName = removePrefix(subTable.getClassName(), upperFirst(subTable.getModuleName()));
  230 + subSimpleClassNames.add(subSimpleClassName);
  231 + subClassNameVars.add(lowerFirst(subSimpleClassName)); // 将 DictType 转换成 dictType,用于变量
  232 + }
  233 + bindingMap.put("subJoinColumns", subJoinColumns);
  234 + bindingMap.put("subSimpleClassNames", subSimpleClassNames);
  235 + bindingMap.put("subClassNameVars", subClassNameVars);
225 236 }
226 237  
227 238 // 执行生成
228 239 Map<String, String> templates = getTemplates(table.getTemplateType(), table.getFrontType());
229 240 Map<String, String> result = Maps.newLinkedHashMapWithExpectedSize(templates.size()); // 有序
230 241 templates.forEach((vmPath, filePath) -> {
231   - filePath = formatFilePath(filePath, bindingMap);
232   - String content = templateEngine.getTemplate(vmPath).render(bindingMap);
233   - // 去除字段后面多余的 , 逗号
234   - content = content.replaceAll(",\n}", "\n}").replaceAll(",\n }", "\n }");
235   - result.put(filePath, content);
  242 + // 特殊:主子表专属逻辑
  243 + if (isSubTemplate(vmPath)) {
  244 + for (int i = 0; i < subTables.size(); i++) {
  245 + bindingMap.put("subIndex", i);
  246 + // TODO 芋艿:这块需要优化下逻辑
  247 + String newFilePath = formatFilePath(filePath, bindingMap);
  248 + String content = templateEngine.getTemplate(vmPath).render(bindingMap);
  249 + // 去除字段后面多余的 , 逗号
  250 + content = content.replaceAll(",\n}", "\n}").replaceAll(",\n }", "\n }");
  251 + result.put(newFilePath, content);
  252 + bindingMap.remove("subIndex");
  253 + }
  254 + } else {
  255 + filePath = formatFilePath(filePath, bindingMap);
  256 + String content = templateEngine.getTemplate(vmPath).render(bindingMap);
  257 + // 去除字段后面多余的 , 逗号
  258 + content = content.replaceAll(",\n}", "\n}").replaceAll(",\n }", "\n }");
  259 + result.put(filePath, content);
  260 + }
236 261 });
237 262 return result;
238 263 }
... ... @@ -242,7 +267,7 @@ public class CodegenEngine {
242 267 templates.putAll(SERVER_TEMPLATES);
243 268 templates.putAll(FRONT_TEMPLATES.row(frontType));
244 269 // 特殊:主子表专属逻辑
245   - if (ObjUtil.notEqual(templateType, CodegenTemplateTypeEnum.MASTER_SUB.getType())) {
  270 + if (ObjUtil.notEqual(templateType, CodegenTemplateTypeEnum.MASTER.getType())) {
246 271 templates.remove(javaTemplatePath("dal/do_sub"));
247 272 templates.remove(javaTemplatePath("dal/mapper_sub"));
248 273 }
... ... @@ -266,8 +291,11 @@ public class CodegenEngine {
266 291 filePath = StrUtil.replace(filePath, "${table.businessName}", table.getBusinessName());
267 292 filePath = StrUtil.replace(filePath, "${table.className}", table.getClassName());
268 293 // 特殊:主子表专属逻辑
269   - CodegenTableDO subTable = (CodegenTableDO) bindingMap.get("subTable");
270   - if (subTable != null) {
  294 + Integer subIndex = (Integer) bindingMap.get("subIndex");
  295 + if (subIndex != null) {
  296 + CodegenTableDO subTable = ((List<CodegenTableDO>) bindingMap.get("subTables")).get(subIndex);
  297 + filePath = StrUtil.replace(filePath, "${subTable.moduleName}", subTable.getModuleName());
  298 + filePath = StrUtil.replace(filePath, "${subTable.businessName}", subTable.getBusinessName());
271 299 filePath = StrUtil.replace(filePath, "${subTable.className}", subTable.getClassName());
272 300 }
273 301 return filePath;
... ... @@ -336,4 +364,8 @@ public class CodegenEngine {
336 364 private static String vue3VbenTemplatePath(String path) {
337 365 return "codegen/vue3_vben/" + path + ".vm";
338 366 }
  367 +
  368 + private static boolean isSubTemplate(String path) {
  369 + return path.contains("_sub");
  370 + }
339 371 }
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/demo02/InfraDemoStudentService.java 0 → 100644
  1 +package cn.iocoder.yudao.module.infra.service.demo02;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  4 +import cn.iocoder.yudao.module.infra.controller.admin.demo02.vo.InfraDemoStudentCreateReqVO;
  5 +import cn.iocoder.yudao.module.infra.controller.admin.demo02.vo.InfraDemoStudentExportReqVO;
  6 +import cn.iocoder.yudao.module.infra.controller.admin.demo02.vo.InfraDemoStudentPageReqVO;
  7 +import cn.iocoder.yudao.module.infra.controller.admin.demo02.vo.InfraDemoStudentUpdateReqVO;
  8 +import cn.iocoder.yudao.module.infra.dal.dataobject.demo02.InfraDemoStudentDO;
  9 +
  10 +import javax.validation.Valid;
  11 +import java.util.Collection;
  12 +import java.util.List;
  13 +
  14 +/**
  15 + * 学生 Service 接口
  16 + *
  17 + * @author 芋道源码
  18 + */
  19 +public interface InfraDemoStudentService {
  20 +
  21 + /**
  22 + * 创建学生
  23 + *
  24 + * @param createReqVO 创建信息
  25 + * @return 编号
  26 + */
  27 + Long createDemoStudent(@Valid InfraDemoStudentCreateReqVO createReqVO);
  28 +
  29 + /**
  30 + * 更新学生
  31 + *
  32 + * @param updateReqVO 更新信息
  33 + */
  34 + void updateDemoStudent(@Valid InfraDemoStudentUpdateReqVO updateReqVO);
  35 +
  36 + /**
  37 + * 删除学生
  38 + *
  39 + * @param id 编号
  40 + */
  41 + void deleteDemoStudent(Long id);
  42 +
  43 + /**
  44 + * 获得学生
  45 + *
  46 + * @param id 编号
  47 + * @return 学生
  48 + */
  49 + InfraDemoStudentDO getDemoStudent(Long id);
  50 +
  51 + /**
  52 + * 获得学生分页
  53 + *
  54 + * @param pageReqVO 分页查询
  55 + * @return 学生分页
  56 + */
  57 + PageResult<InfraDemoStudentDO> getDemoStudentPage(InfraDemoStudentPageReqVO pageReqVO);
  58 +
  59 + /**
  60 + * 获得学生列表, 用于 Excel 导出
  61 + *
  62 + * @param exportReqVO 查询条件
  63 + * @return 学生列表
  64 + */
  65 + List<InfraDemoStudentDO> getDemoStudentList(InfraDemoStudentExportReqVO exportReqVO);
  66 +
  67 +
  68 +}
0 69 \ No newline at end of file
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/demo02/InfraDemoStudentServiceImpl.java 0 → 100644
  1 +package cn.iocoder.yudao.module.infra.service.demo02;
  2 +
  3 +import org.springframework.stereotype.Service;
  4 +import javax.annotation.Resource;
  5 +import org.springframework.validation.annotation.Validated;
  6 +import org.springframework.transaction.annotation.Transactional;
  7 +
  8 +import java.util.*;
  9 +import cn.iocoder.yudao.module.infra.controller.admin.demo02.vo.*;
  10 +import cn.iocoder.yudao.module.infra.dal.dataobject.demo02.InfraDemoStudentDO;
  11 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  12 +
  13 +import cn.iocoder.yudao.module.infra.convert.demo02.InfraDemoStudentConvert;
  14 +import cn.iocoder.yudao.module.infra.dal.mysql.demo02.InfraDemoStudentMapper;
  15 +import cn.iocoder.yudao.module.infra.dal.mysql.demo02.InfraDemoStudentContactMapper;
  16 +import cn.iocoder.yudao.module.infra.dal.mysql.demo02.InfraDemoStudentAddressMapper;
  17 +
  18 +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
  19 +import static cn.iocoder.yudao.module.infra.enums.ErrorCodeConstants.*;
  20 +
  21 +import cn.hutool.core.collection.CollUtil;
  22 +import cn.hutool.core.collection.ListUtil;
  23 +
  24 +/**
  25 + * 学生 Service 实现类
  26 + *
  27 + * @author 芋道源码
  28 + */
  29 +@Service
  30 +@Validated
  31 +public class InfraDemoStudentServiceImpl implements InfraDemoStudentService {
  32 +
  33 + @Resource
  34 + private InfraDemoStudentMapper demoStudentMapper;
  35 + @Resource
  36 + private InfraDemoStudentContactMapper demoStudentContactMapper;
  37 + @Resource
  38 + private InfraDemoStudentAddressMapper demoStudentAddressMapper;
  39 +
  40 + @Override
  41 + @Transactional(rollbackFor = Exception.class)
  42 + public Long createDemoStudent(InfraDemoStudentCreateReqVO createReqVO) {
  43 + // 插入
  44 + InfraDemoStudentDO demoStudent = InfraDemoStudentConvert.INSTANCE.convert(createReqVO);
  45 + demoStudentMapper.insert(demoStudent);
  46 + // 插入子表(学生联系人)
  47 + createReqVO.getDemoStudentContacts().forEach(o -> o.setStudentId(demoStudent.getId()));
  48 + demoStudentContactMapper.insertBatch(createReqVO.getDemoStudentContacts());
  49 + // 插入子表(学生地址)
  50 + createReqVO.getDemoStudentAddress().setStudentId(demoStudent.getId());
  51 + demoStudentAddressMapper.insert(createReqVO.getDemoStudentAddress());
  52 + // 返回
  53 + return demoStudent.getId();
  54 + }
  55 +
  56 + @Override
  57 + @Transactional(rollbackFor = Exception.class)
  58 + public void updateDemoStudent(InfraDemoStudentUpdateReqVO updateReqVO) {
  59 + // 校验存在
  60 + validateDemoStudentExists(updateReqVO.getId());
  61 + // 更新
  62 + InfraDemoStudentDO updateObj = InfraDemoStudentConvert.INSTANCE.convert(updateReqVO);
  63 + demoStudentMapper.updateById(updateObj);
  64 + // 更新子表(学生联系人)
  65 + demoStudentContactMapper.deleteByStudentId(updateReqVO.getId());
  66 + updateReqVO.getDemoStudentContacts().forEach(o -> o.setStudentId(updateReqVO.getId()));
  67 + demoStudentContactMapper.insertBatch(updateReqVO.getDemoStudentContacts());
  68 + // 更新子表(学生地址)
  69 + updateReqVO.getDemoStudentAddress().setStudentId(updateReqVO.getId());
  70 + demoStudentAddressMapper.updateById(updateReqVO.getDemoStudentAddress());
  71 + }
  72 +
  73 + @Override
  74 + @Transactional(rollbackFor = Exception.class)
  75 + public void deleteDemoStudent(Long id) {
  76 + // 校验存在
  77 + validateDemoStudentExists(id);
  78 + // 删除
  79 + demoStudentMapper.deleteById(id);
  80 + // 删除子表(学生联系人)
  81 + demoStudentContactMapper.deleteByStudentId(id);
  82 + // 删除子表(学生地址)
  83 + demoStudentAddressMapper.deleteByStudentId(id);
  84 + }
  85 +
  86 + private void validateDemoStudentExists(Long id) {
  87 + if (demoStudentMapper.selectById(id) == null) {
  88 + throw exception(DEMO_STUDENT_NOT_EXISTS);
  89 + }
  90 + }
  91 +
  92 + @Override
  93 + public InfraDemoStudentDO getDemoStudent(Long id) {
  94 + return demoStudentMapper.selectById(id);
  95 + }
  96 +
  97 + @Override
  98 + public PageResult<InfraDemoStudentDO> getDemoStudentPage(InfraDemoStudentPageReqVO pageReqVO) {
  99 + return demoStudentMapper.selectPage(pageReqVO);
  100 + }
  101 +
  102 + @Override
  103 + public List<InfraDemoStudentDO> getDemoStudentList(InfraDemoStudentExportReqVO exportReqVO) {
  104 + return demoStudentMapper.selectList(exportReqVO);
  105 + }
  106 +
  107 +}
0 108 \ No newline at end of file
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/controller/controller.vm
... ... @@ -76,16 +76,6 @@ public class ${sceneEnum.prefixClass}${table.className}Controller {
76 76 return success(${table.className}Convert.INSTANCE.convert(${classNameVar}));
77 77 }
78 78  
79   - @GetMapping("/list")
80   - @Operation(summary = "获得${table.classComment}列表")
81   - @Parameter(name = "ids", description = "编号列表", required = true, example = "1024,2048")
82   -#if ($sceneEnum.scene == 1) @PreAuthorize("@ss.hasPermission('${permissionPrefix}:query')")#end
83   -
84   - public CommonResult<List<${sceneEnum.prefixClass}${table.className}RespVO>> get${simpleClassName}List(@RequestParam("ids") Collection<${primaryColumn.javaType}> ids) {
85   - List<${table.className}DO> list = ${classNameVar}Service.get${simpleClassName}List(ids);
86   - return success(${table.className}Convert.INSTANCE.convertList(list));
87   - }
88   -
89 79 @GetMapping("/page")
90 80 @Operation(summary = "获得${table.classComment}分页")
91 81 #if ($sceneEnum.scene == 1) @PreAuthorize("@ss.hasPermission('${permissionPrefix}:query')")#end
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/controller/vo/baseVO.vm
... ... @@ -23,7 +23,7 @@ import static ${DateUtilsClassName}.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
23 23 #end
24 24 #end
25 25 ## 特殊:主子表专属逻辑
26   -#if ( $subTable )
  26 +#foreach ($subTable in $subTables)
27 27 import ${basePackage}.module.${subTable.moduleName}.dal.dataobject.${subTable.businessName}.${subTable.className}DO;
28 28 #end
29 29  
... ... @@ -41,8 +41,14 @@ public class ${sceneEnum.prefixClass}${table.className}BaseVO {
41 41 #end
42 42 #end
43 43 ## 特殊:主子表专属逻辑
44   -#if ( $subTable )
45   - private List<${subTable.className}DO> ${subClassNameVar}s;
  44 +#foreach ($subTable in $subTables)
  45 +#set ($index = $foreach.count - 1)
  46 + #if ( $subTable.subJoinMany)
  47 + private List<${subTable.className}DO> ${subClassNameVars.get($index)}s;
46 48  
  49 + #else
  50 + private ${subTable.className}DO ${subClassNameVars.get($index)};
  51 +
  52 + #end
47 53 #end
48 54 }
49 55 \ No newline at end of file
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/dal/do_sub.vm
  1 +#set ($subTable = $subTables.get($subIndex))##当前表
  2 +#set ($subColumns = $subColumnsList.get($subIndex))##当前字段数组
1 3 package ${basePackage}.module.${subTable.moduleName}.dal.dataobject.${subTable.businessName};
2 4  
3 5 import lombok.*;
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/dal/mapper_sub.vm
  1 +#set ($subTable = $subTables.get($subIndex))##当前表
  2 +#set ($subColumns = $subJoinColumnsList.get($subIndex))##当前字段数组
  3 +#set ($subJoinColumn = $subJoinColumns.get($subIndex))##当前 join 字段
  4 +#set ($SubJoinColumnName = $subJoinColumn.javaField.substring(0,1).toUpperCase() + ${subJoinColumn.javaField.substring(1)})##首字母大写
1 5 package ${basePackage}.module.${subTable.moduleName}.dal.mysql.${subTable.businessName};
2 6  
3 7 import java.util.*;
... ... @@ -6,7 +10,6 @@ import ${BaseMapperClassName};
6 10 import ${basePackage}.module.${subTable.moduleName}.dal.dataobject.${subTable.businessName}.${subTable.className}DO;
7 11 import org.apache.ibatis.annotations.Mapper;
8 12  
9   -#set ($SubColumnName = $subColumn.javaField.substring(0,1).toUpperCase() + ${subColumn.javaField.substring(1)})##首字母大写
10 13 /**
11 14 * ${subTable.classComment} Mapper
12 15 *
... ... @@ -15,12 +18,23 @@ import org.apache.ibatis.annotations.Mapper;
15 18 @Mapper
16 19 public interface ${subTable.className}Mapper extends BaseMapperX<${subTable.className}DO> {
17 20  
18   - default List<${subTable.className}DO> selectListBy${SubColumnName}(${subColumn.javaType} ${subColumn.javaField}) {
19   - return selectList(${subTable.className}DO::get${SubColumnName}, ${subColumn.javaField});
  21 +#if ( $subTable.subJoinMany)
  22 + default List<${subTable.className}DO> selectListBy${SubJoinColumnName}(${subJoinColumn.javaType} ${subJoinColumn.javaField}) {
  23 + return selectList(${subTable.className}DO::get${SubJoinColumnName}, ${subJoinColumn.javaField});
20 24 }
21 25  
22   - default List<${subTable.className}DO> selectListBy${SubColumnName}(List<${subColumn.javaType}> ${subColumn.javaField}s) {
23   - return selectList(${subTable.className}DO::get${SubColumnName}, ${subColumn.javaField}s);
  26 +#else
  27 + default ${subTable.className}DO selectBy${SubJoinColumnName}(${subJoinColumn.javaType} ${subJoinColumn.javaField}) {
  28 + return selectOne(${subTable.className}DO::get${SubJoinColumnName}, ${subJoinColumn.javaField});
  29 + }
  30 +
  31 +#end
  32 + default List<${subTable.className}DO> selectListBy${SubJoinColumnName}(List<${subJoinColumn.javaType}> ${subJoinColumn.javaField}s) {
  33 + return selectList(${subTable.className}DO::get${SubJoinColumnName}, ${subJoinColumn.javaField}s);
  34 + }
  35 +
  36 + default int deleteBy${SubJoinColumnName}(${subJoinColumn.javaType} ${subJoinColumn.javaField}) {
  37 + return delete(${subTable.className}DO::get${SubJoinColumnName}, ${subJoinColumn.javaField});
24 38 }
25 39  
26 40 }
27 41 \ No newline at end of file
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/service/service.vm
... ... @@ -44,14 +44,6 @@ public interface ${table.className}Service {
44 44 ${table.className}DO get${simpleClassName}(${primaryColumn.javaType} id);
45 45  
46 46 /**
47   - * 获得${table.classComment}列表
48   - *
49   - * @param ids 编号
50   - * @return ${table.classComment}列表
51   - */
52   - List<${table.className}DO> get${simpleClassName}List(Collection<${primaryColumn.javaType}> ids);
53   -
54   - /**
55 47 * 获得${table.classComment}分页
56 48 *
57 49 * @param pageReqVO 分页查询
... ... @@ -67,4 +59,30 @@ public interface ${table.className}Service {
67 59 */
68 60 List<${table.className}DO> get${simpleClassName}List(${sceneEnum.prefixClass}${table.className}ExportReqVO exportReqVO);
69 61  
  62 +## 特殊:主子表专属逻辑
  63 +#foreach ($subTable in $subTables)
  64 +#set ($index = $foreach.count - 1)
  65 +#set ($subSimpleClassName = $subSimpleClassNames.get($index))
  66 +#set ($subJoinColumn = $subJoinColumns.get($index))##当前 join 字段
  67 +#set ($SubJoinColumnName = $subJoinColumn.javaField.substring(0,1).toUpperCase() + ${subJoinColumn.javaField.substring(1)})##首字母大写
  68 + #if ( $subTable.subJoinMany )
  69 + /**
  70 + * 获得${subTable.classComment}列表
  71 + *
  72 + * @param ${subJoinColumn.javaField} ${subJoinColumn.columnComment}
  73 + * @return ${subTable.classComment}列表
  74 + */
  75 + List<${subTable.className}DO> get${subSimpleClassName}ListBy${SubJoinColumnName}(${subJoinColumn.javaType} ${subJoinColumn.javaField});
  76 +
  77 + #else
  78 + /**
  79 + * 获得${subTable.classComment}
  80 + *
  81 + * @param ${subJoinColumn.javaField} ${subJoinColumn.columnComment}
  82 + * @return ${subTable.classComment}
  83 + */
  84 + ${subTable.className}DO get${subSimpleClassName}By${SubJoinColumnName}(${subJoinColumn.javaType} ${subJoinColumn.javaField});
  85 +
  86 + #end
  87 +#end
70 88 }
71 89 \ No newline at end of file
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/service/serviceImpl.vm
... ... @@ -3,6 +3,7 @@ package ${basePackage}.module.${table.moduleName}.service.${table.businessName};
3 3 import org.springframework.stereotype.Service;
4 4 import javax.annotation.Resource;
5 5 import org.springframework.validation.annotation.Validated;
  6 +import org.springframework.transaction.annotation.Transactional;
6 7  
7 8 import java.util.*;
8 9 import ${basePackage}.module.${table.moduleName}.controller.${sceneEnum.basePackage}.${table.businessName}.vo.*;
... ... @@ -16,8 +17,9 @@ import ${PageResultClassName};
16 17 import ${basePackage}.module.${table.moduleName}.convert.${table.businessName}.${table.className}Convert;
17 18 import ${basePackage}.module.${table.moduleName}.dal.mysql.${table.businessName}.${table.className}Mapper;
18 19 ## 特殊:主子表专属逻辑
19   -#if( $subTable )
20   -import ${basePackage}.module.${subTable.moduleName}.dal.mysql.${subTable.businessName}.${subClassNameVar}Mapper;
  20 +#foreach ($subTable in $subTables)
  21 +#set ($index = $foreach.count - 1)
  22 +import ${basePackage}.module.${subTable.moduleName}.dal.mysql.${subTable.businessName}.${subTable.className}Mapper;
21 23 #end
22 24  
23 25 import static ${ServiceExceptionUtilClassName}.exception;
... ... @@ -38,40 +40,85 @@ public class ${table.className}ServiceImpl implements ${table.className}Service
38 40 @Resource
39 41 private ${table.className}Mapper ${classNameVar}Mapper;
40 42 ## 特殊:主子表专属逻辑
41   -#if( $subTable )
  43 +#foreach ($subTable in $subTables)
  44 +#set ($index = $foreach.count - 1)
42 45 @Resource
43   - private ${subTable.className}Mapper ${subClassNameVar}Mapper;
  46 + private ${subTable.className}Mapper ${subClassNameVars.get($index)}Mapper;
44 47 #end
45 48  
46 49 @Override
  50 +## 特殊:主子表专属逻辑
  51 +#if ( $subTables.size() > 0)
  52 + @Transactional(rollbackFor = Exception.class)
  53 +#end
47 54 public ${primaryColumn.javaType} create${simpleClassName}(${sceneEnum.prefixClass}${table.className}CreateReqVO createReqVO) {
48 55 // 插入
49 56 ${table.className}DO ${classNameVar} = ${table.className}Convert.INSTANCE.convert(createReqVO);
50 57 ${classNameVar}Mapper.insert(${classNameVar});
51 58 ## 特殊:主子表专属逻辑
52   -#if( $subTable )
53   - // 插入子表
54   - ${subClassNameVar}Mapper.insertBatch(createReqVO.get${subSimpleClassName}s);
  59 +#foreach ($subTable in $subTables)
  60 +#set ($index = $foreach.count - 1)
  61 +#set ($subJoinColumn = $subJoinColumns.get($index))##当前 join 字段
  62 +#set ($SubJoinColumnName = $subJoinColumn.javaField.substring(0,1).toUpperCase() + ${subJoinColumn.javaField.substring(1)})##首字母大写
  63 + // 插入子表($subTable.classComment)
  64 + #if ( $subTable.subJoinMany)
  65 + createReqVO.get${subSimpleClassNames.get($index)}s().forEach(o -> o.set$SubJoinColumnName(${classNameVar}.getId()));
  66 + ${subClassNameVars.get($index)}Mapper.insertBatch(createReqVO.get${subSimpleClassNames.get($index)}s());
  67 + #else
  68 + createReqVO.get${subSimpleClassNames.get($index)}().set$SubJoinColumnName(${classNameVar}.getId());
  69 + ${subClassNameVars.get($index)}Mapper.insert(createReqVO.get${subSimpleClassNames.get($index)}());
  70 + #end
55 71 #end
56 72 // 返回
57 73 return ${classNameVar}.getId();
58 74 }
59 75  
60 76 @Override
  77 +## 特殊:主子表专属逻辑
  78 +#if ( $subTables.size() > 0)
  79 + @Transactional(rollbackFor = Exception.class)
  80 +#end
61 81 public void update${simpleClassName}(${sceneEnum.prefixClass}${table.className}UpdateReqVO updateReqVO) {
62 82 // 校验存在
63 83 validate${simpleClassName}Exists(updateReqVO.getId());
64 84 // 更新
65 85 ${table.className}DO updateObj = ${table.className}Convert.INSTANCE.convert(updateReqVO);
66 86 ${classNameVar}Mapper.updateById(updateObj);
  87 +## 特殊:主子表专属逻辑
  88 +#foreach ($subTable in $subTables)
  89 +#set ($index = $foreach.count - 1)
  90 +#set ($subJoinColumn = $subJoinColumns.get($index))##当前 join 字段
  91 +#set ($SubJoinColumnName = $subJoinColumn.javaField.substring(0,1).toUpperCase() + ${subJoinColumn.javaField.substring(1)})##首字母大写
  92 + // 更新子表($subTable.classComment)
  93 + #if ( $subTable.subJoinMany)
  94 + ${subClassNameVars.get($index)}Mapper.deleteBy${SubJoinColumnName}(updateReqVO.getId());
  95 + updateReqVO.get${subSimpleClassNames.get($index)}s().forEach(o -> o.set$SubJoinColumnName(updateReqVO.getId()));
  96 + ${subClassNameVars.get($index)}Mapper.insertBatch(updateReqVO.get${subSimpleClassNames.get($index)}s());
  97 + #else
  98 + updateReqVO.get${subSimpleClassNames.get($index)}().set$SubJoinColumnName(updateReqVO.getId());
  99 + ${subClassNameVars.get($index)}Mapper.updateById(updateReqVO.get${subSimpleClassNames.get($index)}());
  100 + #end
  101 +#end
67 102 }
68 103  
69 104 @Override
  105 +## 特殊:主子表专属逻辑
  106 +#if ( $subTables.size() > 0)
  107 + @Transactional(rollbackFor = Exception.class)
  108 +#end
70 109 public void delete${simpleClassName}(${primaryColumn.javaType} id) {
71 110 // 校验存在
72 111 validate${simpleClassName}Exists(id);
73 112 // 删除
74 113 ${classNameVar}Mapper.deleteById(id);
  114 +## 特殊:主子表专属逻辑
  115 +#foreach ($subTable in $subTables)
  116 +#set ($index = $foreach.count - 1)
  117 +#set ($subJoinColumn = $subJoinColumns.get($index))##当前 join 字段
  118 +#set ($SubJoinColumnName = $subJoinColumn.javaField.substring(0,1).toUpperCase() + ${subJoinColumn.javaField.substring(1)})##首字母大写
  119 + // 删除子表($subTable.classComment)
  120 + ${subClassNameVars.get($index)}Mapper.deleteBy${SubJoinColumnName}(id);
  121 +#end
75 122 }
76 123  
77 124 private void validate${simpleClassName}Exists(${primaryColumn.javaType} id) {
... ... @@ -86,14 +133,6 @@ public class ${table.className}ServiceImpl implements ${table.className}Service
86 133 }
87 134  
88 135 @Override
89   - public List<${table.className}DO> get${simpleClassName}List(Collection<${primaryColumn.javaType}> ids) {
90   - if (CollUtil.isEmpty(ids)) {
91   - return ListUtil.empty();
92   - }
93   - return ${classNameVar}Mapper.selectBatchIds(ids);
94   - }
95   -
96   - @Override
97 136 public PageResult<${table.className}DO> get${simpleClassName}Page(${sceneEnum.prefixClass}${table.className}PageReqVO pageReqVO) {
98 137 return ${classNameVar}Mapper.selectPage(pageReqVO);
99 138 }
... ...
yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/service/codegen/inner/CodegenEngineTest.java
... ... @@ -31,7 +31,7 @@ public class CodegenEngineTest extends BaseMockitoUnitTest {
31 31  
32 32 @Spy
33 33 private CodegenProperties codegenProperties = new CodegenProperties()
34   - .setBasePackage("cn.iocoder.yudao.module");
  34 + .setBasePackage("cn.iocoder.yudao");
35 35  
36 36 @BeforeEach
37 37 public void setUp() {
... ... @@ -45,7 +45,7 @@ public class CodegenEngineTest extends BaseMockitoUnitTest {
45 45 .setTableName("system_user").setTableComment("用户表")
46 46 .setModuleName("system").setBusinessName("user").setClassName("SystemUser")
47 47 .setClassComment("用户").setAuthor("芋道源码")
48   - .setTemplateType(CodegenTemplateTypeEnum.CRUD.getType())
  48 + .setTemplateType(CodegenTemplateTypeEnum.ONE.getType())
49 49 .setFrontType(CodegenFrontTypeEnum.VUE3.getType())
50 50 .setParentMenuId(10L);
51 51 CodegenColumnDO idColumn = new CodegenColumnDO().setColumnName("id").setDataType(JdbcType.BIGINT.name())
... ... @@ -125,32 +125,32 @@ public class CodegenEngineTest extends BaseMockitoUnitTest {
125 125 for (String vo : new String[]{"SystemUserBaseVO", "SystemUserCreateReqVO", "SystemUserUpdateReqVO", "SystemUserRespVO",
126 126 "SystemUserPageReqVO", "SystemUserExportReqVO", "SystemUserExcelVO"}) {
127 127 assertPathContentEquals("vue3_crud/java/" + vo,
128   - result, "yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/module/system/controller/admin/user/vo/" + vo + ".java");
  128 + result, "yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/" + vo + ".java");
129 129 }
130 130 // 断言 controller 类
131 131 assertPathContentEquals("vue3_crud/java/SystemUserController",
132   - result, "yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/module/system/controller/admin/user/SystemUserController.java");
  132 + result, "yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/SystemUserController.java");
133 133 // 断言 service 类
134 134 assertPathContentEquals("vue3_crud/java/SystemUserService",
135   - result, "yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/module/system/service/user/SystemUserService.java");
  135 + result, "yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/SystemUserService.java");
136 136 assertPathContentEquals("vue3_crud/java/SystemUserServiceImpl",
137   - result, "yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/module/system/service/user/SystemUserServiceImpl.java");
  137 + result, "yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/SystemUserServiceImpl.java");
138 138 // 断言 convert 类
139 139 assertPathContentEquals("vue3_crud/java/SystemUserConvert",
140   - result, "yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/module/system/convert/user/SystemUserConvert.java");
  140 + result, "yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/convert/user/SystemUserConvert.java");
141 141 // 断言 enums 类
142 142 assertPathContentEquals("vue3_crud/java/ErrorCodeConstants",
143   - result, "yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/module/system/enums/ErrorCodeConstants_手动操作.java");
  143 + result, "yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/ErrorCodeConstants_手动操作.java");
144 144 // 断言 dal 类
145 145 assertPathContentEquals("vue3_crud/java/SystemUserDO",
146   - result, "yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/module/system/dal/dataobject/user/SystemUserDO.java");
  146 + result, "yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/user/SystemUserDO.java");
147 147 assertPathContentEquals("vue3_crud/java/SystemUserMapper",
148   - result, "yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/module/system/dal/mysql/user/SystemUserMapper.java");
  148 + result, "yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/user/SystemUserMapper.java");
149 149 assertPathContentEquals("vue3_crud/java/SystemUserMapper_xml",
150 150 result, "yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/user/SystemUserMapper.xml");
151 151 // 断言 test 类
152 152 assertPathContentEquals("vue3_crud/java/SystemUserServiceImplTest",
153   - result, "yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/module/system/service/user/SystemUserServiceImplTest.java");
  153 + result, "yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/user/SystemUserServiceImplTest.java");
154 154 // 断言 sql 语句
155 155 assertPathContentEquals("vue3_crud/sql/h2",
156 156 result, "sql/h2.sql");
... ... @@ -170,73 +170,116 @@ public class CodegenEngineTest extends BaseMockitoUnitTest {
170 170 // 准备请求参数
171 171 // 主表
172 172 CodegenTableDO table = new CodegenTableDO().setScene(CodegenSceneEnum.ADMIN.getScene())
173   - .setTableName("system_user").setTableComment("用户表")
174   - .setModuleName("system").setBusinessName("user").setClassName("SystemUser")
175   - .setClassComment("用户").setAuthor("芋道源码")
176   - .setTemplateType(CodegenTemplateTypeEnum.MASTER_SUB.getType()).setSubColumnId(100L)
177   - .setFrontType(CodegenFrontTypeEnum.VUE3.getType())
178   - .setParentMenuId(10L);
  173 + .setTableName("infra_demo_student").setTableComment("学生表")
  174 + .setModuleName("infra").setBusinessName("demo02").setClassName("InfraDemoStudent")
  175 + .setClassComment("学生").setAuthor("芋道源码")
  176 + .setTemplateType(CodegenTemplateTypeEnum.MASTER.getType())
  177 + .setFrontType(CodegenFrontTypeEnum.VUE3.getType());
179 178 CodegenColumnDO idColumn = new CodegenColumnDO().setColumnName("id").setDataType(JdbcType.BIGINT.name())
180 179 .setColumnComment("编号").setNullable(false).setPrimaryKey(true).setAutoIncrement(true)
181 180 .setOrdinalPosition(1).setJavaType("Long").setJavaField("id").setExample("1024")
182 181 .setCreateOperation(false).setUpdateOperation(true).setListOperation(false)
183 182 .setListOperationResult(true);
  183 +
184 184 List<CodegenColumnDO> columns = Collections.singletonList(idColumn);
185   - // 子表
186   - CodegenTableDO subTable = new CodegenTableDO().setScene(CodegenSceneEnum.ADMIN.getScene())
187   - .setTableName("system_user_contact").setTableComment("用户联系人表")
188   - .setModuleName("system").setBusinessName("user").setClassName("SystemUserContact")
189   - .setClassComment("用户联系人").setAuthor("芋道源码")
190   - .setTemplateType(CodegenTemplateTypeEnum.CRUD.getType())
191   - .setFrontType(CodegenFrontTypeEnum.VUE3.getType());
192   - CodegenColumnDO subIdColumn = new CodegenColumnDO().setColumnName("id").setDataType(JdbcType.BIGINT.name())
  185 + // 子表(联系人)
  186 + CodegenTableDO contactTable = new CodegenTableDO().setScene(CodegenSceneEnum.ADMIN.getScene())
  187 + .setTableName("infra_demo_student_contact").setTableComment("学生联系人表")
  188 + .setModuleName("infra").setBusinessName("demo02").setClassName("InfraDemoStudentContact")
  189 + .setClassComment("学生联系人").setAuthor("芋道源码")
  190 + .setTemplateType(CodegenTemplateTypeEnum.SUB.getType())
  191 + .setFrontType(CodegenFrontTypeEnum.VUE3.getType())
  192 + .setSubJoinColumnId(100L).setSubJoinMany(true);
  193 + CodegenColumnDO contactIdColumn = new CodegenColumnDO().setColumnName("id").setDataType(JdbcType.BIGINT.name())
193 194 .setColumnComment("编号").setNullable(false).setPrimaryKey(true).setAutoIncrement(true)
194 195 .setOrdinalPosition(1).setJavaType("Long").setJavaField("id").setExample("1024")
195 196 .setCreateOperation(false).setUpdateOperation(true).setListOperation(false)
196 197 .setListOperationResult(true);
197   - CodegenColumnDO userIdColumn = new CodegenColumnDO().setColumnName("user_id").setDataType(JdbcType.BIGINT.name())
198   - .setColumnComment("用户编号").setNullable(false).setPrimaryKey(false)
199   - .setOrdinalPosition(2).setJavaType("Long").setJavaField("userId").setExample("2048")
  198 + CodegenColumnDO contactStudentIdColumn = new CodegenColumnDO().setColumnName("student_id").setDataType(JdbcType.BIGINT.name())
  199 + .setColumnComment("学生编号").setNullable(false).setPrimaryKey(false)
  200 + .setOrdinalPosition(2).setJavaType("Long").setJavaField("studentId").setExample("2048")
200 201 .setCreateOperation(false).setUpdateOperation(true).setListOperation(false)
201 202 .setListOperationResult(true)
202 203 .setId(100L);
203   - List<CodegenColumnDO> subColumns = Arrays.asList(subIdColumn, userIdColumn);
  204 + CodegenColumnDO contactNameColumn = new CodegenColumnDO().setColumnName("name").setDataType(JdbcType.VARCHAR.name())
  205 + .setColumnComment("名字").setNullable(false).setPrimaryKey(false)
  206 + .setOrdinalPosition(3).setJavaType("String").setJavaField("name").setExample("芋头")
  207 + .setCreateOperation(true).setUpdateOperation(true).setListOperation(true)
  208 + .setListOperationCondition(CodegenColumnListConditionEnum.LIKE.getCondition()).setListOperationResult(true)
  209 + .setHtmlType(CodegenColumnHtmlTypeEnum.INPUT.getType());
  210 + List<CodegenColumnDO> contactColumns = Arrays.asList(contactIdColumn, contactStudentIdColumn, contactNameColumn);
  211 + // 子表(地址)
  212 + CodegenTableDO addressTable = new CodegenTableDO().setScene(CodegenSceneEnum.ADMIN.getScene())
  213 + .setTableName("infra_demo_student_address").setTableComment("学生地址表")
  214 + .setModuleName("infra").setBusinessName("demo02").setClassName("InfraDemoStudentAddress")
  215 + .setClassComment("学生地址").setAuthor("芋道源码")
  216 + .setTemplateType(CodegenTemplateTypeEnum.SUB.getType())
  217 + .setFrontType(CodegenFrontTypeEnum.VUE3.getType())
  218 + .setSubJoinColumnId(200L).setSubJoinMany(false);
  219 + CodegenColumnDO addressIdColumn = new CodegenColumnDO().setColumnName("id").setDataType(JdbcType.BIGINT.name())
  220 + .setColumnComment("编号").setNullable(false).setPrimaryKey(true).setAutoIncrement(true)
  221 + .setOrdinalPosition(1).setJavaType("Long").setJavaField("id").setExample("1024")
  222 + .setCreateOperation(false).setUpdateOperation(true).setListOperation(false)
  223 + .setListOperationResult(true);
  224 + CodegenColumnDO addressStudentColumn = new CodegenColumnDO().setColumnName("student_id").setDataType(JdbcType.BIGINT.name())
  225 + .setColumnComment("学生编号").setNullable(false).setPrimaryKey(false)
  226 + .setOrdinalPosition(2).setJavaType("Long").setJavaField("studentId").setExample("2048")
  227 + .setCreateOperation(false).setUpdateOperation(true).setListOperation(false)
  228 + .setListOperationResult(true)
  229 + .setId(200L);
  230 + CodegenColumnDO addressDetailColumn = new CodegenColumnDO().setColumnName("detail").setDataType(JdbcType.VARCHAR.name())
  231 + .setColumnComment("明细").setNullable(false).setPrimaryKey(false)
  232 + .setOrdinalPosition(3).setJavaType("String").setJavaField("detail").setExample("码头路 88 号")
  233 + .setCreateOperation(true).setUpdateOperation(true).setListOperation(true)
  234 + .setListOperationCondition(CodegenColumnListConditionEnum.LIKE.getCondition()).setListOperationResult(true)
  235 + .setHtmlType(CodegenColumnHtmlTypeEnum.INPUT.getType());
  236 + List<CodegenColumnDO> addressColumns = Arrays.asList(addressIdColumn, addressStudentColumn, addressDetailColumn);
204 237  
205 238 // 调用
206   - Map<String, String> result = codegenEngine.execute(table, columns, subTable, subColumns);
  239 + Map<String, String> result = codegenEngine.execute(table, columns,
  240 + Arrays.asList(contactTable, addressTable), Arrays.asList(contactColumns, addressColumns));
207 241  
208 242 // 断言
209   - assertEquals(23, result.size());
  243 + assertEquals(25, result.size());
  244 +
  245 + for (Map.Entry<String, String> entry : result.entrySet()) {
  246 + System.out.println(entry.getKey());
  247 + System.out.println(entry.getValue());
  248 + System.out.println("");
  249 + System.out.println("");
  250 + System.out.println("");
  251 + }
  252 +
210 253 // // 断言 vo 类
211 254 // for (String vo : new String[]{"SystemUserBaseVO", "SystemUserCreateReqVO", "SystemUserUpdateReqVO", "SystemUserRespVO",
212 255 // "SystemUserPageReqVO", "SystemUserExportReqVO", "SystemUserExcelVO"}) {
213 256 // assertPathContentEquals("vue3_crud/java/" + vo,
214   -// result, "yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/module/system/controller/admin/user/vo/" + vo + ".java");
  257 +// result, "yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/" + vo + ".java");
215 258 // }
216 259 // // 断言 controller 类
217 260 // assertPathContentEquals("vue3_crud/java/SystemUserController",
218   -// result, "yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/module/system/controller/admin/user/SystemUserController.java");
  261 +// result, "yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/SystemUserController.java");
219 262 // // 断言 service 类
220 263 // assertPathContentEquals("vue3_crud/java/SystemUserService",
221   -// result, "yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/module/system/service/user/SystemUserService.java");
  264 +// result, "yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/SystemUserService.java");
222 265 // assertPathContentEquals("vue3_crud/java/SystemUserServiceImpl",
223   -// result, "yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/module/system/service/user/SystemUserServiceImpl.java");
  266 +// result, "yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/SystemUserServiceImpl.java");
224 267 // // 断言 convert 类
225 268 // assertPathContentEquals("vue3_crud/java/SystemUserConvert",
226   -// result, "yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/module/system/convert/user/SystemUserConvert.java");
  269 +// result, "yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/convert/user/SystemUserConvert.java");
227 270 // // 断言 enums 类
228 271 // assertPathContentEquals("vue3_crud/java/ErrorCodeConstants",
229   -// result, "yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/module/system/enums/ErrorCodeConstants_手动操作.java");
  272 +// result, "yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/ErrorCodeConstants_手动操作.java");
230 273 // // 断言 dal 类
231 274 // assertPathContentEquals("vue3_crud/java/SystemUserDO",
232   -// result, "yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/module/system/dal/dataobject/user/SystemUserDO.java");
  275 +// result, "yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/user/SystemUserDO.java");
233 276 // assertPathContentEquals("vue3_crud/java/SystemUserMapper",
234   -// result, "yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/module/system/dal/mysql/user/SystemUserMapper.java");
  277 +// result, "yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/user/SystemUserMapper.java");
235 278 // assertPathContentEquals("vue3_crud/java/SystemUserMapper_xml",
236 279 // result, "yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/user/SystemUserMapper.xml");
237 280 // // 断言 test 类
238 281 // assertPathContentEquals("vue3_crud/java/SystemUserServiceImplTest",
239   -// result, "yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/module/system/service/user/SystemUserServiceImplTest.java");
  282 +// result, "yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/user/SystemUserServiceImplTest.java");
240 283 // // 断言 sql 语句
241 284 // assertPathContentEquals("vue3_crud/sql/h2",
242 285 // result, "sql/h2.sql");
... ...
yudao-module-infra/yudao-module-infra-biz/src/test/resources/codegen/vue3_crud/java/SystemUserBaseVO
1   -package cn.iocoder.yudao.module.module.system.controller.admin.user.vo;
  1 +package cn.iocoder.yudao.module.system.controller.admin.user.vo;
2 2  
3 3 import io.swagger.v3.oas.annotations.media.Schema;
4 4 import lombok.*;
... ...
yudao-module-infra/yudao-module-infra-biz/src/test/resources/codegen/vue3_crud/java/SystemUserController
1   -package cn.iocoder.yudao.module.module.system.controller.admin.user;
  1 +package cn.iocoder.yudao.module.system.controller.admin.user;
2 2  
3 3 import org.springframework.web.bind.annotation.*;
4 4 import javax.annotation.Resource;
... ... @@ -23,10 +23,10 @@ import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
23 23 import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
24 24 import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.*;
25 25  
26   -import cn.iocoder.yudao.module.module.system.controller.admin.user.vo.*;
27   -import cn.iocoder.yudao.module.module.system.dal.dataobject.user.SystemUserDO;
28   -import cn.iocoder.yudao.module.module.system.convert.user.SystemUserConvert;
29   -import cn.iocoder.yudao.module.module.system.service.user.SystemUserService;
  26 +import cn.iocoder.yudao.module.system.controller.admin.user.vo.*;
  27 +import cn.iocoder.yudao.module.system.dal.dataobject.user.SystemUserDO;
  28 +import cn.iocoder.yudao.module.system.convert.user.SystemUserConvert;
  29 +import cn.iocoder.yudao.module.system.service.user.SystemUserService;
30 30  
31 31 @Tag(name = "管理后台 - 用户")
32 32 @RestController
... ...
yudao-module-infra/yudao-module-infra-biz/src/test/resources/codegen/vue3_crud/java/SystemUserConvert
1   -package cn.iocoder.yudao.module.module.system.convert.user;
  1 +package cn.iocoder.yudao.module.system.convert.user;
2 2  
3 3 import java.util.*;
4 4  
... ... @@ -6,8 +6,8 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
6 6  
7 7 import org.mapstruct.Mapper;
8 8 import org.mapstruct.factory.Mappers;
9   -import cn.iocoder.yudao.module.module.system.controller.admin.user.vo.*;
10   -import cn.iocoder.yudao.module.module.system.dal.dataobject.user.SystemUserDO;
  9 +import cn.iocoder.yudao.module.system.controller.admin.user.vo.*;
  10 +import cn.iocoder.yudao.module.system.dal.dataobject.user.SystemUserDO;
11 11  
12 12 /**
13 13 * 用户 Convert
... ...
yudao-module-infra/yudao-module-infra-biz/src/test/resources/codegen/vue3_crud/java/SystemUserCreateReqVO
1   -package cn.iocoder.yudao.module.module.system.controller.admin.user.vo;
  1 +package cn.iocoder.yudao.module.system.controller.admin.user.vo;
2 2  
3 3 import lombok.*;
4 4 import java.util.*;
... ...
yudao-module-infra/yudao-module-infra-biz/src/test/resources/codegen/vue3_crud/java/SystemUserDO
1   -package cn.iocoder.yudao.module.module.system.dal.dataobject.user;
  1 +package cn.iocoder.yudao.module.system.dal.dataobject.user;
2 2  
3 3 import lombok.*;
4 4 import java.util.*;
... ...
yudao-module-infra/yudao-module-infra-biz/src/test/resources/codegen/vue3_crud/java/SystemUserExcelVO
1   -package cn.iocoder.yudao.module.module.system.controller.admin.user.vo;
  1 +package cn.iocoder.yudao.module.system.controller.admin.user.vo;
2 2  
3 3 import io.swagger.v3.oas.annotations.media.Schema;
4 4 import lombok.*;
... ...
yudao-module-infra/yudao-module-infra-biz/src/test/resources/codegen/vue3_crud/java/SystemUserExportReqVO
1   -package cn.iocoder.yudao.module.module.system.controller.admin.user.vo;
  1 +package cn.iocoder.yudao.module.system.controller.admin.user.vo;
2 2  
3 3 import lombok.*;
4 4 import java.util.*;
... ...
yudao-module-infra/yudao-module-infra-biz/src/test/resources/codegen/vue3_crud/java/SystemUserMapper
1   -package cn.iocoder.yudao.module.module.system.dal.mysql.user;
  1 +package cn.iocoder.yudao.module.system.dal.mysql.user;
2 2  
3 3 import java.util.*;
4 4  
5 5 import cn.iocoder.yudao.framework.common.pojo.PageResult;
6 6 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
7 7 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
8   -import cn.iocoder.yudao.module.module.system.dal.dataobject.user.SystemUserDO;
  8 +import cn.iocoder.yudao.module.system.dal.dataobject.user.SystemUserDO;
9 9 import org.apache.ibatis.annotations.Mapper;
10   -import cn.iocoder.yudao.module.module.system.controller.admin.user.vo.*;
  10 +import cn.iocoder.yudao.module.system.controller.admin.user.vo.*;
11 11  
12 12 /**
13 13 * 用户 Mapper
... ...
yudao-module-infra/yudao-module-infra-biz/src/test/resources/codegen/vue3_crud/java/SystemUserMapper_xml
1 1 <?xml version="1.0" encoding="UTF-8"?>
2 2 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
3   -<mapper namespace="cn.iocoder.yudao.module.module.system.dal.mysql.user.SystemUserMapper">
  3 +<mapper namespace="cn.iocoder.yudao.module.system.dal.mysql.user.SystemUserMapper">
4 4  
5 5 <!--
6 6 一般情况下,尽可能使用 Mapper 进行 CRUD 增删改查即可。
... ...
yudao-module-infra/yudao-module-infra-biz/src/test/resources/codegen/vue3_crud/java/SystemUserPageReqVO
1   -package cn.iocoder.yudao.module.module.system.controller.admin.user.vo;
  1 +package cn.iocoder.yudao.module.system.controller.admin.user.vo;
2 2  
3 3 import lombok.*;
4 4 import java.util.*;
... ...
yudao-module-infra/yudao-module-infra-biz/src/test/resources/codegen/vue3_crud/java/SystemUserRespVO
1   -package cn.iocoder.yudao.module.module.system.controller.admin.user.vo;
  1 +package cn.iocoder.yudao.module.system.controller.admin.user.vo;
2 2  
3 3 import io.swagger.v3.oas.annotations.media.Schema;
4 4 import lombok.*;
... ...
yudao-module-infra/yudao-module-infra-biz/src/test/resources/codegen/vue3_crud/java/SystemUserService
1   -package cn.iocoder.yudao.module.module.system.service.user;
  1 +package cn.iocoder.yudao.module.system.service.user;
2 2  
3 3 import java.util.*;
4 4 import javax.validation.*;
5   -import cn.iocoder.yudao.module.module.system.controller.admin.user.vo.*;
6   -import cn.iocoder.yudao.module.module.system.dal.dataobject.user.SystemUserDO;
  5 +import cn.iocoder.yudao.module.system.controller.admin.user.vo.*;
  6 +import cn.iocoder.yudao.module.system.dal.dataobject.user.SystemUserDO;
7 7 import cn.iocoder.yudao.framework.common.pojo.PageResult;
8 8  
9 9 /**
... ...
yudao-module-infra/yudao-module-infra-biz/src/test/resources/codegen/vue3_crud/java/SystemUserServiceImpl
1   -package cn.iocoder.yudao.module.module.system.service.user;
  1 +package cn.iocoder.yudao.module.system.service.user;
2 2  
3 3 import org.springframework.stereotype.Service;
4 4 import javax.annotation.Resource;
5 5 import org.springframework.validation.annotation.Validated;
6 6  
7 7 import java.util.*;
8   -import cn.iocoder.yudao.module.module.system.controller.admin.user.vo.*;
9   -import cn.iocoder.yudao.module.module.system.dal.dataobject.user.SystemUserDO;
  8 +import cn.iocoder.yudao.module.system.controller.admin.user.vo.*;
  9 +import cn.iocoder.yudao.module.system.dal.dataobject.user.SystemUserDO;
10 10 import cn.iocoder.yudao.framework.common.pojo.PageResult;
11 11  
12   -import cn.iocoder.yudao.module.module.system.convert.user.SystemUserConvert;
13   -import cn.iocoder.yudao.module.module.system.dal.mysql.user.SystemUserMapper;
  12 +import cn.iocoder.yudao.module.system.convert.user.SystemUserConvert;
  13 +import cn.iocoder.yudao.module.system.dal.mysql.user.SystemUserMapper;
14 14  
15 15 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
16   -import static cn.iocoder.yudao.module.module.system.enums.ErrorCodeConstants.*;
  16 +import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;
17 17  
18 18 import cn.hutool.core.collection.CollUtil;
19 19 import cn.hutool.core.collection.ListUtil;
... ...
yudao-module-infra/yudao-module-infra-biz/src/test/resources/codegen/vue3_crud/java/SystemUserServiceImplTest
1   -package cn.iocoder.yudao.module.module.system.service.user;
  1 +package cn.iocoder.yudao.module.system.service.user;
2 2  
3 3 import org.junit.jupiter.api.Disabled;
4 4 import org.junit.jupiter.api.Test;
... ... @@ -8,9 +8,9 @@ import javax.annotation.Resource;
8 8  
9 9 import cn.iocoder.yudao.module.framework.test.core.ut.BaseDbUnitTest;
10 10  
11   -import cn.iocoder.yudao.module.module.system.controller.admin.user.vo.*;
12   -import cn.iocoder.yudao.module.module.system.dal.dataobject.user.SystemUserDO;
13   -import cn.iocoder.yudao.module.module.system.dal.mysql.user.SystemUserMapper;
  11 +import cn.iocoder.yudao.module.system.controller.admin.user.vo.*;
  12 +import cn.iocoder.yudao.module.system.dal.dataobject.user.SystemUserDO;
  13 +import cn.iocoder.yudao.module.system.dal.mysql.user.SystemUserMapper;
14 14 import cn.iocoder.yudao.framework.common.pojo.PageResult;
15 15  
16 16 import javax.annotation.Resource;
... ... @@ -19,7 +19,7 @@ import java.util.*;
19 19 import java.time.LocalDateTime;
20 20  
21 21 import static cn.hutool.core.util.RandomUtil.*;
22   -import static cn.iocoder.yudao.module.module.system.enums.ErrorCodeConstants.*;
  22 +import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;
23 23 import static cn.iocoder.yudao.module.framework.test.core.util.AssertUtils.*;
24 24 import static cn.iocoder.yudao.module.framework.test.core.util.RandomUtils.*;
25 25 import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.*;
... ...
yudao-module-infra/yudao-module-infra-biz/src/test/resources/codegen/vue3_crud/java/SystemUserUpdateReqVO
1   -package cn.iocoder.yudao.module.module.system.controller.admin.user.vo;
  1 +package cn.iocoder.yudao.module.system.controller.admin.user.vo;
2 2  
3 3 import io.swagger.v3.oas.annotations.media.Schema;
4 4 import lombok.*;
... ...