Commit 256c560d43b5a2b6587916ab2cd800c9c0c0423c

Authored by YunaiV
1 parent e67a6a2f

代码生成:增加主子表的示例

Showing 24 changed files with 1219 additions and 151 deletions
yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/mapper/BaseMapperX.java
... ... @@ -128,7 +128,11 @@ public interface BaseMapperX<T> extends MPJBaseMapper<T> {
128 128 Db.updateBatchById(entities, size);
129 129 }
130 130  
131   - default void saveOrUpdateBatch(Collection<T> collection) {
  131 + default void insertOrUpdate(T entity) {
  132 + Db.saveOrUpdate(entity);
  133 + }
  134 +
  135 + default void insertOrUpdateBatch(Collection<T> collection) {
132 136 Db.saveOrUpdateBatch(collection);
133 137 }
134 138  
... ...
yudao-module-infra/yudao-module-infra-api/src/main/java/cn/iocoder/yudao/module/infra/enums/ErrorCodeConstants.java
... ... @@ -54,6 +54,10 @@ public interface ErrorCodeConstants {
54 54 // ========== 数据源配置 1-001-107-000 ==========
55 55 ErrorCode DEMO_STUDENT_NOT_EXISTS = new ErrorCode(1_001_107_000, "学生不存在");
56 56  
57   - // ========== 学生(CodegenTemplateTypeEnum.ONE 示例) 1-001-200-000 ==========
  57 + // ========== 学生(CodegenTemplateTypeEnum.ONE 示例) 1-001-201-000 ==========
58 58 ErrorCode DEMO01_STUDENT_NOT_EXISTS = new ErrorCode(1_001_200_000, "学生不存在");
  59 +
  60 + // ========== 学生(CodegenTemplateTypeEnum.ONE 示例) 1-001-211-000 ==========
  61 + ErrorCode DEMO11_STUDENT_NOT_EXISTS = new ErrorCode(1_001_211_000, "学生不存在");
  62 +
59 63 }
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/demo11/InfraDemo11StudentController.java 0 → 100644
  1 +package cn.iocoder.yudao.module.infra.controller.admin.demo11;
  2 +
  3 +import org.springframework.web.bind.annotation.*;
  4 +import javax.annotation.Resource;
  5 +import org.springframework.validation.annotation.Validated;
  6 +import org.springframework.security.access.prepost.PreAuthorize;
  7 +import io.swagger.v3.oas.annotations.tags.Tag;
  8 +import io.swagger.v3.oas.annotations.Parameter;
  9 +import io.swagger.v3.oas.annotations.Operation;
  10 +
  11 +import javax.validation.constraints.*;
  12 +import javax.validation.*;
  13 +import javax.servlet.http.*;
  14 +import java.util.*;
  15 +import java.io.IOException;
  16 +
  17 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  18 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  19 +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  20 +
  21 +import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
  22 +
  23 +import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
  24 +import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.*;
  25 +
  26 +import cn.iocoder.yudao.module.infra.controller.admin.demo11.vo.*;
  27 +import cn.iocoder.yudao.module.infra.dal.dataobject.demo11.InfraDemo11StudentDO;
  28 +import cn.iocoder.yudao.module.infra.dal.dataobject.demo11.InfraDemo11StudentContactDO;
  29 +import cn.iocoder.yudao.module.infra.dal.dataobject.demo11.InfraDemo11StudentTeacherDO;
  30 +import cn.iocoder.yudao.module.infra.convert.demo11.InfraDemo11StudentConvert;
  31 +import cn.iocoder.yudao.module.infra.service.demo11.InfraDemo11StudentService;
  32 +
  33 +@Tag(name = "管理后台 - 学生")
  34 +@RestController
  35 +@RequestMapping("/infra/demo11-student")
  36 +@Validated
  37 +public class InfraDemo11StudentController {
  38 +
  39 + @Resource
  40 + private InfraDemo11StudentService demo11StudentService;
  41 +
  42 + @PostMapping("/create")
  43 + @Operation(summary = "创建学生")
  44 + @PreAuthorize("@ss.hasPermission('infra:demo11-student:create')")
  45 + public CommonResult<Long> createDemo11Student(@Valid @RequestBody InfraDemo11StudentCreateReqVO createReqVO) {
  46 + return success(demo11StudentService.createDemo11Student(createReqVO));
  47 + }
  48 +
  49 + @PutMapping("/update")
  50 + @Operation(summary = "更新学生")
  51 + @PreAuthorize("@ss.hasPermission('infra:demo11-student:update')")
  52 + public CommonResult<Boolean> updateDemo11Student(@Valid @RequestBody InfraDemo11StudentUpdateReqVO updateReqVO) {
  53 + demo11StudentService.updateDemo11Student(updateReqVO);
  54 + return success(true);
  55 + }
  56 +
  57 + @DeleteMapping("/delete")
  58 + @Operation(summary = "删除学生")
  59 + @Parameter(name = "id", description = "编号", required = true)
  60 + @PreAuthorize("@ss.hasPermission('infra:demo11-student:delete')")
  61 + public CommonResult<Boolean> deleteDemo11Student(@RequestParam("id") Long id) {
  62 + demo11StudentService.deleteDemo11Student(id);
  63 + return success(true);
  64 + }
  65 +
  66 + @GetMapping("/get")
  67 + @Operation(summary = "获得学生")
  68 + @Parameter(name = "id", description = "编号", required = true, example = "1024")
  69 + @PreAuthorize("@ss.hasPermission('infra:demo11-student:query')")
  70 + public CommonResult<InfraDemo11StudentRespVO> getDemo11Student(@RequestParam("id") Long id) {
  71 + InfraDemo11StudentDO demo11Student = demo11StudentService.getDemo11Student(id);
  72 + return success(InfraDemo11StudentConvert.INSTANCE.convert(demo11Student));
  73 + }
  74 +
  75 + @GetMapping("/page")
  76 + @Operation(summary = "获得学生分页")
  77 + @PreAuthorize("@ss.hasPermission('infra:demo11-student:query')")
  78 + public CommonResult<PageResult<InfraDemo11StudentRespVO>> getDemo11StudentPage(@Valid InfraDemo11StudentPageReqVO pageVO) {
  79 + PageResult<InfraDemo11StudentDO> pageResult = demo11StudentService.getDemo11StudentPage(pageVO);
  80 + return success(InfraDemo11StudentConvert.INSTANCE.convertPage(pageResult));
  81 + }
  82 +
  83 + @GetMapping("/export-excel")
  84 + @Operation(summary = "导出学生 Excel")
  85 + @PreAuthorize("@ss.hasPermission('infra:demo11-student:export')")
  86 + @OperateLog(type = EXPORT)
  87 + public void exportDemo11StudentExcel(@Valid InfraDemo11StudentExportReqVO exportReqVO,
  88 + HttpServletResponse response) throws IOException {
  89 + List<InfraDemo11StudentDO> list = demo11StudentService.getDemo11StudentList(exportReqVO);
  90 + // 导出 Excel
  91 + List<InfraDemo11StudentExcelVO> datas = InfraDemo11StudentConvert.INSTANCE.convertList02(list);
  92 + ExcelUtils.write(response, "学生.xls", "数据", InfraDemo11StudentExcelVO.class, datas);
  93 + }
  94 +
  95 + // ==================== 子表(学生联系人) ====================
  96 +
  97 + @GetMapping("/demo11-student/list-by-student-id")
  98 + @Operation(summary = "获得学生联系人列表")
  99 + @Parameter(name = "studentId", description = "学生编号")
  100 + @PreAuthorize("@ss.hasPermission('infra:demo11-student:query')")
  101 + public CommonResult<List<InfraDemo11StudentContactDO>> getDemo11StudentContactListByStudentId(@RequestParam("studentId") Long studentId) {
  102 + return success(demo11StudentService.getDemo11StudentContactListByStudentId(studentId));
  103 + }
  104 +
  105 + // ==================== 子表(学生班主任) ====================
  106 +
  107 + @GetMapping("/demo11-student/get-by-student-id")
  108 + @Operation(summary = "获得学生班主任")
  109 + @Parameter(name = "studentId", description = "学生编号")
  110 + @PreAuthorize("@ss.hasPermission('infra:demo11-student:query')")
  111 + public CommonResult<InfraDemo11StudentTeacherDO> getDemo11StudentTeacherByStudentId(@RequestParam("studentId") Long studentId) {
  112 + return success(demo11StudentService.getDemo11StudentTeacherByStudentId(studentId));
  113 + }
  114 +
  115 +}
0 116 \ No newline at end of file
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/demo11/package-info.java 0 → 100644
  1 +/**
  2 + * 代码生成示例:单表(增删改查)
  3 + *
  4 + * @see cn.iocoder.yudao.module.infra.enums.codegen.CodegenTemplateTypeEnum#getType()
  5 + */
  6 +package cn.iocoder.yudao.module.infra.controller.admin.demo11;
0 7 \ No newline at end of file
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/demo11/vo/InfraDemo11StudentBaseVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.infra.controller.admin.demo11.vo;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.*;
  5 +import java.util.*;
  6 +import java.time.LocalDateTime;
  7 +import javax.validation.constraints.*;
  8 +import org.springframework.format.annotation.DateTimeFormat;
  9 +
  10 +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
  11 +import cn.iocoder.yudao.module.infra.dal.dataobject.demo11.InfraDemo11StudentContactDO;
  12 +import cn.iocoder.yudao.module.infra.dal.dataobject.demo11.InfraDemo11StudentTeacherDO;
  13 +
  14 +/**
  15 + * 学生 Base VO,提供给添加、修改、详细的子 VO 使用
  16 + * 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
  17 + */
  18 +@Data
  19 +public class InfraDemo11StudentBaseVO {
  20 +
  21 + @Schema(description = "名字", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋头")
  22 + @NotEmpty(message = "名字不能为空")
  23 + private String name;
  24 +
  25 + @Schema(description = "简介", requiredMode = Schema.RequiredMode.REQUIRED, example = "我是介绍")
  26 + @NotEmpty(message = "简介不能为空")
  27 + private String description;
  28 +
  29 + @Schema(description = "出生日期", requiredMode = Schema.RequiredMode.REQUIRED)
  30 + @NotNull(message = "出生日期不能为空")
  31 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  32 + private LocalDateTime birthday;
  33 +
  34 + @Schema(description = "性别", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  35 + @NotNull(message = "性别不能为空")
  36 + private Integer sex;
  37 +
  38 + @Schema(description = "是否有效", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
  39 + @NotNull(message = "是否有效不能为空")
  40 + private Boolean enabled;
  41 +
  42 + @Schema(description = "头像", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.iocoder.cn/1.png")
  43 + @NotEmpty(message = "头像不能为空")
  44 + private String avatar;
  45 +
  46 + @Schema(description = "附件", example = "https://www.iocoder.cn/1.mp4")
  47 + private String video;
  48 +
  49 + @Schema(description = "备注", requiredMode = Schema.RequiredMode.REQUIRED, example = "我是备注")
  50 + @NotEmpty(message = "备注不能为空")
  51 + private String memo;
  52 +
  53 + private List<InfraDemo11StudentContactDO> demo11StudentContacts;
  54 +
  55 + private InfraDemo11StudentTeacherDO demo11StudentTeacher;
  56 +
  57 +}
0 58 \ No newline at end of file
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/demo11/vo/InfraDemo11StudentCreateReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.infra.controller.admin.demo11.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 InfraDemo11StudentCreateReqVO extends InfraDemo11StudentBaseVO {
  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/demo11/vo/InfraDemo11StudentExcelVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.infra.controller.admin.demo11.vo;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.*;
  5 +import java.util.*;
  6 +import java.time.LocalDateTime;
  7 +
  8 +import com.alibaba.excel.annotation.ExcelProperty;
  9 +import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
  10 +import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
  11 +
  12 +
  13 +/**
  14 + * 学生 Excel VO
  15 + *
  16 + * @author 芋道源码
  17 + */
  18 +@Data
  19 +public class InfraDemo11StudentExcelVO {
  20 +
  21 + @ExcelProperty("编号")
  22 + private Long id;
  23 +
  24 + @ExcelProperty("名字")
  25 + private String name;
  26 +
  27 + @ExcelProperty("简介")
  28 + private String description;
  29 +
  30 + @ExcelProperty("出生日期")
  31 + private LocalDateTime birthday;
  32 +
  33 + @ExcelProperty(value = "性别", converter = DictConvert.class)
  34 + @DictFormat("system_user_sex") // TODO 代码优化:建议设置到对应的 XXXDictTypeConstants 枚举类中
  35 + private Integer sex;
  36 +
  37 + @ExcelProperty(value = "是否有效", converter = DictConvert.class)
  38 + @DictFormat("infra_boolean_string") // TODO 代码优化:建议设置到对应的 XXXDictTypeConstants 枚举类中
  39 + private Boolean enabled;
  40 +
  41 + @ExcelProperty("头像")
  42 + private String avatar;
  43 +
  44 + @ExcelProperty("附件")
  45 + private String video;
  46 +
  47 + @ExcelProperty("备注")
  48 + private String memo;
  49 +
  50 + @ExcelProperty("创建时间")
  51 + private LocalDateTime createTime;
  52 +
  53 +}
0 54 \ No newline at end of file
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/demo11/vo/InfraDemo11StudentExportReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.infra.controller.admin.demo11.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 +import java.time.LocalDateTime;
  8 +import org.springframework.format.annotation.DateTimeFormat;
  9 +
  10 +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
  11 +
  12 +@Schema(description = "管理后台 - 学生 Excel 导出 Request VO,参数和 InfraDemo11StudentPageReqVO 是一致的")
  13 +@Data
  14 +public class InfraDemo11StudentExportReqVO {
  15 +
  16 + @Schema(description = "名字", example = "芋头")
  17 + private String name;
  18 +
  19 + @Schema(description = "出生日期")
  20 + private LocalDateTime birthday;
  21 +
  22 + @Schema(description = "性别", example = "1")
  23 + private Integer sex;
  24 +
  25 + @Schema(description = "是否有效", example = "true")
  26 + private Boolean enabled;
  27 +
  28 + @Schema(description = "创建时间")
  29 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  30 + private LocalDateTime[] createTime;
  31 +
  32 +}
0 33 \ No newline at end of file
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/demo11/vo/InfraDemo11StudentPageReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.infra.controller.admin.demo11.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 +import org.springframework.format.annotation.DateTimeFormat;
  8 +import java.time.LocalDateTime;
  9 +
  10 +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
  11 +
  12 +@Schema(description = "管理后台 - 学生分页 Request VO")
  13 +@Data
  14 +@EqualsAndHashCode(callSuper = true)
  15 +@ToString(callSuper = true)
  16 +public class InfraDemo11StudentPageReqVO extends PageParam {
  17 +
  18 + @Schema(description = "名字", example = "芋头")
  19 + private String name;
  20 +
  21 + @Schema(description = "出生日期")
  22 + private LocalDateTime birthday;
  23 +
  24 + @Schema(description = "性别", example = "1")
  25 + private Integer sex;
  26 +
  27 + @Schema(description = "是否有效", example = "true")
  28 + private Boolean enabled;
  29 +
  30 + @Schema(description = "创建时间")
  31 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  32 + private LocalDateTime[] createTime;
  33 +
  34 +}
0 35 \ No newline at end of file
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/demo11/vo/InfraDemo11StudentRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.infra.controller.admin.demo11.vo;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.*;
  5 +import java.time.LocalDateTime;
  6 +
  7 +@Schema(description = "管理后台 - 学生 Response VO")
  8 +@Data
  9 +@EqualsAndHashCode(callSuper = true)
  10 +@ToString(callSuper = true)
  11 +public class InfraDemo11StudentRespVO extends InfraDemo11StudentBaseVO {
  12 +
  13 + @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
  14 + private Long id;
  15 +
  16 + @Schema(description = "创建时间")
  17 + private LocalDateTime createTime;
  18 +
  19 +}
0 20 \ No newline at end of file
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/demo11/vo/InfraDemo11StudentUpdateReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.infra.controller.admin.demo11.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 InfraDemo11StudentUpdateReqVO extends InfraDemo11StudentBaseVO {
  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/demo11/InfraDemo11StudentConvert.java 0 → 100644
  1 +package cn.iocoder.yudao.module.infra.convert.demo11;
  2 +
  3 +import java.util.*;
  4 +
  5 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  6 +
  7 +import org.mapstruct.Mapper;
  8 +import org.mapstruct.factory.Mappers;
  9 +import cn.iocoder.yudao.module.infra.controller.admin.demo11.vo.*;
  10 +import cn.iocoder.yudao.module.infra.dal.dataobject.demo11.InfraDemo11StudentDO;
  11 +
  12 +/**
  13 + * 学生 Convert
  14 + *
  15 + * @author 芋道源码
  16 + */
  17 +@Mapper
  18 +public interface InfraDemo11StudentConvert {
  19 +
  20 + InfraDemo11StudentConvert INSTANCE = Mappers.getMapper(InfraDemo11StudentConvert.class);
  21 +
  22 + InfraDemo11StudentDO convert(InfraDemo11StudentCreateReqVO bean);
  23 +
  24 + InfraDemo11StudentDO convert(InfraDemo11StudentUpdateReqVO bean);
  25 +
  26 + InfraDemo11StudentRespVO convert(InfraDemo11StudentDO bean);
  27 +
  28 + List<InfraDemo11StudentRespVO> convertList(List<InfraDemo11StudentDO> list);
  29 +
  30 + PageResult<InfraDemo11StudentRespVO> convertPage(PageResult<InfraDemo11StudentDO> page);
  31 +
  32 + List<InfraDemo11StudentExcelVO> convertList02(List<InfraDemo11StudentDO> list);
  33 +
  34 +}
0 35 \ No newline at end of file
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/dataobject/demo11/InfraDemo11StudentContactDO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.infra.dal.dataobject.demo11;
  2 +
  3 +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
  4 +import com.baomidou.mybatisplus.annotation.KeySequence;
  5 +import com.baomidou.mybatisplus.annotation.TableId;
  6 +import com.baomidou.mybatisplus.annotation.TableName;
  7 +import lombok.*;
  8 +
  9 +import java.time.LocalDateTime;
  10 +
  11 +/**
  12 + * 学生联系人 DO
  13 + *
  14 + * @author 芋道源码
  15 + */
  16 +@TableName("infra_demo11_student_contact")
  17 +@KeySequence("infra_demo11_student_contact_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
  18 +@Data
  19 +@EqualsAndHashCode(callSuper = true)
  20 +@ToString(callSuper = true)
  21 +@Builder
  22 +@NoArgsConstructor
  23 +@AllArgsConstructor
  24 +public class InfraDemo11StudentContactDO extends BaseDO {
  25 +
  26 + /**
  27 + * 编号
  28 + */
  29 + @TableId
  30 + private Long id;
  31 + /**
  32 + * 学生编号
  33 + */
  34 + private Long studentId;
  35 + /**
  36 + * 名字
  37 + */
  38 + private String name;
  39 + /**
  40 + * 简介
  41 + */
  42 + private String description;
  43 + /**
  44 + * 出生日期
  45 + */
  46 + private LocalDateTime birthday;
  47 + /**
  48 + * 性别
  49 + *
  50 + * 枚举 {@link TODO system_user_sex 对应的类}
  51 + */
  52 + private Integer sex;
  53 + /**
  54 + * 是否有效
  55 + *
  56 + * 枚举 {@link TODO infra_boolean_string 对应的类}
  57 + */
  58 + private Boolean enabled;
  59 + /**
  60 + * 头像
  61 + */
  62 + private String avatar;
  63 + /**
  64 + * 附件
  65 + */
  66 + private String video;
  67 + /**
  68 + * 备注
  69 + */
  70 + private String memo;
  71 +
  72 +}
0 73 \ No newline at end of file
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/dataobject/demo11/InfraDemo11StudentDO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.infra.dal.dataobject.demo11;
  2 +
  3 +import lombok.*;
  4 +import java.util.*;
  5 +import java.time.LocalDateTime;
  6 +import java.time.LocalDateTime;
  7 +import com.baomidou.mybatisplus.annotation.*;
  8 +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
  9 +
  10 +/**
  11 + * 学生 DO
  12 + *
  13 + * @author 芋道源码
  14 + */
  15 +@TableName("infra_demo11_student")
  16 +@KeySequence("infra_demo11_student_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
  17 +@Data
  18 +@EqualsAndHashCode(callSuper = true)
  19 +@ToString(callSuper = true)
  20 +@Builder
  21 +@NoArgsConstructor
  22 +@AllArgsConstructor
  23 +public class InfraDemo11StudentDO extends BaseDO {
  24 +
  25 + /**
  26 + * 编号
  27 + */
  28 + @TableId
  29 + private Long id;
  30 + /**
  31 + * 名字
  32 + */
  33 + private String name;
  34 + /**
  35 + * 简介
  36 + */
  37 + private String description;
  38 + /**
  39 + * 出生日期
  40 + */
  41 + private LocalDateTime birthday;
  42 + /**
  43 + * 性别
  44 + *
  45 + * 枚举 {@link TODO system_user_sex 对应的类}
  46 + */
  47 + private Integer sex;
  48 + /**
  49 + * 是否有效
  50 + *
  51 + * 枚举 {@link TODO infra_boolean_string 对应的类}
  52 + */
  53 + private Boolean enabled;
  54 + /**
  55 + * 头像
  56 + */
  57 + private String avatar;
  58 + /**
  59 + * 附件
  60 + */
  61 + private String video;
  62 + /**
  63 + * 备注
  64 + */
  65 + private String memo;
  66 +
  67 +}
0 68 \ No newline at end of file
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/dataobject/demo11/InfraDemo11StudentTeacherDO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.infra.dal.dataobject.demo11;
  2 +
  3 +import lombok.*;
  4 +import java.util.*;
  5 +import java.time.LocalDateTime;
  6 +import java.time.LocalDateTime;
  7 +import com.baomidou.mybatisplus.annotation.*;
  8 +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
  9 +
  10 +/**
  11 + * 学生班主任 DO
  12 + *
  13 + * @author 芋道源码
  14 + */
  15 +@TableName("infra_demo11_student_teacher")
  16 +@KeySequence("infra_demo11_student_teacher_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
  17 +@Data
  18 +@EqualsAndHashCode(callSuper = true)
  19 +@ToString(callSuper = true)
  20 +@Builder
  21 +@NoArgsConstructor
  22 +@AllArgsConstructor
  23 +public class InfraDemo11StudentTeacherDO extends BaseDO {
  24 +
  25 + /**
  26 + * 编号
  27 + */
  28 + @TableId
  29 + private Long id;
  30 + /**
  31 + * 学生编号
  32 + */
  33 + private Long studentId;
  34 + /**
  35 + * 名字
  36 + */
  37 + private String name;
  38 + /**
  39 + * 简介
  40 + */
  41 + private String description;
  42 + /**
  43 + * 出生日期
  44 + */
  45 + private LocalDateTime birthday;
  46 + /**
  47 + * 性别
  48 + *
  49 + * 枚举 {@link TODO system_user_sex 对应的类}
  50 + */
  51 + private Integer sex;
  52 + /**
  53 + * 是否有效
  54 + *
  55 + * 枚举 {@link TODO infra_boolean_string 对应的类}
  56 + */
  57 + private Boolean enabled;
  58 + /**
  59 + * 头像
  60 + */
  61 + private String avatar;
  62 + /**
  63 + * 附件
  64 + */
  65 + private String video;
  66 + /**
  67 + * 备注
  68 + */
  69 + private String memo;
  70 +
  71 +}
0 72 \ No newline at end of file
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/mysql/demo11/InfraDemo11StudentContactMapper.java 0 → 100644
  1 +package cn.iocoder.yudao.module.infra.dal.mysql.demo11;
  2 +
  3 +import java.util.*;
  4 +
  5 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  6 +import cn.iocoder.yudao.framework.common.pojo.PageParam;
  7 +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
  8 +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
  9 +import cn.iocoder.yudao.module.infra.dal.dataobject.demo11.InfraDemo11StudentContactDO;
  10 +import org.apache.ibatis.annotations.Mapper;
  11 +
  12 +/**
  13 + * 学生联系人 Mapper
  14 + *
  15 + * @author 芋道源码
  16 + */
  17 +@Mapper
  18 +public interface InfraDemo11StudentContactMapper extends BaseMapperX<InfraDemo11StudentContactDO> {
  19 +
  20 + default List<InfraDemo11StudentContactDO> selectListByStudentId(Long studentId) {
  21 + return selectList(InfraDemo11StudentContactDO::getStudentId, studentId);
  22 + }
  23 +
  24 + default int deleteByStudentId(Long studentId) {
  25 + return delete(InfraDemo11StudentContactDO::getStudentId, studentId);
  26 + }
  27 +
  28 +}
0 29 \ No newline at end of file
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/mysql/demo11/InfraDemo11StudentMapper.java 0 → 100644
  1 +package cn.iocoder.yudao.module.infra.dal.mysql.demo11;
  2 +
  3 +import java.util.*;
  4 +
  5 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  6 +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
  7 +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
  8 +import cn.iocoder.yudao.module.infra.dal.dataobject.demo11.InfraDemo11StudentDO;
  9 +import org.apache.ibatis.annotations.Mapper;
  10 +import cn.iocoder.yudao.module.infra.controller.admin.demo11.vo.*;
  11 +
  12 +/**
  13 + * 学生 Mapper
  14 + *
  15 + * @author 芋道源码
  16 + */
  17 +@Mapper
  18 +public interface InfraDemo11StudentMapper extends BaseMapperX<InfraDemo11StudentDO> {
  19 +
  20 + default PageResult<InfraDemo11StudentDO> selectPage(InfraDemo11StudentPageReqVO reqVO) {
  21 + return selectPage(reqVO, new LambdaQueryWrapperX<InfraDemo11StudentDO>()
  22 + .likeIfPresent(InfraDemo11StudentDO::getName, reqVO.getName())
  23 + .eqIfPresent(InfraDemo11StudentDO::getBirthday, reqVO.getBirthday())
  24 + .eqIfPresent(InfraDemo11StudentDO::getSex, reqVO.getSex())
  25 + .eqIfPresent(InfraDemo11StudentDO::getEnabled, reqVO.getEnabled())
  26 + .betweenIfPresent(InfraDemo11StudentDO::getCreateTime, reqVO.getCreateTime())
  27 + .orderByDesc(InfraDemo11StudentDO::getId));
  28 + }
  29 +
  30 + default List<InfraDemo11StudentDO> selectList(InfraDemo11StudentExportReqVO reqVO) {
  31 + return selectList(new LambdaQueryWrapperX<InfraDemo11StudentDO>()
  32 + .likeIfPresent(InfraDemo11StudentDO::getName, reqVO.getName())
  33 + .eqIfPresent(InfraDemo11StudentDO::getBirthday, reqVO.getBirthday())
  34 + .eqIfPresent(InfraDemo11StudentDO::getSex, reqVO.getSex())
  35 + .eqIfPresent(InfraDemo11StudentDO::getEnabled, reqVO.getEnabled())
  36 + .betweenIfPresent(InfraDemo11StudentDO::getCreateTime, reqVO.getCreateTime())
  37 + .orderByDesc(InfraDemo11StudentDO::getId));
  38 + }
  39 +
  40 +}
0 41 \ No newline at end of file
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/mysql/demo11/InfraDemo11StudentTeacherMapper.java 0 → 100644
  1 +package cn.iocoder.yudao.module.infra.dal.mysql.demo11;
  2 +
  3 +import java.util.*;
  4 +
  5 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  6 +import cn.iocoder.yudao.framework.common.pojo.PageParam;
  7 +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
  8 +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
  9 +import cn.iocoder.yudao.module.infra.dal.dataobject.demo11.InfraDemo11StudentTeacherDO;
  10 +import org.apache.ibatis.annotations.Mapper;
  11 +
  12 +/**
  13 + * 学生班主任 Mapper
  14 + *
  15 + * @author 芋道源码
  16 + */
  17 +@Mapper
  18 +public interface InfraDemo11StudentTeacherMapper extends BaseMapperX<InfraDemo11StudentTeacherDO> {
  19 +
  20 + default InfraDemo11StudentTeacherDO selectByStudentId(Long studentId) {
  21 + return selectOne(InfraDemo11StudentTeacherDO::getStudentId, studentId);
  22 + }
  23 +
  24 + default int deleteByStudentId(Long studentId) {
  25 + return delete(InfraDemo11StudentTeacherDO::getStudentId, studentId);
  26 + }
  27 +
  28 +}
0 29 \ No newline at end of file
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/demo11/InfraDemo11StudentService.java 0 → 100644
  1 +package cn.iocoder.yudao.module.infra.service.demo11;
  2 +
  3 +import java.util.*;
  4 +import javax.validation.*;
  5 +import cn.iocoder.yudao.module.infra.controller.admin.demo11.vo.*;
  6 +import cn.iocoder.yudao.module.infra.dal.dataobject.demo11.InfraDemo11StudentDO;
  7 +import cn.iocoder.yudao.module.infra.dal.dataobject.demo11.InfraDemo11StudentContactDO;
  8 +import cn.iocoder.yudao.module.infra.dal.dataobject.demo11.InfraDemo11StudentTeacherDO;
  9 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  10 +
  11 +/**
  12 + * 学生 Service 接口
  13 + *
  14 + * @author 芋道源码
  15 + */
  16 +public interface InfraDemo11StudentService {
  17 +
  18 + /**
  19 + * 创建学生
  20 + *
  21 + * @param createReqVO 创建信息
  22 + * @return 编号
  23 + */
  24 + Long createDemo11Student(@Valid InfraDemo11StudentCreateReqVO createReqVO);
  25 +
  26 + /**
  27 + * 更新学生
  28 + *
  29 + * @param updateReqVO 更新信息
  30 + */
  31 + void updateDemo11Student(@Valid InfraDemo11StudentUpdateReqVO updateReqVO);
  32 +
  33 + /**
  34 + * 删除学生
  35 + *
  36 + * @param id 编号
  37 + */
  38 + void deleteDemo11Student(Long id);
  39 +
  40 + /**
  41 + * 获得学生
  42 + *
  43 + * @param id 编号
  44 + * @return 学生
  45 + */
  46 + InfraDemo11StudentDO getDemo11Student(Long id);
  47 +
  48 + /**
  49 + * 获得学生分页
  50 + *
  51 + * @param pageReqVO 分页查询
  52 + * @return 学生分页
  53 + */
  54 + PageResult<InfraDemo11StudentDO> getDemo11StudentPage(InfraDemo11StudentPageReqVO pageReqVO);
  55 +
  56 + /**
  57 + * 获得学生列表, 用于 Excel 导出
  58 + *
  59 + * @param exportReqVO 查询条件
  60 + * @return 学生列表
  61 + */
  62 + List<InfraDemo11StudentDO> getDemo11StudentList(InfraDemo11StudentExportReqVO exportReqVO);
  63 +
  64 +
  65 + // ==================== 子表(学生联系人) ====================
  66 +
  67 + /**
  68 + * 获得学生联系人列表
  69 + *
  70 + * @param studentId 学生编号
  71 + * @return 学生联系人列表
  72 + */
  73 + List<InfraDemo11StudentContactDO> getDemo11StudentContactListByStudentId(Long studentId);
  74 +
  75 +
  76 + // ==================== 子表(学生班主任) ====================
  77 +
  78 + /**
  79 + * 获得学生班主任
  80 + *
  81 + * @param studentId 学生编号
  82 + * @return 学生班主任
  83 + */
  84 + InfraDemo11StudentTeacherDO getDemo11StudentTeacherByStudentId(Long studentId);
  85 +
  86 +}
0 87 \ No newline at end of file
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/demo11/InfraDemo11StudentServiceImpl.java 0 → 100644
  1 +package cn.iocoder.yudao.module.infra.service.demo11;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  4 +import cn.iocoder.yudao.module.infra.controller.admin.demo11.vo.InfraDemo11StudentCreateReqVO;
  5 +import cn.iocoder.yudao.module.infra.controller.admin.demo11.vo.InfraDemo11StudentExportReqVO;
  6 +import cn.iocoder.yudao.module.infra.controller.admin.demo11.vo.InfraDemo11StudentPageReqVO;
  7 +import cn.iocoder.yudao.module.infra.controller.admin.demo11.vo.InfraDemo11StudentUpdateReqVO;
  8 +import cn.iocoder.yudao.module.infra.convert.demo11.InfraDemo11StudentConvert;
  9 +import cn.iocoder.yudao.module.infra.dal.dataobject.demo11.InfraDemo11StudentContactDO;
  10 +import cn.iocoder.yudao.module.infra.dal.dataobject.demo11.InfraDemo11StudentDO;
  11 +import cn.iocoder.yudao.module.infra.dal.dataobject.demo11.InfraDemo11StudentTeacherDO;
  12 +import cn.iocoder.yudao.module.infra.dal.mysql.demo11.InfraDemo11StudentContactMapper;
  13 +import cn.iocoder.yudao.module.infra.dal.mysql.demo11.InfraDemo11StudentMapper;
  14 +import cn.iocoder.yudao.module.infra.dal.mysql.demo11.InfraDemo11StudentTeacherMapper;
  15 +import org.springframework.stereotype.Service;
  16 +import org.springframework.transaction.annotation.Transactional;
  17 +import org.springframework.validation.annotation.Validated;
  18 +
  19 +import javax.annotation.Resource;
  20 +import java.util.List;
  21 +
  22 +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
  23 +import static cn.iocoder.yudao.module.infra.enums.ErrorCodeConstants.DEMO11_STUDENT_NOT_EXISTS;
  24 +
  25 +/**
  26 + * 学生 Service 实现类
  27 + *
  28 + * @author 芋道源码
  29 + */
  30 +@Service
  31 +@Validated
  32 +public class InfraDemo11StudentServiceImpl implements InfraDemo11StudentService {
  33 +
  34 + @Resource
  35 + private InfraDemo11StudentMapper demo11StudentMapper;
  36 + @Resource
  37 + private InfraDemo11StudentContactMapper demo11StudentContactMapper;
  38 + @Resource
  39 + private InfraDemo11StudentTeacherMapper demo11StudentTeacherMapper;
  40 +
  41 + @Override
  42 + @Transactional(rollbackFor = Exception.class)
  43 + public Long createDemo11Student(InfraDemo11StudentCreateReqVO createReqVO) {
  44 + // 插入
  45 + InfraDemo11StudentDO demo11Student = InfraDemo11StudentConvert.INSTANCE.convert(createReqVO);
  46 + demo11StudentMapper.insert(demo11Student);
  47 +
  48 + // 插入子表
  49 + createDemo11StudentContactList(demo11Student.getId(), createReqVO.getDemo11StudentContacts());
  50 + createDemo11StudentTeacher(demo11Student.getId(), createReqVO.getDemo11StudentTeacher());
  51 + // 返回
  52 + return demo11Student.getId();
  53 + }
  54 +
  55 + @Override
  56 + @Transactional(rollbackFor = Exception.class)
  57 + public void updateDemo11Student(InfraDemo11StudentUpdateReqVO updateReqVO) {
  58 + // 校验存在
  59 + validateDemo11StudentExists(updateReqVO.getId());
  60 + // 更新
  61 + InfraDemo11StudentDO updateObj = InfraDemo11StudentConvert.INSTANCE.convert(updateReqVO);
  62 + demo11StudentMapper.updateById(updateObj);
  63 +
  64 + // 更新子表
  65 + updateDemo11StudentContactList(updateReqVO.getId(), updateReqVO.getDemo11StudentContacts());
  66 + updateDemo11StudentTeacher(updateReqVO.getId(), updateReqVO.getDemo11StudentTeacher());
  67 + }
  68 +
  69 + @Override
  70 + @Transactional(rollbackFor = Exception.class)
  71 + public void deleteDemo11Student(Long id) {
  72 + // 校验存在
  73 + validateDemo11StudentExists(id);
  74 + // 删除
  75 + demo11StudentMapper.deleteById(id);
  76 +
  77 + // 删除子表
  78 + deleteDemo11StudentContactByStudentId(id);
  79 + deleteDemo11StudentTeacherByStudentId(id);
  80 + }
  81 +
  82 + private void validateDemo11StudentExists(Long id) {
  83 + if (demo11StudentMapper.selectById(id) == null) {
  84 + throw exception(DEMO11_STUDENT_NOT_EXISTS);
  85 + }
  86 + }
  87 +
  88 + @Override
  89 + public InfraDemo11StudentDO getDemo11Student(Long id) {
  90 + return demo11StudentMapper.selectById(id);
  91 + }
  92 +
  93 + @Override
  94 + public PageResult<InfraDemo11StudentDO> getDemo11StudentPage(InfraDemo11StudentPageReqVO pageReqVO) {
  95 + return demo11StudentMapper.selectPage(pageReqVO);
  96 + }
  97 +
  98 + @Override
  99 + public List<InfraDemo11StudentDO> getDemo11StudentList(InfraDemo11StudentExportReqVO exportReqVO) {
  100 + return demo11StudentMapper.selectList(exportReqVO);
  101 + }
  102 +
  103 + // ==================== 子表(学生联系人) ====================
  104 +
  105 + @Override
  106 + public List<InfraDemo11StudentContactDO> getDemo11StudentContactListByStudentId(Long studentId) {
  107 + return demo11StudentContactMapper.selectListByStudentId(studentId);
  108 + }
  109 +
  110 + private void createDemo11StudentContactList(Long studentId, List<InfraDemo11StudentContactDO> list) {
  111 + list.forEach(o -> o.setStudentId(studentId));
  112 + demo11StudentContactMapper.insertBatch(list);
  113 + }
  114 +
  115 + private void updateDemo11StudentContactList(Long studentId, List<InfraDemo11StudentContactDO> list) {
  116 + deleteDemo11StudentContactByStudentId(studentId);
  117 + list.forEach(o -> o.setId(null).setUpdater(null).setUpdateTime(null)); // 解决更新情况下:1)id 冲突;2)updateTime 不更新
  118 + createDemo11StudentContactList(studentId, list);
  119 + }
  120 +
  121 + private void deleteDemo11StudentContactByStudentId(Long studentId) {
  122 + demo11StudentContactMapper.deleteByStudentId(studentId);
  123 + }
  124 +
  125 + // ==================== 子表(学生班主任) ====================
  126 +
  127 + @Override
  128 + public InfraDemo11StudentTeacherDO getDemo11StudentTeacherByStudentId(Long studentId) {
  129 + return demo11StudentTeacherMapper.selectByStudentId(studentId);
  130 + }
  131 +
  132 + private void createDemo11StudentTeacher(Long studentId, InfraDemo11StudentTeacherDO demo11StudentTeacher) {
  133 + if (demo11StudentTeacher == null) {
  134 + return;
  135 + }
  136 + demo11StudentTeacher.setStudentId(studentId);
  137 + demo11StudentTeacherMapper.insert(demo11StudentTeacher);
  138 + }
  139 +
  140 + private void updateDemo11StudentTeacher(Long studentId, InfraDemo11StudentTeacherDO demo11StudentTeacher) {
  141 + if (demo11StudentTeacher == null) {
  142 + return;
  143 + }
  144 + demo11StudentTeacher.setStudentId(studentId);
  145 + demo11StudentTeacher.setUpdater(null).setUpdateTime(null); // 解决更新情况下:updateTime 不更新
  146 + demo11StudentTeacherMapper.insertOrUpdate(demo11StudentTeacher);
  147 + }
  148 +
  149 + private void deleteDemo11StudentTeacherByStudentId(Long studentId) {
  150 + demo11StudentTeacherMapper.deleteByStudentId(studentId);
  151 + }
  152 +
  153 +}
0 154 \ No newline at end of file
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/service/serviceImpl.vm
... ... @@ -25,9 +25,6 @@ import ${basePackage}.module.${subTable.moduleName}.dal.mysql.${subTable.busines
25 25 import static ${ServiceExceptionUtilClassName}.exception;
26 26 import static ${basePackage}.module.${table.moduleName}.enums.ErrorCodeConstants.*;
27 27  
28   -import cn.hutool.core.collection.CollUtil;
29   -import cn.hutool.core.collection.ListUtil;
30   -
31 28 /**
32 29 * ${table.classComment} Service 实现类
33 30 *
... ... @@ -58,7 +55,7 @@ public class ${table.className}ServiceImpl implements ${table.className}Service
58 55 ## 特殊:主子表专属逻辑
59 56 #if ( $subTables && $subTables.size() > 0)
60 57  
61   - // 插入子表($subTable.classComment)
  58 + // 插入子表
62 59 #foreach ($subTable in $subTables)
63 60 #set ($index = $foreach.count - 1)
64 61 #set ($subSimpleClassName = $subSimpleClassNames.get($index))
... ... @@ -210,18 +207,26 @@ public class ${table.className}ServiceImpl implements ${table.className}Service
210 207  
211 208 private void update${subSimpleClassName}List(${primaryColumn.javaType} ${subJoinColumn.javaField}, List<${subTable.className}DO> list) {
212 209 delete${subSimpleClassName}By${SubJoinColumnName}(${subJoinColumn.javaField});
  210 + list.forEach(o -> o.setId(null).setUpdater(null).setUpdateTime(null)); // 解决更新情况下:1)id 冲突;2)updateTime 不更新
213 211 create${subSimpleClassName}List(${subJoinColumn.javaField}, list);
214 212 }
215 213  
216 214 #else
217 215 private void create${subSimpleClassName}(${primaryColumn.javaType} ${subJoinColumn.javaField}, ${subTable.className}DO ${subClassNameVar}) {
  216 + if (${subClassNameVar} == null) {
  217 + return;
  218 + }
218 219 ${subClassNameVar}.set$SubJoinColumnName(${subJoinColumn.javaField});
219 220 ${subClassNameVars.get($index)}Mapper.insert(${subClassNameVar});
220 221 }
221 222  
222 223 private void update${subSimpleClassName}(${primaryColumn.javaType} ${subJoinColumn.javaField}, ${subTable.className}DO ${subClassNameVar}) {
  224 + if (${subClassNameVar} == null) {
  225 + return;
  226 + }
223 227 ${subClassNameVar}.set$SubJoinColumnName(${subJoinColumn.javaField});
224   - ${subClassNameVars.get($index)}Mapper.updateById(${subClassNameVar});
  228 + ${subClassNameVar}.setUpdater(null).setUpdateTime(null); // 解决更新情况下:updateTime 不更新
  229 + ${subClassNameVars.get($index)}Mapper.insertOrUpdate(${subClassNameVar});
225 230 }
226 231  
227 232 #end
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3/views/components/form_sub_normal.vue.vm
... ... @@ -253,6 +253,7 @@
253 253 #end
254 254 #end
255 255 #end
  256 + </el-form>
256 257 #end
257 258 </template>
258 259 <script setup lang="ts">
... ... @@ -278,32 +279,36 @@ const formRef = ref() // 表单 Ref
278 279 watch(
279 280 () => props.${subJoinColumn.javaField},
280 281 async (val) => {
281   - // 情况一:val 为空,说明是新增,则置空
282   - if (!val) {
  282 + // 1. 重置表单
283 283 #if ( $subTable.subJoinMany )
284   - formData.value = []
  284 + formData.value = []
285 285 #else
286   - formData.value = {
287   - #foreach ($column in $subColumns)
288   - #if ($column.createOperation || $column.updateOperation)
289   - #if ($column.htmlType == "checkbox")
290   - $column.javaField: [],
291   - #else
292   - $column.javaField: undefined,
293   - #end
  286 + formData.value = {
  287 + #foreach ($column in $subColumns)
  288 + #if ($column.createOperation || $column.updateOperation)
  289 + #if ($column.htmlType == "checkbox")
  290 + $column.javaField: [],
  291 + #else
  292 + $column.javaField: undefined,
294 293 #end
295 294 #end
296   - }
  295 + #end
  296 + }
297 297 #end
  298 + // 2. val 非空,则加载数据
  299 + if (!val) {
298 300 return;
299 301 }
300   - // 情况二:val 非空,说明是修改,则加载数据
301 302 try {
302 303 formLoading.value = true
303 304 #if ( $subTable.subJoinMany )
304 305 formData.value = await ${simpleClassName}Api.get${subSimpleClassName}ListBy${SubJoinColumnName}(val)
305 306 #else
306   - formData.value = await ${simpleClassName}Api.get${subSimpleClassName}By${SubJoinColumnName}(val)
  307 + const data = await ${simpleClassName}Api.get${subSimpleClassName}By${SubJoinColumnName}(val)
  308 + if (!data) {
  309 + return
  310 + }
  311 + formData.value = data
307 312 #end
308 313 } finally {
309 314 formLoading.value = false
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/resources/mapper/demo11/InfraDemo11StudentMapper.xml 0 → 100644
  1 +<?xml version="1.0" encoding="UTF-8"?>
  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.infra.dal.mysql.demo11.InfraDemo11StudentMapper">
  4 +
  5 + <!--
  6 + 一般情况下,尽可能使用 Mapper 进行 CRUD 增删改查即可。
  7 + 无法满足的场景,例如说多表关联查询,才使用 XML 编写 SQL。
  8 + 代码生成器暂时只生成 Mapper XML 文件本身,更多推荐 MybatisX 快速开发插件来生成查询。
  9 + 文档可见:https://www.iocoder.cn/MyBatis/x-plugins/
  10 + -->
  11 +
  12 +</mapper>
0 13 \ No newline at end of file
... ...
yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/service/codegen/inner/CodegenEngineTest.java
... ... @@ -129,12 +129,7 @@ public class CodegenEngineTest extends BaseMockitoUnitTest {
129 129 Map<String, String> result = codegenEngine.execute(table, columns, null, null);
130 130  
131 131 // 构建 zip 包
132   - String[] paths = result.keySet().toArray(new String[0]);
133   - ByteArrayInputStream[] ins = result.values().stream().map(IoUtil::toUtf8Stream).toArray(ByteArrayInputStream[]::new);
134   - ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
135   - ZipUtil.zip(outputStream, paths, ins);
136   -
137   - FileUtil.writeBytes(outputStream.toByteArray(), "/Users/yunai/test/demo01.zip");
  132 + writeFile(result, "/Users/yunai/test/demo01.zip");
138 133  
139 134 // 断言
140 135 assertEquals(21, result.size());
... ... @@ -186,175 +181,273 @@ public class CodegenEngineTest extends BaseMockitoUnitTest {
186 181 public void testExecute_vue3_masterSub() {
187 182 // 准备请求参数
188 183 // 主表
  184 + CodegenTableDO table = new CodegenTableDO().setScene(CodegenSceneEnum.ADMIN.getScene()).setParentMenuId(888L)
  185 + .setTableName("infra_demo11_student").setTableComment("学生表")
  186 + .setModuleName("infra").setBusinessName("demo11").setClassName("InfraDemo11Student")
  187 + .setClassComment("学生").setAuthor("芋道源码")
  188 + .setTemplateType(CodegenTemplateTypeEnum.MASTER_NORMAL.getType())
  189 + .setFrontType(CodegenFrontTypeEnum.VUE3.getType());
  190 + CodegenColumnDO idColumn = new CodegenColumnDO().setColumnName("id").setDataType(JdbcType.BIGINT.name())
  191 + .setId(100L)
  192 + .setColumnComment("编号").setNullable(false).setPrimaryKey(true).setAutoIncrement(true)
  193 + .setJavaType("Long").setJavaField("id").setExample("1024")
  194 + .setCreateOperation(false).setUpdateOperation(true)
  195 + .setListOperation(false)
  196 + .setListOperationResult(true);
  197 + CodegenColumnDO nameColumn = new CodegenColumnDO().setColumnName("name").setDataType(JdbcType.VARCHAR.name())
  198 + .setColumnComment("名字").setNullable(false)
  199 + .setJavaType("String").setJavaField("name").setExample("芋头")
  200 + .setCreateOperation(true).setUpdateOperation(true)
  201 + .setListOperation(true).setListOperationCondition(CodegenColumnListConditionEnum.LIKE.getCondition())
  202 + .setListOperationResult(true)
  203 + .setHtmlType(CodegenColumnHtmlTypeEnum.INPUT.getType());
  204 + CodegenColumnDO descriptionColumn = new CodegenColumnDO().setColumnName("description").setDataType(JdbcType.VARCHAR.name())
  205 + .setColumnComment("简介").setNullable(false)
  206 + .setJavaType("String").setJavaField("description").setExample("我是介绍")
  207 + .setCreateOperation(true).setUpdateOperation(true)
  208 + .setListOperation(false)
  209 + .setListOperationResult(true)
  210 + .setHtmlType(CodegenColumnHtmlTypeEnum.TEXTAREA.getType());
  211 + CodegenColumnDO birthdayColumn = new CodegenColumnDO().setColumnName("birthday").setDataType(JdbcType.DATE.name())
  212 + .setColumnComment("出生日期").setNullable(false)
  213 + .setJavaType("LocalDateTime").setJavaField("birthday")
  214 + .setCreateOperation(true).setUpdateOperation(true)
  215 + .setListOperation(true).setListOperationCondition(CodegenColumnListConditionEnum.EQ.getCondition())
  216 + .setListOperationResult(true)
  217 + .setHtmlType(CodegenColumnHtmlTypeEnum.DATETIME.getType());
  218 + CodegenColumnDO sexColumn = new CodegenColumnDO().setColumnName("sex").setDataType(JdbcType.INTEGER.name())
  219 + .setColumnComment("性别").setNullable(false)
  220 + .setJavaType("Integer").setJavaField("sex").setExample("1")
  221 + .setCreateOperation(true).setUpdateOperation(true)
  222 + .setListOperation(true).setListOperationCondition(CodegenColumnListConditionEnum.EQ.getCondition())
  223 + .setListOperationResult(true)
  224 + .setHtmlType(CodegenColumnHtmlTypeEnum.SELECT.getType())
  225 + .setDictType("system_user_sex");
  226 + CodegenColumnDO enabledColumn = new CodegenColumnDO().setColumnName("enabled").setDataType(JdbcType.BOOLEAN.name())
  227 + .setColumnComment("是否有效").setNullable(false)
  228 + .setJavaType("Boolean").setJavaField("enabled").setExample("true")
  229 + .setCreateOperation(true).setUpdateOperation(true)
  230 + .setListOperation(true).setListOperationCondition(CodegenColumnListConditionEnum.EQ.getCondition())
  231 + .setListOperationResult(true)
  232 + .setHtmlType(CodegenColumnHtmlTypeEnum.RADIO.getType())
  233 + .setDictType("infra_boolean_string");
  234 + CodegenColumnDO avatarColumn = new CodegenColumnDO().setColumnName("avatar").setDataType(JdbcType.VARCHAR.name())
  235 + .setColumnComment("头像").setNullable(false)
  236 + .setJavaType("String").setJavaField("avatar").setExample("https://www.iocoder.cn/1.png")
  237 + .setCreateOperation(true).setUpdateOperation(true)
  238 + .setListOperation(false)
  239 + .setListOperationResult(true)
  240 + .setHtmlType(CodegenColumnHtmlTypeEnum.IMAGE_UPLOAD.getType());
  241 + CodegenColumnDO videoColumn = new CodegenColumnDO().setColumnName("video").setDataType(JdbcType.VARCHAR.name())
  242 + .setColumnComment("附件").setNullable(true)
  243 + .setJavaType("String").setJavaField("video").setExample("https://www.iocoder.cn/1.mp4")
  244 + .setCreateOperation(true).setUpdateOperation(true)
  245 + .setListOperation(false)
  246 + .setListOperationResult(true)
  247 + .setHtmlType(CodegenColumnHtmlTypeEnum.FILE_UPLOAD.getType());
  248 + CodegenColumnDO memoColumn = new CodegenColumnDO().setColumnName("memo").setDataType(JdbcType.VARCHAR.name())
  249 + .setColumnComment("备注").setNullable(false)
  250 + .setJavaType("String").setJavaField("memo").setExample("我是备注")
  251 + .setCreateOperation(true).setUpdateOperation(true)
  252 + .setListOperation(false)
  253 + .setListOperationResult(true)
  254 + .setHtmlType(CodegenColumnHtmlTypeEnum.EDITOR.getType());
  255 + CodegenColumnDO createTimeColumn = new CodegenColumnDO().setColumnName("create_time").setDataType(JdbcType.DATE.name())
  256 + .setColumnComment("创建时间").setNullable(true)
  257 + .setJavaType("LocalDateTime").setJavaField("createTime")
  258 + .setCreateOperation(false).setUpdateOperation(false)
  259 + .setListOperation(true).setListOperationCondition(CodegenColumnListConditionEnum.BETWEEN.getCondition())
  260 + .setListOperationResult(true)
  261 + .setHtmlType(CodegenColumnHtmlTypeEnum.DATETIME.getType());
  262 + List<CodegenColumnDO> columns = Arrays.asList(idColumn, nameColumn, descriptionColumn, birthdayColumn,
  263 + sexColumn, enabledColumn, avatarColumn, videoColumn, memoColumn, createTimeColumn);
189 264  
190 265 // 子表(联系人)
191 266 CodegenTableDO contactTable = new CodegenTableDO().setScene(CodegenSceneEnum.ADMIN.getScene())
192   - .setTableName("infra_demo_student_contact").setTableComment("学生联系人表")
193   - .setModuleName("infra").setBusinessName("demo02").setClassName("InfraDemoStudentContact")
  267 + .setTableName("infra_demo11_student_contact").setTableComment("学生联系人表")
  268 + .setModuleName("infra").setBusinessName("demo11").setClassName("InfraDemo11StudentContact")
194 269 .setClassComment("学生联系人").setAuthor("芋道源码")
195 270 .setTemplateType(CodegenTemplateTypeEnum.SUB.getType())
196 271 .setFrontType(CodegenFrontTypeEnum.VUE3.getType())
197 272 .setSubJoinColumnId(100L).setSubJoinMany(true);
198 273 CodegenColumnDO contactIdColumn = new CodegenColumnDO().setColumnName("id").setDataType(JdbcType.BIGINT.name())
199 274 .setColumnComment("编号").setNullable(false).setPrimaryKey(true).setAutoIncrement(true)
200   - .setOrdinalPosition(1).setJavaType("Long").setJavaField("id").setExample("1024")
201   - .setCreateOperation(false).setUpdateOperation(true).setListOperation(false)
  275 + .setJavaType("Long").setJavaField("id").setExample("1024")
  276 + .setCreateOperation(false).setUpdateOperation(true)
  277 + .setListOperation(false)
202 278 .setListOperationResult(true);
203 279 CodegenColumnDO contactStudentIdColumn = new CodegenColumnDO().setColumnName("student_id").setDataType(JdbcType.BIGINT.name())
204 280 .setColumnComment("学生编号").setNullable(false).setPrimaryKey(false)
205   - .setOrdinalPosition(2).setJavaType("Long").setJavaField("studentId").setExample("2048")
206   - .setCreateOperation(false).setUpdateOperation(true).setListOperation(false)
  281 + .setJavaType("Long").setJavaField("studentId").setExample("2048")
  282 + .setCreateOperation(true).setUpdateOperation(true)
  283 + .setListOperation(false)
207 284 .setListOperationResult(true)
208 285 .setId(100L);
209 286 CodegenColumnDO contactNameColumn = new CodegenColumnDO().setColumnName("name").setDataType(JdbcType.VARCHAR.name())
210   - .setColumnComment("名字").setNullable(false).setPrimaryKey(false)
211   - .setOrdinalPosition(3).setJavaType("String").setJavaField("name").setExample("芋头")
212   - .setCreateOperation(true).setUpdateOperation(true).setListOperation(true)
213   - .setListOperationCondition(CodegenColumnListConditionEnum.LIKE.getCondition()).setListOperationResult(true)
  287 + .setColumnComment("名字").setNullable(false)
  288 + .setJavaType("String").setJavaField("name").setExample("芋头")
  289 + .setCreateOperation(true).setUpdateOperation(true)
  290 + .setListOperation(true).setListOperationCondition(CodegenColumnListConditionEnum.LIKE.getCondition())
  291 + .setListOperationResult(true)
214 292 .setHtmlType(CodegenColumnHtmlTypeEnum.INPUT.getType());
215   - CodegenColumnDO contactsAvatarColumn = new CodegenColumnDO().setColumnName("avatar").setDataType(JdbcType.VARCHAR.name())
216   - .setColumnComment("头像").setNullable(false).setPrimaryKey(false)
217   - .setOrdinalPosition(4).setJavaType("String").setJavaField("avatar").setExample("https://www.iocoder.cn/1.png")
218   - .setCreateOperation(true).setUpdateOperation(true).setListOperation(false)
  293 + CodegenColumnDO contactDescriptionColumn = new CodegenColumnDO().setColumnName("description").setDataType(JdbcType.VARCHAR.name())
  294 + .setColumnComment("简介").setNullable(false)
  295 + .setJavaType("String").setJavaField("description").setExample("我是介绍")
  296 + .setCreateOperation(true).setUpdateOperation(true)
  297 + .setListOperation(false)
  298 + .setListOperationResult(true)
  299 + .setHtmlType(CodegenColumnHtmlTypeEnum.TEXTAREA.getType());
  300 + CodegenColumnDO contactBirthdayColumn = new CodegenColumnDO().setColumnName("birthday").setDataType(JdbcType.DATE.name())
  301 + .setColumnComment("出生日期").setNullable(false)
  302 + .setJavaType("LocalDateTime").setJavaField("birthday")
  303 + .setCreateOperation(true).setUpdateOperation(true)
  304 + .setListOperation(true).setListOperationCondition(CodegenColumnListConditionEnum.EQ.getCondition())
  305 + .setListOperationResult(true)
  306 + .setHtmlType(CodegenColumnHtmlTypeEnum.DATETIME.getType());
  307 + CodegenColumnDO contactSexColumn = new CodegenColumnDO().setColumnName("sex").setDataType(JdbcType.INTEGER.name())
  308 + .setColumnComment("性别").setNullable(false)
  309 + .setJavaType("Integer").setJavaField("sex").setExample("1")
  310 + .setCreateOperation(true).setUpdateOperation(true)
  311 + .setListOperation(true).setListOperationCondition(CodegenColumnListConditionEnum.EQ.getCondition())
  312 + .setListOperationResult(true)
  313 + .setHtmlType(CodegenColumnHtmlTypeEnum.SELECT.getType())
  314 + .setDictType("system_user_sex");
  315 + CodegenColumnDO contactEnabledColumn = new CodegenColumnDO().setColumnName("enabled").setDataType(JdbcType.BOOLEAN.name())
  316 + .setColumnComment("是否有效").setNullable(false)
  317 + .setJavaType("Boolean").setJavaField("enabled").setExample("true")
  318 + .setCreateOperation(true).setUpdateOperation(true)
  319 + .setListOperation(true).setListOperationCondition(CodegenColumnListConditionEnum.EQ.getCondition())
  320 + .setListOperationResult(true)
  321 + .setHtmlType(CodegenColumnHtmlTypeEnum.RADIO.getType())
  322 + .setDictType("infra_boolean_string");
  323 + CodegenColumnDO contactAvatarColumn = new CodegenColumnDO().setColumnName("avatar").setDataType(JdbcType.VARCHAR.name())
  324 + .setColumnComment("头像").setNullable(false)
  325 + .setJavaType("String").setJavaField("avatar").setExample("https://www.iocoder.cn/1.png")
  326 + .setCreateOperation(true).setUpdateOperation(true)
  327 + .setListOperation(false)
219 328 .setListOperationResult(true)
220 329 .setHtmlType(CodegenColumnHtmlTypeEnum.IMAGE_UPLOAD.getType());
221 330 CodegenColumnDO contactVideoColumn = new CodegenColumnDO().setColumnName("video").setDataType(JdbcType.VARCHAR.name())
222   - .setColumnComment("视频").setNullable(false).setPrimaryKey(false)
223   - .setOrdinalPosition(5).setJavaType("String").setJavaField("video").setExample("https://www.iocoder.cn/1.mp4")
224   - .setCreateOperation(true).setUpdateOperation(true).setListOperation(false)
  331 + .setColumnComment("附件").setNullable(true)
  332 + .setJavaType("String").setJavaField("video").setExample("https://www.iocoder.cn/1.mp4")
  333 + .setCreateOperation(true).setUpdateOperation(true)
  334 + .setListOperation(false)
225 335 .setListOperationResult(true)
226 336 .setHtmlType(CodegenColumnHtmlTypeEnum.FILE_UPLOAD.getType());
227   - CodegenColumnDO contactDescriptionColumn = new CodegenColumnDO().setColumnName("description").setDataType(JdbcType.VARCHAR.name())
228   - .setColumnComment("个人简介").setNullable(false).setPrimaryKey(false)
229   - .setOrdinalPosition(6).setJavaType("String").setJavaField("description").setExample("我是介绍")
230   - .setCreateOperation(true).setUpdateOperation(true).setListOperation(false)
231   - .setListOperationResult(true)
232   - .setHtmlType(CodegenColumnHtmlTypeEnum.EDITOR.getType());
233   - CodegenColumnDO contactSex1Column = new CodegenColumnDO().setColumnName("sex1").setDataType(JdbcType.VARCHAR.name())
234   - .setColumnComment("性别 1").setNullable(false).setPrimaryKey(false)
235   - .setOrdinalPosition(7).setJavaType("String").setJavaField("sex1").setExample("男")
236   - .setCreateOperation(true).setUpdateOperation(true).setListOperation(true)
237   - .setListOperationCondition(CodegenColumnListConditionEnum.EQ.getCondition()).setListOperationResult(true)
238   - .setHtmlType(CodegenColumnHtmlTypeEnum.SELECT.getType()).setDictType("system_sex1");
239   - CodegenColumnDO contactSex2Column = new CodegenColumnDO().setColumnName("sex2").setDataType(JdbcType.INTEGER.name())
240   - .setColumnComment("性别 2").setNullable(false).setPrimaryKey(false)
241   - .setOrdinalPosition(8).setJavaType("Integer").setJavaField("sex2").setExample("1")
242   - .setCreateOperation(true).setUpdateOperation(true).setListOperation(true)
243   - .setListOperationCondition(CodegenColumnListConditionEnum.EQ.getCondition()).setListOperationResult(true)
244   - .setHtmlType(CodegenColumnHtmlTypeEnum.CHECKBOX.getType()).setDictType("system_sex2");
245   - CodegenColumnDO contactSex3Column = new CodegenColumnDO().setColumnName("sex3").setDataType(JdbcType.BOOLEAN.name())
246   - .setColumnComment("性别 3").setNullable(false).setPrimaryKey(false)
247   - .setOrdinalPosition(9).setJavaType("Boolean").setJavaField("sex3").setExample("true")
248   - .setCreateOperation(true).setUpdateOperation(true).setListOperation(true)
249   - .setListOperationResult(true)
250   - .setHtmlType(CodegenColumnHtmlTypeEnum.RADIO.getType()).setDictType("system_sex3");
251   - CodegenColumnDO contactBirthdayColumn = new CodegenColumnDO().setColumnName("birthday").setDataType(JdbcType.DATE.name())
252   - .setColumnComment("出生日期").setNullable(false).setPrimaryKey(false)
253   - .setOrdinalPosition(10).setJavaType("LocalDateTime").setJavaField("birthday")
254   - .setCreateOperation(true).setUpdateOperation(true).setListOperation(true)
255   - .setListOperationCondition(CodegenColumnListConditionEnum.EQ.getCondition()).setListOperationResult(true)
256   - .setHtmlType(CodegenColumnHtmlTypeEnum.DATETIME.getType());
257 337 CodegenColumnDO contactMemoColumn = new CodegenColumnDO().setColumnName("memo").setDataType(JdbcType.VARCHAR.name())
258   - .setColumnComment("备注").setNullable(false).setPrimaryKey(false)
259   - .setOrdinalPosition(11).setJavaType("String").setJavaField("memo").setExample("我是备注")
260   - .setCreateOperation(true).setUpdateOperation(true).setListOperation(false)
  338 + .setColumnComment("备注").setNullable(false)
  339 + .setJavaType("String").setJavaField("memo").setExample("我是备注")
  340 + .setCreateOperation(true).setUpdateOperation(true)
  341 + .setListOperation(false)
261 342 .setListOperationResult(true)
262   - .setHtmlType(CodegenColumnHtmlTypeEnum.TEXTAREA.getType());
  343 + .setHtmlType(CodegenColumnHtmlTypeEnum.EDITOR.getType());
263 344 CodegenColumnDO contactCreateTimeColumn = new CodegenColumnDO().setColumnName("create_time").setDataType(JdbcType.DATE.name())
264   - .setColumnComment("创建时间").setNullable(false).setPrimaryKey(false)
265   - .setOrdinalPosition(12).setJavaType("LocalDateTime").setJavaField("createTime")
266   - .setCreateOperation(false).setUpdateOperation(false).setListOperation(true)
267   - .setListOperationCondition(CodegenColumnListConditionEnum.BETWEEN.getCondition()).setListOperationResult(true)
  345 + .setColumnComment("创建时间").setNullable(true)
  346 + .setJavaType("LocalDateTime").setJavaField("createTime")
  347 + .setCreateOperation(false).setUpdateOperation(false)
  348 + .setListOperation(true).setListOperationCondition(CodegenColumnListConditionEnum.BETWEEN.getCondition())
  349 + .setListOperationResult(true)
268 350 .setHtmlType(CodegenColumnHtmlTypeEnum.DATETIME.getType());
269 351 List<CodegenColumnDO> contactColumns = Arrays.asList(contactIdColumn, contactStudentIdColumn,
270   - contactNameColumn, contactsAvatarColumn, contactVideoColumn, contactDescriptionColumn,
271   - contactSex1Column, contactSex2Column, contactSex3Column, contactBirthdayColumn, contactMemoColumn, contactCreateTimeColumn);
272   - // 子表(地址)
273   - CodegenTableDO addressTable = new CodegenTableDO().setScene(CodegenSceneEnum.ADMIN.getScene())
274   - .setTableName("infra_demo_student_address").setTableComment("学生地址表")
275   - .setModuleName("infra").setBusinessName("demo02").setClassName("InfraDemoStudentAddress")
276   - .setClassComment("学生地址").setAuthor("芋道源码")
  352 + contactNameColumn, contactDescriptionColumn, contactBirthdayColumn,
  353 + contactSexColumn, contactEnabledColumn, contactAvatarColumn, contactVideoColumn, contactMemoColumn, contactCreateTimeColumn);
  354 +
  355 + // 子表(班主任)
  356 + CodegenTableDO teacherTable = new CodegenTableDO().setScene(CodegenSceneEnum.ADMIN.getScene())
  357 + .setTableName("infra_demo11_student_teacher").setTableComment("学生班主任表")
  358 + .setModuleName("infra").setBusinessName("demo11").setClassName("InfraDemo11StudentTeacher")
  359 + .setClassComment("学生班主任").setAuthor("芋道源码")
277 360 .setTemplateType(CodegenTemplateTypeEnum.SUB.getType())
278 361 .setFrontType(CodegenFrontTypeEnum.VUE3.getType())
279 362 .setSubJoinColumnId(200L).setSubJoinMany(false);
280   - CodegenColumnDO addressIdColumn = new CodegenColumnDO().setColumnName("id").setDataType(JdbcType.BIGINT.name())
  363 + CodegenColumnDO teacherIdColumn = new CodegenColumnDO().setColumnName("id").setDataType(JdbcType.BIGINT.name())
281 364 .setColumnComment("编号").setNullable(false).setPrimaryKey(true).setAutoIncrement(true)
282   - .setOrdinalPosition(1).setJavaType("Long").setJavaField("id").setExample("1024")
283   - .setCreateOperation(false).setUpdateOperation(true).setListOperation(false)
  365 + .setJavaType("Long").setJavaField("id").setExample("1024")
  366 + .setCreateOperation(false).setUpdateOperation(true)
  367 + .setListOperation(false)
284 368 .setListOperationResult(true);
285   - CodegenColumnDO addressStudentIdColumn = new CodegenColumnDO().setColumnName("student_id").setDataType(JdbcType.BIGINT.name())
  369 + CodegenColumnDO teacherStudentIdColumn = new CodegenColumnDO().setColumnName("student_id").setDataType(JdbcType.BIGINT.name())
286 370 .setColumnComment("学生编号").setNullable(false).setPrimaryKey(false)
287   - .setOrdinalPosition(2).setJavaType("Long").setJavaField("studentId").setExample("2048")
288   - .setCreateOperation(false).setUpdateOperation(true).setListOperation(false)
  371 + .setJavaType("Long").setJavaField("studentId").setExample("2048")
  372 + .setCreateOperation(true).setUpdateOperation(true)
  373 + .setListOperation(false)
289 374 .setListOperationResult(true)
290 375 .setId(200L);
291   - CodegenColumnDO addressNameColumn = new CodegenColumnDO().setColumnName("name").setDataType(JdbcType.VARCHAR.name())
292   - .setColumnComment("名字").setNullable(false).setPrimaryKey(false)
293   - .setOrdinalPosition(3).setJavaType("String").setJavaField("name").setExample("芋头")
294   - .setCreateOperation(true).setUpdateOperation(true).setListOperation(true)
295   - .setListOperationCondition(CodegenColumnListConditionEnum.LIKE.getCondition()).setListOperationResult(true)
  376 + CodegenColumnDO teacherNameColumn = new CodegenColumnDO().setColumnName("name").setDataType(JdbcType.VARCHAR.name())
  377 + .setColumnComment("名字").setNullable(false)
  378 + .setJavaType("String").setJavaField("name").setExample("芋头")
  379 + .setCreateOperation(true).setUpdateOperation(true)
  380 + .setListOperation(true).setListOperationCondition(CodegenColumnListConditionEnum.LIKE.getCondition())
  381 + .setListOperationResult(true)
296 382 .setHtmlType(CodegenColumnHtmlTypeEnum.INPUT.getType());
297   - CodegenColumnDO addressAvatarColumn = new CodegenColumnDO().setColumnName("avatar").setDataType(JdbcType.VARCHAR.name())
298   - .setColumnComment("头像").setNullable(false).setPrimaryKey(false)
299   - .setOrdinalPosition(4).setJavaType("String").setJavaField("avatar").setExample("https://www.iocoder.cn/1.png")
300   - .setCreateOperation(true).setUpdateOperation(true).setListOperation(false)
  383 + CodegenColumnDO teacherDescriptionColumn = new CodegenColumnDO().setColumnName("description").setDataType(JdbcType.VARCHAR.name())
  384 + .setColumnComment("简介").setNullable(false)
  385 + .setJavaType("String").setJavaField("description").setExample("我是介绍")
  386 + .setCreateOperation(true).setUpdateOperation(true)
  387 + .setListOperation(false)
  388 + .setListOperationResult(true)
  389 + .setHtmlType(CodegenColumnHtmlTypeEnum.TEXTAREA.getType());
  390 + CodegenColumnDO teacherBirthdayColumn = new CodegenColumnDO().setColumnName("birthday").setDataType(JdbcType.DATE.name())
  391 + .setColumnComment("出生日期").setNullable(false)
  392 + .setJavaType("LocalDateTime").setJavaField("birthday")
  393 + .setCreateOperation(true).setUpdateOperation(true)
  394 + .setListOperation(true).setListOperationCondition(CodegenColumnListConditionEnum.EQ.getCondition())
  395 + .setListOperationResult(true)
  396 + .setHtmlType(CodegenColumnHtmlTypeEnum.DATETIME.getType());
  397 + CodegenColumnDO teacherSexColumn = new CodegenColumnDO().setColumnName("sex").setDataType(JdbcType.INTEGER.name())
  398 + .setColumnComment("性别").setNullable(false)
  399 + .setJavaType("Integer").setJavaField("sex").setExample("1")
  400 + .setCreateOperation(true).setUpdateOperation(true)
  401 + .setListOperation(true).setListOperationCondition(CodegenColumnListConditionEnum.EQ.getCondition())
  402 + .setListOperationResult(true)
  403 + .setHtmlType(CodegenColumnHtmlTypeEnum.SELECT.getType())
  404 + .setDictType("system_user_sex");
  405 + CodegenColumnDO teacherEnabledColumn = new CodegenColumnDO().setColumnName("enabled").setDataType(JdbcType.BOOLEAN.name())
  406 + .setColumnComment("是否有效").setNullable(false)
  407 + .setJavaType("Boolean").setJavaField("enabled").setExample("true")
  408 + .setCreateOperation(true).setUpdateOperation(true)
  409 + .setListOperation(true).setListOperationCondition(CodegenColumnListConditionEnum.EQ.getCondition())
  410 + .setListOperationResult(true)
  411 + .setHtmlType(CodegenColumnHtmlTypeEnum.RADIO.getType())
  412 + .setDictType("infra_boolean_string");
  413 + CodegenColumnDO teacherAvatarColumn = new CodegenColumnDO().setColumnName("avatar").setDataType(JdbcType.VARCHAR.name())
  414 + .setColumnComment("头像").setNullable(false)
  415 + .setJavaType("String").setJavaField("avatar").setExample("https://www.iocoder.cn/1.png")
  416 + .setCreateOperation(true).setUpdateOperation(true)
  417 + .setListOperation(false)
301 418 .setListOperationResult(true)
302 419 .setHtmlType(CodegenColumnHtmlTypeEnum.IMAGE_UPLOAD.getType());
303   - CodegenColumnDO addressVideoColumn = new CodegenColumnDO().setColumnName("video").setDataType(JdbcType.VARCHAR.name())
304   - .setColumnComment("视频").setNullable(false).setPrimaryKey(false)
305   - .setOrdinalPosition(5).setJavaType("String").setJavaField("video").setExample("https://www.iocoder.cn/1.mp4")
306   - .setCreateOperation(true).setUpdateOperation(true).setListOperation(false)
  420 + CodegenColumnDO teacherVideoColumn = new CodegenColumnDO().setColumnName("video").setDataType(JdbcType.VARCHAR.name())
  421 + .setColumnComment("附件").setNullable(true)
  422 + .setJavaType("String").setJavaField("video").setExample("https://www.iocoder.cn/1.mp4")
  423 + .setCreateOperation(true).setUpdateOperation(true)
  424 + .setListOperation(false)
307 425 .setListOperationResult(true)
308 426 .setHtmlType(CodegenColumnHtmlTypeEnum.FILE_UPLOAD.getType());
309   - CodegenColumnDO addressDescriptionColumn = new CodegenColumnDO().setColumnName("description").setDataType(JdbcType.VARCHAR.name())
310   - .setColumnComment("个人简介").setNullable(false).setPrimaryKey(false)
311   - .setOrdinalPosition(6).setJavaType("String").setJavaField("description").setExample("我是介绍")
312   - .setCreateOperation(true).setUpdateOperation(true).setListOperation(false)
  427 + CodegenColumnDO teacherMemoColumn = new CodegenColumnDO().setColumnName("memo").setDataType(JdbcType.VARCHAR.name())
  428 + .setColumnComment("备注").setNullable(false)
  429 + .setJavaType("String").setJavaField("memo").setExample("我是备注")
  430 + .setCreateOperation(true).setUpdateOperation(true)
  431 + .setListOperation(false)
313 432 .setListOperationResult(true)
314 433 .setHtmlType(CodegenColumnHtmlTypeEnum.EDITOR.getType());
315   - CodegenColumnDO addressSex1Column = new CodegenColumnDO().setColumnName("sex1").setDataType(JdbcType.VARCHAR.name())
316   - .setColumnComment("性别 1").setNullable(false).setPrimaryKey(false)
317   - .setOrdinalPosition(7).setJavaType("String").setJavaField("sex1").setExample("男")
318   - .setCreateOperation(true).setUpdateOperation(true).setListOperation(true)
319   - .setListOperationCondition(CodegenColumnListConditionEnum.EQ.getCondition()).setListOperationResult(true)
320   - .setHtmlType(CodegenColumnHtmlTypeEnum.SELECT.getType()).setDictType("system_sex1");
321   - CodegenColumnDO addressSex2Column = new CodegenColumnDO().setColumnName("sex2").setDataType(JdbcType.INTEGER.name())
322   - .setColumnComment("性别 2").setNullable(false).setPrimaryKey(false)
323   - .setOrdinalPosition(8).setJavaType("Integer").setJavaField("sex2").setExample("1")
324   - .setCreateOperation(true).setUpdateOperation(true).setListOperation(true)
325   - .setListOperationCondition(CodegenColumnListConditionEnum.EQ.getCondition()).setListOperationResult(true)
326   - .setHtmlType(CodegenColumnHtmlTypeEnum.CHECKBOX.getType()).setDictType("system_sex2");
327   - CodegenColumnDO addressSex3Column = new CodegenColumnDO().setColumnName("sex3").setDataType(JdbcType.BOOLEAN.name())
328   - .setColumnComment("性别 3").setNullable(false).setPrimaryKey(false)
329   - .setOrdinalPosition(9).setJavaType("Boolean").setJavaField("sex3").setExample("true")
330   - .setCreateOperation(true).setUpdateOperation(true).setListOperation(true)
331   - .setListOperationResult(true)
332   - .setHtmlType(CodegenColumnHtmlTypeEnum.RADIO.getType()).setDictType("system_sex3");
333   - CodegenColumnDO addressBirthdayColumn = new CodegenColumnDO().setColumnName("birthday").setDataType(JdbcType.DATE.name())
334   - .setColumnComment("出生日期").setNullable(false).setPrimaryKey(false)
335   - .setOrdinalPosition(10).setJavaType("LocalDateTime").setJavaField("birthday")
336   - .setCreateOperation(true).setUpdateOperation(true).setListOperation(true)
337   - .setListOperationCondition(CodegenColumnListConditionEnum.EQ.getCondition()).setListOperationResult(true)
338   - .setHtmlType(CodegenColumnHtmlTypeEnum.DATETIME.getType());
339   - CodegenColumnDO addressMemoColumn = new CodegenColumnDO().setColumnName("memo").setDataType(JdbcType.VARCHAR.name())
340   - .setColumnComment("备注").setNullable(false).setPrimaryKey(false)
341   - .setOrdinalPosition(11).setJavaType("String").setJavaField("memo").setExample("我是备注")
342   - .setCreateOperation(true).setUpdateOperation(true).setListOperation(false)
  434 + CodegenColumnDO teacherCreateTimeColumn = new CodegenColumnDO().setColumnName("create_time").setDataType(JdbcType.DATE.name())
  435 + .setColumnComment("创建时间").setNullable(true)
  436 + .setJavaType("LocalDateTime").setJavaField("createTime")
  437 + .setCreateOperation(false).setUpdateOperation(false)
  438 + .setListOperation(true).setListOperationCondition(CodegenColumnListConditionEnum.BETWEEN.getCondition())
343 439 .setListOperationResult(true)
344   - .setHtmlType(CodegenColumnHtmlTypeEnum.TEXTAREA.getType());
345   - CodegenColumnDO addressCreateTimeColumn = new CodegenColumnDO().setColumnName("create_time").setDataType(JdbcType.DATE.name())
346   - .setColumnComment("创建时间").setNullable(false).setPrimaryKey(false)
347   - .setOrdinalPosition(12).setJavaType("LocalDateTime").setJavaField("createTime")
348   - .setCreateOperation(false).setUpdateOperation(false).setListOperation(true)
349   - .setListOperationCondition(CodegenColumnListConditionEnum.BETWEEN.getCondition()).setListOperationResult(true)
350 440 .setHtmlType(CodegenColumnHtmlTypeEnum.DATETIME.getType());
351   - List<CodegenColumnDO> addressColumns = Arrays.asList(addressIdColumn, addressStudentIdColumn,
352   - addressNameColumn, addressAvatarColumn, addressVideoColumn, addressDescriptionColumn,
353   - addressSex1Column, addressSex2Column, addressSex3Column, addressBirthdayColumn, addressMemoColumn, addressCreateTimeColumn);
  441 + List<CodegenColumnDO> teacherColumns = Arrays.asList(teacherIdColumn, teacherStudentIdColumn,
  442 + teacherNameColumn, teacherDescriptionColumn, teacherBirthdayColumn,
  443 + teacherSexColumn, teacherEnabledColumn, teacherAvatarColumn, teacherVideoColumn, teacherMemoColumn, teacherCreateTimeColumn);
354 444  
355 445 // 调用
356   - Map<String, String> result = codegenEngine.execute(null, null,
357   - Arrays.asList(contactTable, addressTable), Arrays.asList(contactColumns, addressColumns));
  446 + Map<String, String> result = codegenEngine.execute(table, columns,
  447 + Arrays.asList(contactTable, teacherTable), Arrays.asList(contactColumns, teacherColumns));
  448 +
  449 + // 构建 zip 包
  450 + writeFile(result, "/Users/yunai/test/demo11.zip");
358 451  
359 452 // 断言
360 453 assertEquals(27, result.size());
... ... @@ -374,4 +467,22 @@ public class CodegenEngineTest extends BaseMockitoUnitTest {
374 467 assertEquals(pathContent, valueContent);
375 468 }
376 469  
  470 + /**
  471 + * 将生成的代码,写入到文件
  472 + *
  473 + * 用途:方便本地调试
  474 + *
  475 + * @param result 生成的代码
  476 + * @param path 写入文件的路径
  477 + */
  478 + private void writeFile(Map<String, String> result, String path) {
  479 + // 生成压缩包
  480 + String[] paths = result.keySet().toArray(new String[0]);
  481 + ByteArrayInputStream[] ins = result.values().stream().map(IoUtil::toUtf8Stream).toArray(ByteArrayInputStream[]::new);
  482 + ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
  483 + ZipUtil.zip(outputStream, paths, ins);
  484 + // 写入文件
  485 + FileUtil.writeBytes(outputStream.toByteArray(), path);
  486 + }
  487 +
377 488 }
... ...