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

This commit is contained in:
zhijiantianya@gmail.com 2023-11-08 21:00:34 +08:00
parent 2afc2caf1d
commit 2f6456e2b0
48 changed files with 916 additions and 147 deletions

View File

@ -136,4 +136,8 @@ public interface BaseMapperX<T> extends MPJBaseMapper<T> {
return delete(new QueryWrapper<T>().eq(field, value));
}
default int delete(SFunction<T, ?> field, Object value) {
return delete(new LambdaQueryWrapper<T>().eq(field, value));
}
}

View File

@ -54,4 +54,7 @@ public interface ErrorCodeConstants {
ErrorCode DATA_SOURCE_CONFIG_NOT_EXISTS = new ErrorCode(1_001_007_000, "数据源配置不存在");
ErrorCode DATA_SOURCE_CONFIG_NOT_OK = new ErrorCode(1_001_007_001, "数据源配置不正确,无法进行连接");
// ========== 数据源配置 1-001-107-000 ==========
ErrorCode DEMO_STUDENT_NOT_EXISTS = new ErrorCode(1_001_107_000, "学生不存在");
}

View File

@ -44,9 +44,10 @@ public class CodegenUpdateReqVO {
|| getParentMenuId() != null;
}
// TODO 芋艿这里有问题哈
@AssertTrue(message = "关联的子表与字段不能为空")
public boolean isSubValid() {
return ObjectUtil.notEqual(getTemplateType(), CodegenTemplateTypeEnum.MASTER_SUB)
return ObjectUtil.notEqual(getTemplateType(), CodegenTemplateTypeEnum.SUB)
|| (getSubTableId() != null && getSubColumnId() != null);
}

View File

@ -0,0 +1,90 @@
package cn.iocoder.yudao.module.infra.controller.admin.demo02;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
import cn.iocoder.yudao.module.infra.controller.admin.demo02.vo.*;
import cn.iocoder.yudao.module.infra.convert.demo02.InfraDemoStudentConvert;
import cn.iocoder.yudao.module.infra.dal.dataobject.demo02.InfraDemoStudentDO;
import cn.iocoder.yudao.module.infra.service.demo02.InfraDemoStudentService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import java.util.Collection;
import java.util.List;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
@Tag(name = "管理后台 - 学生")
@RestController
@RequestMapping("/infra/demo-student")
@Validated
public class InfraDemoStudentController {
@Resource
private InfraDemoStudentService demoStudentService;
@PostMapping("/create")
@Operation(summary = "创建学生")
@PreAuthorize("@ss.hasPermission('infra:demo-student:create')")
public CommonResult<Long> createDemoStudent(@Valid @RequestBody InfraDemoStudentCreateReqVO createReqVO) {
return success(demoStudentService.createDemoStudent(createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新学生")
@PreAuthorize("@ss.hasPermission('infra:demo-student:update')")
public CommonResult<Boolean> updateDemoStudent(@Valid @RequestBody InfraDemoStudentUpdateReqVO updateReqVO) {
demoStudentService.updateDemoStudent(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除学生")
@Parameter(name = "id", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('infra:demo-student:delete')")
public CommonResult<Boolean> deleteDemoStudent(@RequestParam("id") Long id) {
demoStudentService.deleteDemoStudent(id);
return success(true);
}
@GetMapping("/get")
@Operation(summary = "获得学生")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('infra:demo-student:query')")
public CommonResult<InfraDemoStudentRespVO> getDemoStudent(@RequestParam("id") Long id) {
InfraDemoStudentDO demoStudent = demoStudentService.getDemoStudent(id);
return success(InfraDemoStudentConvert.INSTANCE.convert(demoStudent));
}
@GetMapping("/page")
@Operation(summary = "获得学生分页")
@PreAuthorize("@ss.hasPermission('infra:demo-student:query')")
public CommonResult<PageResult<InfraDemoStudentRespVO>> getDemoStudentPage(@Valid InfraDemoStudentPageReqVO pageVO) {
PageResult<InfraDemoStudentDO> pageResult = demoStudentService.getDemoStudentPage(pageVO);
return success(InfraDemoStudentConvert.INSTANCE.convertPage(pageResult));
}
@GetMapping("/export-excel")
@Operation(summary = "导出学生 Excel")
@PreAuthorize("@ss.hasPermission('infra:demo-student:export')")
@OperateLog(type = EXPORT)
public void exportDemoStudentExcel(@Valid InfraDemoStudentExportReqVO exportReqVO,
HttpServletResponse response) throws IOException {
List<InfraDemoStudentDO> list = demoStudentService.getDemoStudentList(exportReqVO);
// 导出 Excel
List<InfraDemoStudentExcelVO> datas = InfraDemoStudentConvert.INSTANCE.convertList02(list);
ExcelUtils.write(response, "学生.xls", "数据", InfraDemoStudentExcelVO.class, datas);
}
}

View File

@ -0,0 +1 @@
package cn.iocoder.yudao.module.infra.controller.admin.demo02;

View File

@ -0,0 +1,21 @@
package cn.iocoder.yudao.module.infra.controller.admin.demo02.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.util.*;
import javax.validation.constraints.*;
import cn.iocoder.yudao.module.infra.dal.dataobject.demo02.InfraDemoStudentContactDO;
import cn.iocoder.yudao.module.infra.dal.dataobject.demo02.InfraDemoStudentAddressDO;
/**
* 学生 Base VO提供给添加修改详细的子 VO 使用
* 如果子 VO 存在差异的字段请不要添加到这里影响 Swagger 文档生成
*/
@Data
public class InfraDemoStudentBaseVO {
private List<InfraDemoStudentContactDO> demoStudentContacts;
private InfraDemoStudentAddressDO demoStudentAddress;
}

View File

@ -0,0 +1,14 @@
package cn.iocoder.yudao.module.infra.controller.admin.demo02.vo;
import lombok.*;
import java.util.*;
import io.swagger.v3.oas.annotations.media.Schema;
import javax.validation.constraints.*;
@Schema(description = "管理后台 - 学生创建 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class InfraDemoStudentCreateReqVO extends InfraDemoStudentBaseVO {
}

View File

@ -0,0 +1,20 @@
package cn.iocoder.yudao.module.infra.controller.admin.demo02.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.util.*;
import com.alibaba.excel.annotation.ExcelProperty;
/**
* 学生 Excel VO
*
* @author 芋道源码
*/
@Data
public class InfraDemoStudentExcelVO {
@ExcelProperty("编号")
private Long id;
}

View File

@ -0,0 +1,12 @@
package cn.iocoder.yudao.module.infra.controller.admin.demo02.vo;
import lombok.*;
import java.util.*;
import io.swagger.v3.oas.annotations.media.Schema;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
@Schema(description = "管理后台 - 学生 Excel 导出 Request VO参数和 InfraDemoStudentPageReqVO 是一致的")
@Data
public class InfraDemoStudentExportReqVO {
}

View File

@ -0,0 +1,14 @@
package cn.iocoder.yudao.module.infra.controller.admin.demo02.vo;
import lombok.*;
import java.util.*;
import io.swagger.v3.oas.annotations.media.Schema;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
@Schema(description = "管理后台 - 学生分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class InfraDemoStudentPageReqVO extends PageParam {
}

View File

@ -0,0 +1,15 @@
package cn.iocoder.yudao.module.infra.controller.admin.demo02.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
@Schema(description = "管理后台 - 学生 Response VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class InfraDemoStudentRespVO extends InfraDemoStudentBaseVO {
@Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
private Long id;
}

View File

@ -0,0 +1,18 @@
package cn.iocoder.yudao.module.infra.controller.admin.demo02.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.util.*;
import javax.validation.constraints.*;
@Schema(description = "管理后台 - 学生更新 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class InfraDemoStudentUpdateReqVO extends InfraDemoStudentBaseVO {
@Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
@NotNull(message = "编号不能为空")
private Long id;
}

View File

@ -0,0 +1,36 @@
package cn.iocoder.yudao.module.infra.convert.demo02;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.infra.controller.admin.demo02.vo.InfraDemoStudentCreateReqVO;
import cn.iocoder.yudao.module.infra.controller.admin.demo02.vo.InfraDemoStudentExcelVO;
import cn.iocoder.yudao.module.infra.controller.admin.demo02.vo.InfraDemoStudentRespVO;
import cn.iocoder.yudao.module.infra.controller.admin.demo02.vo.InfraDemoStudentUpdateReqVO;
import cn.iocoder.yudao.module.infra.dal.dataobject.demo02.InfraDemoStudentDO;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
import java.util.List;
/**
* 学生 Convert
*
* @author 芋道源码
*/
@Mapper
public interface InfraDemoStudentConvert {
InfraDemoStudentConvert INSTANCE = Mappers.getMapper(InfraDemoStudentConvert.class);
InfraDemoStudentDO convert(InfraDemoStudentCreateReqVO bean);
InfraDemoStudentDO convert(InfraDemoStudentUpdateReqVO bean);
InfraDemoStudentRespVO convert(InfraDemoStudentDO bean);
List<InfraDemoStudentRespVO> convertList(List<InfraDemoStudentDO> list);
PageResult<InfraDemoStudentRespVO> convertPage(PageResult<InfraDemoStudentDO> page);
List<InfraDemoStudentExcelVO> convertList02(List<InfraDemoStudentDO> list);
}

View File

@ -119,16 +119,23 @@ public class CodegenTableDO extends BaseDO {
// ========== 主子表相关字段 ==========
/**
* 子表的表编号
* 主表的编号
*
* 关联 {@link CodegenTableDO#getId()}
*/
private Long subTableId;
private Long masterTableId;
/**
* 子表关联字段编号
* 自己子表关联主表的字段编号
*
* 关联 {@link CodegenColumnDO#getId()}
*/
private Long subColumnId;
private Long subJoinColumnId;
/**
* 主表与子表是否一对多
*
* true一对多
* false一对一
*/
private Boolean subJoinMany;
}

View File

@ -0,0 +1,37 @@
package cn.iocoder.yudao.module.infra.dal.dataobject.demo02;
import lombok.*;
import java.util.*;
import com.baomidou.mybatisplus.annotation.*;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
/**
* 学生地址 DO
*
* @author 芋道源码
*/
@TableName("infra_demo_student_address")
@KeySequence("infra_demo_student_address_seq") // 用于 OraclePostgreSQLKingbaseDB2H2 数据库的主键自增如果是 MySQL 等数据库可不写
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class InfraDemoStudentAddressDO extends BaseDO {
/**
* 编号
*/
@TableId
private Long id;
/**
* 学生编号
*/
private Long studentId;
/**
* 明细
*/
private String detail;
}

View File

@ -0,0 +1,37 @@
package cn.iocoder.yudao.module.infra.dal.dataobject.demo02;
import lombok.*;
import java.util.*;
import com.baomidou.mybatisplus.annotation.*;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
/**
* 学生联系人 DO
*
* @author 芋道源码
*/
@TableName("infra_demo_student_contact")
@KeySequence("infra_demo_student_contact_seq") // 用于 OraclePostgreSQLKingbaseDB2H2 数据库的主键自增如果是 MySQL 等数据库可不写
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class InfraDemoStudentContactDO extends BaseDO {
/**
* 编号
*/
@TableId
private Long id;
/**
* 学生编号
*/
private Long studentId;
/**
* 名字
*/
private String name;
}

View File

@ -0,0 +1,29 @@
package cn.iocoder.yudao.module.infra.dal.dataobject.demo02;
import lombok.*;
import java.util.*;
import com.baomidou.mybatisplus.annotation.*;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
/**
* 学生 DO
*
* @author 芋道源码
*/
@TableName("infra_demo_student")
@KeySequence("infra_demo_student_seq") // 用于 OraclePostgreSQLKingbaseDB2H2 数据库的主键自增如果是 MySQL 等数据库可不写
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class InfraDemoStudentDO extends BaseDO {
/**
* 编号
*/
@TableId
private Long id;
}

View File

@ -0,0 +1,29 @@
package cn.iocoder.yudao.module.infra.dal.mysql.demo02;
import java.util.*;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.module.infra.dal.dataobject.demo02.InfraDemoStudentAddressDO;
import org.apache.ibatis.annotations.Mapper;
/**
* 学生地址 Mapper
*
* @author 芋道源码
*/
@Mapper
public interface InfraDemoStudentAddressMapper extends BaseMapperX<InfraDemoStudentAddressDO> {
default InfraDemoStudentAddressDO selectByStudentId(Long studentId) {
return selectOne(InfraDemoStudentAddressDO::getStudentId, studentId);
}
default List<InfraDemoStudentAddressDO> selectListByStudentId(List<Long> studentIds) {
return selectList(InfraDemoStudentAddressDO::getStudentId, studentIds);
}
default int deleteByStudentId(Long studentId) {
return delete(InfraDemoStudentAddressDO::getStudentId, studentId);
}
}

View File

@ -0,0 +1,29 @@
package cn.iocoder.yudao.module.infra.dal.mysql.demo02;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.module.infra.dal.dataobject.demo02.InfraDemoStudentContactDO;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
/**
* 学生联系人 Mapper
*
* @author 芋道源码
*/
@Mapper
public interface InfraDemoStudentContactMapper extends BaseMapperX<InfraDemoStudentContactDO> {
default List<InfraDemoStudentContactDO> selectListByStudentId(Long studentId) {
return selectList(InfraDemoStudentContactDO::getStudentId, studentId);
}
default List<InfraDemoStudentContactDO> selectListByStudentId(List<Long> studentIds) {
return selectList(InfraDemoStudentContactDO::getStudentId, studentIds);
}
default int deleteByStudentId(Long studentId) {
return delete(InfraDemoStudentContactDO::getStudentId, studentId);
}
}

View File

@ -0,0 +1,31 @@
package cn.iocoder.yudao.module.infra.dal.mysql.demo02;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.infra.controller.admin.demo02.vo.InfraDemoStudentExportReqVO;
import cn.iocoder.yudao.module.infra.controller.admin.demo02.vo.InfraDemoStudentPageReqVO;
import cn.iocoder.yudao.module.infra.dal.dataobject.demo02.InfraDemoStudentDO;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
/**
* 学生 Mapper
*
* @author 芋道源码
*/
@Mapper
public interface InfraDemoStudentMapper extends BaseMapperX<InfraDemoStudentDO> {
default PageResult<InfraDemoStudentDO> selectPage(InfraDemoStudentPageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<InfraDemoStudentDO>()
.orderByDesc(InfraDemoStudentDO::getId));
}
default List<InfraDemoStudentDO> selectList(InfraDemoStudentExportReqVO reqVO) {
return selectList(new LambdaQueryWrapperX<InfraDemoStudentDO>()
.orderByDesc(InfraDemoStudentDO::getId));
}
}

View File

@ -12,9 +12,10 @@ import lombok.Getter;
@Getter
public enum CodegenTemplateTypeEnum {
CRUD(1), // 单表增删改查
ONE(1), // 单表增删改查
TREE(2), // 树表增删改查
MASTER_SUB(3), // 主子表
MASTER(10), // 主子表 - 主表
SUB(11), // 主子表 - 子表
;
/**

View File

@ -238,13 +238,14 @@ public class CodegenServiceImpl implements CodegenService {
// 校验子表是否已经存在
CodegenTableDO subTable = null;
List<CodegenColumnDO> subColumns = null;
if (table.getSubTableId() != null) {
subTable = codegenTableMapper.selectById(table.getSubTableId());
subColumns = codegenColumnMapper.selectListByTableId(table.getSubTableId());
if (table.getMasterTableId() != null) {
subTable = codegenTableMapper.selectById(table.getMasterTableId());
subColumns = codegenColumnMapper.selectListByTableId(table.getMasterTableId());
}
// 执行生成
return codegenEngine.execute(table, columns, subTable, subColumns);
// return codegenEngine.execute(table, columns, subTable, subColumns);
return codegenEngine.execute(table, columns, null, null);
}
@Override

View File

@ -118,7 +118,7 @@ public class CodegenBuilder {
table.setClassName(upperFirst(toCamelCase(subAfter(tableName, '_', false))));
// 去除结尾的表作为类描述
table.setClassComment(StrUtil.removeSuffixIgnoreCase(table.getTableComment(), ""));
table.setTemplateType(CodegenTemplateTypeEnum.CRUD.getType());
table.setTemplateType(CodegenTemplateTypeEnum.ONE.getType());
}
public List<CodegenColumnDO> buildColumns(Long tableId, List<TableField> tableFields) {

View File

@ -1,5 +1,6 @@
package cn.iocoder.yudao.module.infra.service.codegen.inner;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
@ -186,12 +187,12 @@ public class CodegenEngine {
*
* @param table 表定义
* @param columns table 的字段定义数组
* @param subTable 子表定义当且仅当主子表时使用
* @param subColumns subTable 的字段定义数组
* @param subTables 子表数组当且仅当主子表时使用
* @param subColumnsList subTables 的字段定义数组
* @return 生成的代码key 是路径value 是对应代码
*/
public Map<String, String> execute(CodegenTableDO table, List<CodegenColumnDO> columns,
CodegenTableDO subTable, List<CodegenColumnDO> subColumns) {
List<CodegenTableDO> subTables, List<List<CodegenColumnDO>> subColumnsList) {
// 创建 bindingMap
Map<String, Object> bindingMap = new HashMap<>(globalBindingMap);
bindingMap.put("table", table);
@ -212,27 +213,51 @@ public class CodegenEngine {
bindingMap.put("permissionPrefix", table.getModuleName() + ":" + simpleClassNameStrikeCase);
// 特殊主子表专属逻辑
if (subTable != null) {
if (CollUtil.isNotEmpty(subTables)) {
// 创建 bindingMap
bindingMap.put("subTable", subTable);
bindingMap.put("subColumns", subColumns);
bindingMap.put("subColumn", CollectionUtils.findFirst(subColumns, // 关联的字段
column -> Objects.equals(column.getId(), table.getSubColumnId())));
// className 相关
String subSimpleClassName = removePrefix(subTable.getClassName(), upperFirst(subTable.getModuleName()));
bindingMap.put("subSimpleClassName", subSimpleClassName);
bindingMap.put("subClassNameVar", lowerFirst(subSimpleClassName)); // DictType 转换成 dictType用于变量
bindingMap.put("subTables", subTables);
bindingMap.put("subColumnsList", subColumnsList);
List<CodegenColumnDO> subJoinColumns = new ArrayList<>();
List<String> subSimpleClassNames = new ArrayList<>();
List<String> subClassNameVars = new ArrayList<>();
for (int i = 0; i < subTables.size(); i++) {
CodegenTableDO subTable = subTables.get(i);
List<CodegenColumnDO> subColumns = subColumnsList.get(i);
subJoinColumns.add(CollectionUtils.findFirst(subColumns, // 关联的字段
column -> Objects.equals(column.getId(), subTable.getSubJoinColumnId())));
// className 相关
String subSimpleClassName = removePrefix(subTable.getClassName(), upperFirst(subTable.getModuleName()));
subSimpleClassNames.add(subSimpleClassName);
subClassNameVars.add(lowerFirst(subSimpleClassName)); // DictType 转换成 dictType用于变量
}
bindingMap.put("subJoinColumns", subJoinColumns);
bindingMap.put("subSimpleClassNames", subSimpleClassNames);
bindingMap.put("subClassNameVars", subClassNameVars);
}
// 执行生成
Map<String, String> templates = getTemplates(table.getTemplateType(), table.getFrontType());
Map<String, String> result = Maps.newLinkedHashMapWithExpectedSize(templates.size()); // 有序
templates.forEach((vmPath, filePath) -> {
filePath = formatFilePath(filePath, bindingMap);
String content = templateEngine.getTemplate(vmPath).render(bindingMap);
// 去除字段后面多余的 , 逗号
content = content.replaceAll(",\n}", "\n}").replaceAll(",\n }", "\n }");
result.put(filePath, content);
// 特殊主子表专属逻辑
if (isSubTemplate(vmPath)) {
for (int i = 0; i < subTables.size(); i++) {
bindingMap.put("subIndex", i);
// TODO 芋艿这块需要优化下逻辑
String newFilePath = formatFilePath(filePath, bindingMap);
String content = templateEngine.getTemplate(vmPath).render(bindingMap);
// 去除字段后面多余的 , 逗号
content = content.replaceAll(",\n}", "\n}").replaceAll(",\n }", "\n }");
result.put(newFilePath, content);
bindingMap.remove("subIndex");
}
} else {
filePath = formatFilePath(filePath, bindingMap);
String content = templateEngine.getTemplate(vmPath).render(bindingMap);
// 去除字段后面多余的 , 逗号
content = content.replaceAll(",\n}", "\n}").replaceAll(",\n }", "\n }");
result.put(filePath, content);
}
});
return result;
}
@ -242,7 +267,7 @@ public class CodegenEngine {
templates.putAll(SERVER_TEMPLATES);
templates.putAll(FRONT_TEMPLATES.row(frontType));
// 特殊主子表专属逻辑
if (ObjUtil.notEqual(templateType, CodegenTemplateTypeEnum.MASTER_SUB.getType())) {
if (ObjUtil.notEqual(templateType, CodegenTemplateTypeEnum.MASTER.getType())) {
templates.remove(javaTemplatePath("dal/do_sub"));
templates.remove(javaTemplatePath("dal/mapper_sub"));
}
@ -266,8 +291,11 @@ public class CodegenEngine {
filePath = StrUtil.replace(filePath, "${table.businessName}", table.getBusinessName());
filePath = StrUtil.replace(filePath, "${table.className}", table.getClassName());
// 特殊主子表专属逻辑
CodegenTableDO subTable = (CodegenTableDO) bindingMap.get("subTable");
if (subTable != null) {
Integer subIndex = (Integer) bindingMap.get("subIndex");
if (subIndex != null) {
CodegenTableDO subTable = ((List<CodegenTableDO>) bindingMap.get("subTables")).get(subIndex);
filePath = StrUtil.replace(filePath, "${subTable.moduleName}", subTable.getModuleName());
filePath = StrUtil.replace(filePath, "${subTable.businessName}", subTable.getBusinessName());
filePath = StrUtil.replace(filePath, "${subTable.className}", subTable.getClassName());
}
return filePath;
@ -336,4 +364,8 @@ public class CodegenEngine {
private static String vue3VbenTemplatePath(String path) {
return "codegen/vue3_vben/" + path + ".vm";
}
private static boolean isSubTemplate(String path) {
return path.contains("_sub");
}
}

View File

@ -0,0 +1,68 @@
package cn.iocoder.yudao.module.infra.service.demo02;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.infra.controller.admin.demo02.vo.InfraDemoStudentCreateReqVO;
import cn.iocoder.yudao.module.infra.controller.admin.demo02.vo.InfraDemoStudentExportReqVO;
import cn.iocoder.yudao.module.infra.controller.admin.demo02.vo.InfraDemoStudentPageReqVO;
import cn.iocoder.yudao.module.infra.controller.admin.demo02.vo.InfraDemoStudentUpdateReqVO;
import cn.iocoder.yudao.module.infra.dal.dataobject.demo02.InfraDemoStudentDO;
import javax.validation.Valid;
import java.util.Collection;
import java.util.List;
/**
* 学生 Service 接口
*
* @author 芋道源码
*/
public interface InfraDemoStudentService {
/**
* 创建学生
*
* @param createReqVO 创建信息
* @return 编号
*/
Long createDemoStudent(@Valid InfraDemoStudentCreateReqVO createReqVO);
/**
* 更新学生
*
* @param updateReqVO 更新信息
*/
void updateDemoStudent(@Valid InfraDemoStudentUpdateReqVO updateReqVO);
/**
* 删除学生
*
* @param id 编号
*/
void deleteDemoStudent(Long id);
/**
* 获得学生
*
* @param id 编号
* @return 学生
*/
InfraDemoStudentDO getDemoStudent(Long id);
/**
* 获得学生分页
*
* @param pageReqVO 分页查询
* @return 学生分页
*/
PageResult<InfraDemoStudentDO> getDemoStudentPage(InfraDemoStudentPageReqVO pageReqVO);
/**
* 获得学生列表, 用于 Excel 导出
*
* @param exportReqVO 查询条件
* @return 学生列表
*/
List<InfraDemoStudentDO> getDemoStudentList(InfraDemoStudentExportReqVO exportReqVO);
}

View File

@ -0,0 +1,107 @@
package cn.iocoder.yudao.module.infra.service.demo02;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.transaction.annotation.Transactional;
import java.util.*;
import cn.iocoder.yudao.module.infra.controller.admin.demo02.vo.*;
import cn.iocoder.yudao.module.infra.dal.dataobject.demo02.InfraDemoStudentDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.infra.convert.demo02.InfraDemoStudentConvert;
import cn.iocoder.yudao.module.infra.dal.mysql.demo02.InfraDemoStudentMapper;
import cn.iocoder.yudao.module.infra.dal.mysql.demo02.InfraDemoStudentContactMapper;
import cn.iocoder.yudao.module.infra.dal.mysql.demo02.InfraDemoStudentAddressMapper;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.infra.enums.ErrorCodeConstants.*;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ListUtil;
/**
* 学生 Service 实现类
*
* @author 芋道源码
*/
@Service
@Validated
public class InfraDemoStudentServiceImpl implements InfraDemoStudentService {
@Resource
private InfraDemoStudentMapper demoStudentMapper;
@Resource
private InfraDemoStudentContactMapper demoStudentContactMapper;
@Resource
private InfraDemoStudentAddressMapper demoStudentAddressMapper;
@Override
@Transactional(rollbackFor = Exception.class)
public Long createDemoStudent(InfraDemoStudentCreateReqVO createReqVO) {
// 插入
InfraDemoStudentDO demoStudent = InfraDemoStudentConvert.INSTANCE.convert(createReqVO);
demoStudentMapper.insert(demoStudent);
// 插入子表学生联系人
createReqVO.getDemoStudentContacts().forEach(o -> o.setStudentId(demoStudent.getId()));
demoStudentContactMapper.insertBatch(createReqVO.getDemoStudentContacts());
// 插入子表学生地址
createReqVO.getDemoStudentAddress().setStudentId(demoStudent.getId());
demoStudentAddressMapper.insert(createReqVO.getDemoStudentAddress());
// 返回
return demoStudent.getId();
}
@Override
@Transactional(rollbackFor = Exception.class)
public void updateDemoStudent(InfraDemoStudentUpdateReqVO updateReqVO) {
// 校验存在
validateDemoStudentExists(updateReqVO.getId());
// 更新
InfraDemoStudentDO updateObj = InfraDemoStudentConvert.INSTANCE.convert(updateReqVO);
demoStudentMapper.updateById(updateObj);
// 更新子表学生联系人
demoStudentContactMapper.deleteByStudentId(updateReqVO.getId());
updateReqVO.getDemoStudentContacts().forEach(o -> o.setStudentId(updateReqVO.getId()));
demoStudentContactMapper.insertBatch(updateReqVO.getDemoStudentContacts());
// 更新子表学生地址
updateReqVO.getDemoStudentAddress().setStudentId(updateReqVO.getId());
demoStudentAddressMapper.updateById(updateReqVO.getDemoStudentAddress());
}
@Override
@Transactional(rollbackFor = Exception.class)
public void deleteDemoStudent(Long id) {
// 校验存在
validateDemoStudentExists(id);
// 删除
demoStudentMapper.deleteById(id);
// 删除子表学生联系人
demoStudentContactMapper.deleteByStudentId(id);
// 删除子表学生地址
demoStudentAddressMapper.deleteByStudentId(id);
}
private void validateDemoStudentExists(Long id) {
if (demoStudentMapper.selectById(id) == null) {
throw exception(DEMO_STUDENT_NOT_EXISTS);
}
}
@Override
public InfraDemoStudentDO getDemoStudent(Long id) {
return demoStudentMapper.selectById(id);
}
@Override
public PageResult<InfraDemoStudentDO> getDemoStudentPage(InfraDemoStudentPageReqVO pageReqVO) {
return demoStudentMapper.selectPage(pageReqVO);
}
@Override
public List<InfraDemoStudentDO> getDemoStudentList(InfraDemoStudentExportReqVO exportReqVO) {
return demoStudentMapper.selectList(exportReqVO);
}
}

View File

@ -76,16 +76,6 @@ public class ${sceneEnum.prefixClass}${table.className}Controller {
return success(${table.className}Convert.INSTANCE.convert(${classNameVar}));
}
@GetMapping("/list")
@Operation(summary = "获得${table.classComment}列表")
@Parameter(name = "ids", description = "编号列表", required = true, example = "1024,2048")
#if ($sceneEnum.scene == 1) @PreAuthorize("@ss.hasPermission('${permissionPrefix}:query')")#end
public CommonResult<List<${sceneEnum.prefixClass}${table.className}RespVO>> get${simpleClassName}List(@RequestParam("ids") Collection<${primaryColumn.javaType}> ids) {
List<${table.className}DO> list = ${classNameVar}Service.get${simpleClassName}List(ids);
return success(${table.className}Convert.INSTANCE.convertList(list));
}
@GetMapping("/page")
@Operation(summary = "获得${table.classComment}分页")
#if ($sceneEnum.scene == 1) @PreAuthorize("@ss.hasPermission('${permissionPrefix}:query')")#end

View File

@ -23,7 +23,7 @@ import static ${DateUtilsClassName}.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
#end
#end
## 特殊:主子表专属逻辑
#if ( $subTable )
#foreach ($subTable in $subTables)
import ${basePackage}.module.${subTable.moduleName}.dal.dataobject.${subTable.businessName}.${subTable.className}DO;
#end
@ -41,8 +41,14 @@ public class ${sceneEnum.prefixClass}${table.className}BaseVO {
#end
#end
## 特殊:主子表专属逻辑
#if ( $subTable )
private List<${subTable.className}DO> ${subClassNameVar}s;
#foreach ($subTable in $subTables)
#set ($index = $foreach.count - 1)
#if ( $subTable.subJoinMany)
private List<${subTable.className}DO> ${subClassNameVars.get($index)}s;
#else
private ${subTable.className}DO ${subClassNameVars.get($index)};
#end
#end
}

View File

@ -1,3 +1,5 @@
#set ($subTable = $subTables.get($subIndex))##当前表
#set ($subColumns = $subColumnsList.get($subIndex))##当前字段数组
package ${basePackage}.module.${subTable.moduleName}.dal.dataobject.${subTable.businessName};
import lombok.*;

View File

@ -1,3 +1,7 @@
#set ($subTable = $subTables.get($subIndex))##当前表
#set ($subColumns = $subJoinColumnsList.get($subIndex))##当前字段数组
#set ($subJoinColumn = $subJoinColumns.get($subIndex))##当前 join 字段
#set ($SubJoinColumnName = $subJoinColumn.javaField.substring(0,1).toUpperCase() + ${subJoinColumn.javaField.substring(1)})##首字母大写
package ${basePackage}.module.${subTable.moduleName}.dal.mysql.${subTable.businessName};
import java.util.*;
@ -6,7 +10,6 @@ import ${BaseMapperClassName};
import ${basePackage}.module.${subTable.moduleName}.dal.dataobject.${subTable.businessName}.${subTable.className}DO;
import org.apache.ibatis.annotations.Mapper;
#set ($SubColumnName = $subColumn.javaField.substring(0,1).toUpperCase() + ${subColumn.javaField.substring(1)})##首字母大写
/**
* ${subTable.classComment} Mapper
*
@ -15,12 +18,23 @@ import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface ${subTable.className}Mapper extends BaseMapperX<${subTable.className}DO> {
default List<${subTable.className}DO> selectListBy${SubColumnName}(${subColumn.javaType} ${subColumn.javaField}) {
return selectList(${subTable.className}DO::get${SubColumnName}, ${subColumn.javaField});
#if ( $subTable.subJoinMany)
default List<${subTable.className}DO> selectListBy${SubJoinColumnName}(${subJoinColumn.javaType} ${subJoinColumn.javaField}) {
return selectList(${subTable.className}DO::get${SubJoinColumnName}, ${subJoinColumn.javaField});
}
default List<${subTable.className}DO> selectListBy${SubColumnName}(List<${subColumn.javaType}> ${subColumn.javaField}s) {
return selectList(${subTable.className}DO::get${SubColumnName}, ${subColumn.javaField}s);
#else
default ${subTable.className}DO selectBy${SubJoinColumnName}(${subJoinColumn.javaType} ${subJoinColumn.javaField}) {
return selectOne(${subTable.className}DO::get${SubJoinColumnName}, ${subJoinColumn.javaField});
}
#end
default List<${subTable.className}DO> selectListBy${SubJoinColumnName}(List<${subJoinColumn.javaType}> ${subJoinColumn.javaField}s) {
return selectList(${subTable.className}DO::get${SubJoinColumnName}, ${subJoinColumn.javaField}s);
}
default int deleteBy${SubJoinColumnName}(${subJoinColumn.javaType} ${subJoinColumn.javaField}) {
return delete(${subTable.className}DO::get${SubJoinColumnName}, ${subJoinColumn.javaField});
}
}

View File

@ -43,14 +43,6 @@ public interface ${table.className}Service {
*/
${table.className}DO get${simpleClassName}(${primaryColumn.javaType} id);
/**
* 获得${table.classComment}列表
*
* @param ids 编号
* @return ${table.classComment}列表
*/
List<${table.className}DO> get${simpleClassName}List(Collection<${primaryColumn.javaType}> ids);
/**
* 获得${table.classComment}分页
*
@ -67,4 +59,30 @@ public interface ${table.className}Service {
*/
List<${table.className}DO> get${simpleClassName}List(${sceneEnum.prefixClass}${table.className}ExportReqVO exportReqVO);
## 特殊:主子表专属逻辑
#foreach ($subTable in $subTables)
#set ($index = $foreach.count - 1)
#set ($subSimpleClassName = $subSimpleClassNames.get($index))
#set ($subJoinColumn = $subJoinColumns.get($index))##当前 join 字段
#set ($SubJoinColumnName = $subJoinColumn.javaField.substring(0,1).toUpperCase() + ${subJoinColumn.javaField.substring(1)})##首字母大写
#if ( $subTable.subJoinMany )
/**
* 获得${subTable.classComment}列表
*
* @param ${subJoinColumn.javaField} ${subJoinColumn.columnComment}
* @return ${subTable.classComment}列表
*/
List<${subTable.className}DO> get${subSimpleClassName}ListBy${SubJoinColumnName}(${subJoinColumn.javaType} ${subJoinColumn.javaField});
#else
/**
* 获得${subTable.classComment}
*
* @param ${subJoinColumn.javaField} ${subJoinColumn.columnComment}
* @return ${subTable.classComment}
*/
${subTable.className}DO get${subSimpleClassName}By${SubJoinColumnName}(${subJoinColumn.javaType} ${subJoinColumn.javaField});
#end
#end
}

View File

@ -3,6 +3,7 @@ package ${basePackage}.module.${table.moduleName}.service.${table.businessName};
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.transaction.annotation.Transactional;
import java.util.*;
import ${basePackage}.module.${table.moduleName}.controller.${sceneEnum.basePackage}.${table.businessName}.vo.*;
@ -16,8 +17,9 @@ import ${PageResultClassName};
import ${basePackage}.module.${table.moduleName}.convert.${table.businessName}.${table.className}Convert;
import ${basePackage}.module.${table.moduleName}.dal.mysql.${table.businessName}.${table.className}Mapper;
## 特殊:主子表专属逻辑
#if( $subTable )
import ${basePackage}.module.${subTable.moduleName}.dal.mysql.${subTable.businessName}.${subClassNameVar}Mapper;
#foreach ($subTable in $subTables)
#set ($index = $foreach.count - 1)
import ${basePackage}.module.${subTable.moduleName}.dal.mysql.${subTable.businessName}.${subTable.className}Mapper;
#end
import static ${ServiceExceptionUtilClassName}.exception;
@ -38,40 +40,85 @@ public class ${table.className}ServiceImpl implements ${table.className}Service
@Resource
private ${table.className}Mapper ${classNameVar}Mapper;
## 特殊:主子表专属逻辑
#if( $subTable )
#foreach ($subTable in $subTables)
#set ($index = $foreach.count - 1)
@Resource
private ${subTable.className}Mapper ${subClassNameVar}Mapper;
private ${subTable.className}Mapper ${subClassNameVars.get($index)}Mapper;
#end
@Override
## 特殊:主子表专属逻辑
#if ( $subTables.size() > 0)
@Transactional(rollbackFor = Exception.class)
#end
public ${primaryColumn.javaType} create${simpleClassName}(${sceneEnum.prefixClass}${table.className}CreateReqVO createReqVO) {
// 插入
${table.className}DO ${classNameVar} = ${table.className}Convert.INSTANCE.convert(createReqVO);
${classNameVar}Mapper.insert(${classNameVar});
## 特殊:主子表专属逻辑
#if( $subTable )
// 插入子表
${subClassNameVar}Mapper.insertBatch(createReqVO.get${subSimpleClassName}s);
#foreach ($subTable in $subTables)
#set ($index = $foreach.count - 1)
#set ($subJoinColumn = $subJoinColumns.get($index))##当前 join 字段
#set ($SubJoinColumnName = $subJoinColumn.javaField.substring(0,1).toUpperCase() + ${subJoinColumn.javaField.substring(1)})##首字母大写
// 插入子表($subTable.classComment
#if ( $subTable.subJoinMany)
createReqVO.get${subSimpleClassNames.get($index)}s().forEach(o -> o.set$SubJoinColumnName(${classNameVar}.getId()));
${subClassNameVars.get($index)}Mapper.insertBatch(createReqVO.get${subSimpleClassNames.get($index)}s());
#else
createReqVO.get${subSimpleClassNames.get($index)}().set$SubJoinColumnName(${classNameVar}.getId());
${subClassNameVars.get($index)}Mapper.insert(createReqVO.get${subSimpleClassNames.get($index)}());
#end
#end
// 返回
return ${classNameVar}.getId();
}
@Override
## 特殊:主子表专属逻辑
#if ( $subTables.size() > 0)
@Transactional(rollbackFor = Exception.class)
#end
public void update${simpleClassName}(${sceneEnum.prefixClass}${table.className}UpdateReqVO updateReqVO) {
// 校验存在
validate${simpleClassName}Exists(updateReqVO.getId());
// 更新
${table.className}DO updateObj = ${table.className}Convert.INSTANCE.convert(updateReqVO);
${classNameVar}Mapper.updateById(updateObj);
## 特殊:主子表专属逻辑
#foreach ($subTable in $subTables)
#set ($index = $foreach.count - 1)
#set ($subJoinColumn = $subJoinColumns.get($index))##当前 join 字段
#set ($SubJoinColumnName = $subJoinColumn.javaField.substring(0,1).toUpperCase() + ${subJoinColumn.javaField.substring(1)})##首字母大写
// 更新子表($subTable.classComment
#if ( $subTable.subJoinMany)
${subClassNameVars.get($index)}Mapper.deleteBy${SubJoinColumnName}(updateReqVO.getId());
updateReqVO.get${subSimpleClassNames.get($index)}s().forEach(o -> o.set$SubJoinColumnName(updateReqVO.getId()));
${subClassNameVars.get($index)}Mapper.insertBatch(updateReqVO.get${subSimpleClassNames.get($index)}s());
#else
updateReqVO.get${subSimpleClassNames.get($index)}().set$SubJoinColumnName(updateReqVO.getId());
${subClassNameVars.get($index)}Mapper.updateById(updateReqVO.get${subSimpleClassNames.get($index)}());
#end
#end
}
@Override
## 特殊:主子表专属逻辑
#if ( $subTables.size() > 0)
@Transactional(rollbackFor = Exception.class)
#end
public void delete${simpleClassName}(${primaryColumn.javaType} id) {
// 校验存在
validate${simpleClassName}Exists(id);
// 删除
${classNameVar}Mapper.deleteById(id);
## 特殊:主子表专属逻辑
#foreach ($subTable in $subTables)
#set ($index = $foreach.count - 1)
#set ($subJoinColumn = $subJoinColumns.get($index))##当前 join 字段
#set ($SubJoinColumnName = $subJoinColumn.javaField.substring(0,1).toUpperCase() + ${subJoinColumn.javaField.substring(1)})##首字母大写
// 删除子表($subTable.classComment
${subClassNameVars.get($index)}Mapper.deleteBy${SubJoinColumnName}(id);
#end
}
private void validate${simpleClassName}Exists(${primaryColumn.javaType} id) {
@ -85,14 +132,6 @@ public class ${table.className}ServiceImpl implements ${table.className}Service
return ${classNameVar}Mapper.selectById(id);
}
@Override
public List<${table.className}DO> get${simpleClassName}List(Collection<${primaryColumn.javaType}> ids) {
if (CollUtil.isEmpty(ids)) {
return ListUtil.empty();
}
return ${classNameVar}Mapper.selectBatchIds(ids);
}
@Override
public PageResult<${table.className}DO> get${simpleClassName}Page(${sceneEnum.prefixClass}${table.className}PageReqVO pageReqVO) {
return ${classNameVar}Mapper.selectPage(pageReqVO);

View File

@ -31,7 +31,7 @@ public class CodegenEngineTest extends BaseMockitoUnitTest {
@Spy
private CodegenProperties codegenProperties = new CodegenProperties()
.setBasePackage("cn.iocoder.yudao.module");
.setBasePackage("cn.iocoder.yudao");
@BeforeEach
public void setUp() {
@ -45,7 +45,7 @@ public class CodegenEngineTest extends BaseMockitoUnitTest {
.setTableName("system_user").setTableComment("用户表")
.setModuleName("system").setBusinessName("user").setClassName("SystemUser")
.setClassComment("用户").setAuthor("芋道源码")
.setTemplateType(CodegenTemplateTypeEnum.CRUD.getType())
.setTemplateType(CodegenTemplateTypeEnum.ONE.getType())
.setFrontType(CodegenFrontTypeEnum.VUE3.getType())
.setParentMenuId(10L);
CodegenColumnDO idColumn = new CodegenColumnDO().setColumnName("id").setDataType(JdbcType.BIGINT.name())
@ -125,32 +125,32 @@ public class CodegenEngineTest extends BaseMockitoUnitTest {
for (String vo : new String[]{"SystemUserBaseVO", "SystemUserCreateReqVO", "SystemUserUpdateReqVO", "SystemUserRespVO",
"SystemUserPageReqVO", "SystemUserExportReqVO", "SystemUserExcelVO"}) {
assertPathContentEquals("vue3_crud/java/" + vo,
result, "yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/module/system/controller/admin/user/vo/" + vo + ".java");
result, "yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/" + vo + ".java");
}
// 断言 controller
assertPathContentEquals("vue3_crud/java/SystemUserController",
result, "yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/module/system/controller/admin/user/SystemUserController.java");
result, "yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/SystemUserController.java");
// 断言 service
assertPathContentEquals("vue3_crud/java/SystemUserService",
result, "yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/module/system/service/user/SystemUserService.java");
result, "yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/SystemUserService.java");
assertPathContentEquals("vue3_crud/java/SystemUserServiceImpl",
result, "yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/module/system/service/user/SystemUserServiceImpl.java");
result, "yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/SystemUserServiceImpl.java");
// 断言 convert
assertPathContentEquals("vue3_crud/java/SystemUserConvert",
result, "yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/module/system/convert/user/SystemUserConvert.java");
result, "yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/convert/user/SystemUserConvert.java");
// 断言 enums
assertPathContentEquals("vue3_crud/java/ErrorCodeConstants",
result, "yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/module/system/enums/ErrorCodeConstants_手动操作.java");
result, "yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/ErrorCodeConstants_手动操作.java");
// 断言 dal
assertPathContentEquals("vue3_crud/java/SystemUserDO",
result, "yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/module/system/dal/dataobject/user/SystemUserDO.java");
result, "yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/user/SystemUserDO.java");
assertPathContentEquals("vue3_crud/java/SystemUserMapper",
result, "yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/module/system/dal/mysql/user/SystemUserMapper.java");
result, "yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/user/SystemUserMapper.java");
assertPathContentEquals("vue3_crud/java/SystemUserMapper_xml",
result, "yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/user/SystemUserMapper.xml");
// 断言 test
assertPathContentEquals("vue3_crud/java/SystemUserServiceImplTest",
result, "yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/module/system/service/user/SystemUserServiceImplTest.java");
result, "yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/user/SystemUserServiceImplTest.java");
// 断言 sql 语句
assertPathContentEquals("vue3_crud/sql/h2",
result, "sql/h2.sql");
@ -170,73 +170,116 @@ public class CodegenEngineTest extends BaseMockitoUnitTest {
// 准备请求参数
// 主表
CodegenTableDO table = new CodegenTableDO().setScene(CodegenSceneEnum.ADMIN.getScene())
.setTableName("system_user").setTableComment("用户表")
.setModuleName("system").setBusinessName("user").setClassName("SystemUser")
.setClassComment("用户").setAuthor("芋道源码")
.setTemplateType(CodegenTemplateTypeEnum.MASTER_SUB.getType()).setSubColumnId(100L)
.setFrontType(CodegenFrontTypeEnum.VUE3.getType())
.setParentMenuId(10L);
.setTableName("infra_demo_student").setTableComment("学生表")
.setModuleName("infra").setBusinessName("demo02").setClassName("InfraDemoStudent")
.setClassComment("学生").setAuthor("芋道源码")
.setTemplateType(CodegenTemplateTypeEnum.MASTER.getType())
.setFrontType(CodegenFrontTypeEnum.VUE3.getType());
CodegenColumnDO idColumn = new CodegenColumnDO().setColumnName("id").setDataType(JdbcType.BIGINT.name())
.setColumnComment("编号").setNullable(false).setPrimaryKey(true).setAutoIncrement(true)
.setOrdinalPosition(1).setJavaType("Long").setJavaField("id").setExample("1024")
.setCreateOperation(false).setUpdateOperation(true).setListOperation(false)
.setListOperationResult(true);
List<CodegenColumnDO> columns = Collections.singletonList(idColumn);
// 子表
CodegenTableDO subTable = new CodegenTableDO().setScene(CodegenSceneEnum.ADMIN.getScene())
.setTableName("system_user_contact").setTableComment("用户联系人表")
.setModuleName("system").setBusinessName("user").setClassName("SystemUserContact")
.setClassComment("用户联系人").setAuthor("芋道源码")
.setTemplateType(CodegenTemplateTypeEnum.CRUD.getType())
.setFrontType(CodegenFrontTypeEnum.VUE3.getType());
CodegenColumnDO subIdColumn = new CodegenColumnDO().setColumnName("id").setDataType(JdbcType.BIGINT.name())
// 子表联系人
CodegenTableDO contactTable = new CodegenTableDO().setScene(CodegenSceneEnum.ADMIN.getScene())
.setTableName("infra_demo_student_contact").setTableComment("学生联系人表")
.setModuleName("infra").setBusinessName("demo02").setClassName("InfraDemoStudentContact")
.setClassComment("学生联系人").setAuthor("芋道源码")
.setTemplateType(CodegenTemplateTypeEnum.SUB.getType())
.setFrontType(CodegenFrontTypeEnum.VUE3.getType())
.setSubJoinColumnId(100L).setSubJoinMany(true);
CodegenColumnDO contactIdColumn = new CodegenColumnDO().setColumnName("id").setDataType(JdbcType.BIGINT.name())
.setColumnComment("编号").setNullable(false).setPrimaryKey(true).setAutoIncrement(true)
.setOrdinalPosition(1).setJavaType("Long").setJavaField("id").setExample("1024")
.setCreateOperation(false).setUpdateOperation(true).setListOperation(false)
.setListOperationResult(true);
CodegenColumnDO userIdColumn = new CodegenColumnDO().setColumnName("user_id").setDataType(JdbcType.BIGINT.name())
.setColumnComment("用户编号").setNullable(false).setPrimaryKey(false)
.setOrdinalPosition(2).setJavaType("Long").setJavaField("userId").setExample("2048")
CodegenColumnDO contactStudentIdColumn = new CodegenColumnDO().setColumnName("student_id").setDataType(JdbcType.BIGINT.name())
.setColumnComment("学生编号").setNullable(false).setPrimaryKey(false)
.setOrdinalPosition(2).setJavaType("Long").setJavaField("studentId").setExample("2048")
.setCreateOperation(false).setUpdateOperation(true).setListOperation(false)
.setListOperationResult(true)
.setId(100L);
List<CodegenColumnDO> subColumns = Arrays.asList(subIdColumn, userIdColumn);
CodegenColumnDO contactNameColumn = new CodegenColumnDO().setColumnName("name").setDataType(JdbcType.VARCHAR.name())
.setColumnComment("名字").setNullable(false).setPrimaryKey(false)
.setOrdinalPosition(3).setJavaType("String").setJavaField("name").setExample("芋头")
.setCreateOperation(true).setUpdateOperation(true).setListOperation(true)
.setListOperationCondition(CodegenColumnListConditionEnum.LIKE.getCondition()).setListOperationResult(true)
.setHtmlType(CodegenColumnHtmlTypeEnum.INPUT.getType());
List<CodegenColumnDO> contactColumns = Arrays.asList(contactIdColumn, contactStudentIdColumn, contactNameColumn);
// 子表地址
CodegenTableDO addressTable = new CodegenTableDO().setScene(CodegenSceneEnum.ADMIN.getScene())
.setTableName("infra_demo_student_address").setTableComment("学生地址表")
.setModuleName("infra").setBusinessName("demo02").setClassName("InfraDemoStudentAddress")
.setClassComment("学生地址").setAuthor("芋道源码")
.setTemplateType(CodegenTemplateTypeEnum.SUB.getType())
.setFrontType(CodegenFrontTypeEnum.VUE3.getType())
.setSubJoinColumnId(200L).setSubJoinMany(false);
CodegenColumnDO addressIdColumn = new CodegenColumnDO().setColumnName("id").setDataType(JdbcType.BIGINT.name())
.setColumnComment("编号").setNullable(false).setPrimaryKey(true).setAutoIncrement(true)
.setOrdinalPosition(1).setJavaType("Long").setJavaField("id").setExample("1024")
.setCreateOperation(false).setUpdateOperation(true).setListOperation(false)
.setListOperationResult(true);
CodegenColumnDO addressStudentColumn = new CodegenColumnDO().setColumnName("student_id").setDataType(JdbcType.BIGINT.name())
.setColumnComment("学生编号").setNullable(false).setPrimaryKey(false)
.setOrdinalPosition(2).setJavaType("Long").setJavaField("studentId").setExample("2048")
.setCreateOperation(false).setUpdateOperation(true).setListOperation(false)
.setListOperationResult(true)
.setId(200L);
CodegenColumnDO addressDetailColumn = new CodegenColumnDO().setColumnName("detail").setDataType(JdbcType.VARCHAR.name())
.setColumnComment("明细").setNullable(false).setPrimaryKey(false)
.setOrdinalPosition(3).setJavaType("String").setJavaField("detail").setExample("码头路 88 号")
.setCreateOperation(true).setUpdateOperation(true).setListOperation(true)
.setListOperationCondition(CodegenColumnListConditionEnum.LIKE.getCondition()).setListOperationResult(true)
.setHtmlType(CodegenColumnHtmlTypeEnum.INPUT.getType());
List<CodegenColumnDO> addressColumns = Arrays.asList(addressIdColumn, addressStudentColumn, addressDetailColumn);
// 调用
Map<String, String> result = codegenEngine.execute(table, columns, subTable, subColumns);
Map<String, String> result = codegenEngine.execute(table, columns,
Arrays.asList(contactTable, addressTable), Arrays.asList(contactColumns, addressColumns));
// 断言
assertEquals(23, result.size());
assertEquals(25, result.size());
for (Map.Entry<String, String> entry : result.entrySet()) {
System.out.println(entry.getKey());
System.out.println(entry.getValue());
System.out.println("");
System.out.println("");
System.out.println("");
}
// // 断言 vo
// for (String vo : new String[]{"SystemUserBaseVO", "SystemUserCreateReqVO", "SystemUserUpdateReqVO", "SystemUserRespVO",
// "SystemUserPageReqVO", "SystemUserExportReqVO", "SystemUserExcelVO"}) {
// assertPathContentEquals("vue3_crud/java/" + vo,
// result, "yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/module/system/controller/admin/user/vo/" + vo + ".java");
// result, "yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/" + vo + ".java");
// }
// // 断言 controller
// assertPathContentEquals("vue3_crud/java/SystemUserController",
// result, "yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/module/system/controller/admin/user/SystemUserController.java");
// result, "yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/SystemUserController.java");
// // 断言 service
// assertPathContentEquals("vue3_crud/java/SystemUserService",
// result, "yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/module/system/service/user/SystemUserService.java");
// result, "yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/SystemUserService.java");
// assertPathContentEquals("vue3_crud/java/SystemUserServiceImpl",
// result, "yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/module/system/service/user/SystemUserServiceImpl.java");
// result, "yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/SystemUserServiceImpl.java");
// // 断言 convert
// assertPathContentEquals("vue3_crud/java/SystemUserConvert",
// result, "yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/module/system/convert/user/SystemUserConvert.java");
// result, "yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/convert/user/SystemUserConvert.java");
// // 断言 enums
// assertPathContentEquals("vue3_crud/java/ErrorCodeConstants",
// result, "yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/module/system/enums/ErrorCodeConstants_手动操作.java");
// result, "yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/ErrorCodeConstants_手动操作.java");
// // 断言 dal
// assertPathContentEquals("vue3_crud/java/SystemUserDO",
// result, "yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/module/system/dal/dataobject/user/SystemUserDO.java");
// result, "yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/user/SystemUserDO.java");
// assertPathContentEquals("vue3_crud/java/SystemUserMapper",
// result, "yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/module/system/dal/mysql/user/SystemUserMapper.java");
// result, "yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/user/SystemUserMapper.java");
// assertPathContentEquals("vue3_crud/java/SystemUserMapper_xml",
// result, "yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/user/SystemUserMapper.xml");
// // 断言 test
// assertPathContentEquals("vue3_crud/java/SystemUserServiceImplTest",
// result, "yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/module/system/service/user/SystemUserServiceImplTest.java");
// result, "yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/user/SystemUserServiceImplTest.java");
// // 断言 sql 语句
// assertPathContentEquals("vue3_crud/sql/h2",
// result, "sql/h2.sql");

View File

@ -1,4 +1,4 @@
package cn.iocoder.yudao.module.module.system.controller.admin.user.vo;
package cn.iocoder.yudao.module.system.controller.admin.user.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;

View File

@ -1,4 +1,4 @@
package cn.iocoder.yudao.module.module.system.controller.admin.user;
package cn.iocoder.yudao.module.system.controller.admin.user;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
@ -23,10 +23,10 @@ import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.*;
import cn.iocoder.yudao.module.module.system.controller.admin.user.vo.*;
import cn.iocoder.yudao.module.module.system.dal.dataobject.user.SystemUserDO;
import cn.iocoder.yudao.module.module.system.convert.user.SystemUserConvert;
import cn.iocoder.yudao.module.module.system.service.user.SystemUserService;
import cn.iocoder.yudao.module.system.controller.admin.user.vo.*;
import cn.iocoder.yudao.module.system.dal.dataobject.user.SystemUserDO;
import cn.iocoder.yudao.module.system.convert.user.SystemUserConvert;
import cn.iocoder.yudao.module.system.service.user.SystemUserService;
@Tag(name = "管理后台 - 用户")
@RestController

View File

@ -1,4 +1,4 @@
package cn.iocoder.yudao.module.module.system.convert.user;
package cn.iocoder.yudao.module.system.convert.user;
import java.util.*;
@ -6,8 +6,8 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
import cn.iocoder.yudao.module.module.system.controller.admin.user.vo.*;
import cn.iocoder.yudao.module.module.system.dal.dataobject.user.SystemUserDO;
import cn.iocoder.yudao.module.system.controller.admin.user.vo.*;
import cn.iocoder.yudao.module.system.dal.dataobject.user.SystemUserDO;
/**
* 用户 Convert

View File

@ -1,4 +1,4 @@
package cn.iocoder.yudao.module.module.system.controller.admin.user.vo;
package cn.iocoder.yudao.module.system.controller.admin.user.vo;
import lombok.*;
import java.util.*;

View File

@ -1,4 +1,4 @@
package cn.iocoder.yudao.module.module.system.dal.dataobject.user;
package cn.iocoder.yudao.module.system.dal.dataobject.user;
import lombok.*;
import java.util.*;

View File

@ -1,4 +1,4 @@
package cn.iocoder.yudao.module.module.system.controller.admin.user.vo;
package cn.iocoder.yudao.module.system.controller.admin.user.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;

View File

@ -1,4 +1,4 @@
package cn.iocoder.yudao.module.module.system.controller.admin.user.vo;
package cn.iocoder.yudao.module.system.controller.admin.user.vo;
import lombok.*;
import java.util.*;

View File

@ -1,13 +1,13 @@
package cn.iocoder.yudao.module.module.system.dal.mysql.user;
package cn.iocoder.yudao.module.system.dal.mysql.user;
import java.util.*;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.module.module.system.dal.dataobject.user.SystemUserDO;
import cn.iocoder.yudao.module.system.dal.dataobject.user.SystemUserDO;
import org.apache.ibatis.annotations.Mapper;
import cn.iocoder.yudao.module.module.system.controller.admin.user.vo.*;
import cn.iocoder.yudao.module.system.controller.admin.user.vo.*;
/**
* 用户 Mapper

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.iocoder.yudao.module.module.system.dal.mysql.user.SystemUserMapper">
<mapper namespace="cn.iocoder.yudao.module.system.dal.mysql.user.SystemUserMapper">
<!--
一般情况下,尽可能使用 Mapper 进行 CRUD 增删改查即可。

View File

@ -1,4 +1,4 @@
package cn.iocoder.yudao.module.module.system.controller.admin.user.vo;
package cn.iocoder.yudao.module.system.controller.admin.user.vo;
import lombok.*;
import java.util.*;

View File

@ -1,4 +1,4 @@
package cn.iocoder.yudao.module.module.system.controller.admin.user.vo;
package cn.iocoder.yudao.module.system.controller.admin.user.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;

View File

@ -1,9 +1,9 @@
package cn.iocoder.yudao.module.module.system.service.user;
package cn.iocoder.yudao.module.system.service.user;
import java.util.*;
import javax.validation.*;
import cn.iocoder.yudao.module.module.system.controller.admin.user.vo.*;
import cn.iocoder.yudao.module.module.system.dal.dataobject.user.SystemUserDO;
import cn.iocoder.yudao.module.system.controller.admin.user.vo.*;
import cn.iocoder.yudao.module.system.dal.dataobject.user.SystemUserDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
/**

View File

@ -1,19 +1,19 @@
package cn.iocoder.yudao.module.module.system.service.user;
package cn.iocoder.yudao.module.system.service.user;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import java.util.*;
import cn.iocoder.yudao.module.module.system.controller.admin.user.vo.*;
import cn.iocoder.yudao.module.module.system.dal.dataobject.user.SystemUserDO;
import cn.iocoder.yudao.module.system.controller.admin.user.vo.*;
import cn.iocoder.yudao.module.system.dal.dataobject.user.SystemUserDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.module.system.convert.user.SystemUserConvert;
import cn.iocoder.yudao.module.module.system.dal.mysql.user.SystemUserMapper;
import cn.iocoder.yudao.module.system.convert.user.SystemUserConvert;
import cn.iocoder.yudao.module.system.dal.mysql.user.SystemUserMapper;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.module.system.enums.ErrorCodeConstants.*;
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ListUtil;

View File

@ -1,4 +1,4 @@
package cn.iocoder.yudao.module.module.system.service.user;
package cn.iocoder.yudao.module.system.service.user;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
@ -8,9 +8,9 @@ import javax.annotation.Resource;
import cn.iocoder.yudao.module.framework.test.core.ut.BaseDbUnitTest;
import cn.iocoder.yudao.module.module.system.controller.admin.user.vo.*;
import cn.iocoder.yudao.module.module.system.dal.dataobject.user.SystemUserDO;
import cn.iocoder.yudao.module.module.system.dal.mysql.user.SystemUserMapper;
import cn.iocoder.yudao.module.system.controller.admin.user.vo.*;
import cn.iocoder.yudao.module.system.dal.dataobject.user.SystemUserDO;
import cn.iocoder.yudao.module.system.dal.mysql.user.SystemUserMapper;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import javax.annotation.Resource;
@ -19,7 +19,7 @@ import java.util.*;
import java.time.LocalDateTime;
import static cn.hutool.core.util.RandomUtil.*;
import static cn.iocoder.yudao.module.module.system.enums.ErrorCodeConstants.*;
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;
import static cn.iocoder.yudao.module.framework.test.core.util.AssertUtils.*;
import static cn.iocoder.yudao.module.framework.test.core.util.RandomUtils.*;
import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.*;

View File

@ -1,4 +1,4 @@
package cn.iocoder.yudao.module.module.system.controller.admin.user.vo;
package cn.iocoder.yudao.module.system.controller.admin.user.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;