集成必要性功能
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
package com.njcn.rdms.module.system.api.logger;
|
||||
|
||||
import com.njcn.rdms.framework.common.biz.infra.logger.ApiAccessLogCommonApi;
|
||||
import com.njcn.rdms.framework.common.biz.infra.logger.dto.ApiAccessLogCreateReqDTO;
|
||||
import com.njcn.rdms.framework.common.biz.system.logger.ApiAccessLogCommonApi;
|
||||
import com.njcn.rdms.framework.common.biz.system.logger.dto.ApiAccessLogCreateReqDTO;
|
||||
import com.njcn.rdms.framework.common.pojo.CommonResult;
|
||||
import com.njcn.rdms.module.system.service.logger.ApiAccessLogService;
|
||||
import jakarta.annotation.Resource;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package com.njcn.rdms.module.system.api.logger;
|
||||
|
||||
import com.njcn.rdms.framework.common.biz.infra.logger.ApiErrorLogCommonApi;
|
||||
import com.njcn.rdms.framework.common.biz.infra.logger.dto.ApiErrorLogCreateReqDTO;
|
||||
import com.njcn.rdms.framework.common.biz.system.logger.ApiErrorLogCommonApi;
|
||||
import com.njcn.rdms.framework.common.biz.system.logger.dto.ApiErrorLogCreateReqDTO;
|
||||
import com.njcn.rdms.framework.common.pojo.CommonResult;
|
||||
import com.njcn.rdms.module.system.service.logger.ApiErrorLogService;
|
||||
import jakarta.annotation.Resource;
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
package com.njcn.rdms.module.system.api.mail;
|
||||
|
||||
import com.njcn.rdms.framework.common.pojo.CommonResult;
|
||||
import com.njcn.rdms.module.system.api.mail.dto.MailSendSingleToUserReqDTO;
|
||||
import com.njcn.rdms.module.system.service.mail.MailSendService;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import static com.njcn.rdms.framework.common.pojo.CommonResult.success;
|
||||
|
||||
@RestController // 提供 RESTful API 接口,给 Feign 调用
|
||||
@Validated
|
||||
public class MailSendApiImpl implements MailSendApi {
|
||||
|
||||
@Resource
|
||||
private MailSendService mailSendService;
|
||||
|
||||
@Override
|
||||
public CommonResult<Long> sendSingleMailToAdmin(MailSendSingleToUserReqDTO reqDTO) {
|
||||
return success(mailSendService.sendSingleMailToAdmin(reqDTO.getUserId(),
|
||||
reqDTO.getToMails(), reqDTO.getCcMails(), reqDTO.getBccMails(),
|
||||
reqDTO.getTemplateCode(), reqDTO.getTemplateParams(), reqDTO.getAttachments()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommonResult<Long> sendSingleMailToMember(MailSendSingleToUserReqDTO reqDTO) {
|
||||
return success(mailSendService.sendSingleMailToMember(reqDTO.getUserId(),
|
||||
reqDTO.getToMails(), reqDTO.getCcMails(), reqDTO.getBccMails(),
|
||||
reqDTO.getTemplateCode(), reqDTO.getTemplateParams(), reqDTO.getAttachments()));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,160 +0,0 @@
|
||||
package com.njcn.rdms.module.system.controller.admin.codegen;
|
||||
|
||||
import cn.hutool.core.io.IoUtil;
|
||||
import cn.hutool.core.util.ZipUtil;
|
||||
import com.njcn.rdms.framework.common.pojo.CommonResult;
|
||||
import com.njcn.rdms.framework.common.pojo.PageResult;
|
||||
import com.njcn.rdms.framework.common.util.object.BeanUtils;
|
||||
import com.njcn.rdms.module.system.controller.admin.codegen.vo.CodegenCreateListReqVO;
|
||||
import com.njcn.rdms.module.system.controller.admin.codegen.vo.CodegenDetailRespVO;
|
||||
import com.njcn.rdms.module.system.controller.admin.codegen.vo.CodegenPreviewRespVO;
|
||||
import com.njcn.rdms.module.system.controller.admin.codegen.vo.CodegenUpdateReqVO;
|
||||
import com.njcn.rdms.module.system.controller.admin.codegen.vo.table.CodegenTablePageReqVO;
|
||||
import com.njcn.rdms.module.system.controller.admin.codegen.vo.table.CodegenTableRespVO;
|
||||
import com.njcn.rdms.module.system.controller.admin.codegen.vo.table.DatabaseTableRespVO;
|
||||
import com.njcn.rdms.module.system.convert.codegen.CodegenConvert;
|
||||
import com.njcn.rdms.module.system.dal.dataobject.codegen.CodegenColumnDO;
|
||||
import com.njcn.rdms.module.system.dal.dataobject.codegen.CodegenTableDO;
|
||||
import com.njcn.rdms.module.system.service.codegen.CodegenService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.Parameters;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import jakarta.validation.Valid;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static com.njcn.rdms.framework.common.pojo.CommonResult.success;
|
||||
import static com.njcn.rdms.framework.security.core.util.SecurityFrameworkUtils.getLoginUserNickname;
|
||||
import static com.njcn.rdms.module.system.framework.file.core.utils.FileTypeUtils.writeAttachment;
|
||||
|
||||
@Tag(name = "管理后台 - 代码生成器")
|
||||
@RestController
|
||||
@RequestMapping("/infra/codegen")
|
||||
@Validated
|
||||
public class CodegenController {
|
||||
|
||||
@Resource
|
||||
private CodegenService codegenService;
|
||||
|
||||
@GetMapping("/db/table/list")
|
||||
@Operation(summary = "获得数据库自带的表定义列表", description = "会过滤掉已经导入 Codegen 的表")
|
||||
@Parameters({
|
||||
@Parameter(name = "dataSourceConfigId", description = "数据源配置的编号", required = true, example = "1"),
|
||||
@Parameter(name = "name", description = "表名,模糊匹配", example = "rdms"),
|
||||
@Parameter(name = "comment", description = "描述,模糊匹配", example = "灿能")
|
||||
})
|
||||
@PreAuthorize("@ss.hasPermission('infra:codegen:query')")
|
||||
public CommonResult<List<DatabaseTableRespVO>> getDatabaseTableList(
|
||||
@RequestParam(value = "dataSourceConfigId") Long dataSourceConfigId,
|
||||
@RequestParam(value = "name", required = false) String name,
|
||||
@RequestParam(value = "comment", required = false) String comment) {
|
||||
return success(codegenService.getDatabaseTableList(dataSourceConfigId, name, comment));
|
||||
}
|
||||
|
||||
@GetMapping("/table/list")
|
||||
@Operation(summary = "获得表定义列表")
|
||||
@Parameter(name = "dataSourceConfigId", description = "数据源配置的编号", required = true, example = "1")
|
||||
@PreAuthorize("@ss.hasPermission('infra:codegen:query')")
|
||||
public CommonResult<List<CodegenTableRespVO>> getCodegenTableList(@RequestParam(value = "dataSourceConfigId") Long dataSourceConfigId) {
|
||||
List<CodegenTableDO> list = codegenService.getCodegenTableList(dataSourceConfigId);
|
||||
return success(BeanUtils.toBean(list, CodegenTableRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/table/page")
|
||||
@Operation(summary = "获得表定义分页")
|
||||
@PreAuthorize("@ss.hasPermission('infra:codegen:query')")
|
||||
public CommonResult<PageResult<CodegenTableRespVO>> getCodegenTablePage(@Valid CodegenTablePageReqVO pageReqVO) {
|
||||
PageResult<CodegenTableDO> pageResult = codegenService.getCodegenTablePage(pageReqVO);
|
||||
return success(BeanUtils.toBean(pageResult, CodegenTableRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/detail")
|
||||
@Operation(summary = "获得表和字段的明细")
|
||||
@Parameter(name = "tableId", description = "表编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('infra:codegen:query')")
|
||||
public CommonResult<CodegenDetailRespVO> getCodegenDetail(@RequestParam("tableId") Long tableId) {
|
||||
CodegenTableDO table = codegenService.getCodegenTable(tableId);
|
||||
List<CodegenColumnDO> columns = codegenService.getCodegenColumnListByTableId(tableId);
|
||||
// 拼装返回
|
||||
return success(CodegenConvert.INSTANCE.convert(table, columns));
|
||||
}
|
||||
|
||||
@Operation(summary = "基于数据库的表结构,创建代码生成器的表和字段定义")
|
||||
@PostMapping("/create-list")
|
||||
@PreAuthorize("@ss.hasPermission('infra:codegen:create')")
|
||||
public CommonResult<List<Long>> createCodegenList(@Valid @RequestBody CodegenCreateListReqVO reqVO) {
|
||||
return success(codegenService.createCodegenList(getLoginUserNickname(), reqVO));
|
||||
}
|
||||
|
||||
@Operation(summary = "更新数据库的表和字段定义")
|
||||
@PutMapping("/update")
|
||||
@PreAuthorize("@ss.hasPermission('infra:codegen:update')")
|
||||
public CommonResult<Boolean> updateCodegen(@Valid @RequestBody CodegenUpdateReqVO updateReqVO) {
|
||||
codegenService.updateCodegen(updateReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@Operation(summary = "基于数据库的表结构,同步数据库的表和字段定义")
|
||||
@PutMapping("/sync-from-db")
|
||||
@Parameter(name = "tableId", description = "表编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('infra:codegen:update')")
|
||||
public CommonResult<Boolean> syncCodegenFromDB(@RequestParam("tableId") Long tableId) {
|
||||
codegenService.syncCodegenFromDB(tableId);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@Operation(summary = "删除数据库的表和字段定义")
|
||||
@DeleteMapping("/delete")
|
||||
@Parameter(name = "tableId", description = "表编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('infra:codegen:delete')")
|
||||
public CommonResult<Boolean> deleteCodegen(@RequestParam("tableId") Long tableId) {
|
||||
codegenService.deleteCodegen(tableId);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@Operation(summary = "批量删除数据库的表和字段定义")
|
||||
@DeleteMapping("/delete-list")
|
||||
@Parameter(name = "tableIds", description = "表编号列表", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('infra:codegen:delete')")
|
||||
public CommonResult<Boolean> deleteCodegenList(@RequestParam("tableIds") List<Long> tableIds) {
|
||||
codegenService.deleteCodegenList(tableIds);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@Operation(summary = "预览生成代码")
|
||||
@GetMapping("/preview")
|
||||
@Parameter(name = "tableId", description = "表编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('infra:codegen:preview')")
|
||||
public CommonResult<List<CodegenPreviewRespVO>> previewCodegen(@RequestParam("tableId") Long tableId) {
|
||||
Map<String, String> codes = codegenService.generationCodes(tableId);
|
||||
return success(CodegenConvert.INSTANCE.convert(codes));
|
||||
}
|
||||
|
||||
@Operation(summary = "下载生成代码")
|
||||
@GetMapping("/download")
|
||||
@Parameter(name = "tableId", description = "表编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('infra:codegen:download')")
|
||||
public void downloadCodegen(@RequestParam("tableId") Long tableId,
|
||||
HttpServletResponse response) throws IOException {
|
||||
// 生成代码
|
||||
Map<String, String> codes = codegenService.generationCodes(tableId);
|
||||
// 构建 zip 包
|
||||
String[] paths = codes.keySet().toArray(new String[0]);
|
||||
ByteArrayInputStream[] ins = codes.values().stream().map(IoUtil::toUtf8Stream).toArray(ByteArrayInputStream[]::new);
|
||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||
ZipUtil.zip(outputStream, paths, ins);
|
||||
// 输出
|
||||
writeAttachment(response, "codegen.zip", outputStream.toByteArray());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
package com.njcn.rdms.module.system.controller.admin.codegen.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Schema(description = "管理后台 - 基于数据库的表结构,创建代码生成器的表和字段定义 Request VO")
|
||||
@Data
|
||||
public class CodegenCreateListReqVO {
|
||||
|
||||
@Schema(description = "数据源配置的编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@NotNull(message = "数据源配置的编号不能为空")
|
||||
private Long dataSourceConfigId;
|
||||
|
||||
@Schema(description = "表名数组", requiredMode = Schema.RequiredMode.REQUIRED, example = "[1, 2, 3]")
|
||||
@NotNull(message = "表名数组不能为空")
|
||||
private List<String> tableNames;
|
||||
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
package com.njcn.rdms.module.system.controller.admin.codegen.vo;
|
||||
|
||||
import com.njcn.rdms.module.system.controller.admin.codegen.vo.column.CodegenColumnRespVO;
|
||||
import com.njcn.rdms.module.system.controller.admin.codegen.vo.table.CodegenTableRespVO;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Schema(description = "管理后台 - 代码生成表和字段的明细 Response VO")
|
||||
@Data
|
||||
public class CodegenDetailRespVO {
|
||||
|
||||
@Schema(description = "表定义")
|
||||
private CodegenTableRespVO table;
|
||||
|
||||
@Schema(description = "字段定义")
|
||||
private List<CodegenColumnRespVO> columns;
|
||||
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
package com.njcn.rdms.module.system.controller.admin.codegen.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
@Schema(description = "管理后台 - 代码生成预览 Response VO,注意,每个文件都是一个该对象")
|
||||
@Data
|
||||
public class CodegenPreviewRespVO {
|
||||
|
||||
@Schema(description = "文件路径", requiredMode = Schema.RequiredMode.REQUIRED, example = "java/com.njcn.rdms/adminserver/modules/system/controller/test/SysTestDemoController.java")
|
||||
private String filePath;
|
||||
|
||||
@Schema(description = "代码", requiredMode = Schema.RequiredMode.REQUIRED, example = "Hello World")
|
||||
private String code;
|
||||
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
package com.njcn.rdms.module.system.controller.admin.codegen.vo;
|
||||
|
||||
import com.njcn.rdms.module.system.controller.admin.codegen.vo.column.CodegenColumnSaveReqVO;
|
||||
import com.njcn.rdms.module.system.controller.admin.codegen.vo.table.CodegenTableSaveReqVO;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.Valid;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Schema(description = "管理后台 - 代码生成表和字段的修改 Request VO")
|
||||
@Data
|
||||
public class CodegenUpdateReqVO {
|
||||
|
||||
@Valid // 校验内嵌的字段
|
||||
@NotNull(message = "表定义不能为空")
|
||||
private CodegenTableSaveReqVO table;
|
||||
|
||||
@Valid // 校验内嵌的字段
|
||||
@NotNull(message = "字段定义不能为空")
|
||||
private List<CodegenColumnSaveReqVO> columns;
|
||||
|
||||
}
|
||||
@@ -1,69 +0,0 @@
|
||||
package com.njcn.rdms.module.system.controller.admin.codegen.vo.column;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Schema(description = "管理后台 - 代码生成字段定义 Response VO")
|
||||
@Data
|
||||
public class CodegenColumnRespVO {
|
||||
|
||||
@Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "表编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private Long tableId;
|
||||
|
||||
@Schema(description = "字段名", requiredMode = Schema.RequiredMode.REQUIRED, example = "user_age")
|
||||
private String columnName;
|
||||
|
||||
@Schema(description = "字段类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "int(11)")
|
||||
private String dataType;
|
||||
|
||||
@Schema(description = "字段描述", requiredMode = Schema.RequiredMode.REQUIRED, example = "年龄")
|
||||
private String columnComment;
|
||||
|
||||
@Schema(description = "是否允许为空", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
|
||||
private Boolean nullable;
|
||||
|
||||
@Schema(description = "是否主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "false")
|
||||
private Boolean primaryKey;
|
||||
|
||||
@Schema(description = "排序", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
|
||||
private Integer ordinalPosition;
|
||||
|
||||
@Schema(description = "Java 属性类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "userAge")
|
||||
private String javaType;
|
||||
|
||||
@Schema(description = "Java 属性名", requiredMode = Schema.RequiredMode.REQUIRED, example = "Integer")
|
||||
private String javaField;
|
||||
|
||||
@Schema(description = "字典类型", example = "sys_gender")
|
||||
private String dictType;
|
||||
|
||||
@Schema(description = "数据示例", example = "1024")
|
||||
private String example;
|
||||
|
||||
@Schema(description = "是否为 Create 创建操作的字段", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
|
||||
private Boolean createOperation;
|
||||
|
||||
@Schema(description = "是否为 Update 更新操作的字段", requiredMode = Schema.RequiredMode.REQUIRED, example = "false")
|
||||
private Boolean updateOperation;
|
||||
|
||||
@Schema(description = "是否为 List 查询操作的字段", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
|
||||
private Boolean listOperation;
|
||||
|
||||
@Schema(description = "List 查询操作的条件类型,参见 CodegenColumnListConditionEnum 枚举", requiredMode = Schema.RequiredMode.REQUIRED, example = "LIKE")
|
||||
private String listOperationCondition;
|
||||
|
||||
@Schema(description = "是否为 List 查询操作的返回字段", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
|
||||
private Boolean listOperationResult;
|
||||
|
||||
@Schema(description = "显示类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "input")
|
||||
private String htmlType;
|
||||
|
||||
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private LocalDateTime createTime;
|
||||
|
||||
}
|
||||
@@ -1,80 +0,0 @@
|
||||
package com.njcn.rdms.module.system.controller.admin.codegen.vo.column;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
@Schema(description = "管理后台 - 代码生成字段定义创建/修改 Request VO")
|
||||
@Data
|
||||
public class CodegenColumnSaveReqVO {
|
||||
|
||||
@Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "表编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@NotNull(message = "表编号不能为空")
|
||||
private Long tableId;
|
||||
|
||||
@Schema(description = "字段名", requiredMode = Schema.RequiredMode.REQUIRED, example = "user_age")
|
||||
@NotNull(message = "字段名不能为空")
|
||||
private String columnName;
|
||||
|
||||
@Schema(description = "字段类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "int(11)")
|
||||
@NotNull(message = "字段类型不能为空")
|
||||
private String dataType;
|
||||
|
||||
@Schema(description = "字段描述", requiredMode = Schema.RequiredMode.REQUIRED, example = "年龄")
|
||||
@NotNull(message = "字段描述不能为空")
|
||||
private String columnComment;
|
||||
|
||||
@Schema(description = "是否允许为空", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
|
||||
@NotNull(message = "是否允许为空不能为空")
|
||||
private Boolean nullable;
|
||||
|
||||
@Schema(description = "是否主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "false")
|
||||
@NotNull(message = "是否主键不能为空")
|
||||
private Boolean primaryKey;
|
||||
|
||||
@Schema(description = "排序", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
|
||||
@NotNull(message = "排序不能为空")
|
||||
private Integer ordinalPosition;
|
||||
|
||||
@Schema(description = "Java 属性类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "userAge")
|
||||
@NotNull(message = "Java 属性类型不能为空")
|
||||
private String javaType;
|
||||
|
||||
@Schema(description = "Java 属性名", requiredMode = Schema.RequiredMode.REQUIRED, example = "Integer")
|
||||
@NotNull(message = "Java 属性名不能为空")
|
||||
private String javaField;
|
||||
|
||||
@Schema(description = "字典类型", example = "sys_gender")
|
||||
private String dictType;
|
||||
|
||||
@Schema(description = "数据示例", example = "1024")
|
||||
private String example;
|
||||
|
||||
@Schema(description = "是否为 Create 创建操作的字段", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
|
||||
@NotNull(message = "是否为 Create 创建操作的字段不能为空")
|
||||
private Boolean createOperation;
|
||||
|
||||
@Schema(description = "是否为 Update 更新操作的字段", requiredMode = Schema.RequiredMode.REQUIRED, example = "false")
|
||||
@NotNull(message = "是否为 Update 更新操作的字段不能为空")
|
||||
private Boolean updateOperation;
|
||||
|
||||
@Schema(description = "是否为 List 查询操作的字段", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
|
||||
@NotNull(message = "是否为 List 查询操作的字段不能为空")
|
||||
private Boolean listOperation;
|
||||
|
||||
@Schema(description = "List 查询操作的条件类型,参见 CodegenColumnListConditionEnum 枚举", requiredMode = Schema.RequiredMode.REQUIRED, example = "LIKE")
|
||||
@NotNull(message = "List 查询操作的条件类型不能为空")
|
||||
private String listOperationCondition;
|
||||
|
||||
@Schema(description = "是否为 List 查询操作的返回字段", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
|
||||
@NotNull(message = "是否为 List 查询操作的返回字段不能为空")
|
||||
private Boolean listOperationResult;
|
||||
|
||||
@Schema(description = "显示类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "input")
|
||||
@NotNull(message = "显示类型不能为空")
|
||||
private String htmlType;
|
||||
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
package com.njcn.rdms.module.system.controller.admin.codegen.vo.table;
|
||||
|
||||
import com.njcn.rdms.framework.common.pojo.PageParam;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import static com.njcn.rdms.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||
|
||||
@Schema(description = "管理后台 - 表定义分页 Request VO")
|
||||
@Data
|
||||
public class CodegenTablePageReqVO extends PageParam {
|
||||
|
||||
@Schema(description = "表名称,模糊匹配", example = "rdms")
|
||||
private String tableName;
|
||||
|
||||
@Schema(description = "表描述,模糊匹配", example = "灿能")
|
||||
private String tableComment;
|
||||
|
||||
@Schema(description = "实体,模糊匹配", example = "Rdms")
|
||||
private String className;
|
||||
|
||||
@Schema(description = "创建时间", example = "[2022-07-01 00:00:00,2022-07-01 23:59:59]")
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
private LocalDateTime[] createTime;
|
||||
|
||||
}
|
||||
@@ -1,72 +0,0 @@
|
||||
package com.njcn.rdms.module.system.controller.admin.codegen.vo.table;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Schema(description = "管理后台 - 代码生成表定义 Response VO")
|
||||
@Data
|
||||
public class CodegenTableRespVO {
|
||||
|
||||
@Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "生成场景,参见 CodegenSceneEnum 枚举", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private Integer scene;
|
||||
|
||||
@Schema(description = "表名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "rdms")
|
||||
private String tableName;
|
||||
|
||||
@Schema(description = "表描述", requiredMode = Schema.RequiredMode.REQUIRED, example = "灿能")
|
||||
private String tableComment;
|
||||
|
||||
@Schema(description = "备注", example = "我是备注")
|
||||
private String remark;
|
||||
|
||||
@Schema(description = "模块名", requiredMode = Schema.RequiredMode.REQUIRED, example = "system")
|
||||
private String moduleName;
|
||||
|
||||
@Schema(description = "业务名", requiredMode = Schema.RequiredMode.REQUIRED, example = "codegen")
|
||||
private String businessName;
|
||||
|
||||
@Schema(description = "类名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "CodegenTable")
|
||||
private String className;
|
||||
|
||||
@Schema(description = "类描述", requiredMode = Schema.RequiredMode.REQUIRED, example = "代码生成器的表定义")
|
||||
private String classComment;
|
||||
|
||||
@Schema(description = "作者", requiredMode = Schema.RequiredMode.REQUIRED, example = "灿能源码")
|
||||
private String author;
|
||||
|
||||
@Schema(description = "模板类型,参见 CodegenTemplateTypeEnum 枚举", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private Integer templateType;
|
||||
|
||||
@Schema(description = "前端类型,参见 CodegenFrontTypeEnum 枚举", requiredMode = Schema.RequiredMode.REQUIRED, example = "20")
|
||||
private Integer frontType;
|
||||
|
||||
@Schema(description = "父菜单编号", example = "1024")
|
||||
private Long parentMenuId;
|
||||
|
||||
@Schema(description = "主表的编号", example = "2048")
|
||||
private Long masterTableId;
|
||||
@Schema(description = "子表关联主表的字段编号", example = "4096")
|
||||
private Long subJoinColumnId;
|
||||
@Schema(description = "主表与子表是否一对多", example = "4096")
|
||||
private Boolean subJoinMany;
|
||||
|
||||
@Schema(description = "树表的父字段编号", example = "8192")
|
||||
private Long treeParentColumnId;
|
||||
@Schema(description = "树表的名字字段编号", example = "16384")
|
||||
private Long treeNameColumnId;
|
||||
|
||||
@Schema(description = "主键编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
private Integer dataSourceConfigId;
|
||||
|
||||
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private LocalDateTime createTime;
|
||||
|
||||
@Schema(description = "更新时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private LocalDateTime updateTime;
|
||||
|
||||
}
|
||||
@@ -1,99 +0,0 @@
|
||||
package com.njcn.rdms.module.system.controller.admin.codegen.vo.table;
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import com.njcn.rdms.module.system.enums.codegen.CodegenSceneEnum;
|
||||
import com.njcn.rdms.module.system.enums.codegen.CodegenTemplateTypeEnum;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.AssertTrue;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
@Schema(description = "管理后台 - 代码生成表定义创建/修改 Response VO")
|
||||
@Data
|
||||
public class CodegenTableSaveReqVO {
|
||||
|
||||
@Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "生成场景,参见 CodegenSceneEnum 枚举", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@NotNull(message = "导入类型不能为空")
|
||||
private Integer scene;
|
||||
|
||||
@Schema(description = "表名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "rdms")
|
||||
@NotNull(message = "表名称不能为空")
|
||||
private String tableName;
|
||||
|
||||
@Schema(description = "表描述", requiredMode = Schema.RequiredMode.REQUIRED, example = "灿能")
|
||||
@NotNull(message = "表描述不能为空")
|
||||
private String tableComment;
|
||||
|
||||
@Schema(description = "备注", example = "我是备注")
|
||||
private String remark;
|
||||
|
||||
@Schema(description = "模块名", requiredMode = Schema.RequiredMode.REQUIRED, example = "system")
|
||||
@NotNull(message = "模块名不能为空")
|
||||
private String moduleName;
|
||||
|
||||
@Schema(description = "业务名", requiredMode = Schema.RequiredMode.REQUIRED, example = "codegen")
|
||||
@NotNull(message = "业务名不能为空")
|
||||
private String businessName;
|
||||
|
||||
@Schema(description = "类名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "CodegenTable")
|
||||
@NotNull(message = "类名称不能为空")
|
||||
private String className;
|
||||
|
||||
@Schema(description = "类描述", requiredMode = Schema.RequiredMode.REQUIRED, example = "代码生成器的表定义")
|
||||
@NotNull(message = "类描述不能为空")
|
||||
private String classComment;
|
||||
|
||||
@Schema(description = "作者", requiredMode = Schema.RequiredMode.REQUIRED, example = "灿能源码")
|
||||
@NotNull(message = "作者不能为空")
|
||||
private String author;
|
||||
|
||||
@Schema(description = "模板类型,参见 CodegenTemplateTypeEnum 枚举", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@NotNull(message = "模板类型不能为空")
|
||||
private Integer templateType;
|
||||
|
||||
@Schema(description = "前端类型,参见 CodegenFrontTypeEnum 枚举", requiredMode = Schema.RequiredMode.REQUIRED, example = "20")
|
||||
@NotNull(message = "前端类型不能为空")
|
||||
private Integer frontType;
|
||||
|
||||
@Schema(description = "父菜单编号", example = "1024")
|
||||
private Long parentMenuId;
|
||||
|
||||
@Schema(description = "主表的编号", example = "2048")
|
||||
private Long masterTableId;
|
||||
@Schema(description = "子表关联主表的字段编号", example = "4096")
|
||||
private Long subJoinColumnId;
|
||||
@Schema(description = "主表与子表是否一对多", example = "4096")
|
||||
private Boolean subJoinMany;
|
||||
|
||||
@Schema(description = "树表的父字段编号", example = "8192")
|
||||
private Long treeParentColumnId;
|
||||
@Schema(description = "树表的名字字段编号", example = "16384")
|
||||
private Long treeNameColumnId;
|
||||
|
||||
@AssertTrue(message = "上级菜单不能为空,请前往 [修改生成配置 -> 生成信息] 界面,设置“上级菜单”字段")
|
||||
@JsonIgnore
|
||||
public boolean isParentMenuIdValid() {
|
||||
// 生成场景为管理后台时,必须设置上级菜单,不然生成的菜单 SQL 是无父级菜单的
|
||||
return ObjectUtil.notEqual(getScene(), CodegenSceneEnum.ADMIN.getScene())
|
||||
|| getParentMenuId() != null;
|
||||
}
|
||||
|
||||
@AssertTrue(message = "关联的父表信息不全")
|
||||
@JsonIgnore
|
||||
public boolean isSubValid() {
|
||||
return ObjectUtil.notEqual(getTemplateType(), CodegenTemplateTypeEnum.SUB)
|
||||
|| (ObjectUtil.isAllNotEmpty(masterTableId, subJoinColumnId, subJoinMany));
|
||||
}
|
||||
|
||||
@AssertTrue(message = "关联的树表信息不全")
|
||||
@JsonIgnore
|
||||
public boolean isTreeValid() {
|
||||
return ObjectUtil.notEqual(templateType, CodegenTemplateTypeEnum.TREE)
|
||||
|| (ObjectUtil.isAllNotEmpty(treeParentColumnId, treeNameColumnId));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
package com.njcn.rdms.module.system.controller.admin.codegen.vo.table;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
@Schema(description = "管理后台 - 数据库的表定义 Response VO")
|
||||
@Data
|
||||
public class DatabaseTableRespVO {
|
||||
|
||||
@Schema(description = "表名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "yuanma")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "表描述", requiredMode = Schema.RequiredMode.REQUIRED, example = "灿能源码")
|
||||
private String comment;
|
||||
|
||||
}
|
||||
@@ -31,7 +31,7 @@ import static com.njcn.rdms.framework.common.pojo.CommonResult.success;
|
||||
|
||||
@Tag(name = "管理后台 - 参数配置")
|
||||
@RestController
|
||||
@RequestMapping("/infra/config")
|
||||
@RequestMapping("/system/config")
|
||||
@Validated
|
||||
public class ConfigController {
|
||||
|
||||
@@ -40,14 +40,14 @@ public class ConfigController {
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(summary = "创建参数配置")
|
||||
@PreAuthorize("@ss.hasPermission('infra:config:create')")
|
||||
@PreAuthorize("@ss.hasPermission('system:config:create')")
|
||||
public CommonResult<Long> createConfig(@Valid @RequestBody ConfigSaveReqVO createReqVO) {
|
||||
return success(configService.createConfig(createReqVO));
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@Operation(summary = "修改参数配置")
|
||||
@PreAuthorize("@ss.hasPermission('infra:config:update')")
|
||||
@PreAuthorize("@ss.hasPermission('system:config:update')")
|
||||
public CommonResult<Boolean> updateConfig(@Valid @RequestBody ConfigSaveReqVO updateReqVO) {
|
||||
configService.updateConfig(updateReqVO);
|
||||
return success(true);
|
||||
@@ -56,7 +56,7 @@ public class ConfigController {
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(summary = "删除参数配置")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('infra:config:delete')")
|
||||
@PreAuthorize("@ss.hasPermission('system:config:delete')")
|
||||
public CommonResult<Boolean> deleteConfig(@RequestParam("id") Long id) {
|
||||
configService.deleteConfig(id);
|
||||
return success(true);
|
||||
@@ -65,7 +65,7 @@ public class ConfigController {
|
||||
@DeleteMapping("/delete-list")
|
||||
@Operation(summary = "批量删除参数配置")
|
||||
@Parameter(name = "ids", description = "编号列表", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('infra:config:delete')")
|
||||
@PreAuthorize("@ss.hasPermission('system:config:delete')")
|
||||
public CommonResult<Boolean> deleteConfigList(@RequestParam("ids") List<Long> ids) {
|
||||
configService.deleteConfigList(ids);
|
||||
return success(true);
|
||||
@@ -74,7 +74,7 @@ public class ConfigController {
|
||||
@GetMapping(value = "/get")
|
||||
@Operation(summary = "获得参数配置")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('infra:config:query')")
|
||||
@PreAuthorize("@ss.hasPermission('system:config:query')")
|
||||
public CommonResult<ConfigRespVO> getConfig(@RequestParam("id") Long id) {
|
||||
return success(ConfigConvert.INSTANCE.convert(configService.getConfig(id)));
|
||||
}
|
||||
@@ -95,7 +95,7 @@ public class ConfigController {
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(summary = "获取参数配置分页")
|
||||
@PreAuthorize("@ss.hasPermission('infra:config:query')")
|
||||
@PreAuthorize("@ss.hasPermission('system:config:query')")
|
||||
public CommonResult<PageResult<ConfigRespVO>> getConfigPage(@Valid ConfigPageReqVO pageReqVO) {
|
||||
PageResult<ConfigDO> page = configService.getConfigPage(pageReqVO);
|
||||
return success(ConfigConvert.INSTANCE.convertPage(page));
|
||||
@@ -103,7 +103,7 @@ public class ConfigController {
|
||||
|
||||
@GetMapping("/export-excel")
|
||||
@Operation(summary = "导出参数配置")
|
||||
@PreAuthorize("@ss.hasPermission('infra:config:export')")
|
||||
@PreAuthorize("@ss.hasPermission('system:config:export')")
|
||||
@ApiAccessLog(operateType = EXPORT)
|
||||
public void exportConfig(ConfigPageReqVO exportReqVO,
|
||||
HttpServletResponse response) throws IOException {
|
||||
@@ -115,3 +115,4 @@ public class ConfigController {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,81 +0,0 @@
|
||||
package com.njcn.rdms.module.system.controller.admin.db;
|
||||
|
||||
import com.njcn.rdms.framework.common.pojo.CommonResult;
|
||||
import com.njcn.rdms.framework.common.util.object.BeanUtils;
|
||||
import com.njcn.rdms.module.system.controller.admin.db.vo.DataSourceConfigRespVO;
|
||||
import com.njcn.rdms.module.system.controller.admin.db.vo.DataSourceConfigSaveReqVO;
|
||||
import com.njcn.rdms.module.system.dal.dataobject.db.DataSourceConfigDO;
|
||||
import com.njcn.rdms.module.system.service.db.DataSourceConfigService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.validation.Valid;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static com.njcn.rdms.framework.common.pojo.CommonResult.success;
|
||||
|
||||
@Tag(name = "管理后台 - 数据源配置")
|
||||
@RestController
|
||||
@RequestMapping("/infra/data-source-config")
|
||||
@Validated
|
||||
public class DataSourceConfigController {
|
||||
|
||||
@Resource
|
||||
private DataSourceConfigService dataSourceConfigService;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(summary = "创建数据源配置")
|
||||
@PreAuthorize("@ss.hasPermission('infra:data-source-config:create')")
|
||||
public CommonResult<Long> createDataSourceConfig(@Valid @RequestBody DataSourceConfigSaveReqVO createReqVO) {
|
||||
return success(dataSourceConfigService.createDataSourceConfig(createReqVO));
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@Operation(summary = "更新数据源配置")
|
||||
@PreAuthorize("@ss.hasPermission('infra:data-source-config:update')")
|
||||
public CommonResult<Boolean> updateDataSourceConfig(@Valid @RequestBody DataSourceConfigSaveReqVO updateReqVO) {
|
||||
dataSourceConfigService.updateDataSourceConfig(updateReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(summary = "删除数据源配置")
|
||||
@Parameter(name = "id", description = "编号", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('infra:data-source-config:delete')")
|
||||
public CommonResult<Boolean> deleteDataSourceConfig(@RequestParam("id") Long id) {
|
||||
dataSourceConfigService.deleteDataSourceConfig(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete-list")
|
||||
@Operation(summary = "批量删除数据源配置")
|
||||
@Parameter(name = "ids", description = "编号列表", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('infra:data-source-config:delete')")
|
||||
public CommonResult<Boolean> deleteDataSourceConfigList(@RequestParam("ids") List<Long> ids) {
|
||||
dataSourceConfigService.deleteDataSourceConfigList(ids);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@Operation(summary = "获得数据源配置")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('infra:data-source-config:query')")
|
||||
public CommonResult<DataSourceConfigRespVO> getDataSourceConfig(@RequestParam("id") Long id) {
|
||||
DataSourceConfigDO config = dataSourceConfigService.getDataSourceConfig(id);
|
||||
return success(BeanUtils.toBean(config, DataSourceConfigRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/list")
|
||||
@Operation(summary = "获得数据源配置列表")
|
||||
@PreAuthorize("@ss.hasPermission('infra:data-source-config:query')")
|
||||
public CommonResult<List<DataSourceConfigRespVO>> getDataSourceConfigList() {
|
||||
List<DataSourceConfigDO> list = dataSourceConfigService.getDataSourceConfigList();
|
||||
return success(BeanUtils.toBean(list, DataSourceConfigRespVO.class));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
package com.njcn.rdms.module.system.controller.admin.db.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Schema(description = "管理后台 - 数据源配置 Response VO")
|
||||
@Data
|
||||
public class DataSourceConfigRespVO {
|
||||
|
||||
@Schema(description = "主键编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "数据源名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "test")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "数据源连接", requiredMode = Schema.RequiredMode.REQUIRED, example = "jdbc:mysql://127.0.0.1:3306/ruoyi-vue-pro")
|
||||
private String url;
|
||||
|
||||
@Schema(description = "用户名", requiredMode = Schema.RequiredMode.REQUIRED, example = "root")
|
||||
private String username;
|
||||
|
||||
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private LocalDateTime createTime;
|
||||
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
package com.njcn.rdms.module.system.controller.admin.db.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
@Schema(description = "管理后台 - 数据源配置创建/修改 Request VO")
|
||||
@Data
|
||||
public class DataSourceConfigSaveReqVO {
|
||||
|
||||
@Schema(description = "主键编号", example = "1024")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "数据源名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "test")
|
||||
@NotNull(message = "数据源名称不能为空")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "数据源连接", requiredMode = Schema.RequiredMode.REQUIRED, example = "jdbc:mysql://127.0.0.1:3306/ruoyi-vue-pro")
|
||||
@NotNull(message = "数据源连接不能为空")
|
||||
private String url;
|
||||
|
||||
@Schema(description = "用户名", requiredMode = Schema.RequiredMode.REQUIRED, example = "root")
|
||||
@NotNull(message = "用户名不能为空")
|
||||
private String username;
|
||||
|
||||
@Schema(description = "密码", requiredMode = Schema.RequiredMode.REQUIRED, example = "123456")
|
||||
@NotNull(message = "密码不能为空")
|
||||
private String password;
|
||||
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
### 请求 /infra/file-config/create 接口 => 成功
|
||||
POST {{baseUrl}}/infra/file-config/create
|
||||
### 请求 /system/file-config/create 接口 => 成功
|
||||
POST {{baseUrl}}/system/file-config/create
|
||||
Content-Type: application/json
|
||||
tenant-id: {{adminTenantId}}
|
||||
Authorization: Bearer {{token}}
|
||||
@@ -18,8 +18,8 @@ Authorization: Bearer {{token}}
|
||||
}
|
||||
}
|
||||
|
||||
### 请求 /infra/file-config/update 接口 => 成功
|
||||
PUT {{baseUrl}}/infra/file-config/update
|
||||
### 请求 /system/file-config/update 接口 => 成功
|
||||
PUT {{baseUrl}}/system/file-config/update
|
||||
Content-Type: application/json
|
||||
tenant-id: {{adminTenantId}}
|
||||
Authorization: Bearer {{token}}
|
||||
@@ -38,8 +38,9 @@ Authorization: Bearer {{token}}
|
||||
}
|
||||
}
|
||||
|
||||
### 请求 /infra/file-config/test 接口 => 成功
|
||||
GET {{baseUrl}}/infra/file-config/test?id=2
|
||||
### 请求 /system/file-config/test 接口 => 成功
|
||||
GET {{baseUrl}}/system/file-config/test?id=2
|
||||
Content-Type: application/json
|
||||
tenant-id: {{adminTenantId}}
|
||||
Authorization: Bearer {{token}}
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ import static com.njcn.rdms.framework.common.pojo.CommonResult.success;
|
||||
|
||||
@Tag(name = "管理后台 - 文件配置")
|
||||
@RestController
|
||||
@RequestMapping("/infra/file-config")
|
||||
@RequestMapping("/system/file-config")
|
||||
@Validated
|
||||
public class FileConfigController {
|
||||
|
||||
@@ -32,14 +32,14 @@ public class FileConfigController {
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(summary = "创建文件配置")
|
||||
@PreAuthorize("@ss.hasPermission('infra:file-config:create')")
|
||||
@PreAuthorize("@ss.hasPermission('system:file-config:create')")
|
||||
public CommonResult<Long> createFileConfig(@Valid @RequestBody FileConfigSaveReqVO createReqVO) {
|
||||
return success(fileConfigService.createFileConfig(createReqVO));
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@Operation(summary = "更新文件配置")
|
||||
@PreAuthorize("@ss.hasPermission('infra:file-config:update')")
|
||||
@PreAuthorize("@ss.hasPermission('system:file-config:update')")
|
||||
public CommonResult<Boolean> updateFileConfig(@Valid @RequestBody FileConfigSaveReqVO updateReqVO) {
|
||||
fileConfigService.updateFileConfig(updateReqVO);
|
||||
return success(true);
|
||||
@@ -47,7 +47,7 @@ public class FileConfigController {
|
||||
|
||||
@PutMapping("/update-master")
|
||||
@Operation(summary = "更新文件配置为 Master")
|
||||
@PreAuthorize("@ss.hasPermission('infra:file-config:update')")
|
||||
@PreAuthorize("@ss.hasPermission('system:file-config:update')")
|
||||
public CommonResult<Boolean> updateFileConfigMaster(@RequestParam("id") Long id) {
|
||||
fileConfigService.updateFileConfigMaster(id);
|
||||
return success(true);
|
||||
@@ -56,7 +56,7 @@ public class FileConfigController {
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(summary = "删除文件配置")
|
||||
@Parameter(name = "id", description = "编号", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('infra:file-config:delete')")
|
||||
@PreAuthorize("@ss.hasPermission('system:file-config:delete')")
|
||||
public CommonResult<Boolean> deleteFileConfig(@RequestParam("id") Long id) {
|
||||
fileConfigService.deleteFileConfig(id);
|
||||
return success(true);
|
||||
@@ -65,7 +65,7 @@ public class FileConfigController {
|
||||
@DeleteMapping("/delete-list")
|
||||
@Operation(summary = "批量删除文件配置")
|
||||
@Parameter(name = "ids", description = "编号列表", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('infra:file-config:delete')")
|
||||
@PreAuthorize("@ss.hasPermission('system:file-config:delete')")
|
||||
public CommonResult<Boolean> deleteFileConfigList(@RequestParam("ids") List<Long> ids) {
|
||||
fileConfigService.deleteFileConfigList(ids);
|
||||
return success(true);
|
||||
@@ -74,7 +74,7 @@ public class FileConfigController {
|
||||
@GetMapping("/get")
|
||||
@Operation(summary = "获得文件配置")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('infra:file-config:query')")
|
||||
@PreAuthorize("@ss.hasPermission('system:file-config:query')")
|
||||
public CommonResult<FileConfigRespVO> getFileConfig(@RequestParam("id") Long id) {
|
||||
FileConfigDO config = fileConfigService.getFileConfig(id);
|
||||
return success(BeanUtils.toBean(config, FileConfigRespVO.class));
|
||||
@@ -82,7 +82,7 @@ public class FileConfigController {
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(summary = "获得文件配置分页")
|
||||
@PreAuthorize("@ss.hasPermission('infra:file-config:query')")
|
||||
@PreAuthorize("@ss.hasPermission('system:file-config:query')")
|
||||
public CommonResult<PageResult<FileConfigRespVO>> getFileConfigPage(@Valid FileConfigPageReqVO pageVO) {
|
||||
PageResult<FileConfigDO> pageResult = fileConfigService.getFileConfigPage(pageVO);
|
||||
return success(BeanUtils.toBean(pageResult, FileConfigRespVO.class));
|
||||
@@ -90,9 +90,10 @@ public class FileConfigController {
|
||||
|
||||
@GetMapping("/test")
|
||||
@Operation(summary = "测试文件配置是否正确")
|
||||
@PreAuthorize("@ss.hasPermission('infra:file-config:query')")
|
||||
@PreAuthorize("@ss.hasPermission('system:file-config:query')")
|
||||
public CommonResult<String> testFileConfig(@RequestParam("id") Long id) throws Exception {
|
||||
String url = fileConfigService.testFileConfig(id);
|
||||
return success(url);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ import static com.njcn.rdms.module.system.framework.file.core.utils.FileTypeUtil
|
||||
|
||||
@Tag(name = "管理后台 - 文件存储")
|
||||
@RestController
|
||||
@RequestMapping("/infra/file")
|
||||
@RequestMapping("/system/file")
|
||||
@Validated
|
||||
@Slf4j
|
||||
public class FileController {
|
||||
@@ -74,7 +74,7 @@ public class FileController {
|
||||
@GetMapping("/get")
|
||||
@Operation(summary = "获得文件")
|
||||
@Parameter(name = "id", description = "编号", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('infra:file:query')")
|
||||
@PreAuthorize("@ss.hasPermission('system:file:query')")
|
||||
public CommonResult<FileRespVO> getFile(@RequestParam("id") Long id) {
|
||||
return success(BeanUtils.toBean(fileService.getFile(id), FileRespVO.class));
|
||||
}
|
||||
@@ -82,7 +82,7 @@ public class FileController {
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(summary = "删除文件")
|
||||
@Parameter(name = "id", description = "编号", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('infra:file:delete')")
|
||||
@PreAuthorize("@ss.hasPermission('system:file:delete')")
|
||||
public CommonResult<Boolean> deleteFile(@RequestParam("id") Long id) throws Exception {
|
||||
fileService.deleteFile(id);
|
||||
return success(true);
|
||||
@@ -91,7 +91,7 @@ public class FileController {
|
||||
@DeleteMapping("/delete-list")
|
||||
@Operation(summary = "批量删除文件")
|
||||
@Parameter(name = "ids", description = "编号列表", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('infra:file:delete')")
|
||||
@PreAuthorize("@ss.hasPermission('system:file:delete')")
|
||||
public CommonResult<Boolean> deleteFileList(@RequestParam("ids") List<Long> ids) throws Exception {
|
||||
fileService.deleteFileList(ids);
|
||||
return success(true);
|
||||
@@ -127,10 +127,11 @@ public class FileController {
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(summary = "获得文件分页")
|
||||
@PreAuthorize("@ss.hasPermission('infra:file:query')")
|
||||
@PreAuthorize("@ss.hasPermission('system:file:query')")
|
||||
public CommonResult<PageResult<FileRespVO>> getFilePage(@Valid FilePageReqVO pageVO) {
|
||||
PageResult<FileDO> pageResult = fileService.getFilePage(pageVO);
|
||||
return success(BeanUtils.toBean(pageResult, FileRespVO.class));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ import static com.njcn.rdms.framework.common.pojo.CommonResult.success;
|
||||
|
||||
@Tag(name = "管理后台 - API 访问日志")
|
||||
@RestController
|
||||
@RequestMapping("/infra/api-access-log")
|
||||
@RequestMapping("/system/api-access-log")
|
||||
@Validated
|
||||
public class ApiAccessLogController {
|
||||
|
||||
@@ -41,7 +41,7 @@ public class ApiAccessLogController {
|
||||
@GetMapping("/get")
|
||||
@Operation(summary = "获得 API 访问日志")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('infra:api-access-log:query')")
|
||||
@PreAuthorize("@ss.hasPermission('system:api-access-log:query')")
|
||||
public CommonResult<ApiAccessLogRespVO> getApiAccessLog(@RequestParam("id") Long id) {
|
||||
ApiAccessLogDO apiAccessLog = apiAccessLogService.getApiAccessLog(id);
|
||||
return success(BeanUtils.toBean(apiAccessLog, ApiAccessLogRespVO.class));
|
||||
@@ -49,7 +49,7 @@ public class ApiAccessLogController {
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(summary = "获得API 访问日志分页")
|
||||
@PreAuthorize("@ss.hasPermission('infra:api-access-log:query')")
|
||||
@PreAuthorize("@ss.hasPermission('system:api-access-log:query')")
|
||||
public CommonResult<PageResult<ApiAccessLogRespVO>> getApiAccessLogPage(@Valid ApiAccessLogPageReqVO pageReqVO) {
|
||||
PageResult<ApiAccessLogDO> pageResult = apiAccessLogService.getApiAccessLogPage(pageReqVO);
|
||||
return success(BeanUtils.toBean(pageResult, ApiAccessLogRespVO.class));
|
||||
@@ -57,7 +57,7 @@ public class ApiAccessLogController {
|
||||
|
||||
@GetMapping("/export-excel")
|
||||
@Operation(summary = "导出API 访问日志 Excel")
|
||||
@PreAuthorize("@ss.hasPermission('infra:api-access-log:export')")
|
||||
@PreAuthorize("@ss.hasPermission('system:api-access-log:export')")
|
||||
@ApiAccessLog(operateType = EXPORT)
|
||||
public void exportApiAccessLogExcel(@Valid ApiAccessLogPageReqVO exportReqVO,
|
||||
HttpServletResponse response) throws IOException {
|
||||
@@ -69,3 +69,4 @@ public class ApiAccessLogController {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ import static com.njcn.rdms.framework.security.core.util.SecurityFrameworkUtils.
|
||||
|
||||
@Tag(name = "管理后台 - API 错误日志")
|
||||
@RestController
|
||||
@RequestMapping("/infra/api-error-log")
|
||||
@RequestMapping("/system/api-error-log")
|
||||
@Validated
|
||||
public class ApiErrorLogController {
|
||||
|
||||
@@ -43,7 +43,7 @@ public class ApiErrorLogController {
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1024"),
|
||||
@Parameter(name = "processStatus", description = "处理状态", required = true, example = "1")
|
||||
})
|
||||
@PreAuthorize("@ss.hasPermission('infra:api-error-log:update-status')")
|
||||
@PreAuthorize("@ss.hasPermission('system:api-error-log:update-status')")
|
||||
public CommonResult<Boolean> updateApiErrorLogProcess(@RequestParam("id") Long id,
|
||||
@RequestParam("processStatus") Integer processStatus) {
|
||||
apiErrorLogService.updateApiErrorLogProcess(id, processStatus, getLoginUserId());
|
||||
@@ -53,7 +53,7 @@ public class ApiErrorLogController {
|
||||
@GetMapping("/get")
|
||||
@Operation(summary = "获得 API 错误日志")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('infra:api-error-log:query')")
|
||||
@PreAuthorize("@ss.hasPermission('system:api-error-log:query')")
|
||||
public CommonResult<ApiErrorLogRespVO> getApiErrorLog(@RequestParam("id") Long id) {
|
||||
ApiErrorLogDO apiErrorLog = apiErrorLogService.getApiErrorLog(id);
|
||||
return success(BeanUtils.toBean(apiErrorLog, ApiErrorLogRespVO.class));
|
||||
@@ -61,7 +61,7 @@ public class ApiErrorLogController {
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(summary = "获得 API 错误日志分页")
|
||||
@PreAuthorize("@ss.hasPermission('infra:api-error-log:query')")
|
||||
@PreAuthorize("@ss.hasPermission('system:api-error-log:query')")
|
||||
public CommonResult<PageResult<ApiErrorLogRespVO>> getApiErrorLogPage(@Valid ApiErrorLogPageReqVO pageReqVO) {
|
||||
PageResult<ApiErrorLogDO> pageResult = apiErrorLogService.getApiErrorLogPage(pageReqVO);
|
||||
return success(BeanUtils.toBean(pageResult, ApiErrorLogRespVO.class));
|
||||
@@ -69,7 +69,7 @@ public class ApiErrorLogController {
|
||||
|
||||
@GetMapping("/export-excel")
|
||||
@Operation(summary = "导出 API 错误日志 Excel")
|
||||
@PreAuthorize("@ss.hasPermission('infra:api-error-log:export')")
|
||||
@PreAuthorize("@ss.hasPermission('system:api-error-log:export')")
|
||||
@ApiAccessLog(operateType = EXPORT)
|
||||
public void exportApiErrorLogExcel(@Valid ApiErrorLogPageReqVO exportReqVO,
|
||||
HttpServletResponse response) throws IOException {
|
||||
@@ -81,3 +81,4 @@ public class ApiErrorLogController {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -89,7 +89,7 @@ public class ApiAccessLogRespVO {
|
||||
@ExcelProperty("结果码")
|
||||
private Integer resultCode;
|
||||
|
||||
@Schema(description = "结果提示", example = "灿能源码,牛逼!")
|
||||
@Schema(description = "结果提示", example = "灿能,牛逼!")
|
||||
@ExcelProperty("结果提示")
|
||||
private String resultMsg;
|
||||
|
||||
|
||||
@@ -1,90 +0,0 @@
|
||||
package com.njcn.rdms.module.system.controller.admin.mail;
|
||||
|
||||
|
||||
import com.njcn.rdms.framework.common.pojo.CommonResult;
|
||||
import com.njcn.rdms.framework.common.pojo.PageResult;
|
||||
import com.njcn.rdms.framework.common.util.object.BeanUtils;
|
||||
import com.njcn.rdms.module.system.controller.admin.mail.vo.account.MailAccountPageReqVO;
|
||||
import com.njcn.rdms.module.system.controller.admin.mail.vo.account.MailAccountRespVO;
|
||||
import com.njcn.rdms.module.system.controller.admin.mail.vo.account.MailAccountSaveReqVO;
|
||||
import com.njcn.rdms.module.system.controller.admin.mail.vo.account.MailAccountSimpleRespVO;
|
||||
import com.njcn.rdms.module.system.dal.dataobject.mail.MailAccountDO;
|
||||
import com.njcn.rdms.module.system.service.mail.MailAccountService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.validation.Valid;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static com.njcn.rdms.framework.common.pojo.CommonResult.success;
|
||||
|
||||
@Tag(name = "管理后台 - 邮箱账号")
|
||||
@RestController
|
||||
@RequestMapping("/system/mail-account")
|
||||
public class MailAccountController {
|
||||
|
||||
@Resource
|
||||
private MailAccountService mailAccountService;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(summary = "创建邮箱账号")
|
||||
@PreAuthorize("@ss.hasPermission('system:mail-account:create')")
|
||||
public CommonResult<Long> createMailAccount(@Valid @RequestBody MailAccountSaveReqVO createReqVO) {
|
||||
return success(mailAccountService.createMailAccount(createReqVO));
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@Operation(summary = "修改邮箱账号")
|
||||
@PreAuthorize("@ss.hasPermission('system:mail-account:update')")
|
||||
public CommonResult<Boolean> updateMailAccount(@Valid @RequestBody MailAccountSaveReqVO updateReqVO) {
|
||||
mailAccountService.updateMailAccount(updateReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(summary = "删除邮箱账号")
|
||||
@Parameter(name = "id", description = "编号", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('system:mail-account:delete')")
|
||||
public CommonResult<Boolean> deleteMailAccount(@RequestParam Long id) {
|
||||
mailAccountService.deleteMailAccount(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete-list")
|
||||
@Operation(summary = "批量删除邮箱账号")
|
||||
@Parameter(name = "ids", description = "编号列表", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('system:mail-account:delete')")
|
||||
public CommonResult<Boolean> deleteMailAccountList(@RequestParam("ids") List<Long> ids) {
|
||||
mailAccountService.deleteMailAccountList(ids);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@Operation(summary = "获得邮箱账号")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('system:mail-account:query')")
|
||||
public CommonResult<MailAccountRespVO> getMailAccount(@RequestParam("id") Long id) {
|
||||
MailAccountDO account = mailAccountService.getMailAccount(id);
|
||||
return success(BeanUtils.toBean(account, MailAccountRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(summary = "获得邮箱账号分页")
|
||||
@PreAuthorize("@ss.hasPermission('system:mail-account:query')")
|
||||
public CommonResult<PageResult<MailAccountRespVO>> getMailAccountPage(@Valid MailAccountPageReqVO pageReqVO) {
|
||||
PageResult<MailAccountDO> pageResult = mailAccountService.getMailAccountPage(pageReqVO);
|
||||
return success(BeanUtils.toBean(pageResult, MailAccountRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping({"/list-all-simple", "simple-list"})
|
||||
@Operation(summary = "获得邮箱账号精简列表")
|
||||
public CommonResult<List<MailAccountSimpleRespVO>> getSimpleMailAccountList() {
|
||||
List<MailAccountDO> list = mailAccountService.getMailAccountList();
|
||||
return success(BeanUtils.toBean(list, MailAccountSimpleRespVO.class));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
package com.njcn.rdms.module.system.controller.admin.mail;
|
||||
|
||||
import com.njcn.rdms.framework.common.pojo.CommonResult;
|
||||
import com.njcn.rdms.framework.common.pojo.PageResult;
|
||||
import com.njcn.rdms.framework.common.util.object.BeanUtils;
|
||||
import com.njcn.rdms.module.system.controller.admin.mail.vo.log.MailLogPageReqVO;
|
||||
import com.njcn.rdms.module.system.controller.admin.mail.vo.log.MailLogRespVO;
|
||||
import com.njcn.rdms.module.system.dal.dataobject.mail.MailLogDO;
|
||||
import com.njcn.rdms.module.system.service.mail.MailLogService;
|
||||
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.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.validation.Valid;
|
||||
|
||||
import static com.njcn.rdms.framework.common.pojo.CommonResult.success;
|
||||
|
||||
@Tag(name = "管理后台 - 邮件日志")
|
||||
@RestController
|
||||
@RequestMapping("/system/mail-log")
|
||||
public class MailLogController {
|
||||
|
||||
@Resource
|
||||
private MailLogService mailLogService;
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(summary = "获得邮箱日志分页")
|
||||
@PreAuthorize("@ss.hasPermission('system:mail-log:query')")
|
||||
public CommonResult<PageResult<MailLogRespVO>> getMailLogPage(@Valid MailLogPageReqVO pageVO) {
|
||||
PageResult<MailLogDO> pageResult = mailLogService.getMailLogPage(pageVO);
|
||||
return success(BeanUtils.toBean(pageResult, MailLogRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@Operation(summary = "获得邮箱日志")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('system:mail-log:query')")
|
||||
public CommonResult<MailLogRespVO> getMailTemplate(@RequestParam("id") Long id) {
|
||||
MailLogDO log = mailLogService.getMailLog(id);
|
||||
return success(BeanUtils.toBean(log, MailLogRespVO.class));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
### 请求 /system/mail-template/send-mail 接口 => 成功
|
||||
POST {{baseUrl}}/system/mail-template/send-mail
|
||||
Authorization: Bearer {{token}}
|
||||
Content-Type: application/json
|
||||
tenant-id: {{adminTenantId}}
|
||||
|
||||
{
|
||||
"templateCode": "test_01",
|
||||
"mail": "7685413@qq.com",
|
||||
"templateParams": {
|
||||
"key01": "value01",
|
||||
"key02": "value02"
|
||||
}
|
||||
}
|
||||
@@ -1,99 +0,0 @@
|
||||
package com.njcn.rdms.module.system.controller.admin.mail;
|
||||
|
||||
import com.njcn.rdms.framework.common.pojo.CommonResult;
|
||||
import com.njcn.rdms.framework.common.pojo.PageResult;
|
||||
import com.njcn.rdms.framework.common.util.object.BeanUtils;
|
||||
import com.njcn.rdms.module.system.controller.admin.mail.vo.template.*;
|
||||
import com.njcn.rdms.module.system.dal.dataobject.mail.MailTemplateDO;
|
||||
import com.njcn.rdms.module.system.service.mail.MailSendService;
|
||||
import com.njcn.rdms.module.system.service.mail.MailTemplateService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.validation.Valid;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static com.njcn.rdms.framework.common.pojo.CommonResult.success;
|
||||
import static com.njcn.rdms.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
|
||||
|
||||
@Tag(name = "管理后台 - 邮件模版")
|
||||
@RestController
|
||||
@RequestMapping("/system/mail-template")
|
||||
public class MailTemplateController {
|
||||
|
||||
@Resource
|
||||
private MailTemplateService mailTempleService;
|
||||
@Resource
|
||||
private MailSendService mailSendService;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(summary = "创建邮件模版")
|
||||
@PreAuthorize("@ss.hasPermission('system:mail-template:create')")
|
||||
public CommonResult<Long> createMailTemplate(@Valid @RequestBody MailTemplateSaveReqVO createReqVO){
|
||||
return success(mailTempleService.createMailTemplate(createReqVO));
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@Operation(summary = "修改邮件模版")
|
||||
@PreAuthorize("@ss.hasPermission('system:mail-template:update')")
|
||||
public CommonResult<Boolean> updateMailTemplate(@Valid @RequestBody MailTemplateSaveReqVO updateReqVO){
|
||||
mailTempleService.updateMailTemplate(updateReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(summary = "删除邮件模版")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('system:mail-template:delete')")
|
||||
public CommonResult<Boolean> deleteMailTemplate(@RequestParam("id") Long id) {
|
||||
mailTempleService.deleteMailTemplate(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete-list")
|
||||
@Operation(summary = "批量删除邮件模版")
|
||||
@Parameter(name = "ids", description = "编号列表", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('system:mail-template:delete')")
|
||||
public CommonResult<Boolean> deleteMailTemplateList(@RequestParam("ids") List<Long> ids) {
|
||||
mailTempleService.deleteMailTemplateList(ids);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@Operation(summary = "获得邮件模版")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('system:mail-template:query')")
|
||||
public CommonResult<MailTemplateRespVO> getMailTemplate(@RequestParam("id") Long id) {
|
||||
MailTemplateDO template = mailTempleService.getMailTemplate(id);
|
||||
return success(BeanUtils.toBean(template, MailTemplateRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(summary = "获得邮件模版分页")
|
||||
@PreAuthorize("@ss.hasPermission('system:mail-template:query')")
|
||||
public CommonResult<PageResult<MailTemplateRespVO>> getMailTemplatePage(@Valid MailTemplatePageReqVO pageReqVO) {
|
||||
PageResult<MailTemplateDO> pageResult = mailTempleService.getMailTemplatePage(pageReqVO);
|
||||
return success(BeanUtils.toBean(pageResult, MailTemplateRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping({"/list-all-simple", "simple-list"})
|
||||
@Operation(summary = "获得邮件模版精简列表")
|
||||
public CommonResult<List<MailTemplateSimpleRespVO>> getSimpleTemplateList() {
|
||||
List<MailTemplateDO> list = mailTempleService.getMailTemplateList();
|
||||
return success(BeanUtils.toBean(list, MailTemplateSimpleRespVO.class));
|
||||
}
|
||||
|
||||
@PostMapping("/send-mail")
|
||||
@Operation(summary = "发送邮件")
|
||||
@PreAuthorize("@ss.hasPermission('system:mail-template:send-mail')")
|
||||
public CommonResult<Long> sendMail(@Valid @RequestBody MailTemplateSendReqVO sendReqVO) {
|
||||
return success(mailSendService.sendSingleMailToAdmin(getLoginUserId(),
|
||||
sendReqVO.getToMails(), sendReqVO.getCcMails(), sendReqVO.getBccMails(),
|
||||
sendReqVO.getTemplateCode(), sendReqVO.getTemplateParams()));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
package com.njcn.rdms.module.system.controller.admin.mail.vo.account;
|
||||
|
||||
import com.njcn.rdms.framework.common.pojo.PageParam;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
@Schema(description = "管理后台 - 邮箱账号分页 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class MailAccountPageReqVO extends PageParam {
|
||||
|
||||
@Schema(description = "邮箱", requiredMode = Schema.RequiredMode.REQUIRED, example = "rdmsyuanma@123.com")
|
||||
private String mail;
|
||||
|
||||
@Schema(description = "用户名" , requiredMode = Schema.RequiredMode.REQUIRED , example = "rdms")
|
||||
private String username;
|
||||
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
package com.njcn.rdms.module.system.controller.admin.mail.vo.account;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Schema(description = "管理后台 - 邮箱账号 Response VO")
|
||||
@Data
|
||||
public class MailAccountRespVO {
|
||||
|
||||
@Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "邮箱", requiredMode = Schema.RequiredMode.REQUIRED, example = "rdmsyuanma@123.com")
|
||||
private String mail;
|
||||
|
||||
@Schema(description = "用户名", requiredMode = Schema.RequiredMode.REQUIRED, example = "rdms")
|
||||
private String username;
|
||||
|
||||
@Schema(description = "密码", requiredMode = Schema.RequiredMode.REQUIRED, example = "123456")
|
||||
private String password;
|
||||
|
||||
@Schema(description = "SMTP 服务器域名", requiredMode = Schema.RequiredMode.REQUIRED, example = "www.iocoder.cn")
|
||||
private String host;
|
||||
|
||||
@Schema(description = "SMTP 服务器端口", requiredMode = Schema.RequiredMode.REQUIRED, example = "80")
|
||||
private Integer port;
|
||||
|
||||
@Schema(description = "是否开启 ssl", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
|
||||
private Boolean sslEnable;
|
||||
|
||||
@Schema(description = "是否开启 starttls", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
|
||||
private Boolean starttlsEnable;
|
||||
|
||||
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private LocalDateTime createTime;
|
||||
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
package com.njcn.rdms.module.system.controller.admin.mail.vo.account;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.Email;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
@Schema(description = "管理后台 - 邮箱账号创建/修改 Request VO")
|
||||
@Data
|
||||
public class MailAccountSaveReqVO {
|
||||
|
||||
@Schema(description = "编号", example = "1024")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "邮箱", requiredMode = Schema.RequiredMode.REQUIRED, example = "rdmsyuanma@123.com")
|
||||
@NotNull(message = "邮箱不能为空")
|
||||
@Email(message = "必须是 Email 格式")
|
||||
private String mail;
|
||||
|
||||
@Schema(description = "用户名", requiredMode = Schema.RequiredMode.REQUIRED, example = "rdms")
|
||||
@NotNull(message = "用户名不能为空")
|
||||
private String username;
|
||||
|
||||
@Schema(description = "密码", requiredMode = Schema.RequiredMode.REQUIRED, example = "123456")
|
||||
@NotNull(message = "密码必填")
|
||||
private String password;
|
||||
|
||||
@Schema(description = "SMTP 服务器域名", requiredMode = Schema.RequiredMode.REQUIRED, example = "www.iocoder.cn")
|
||||
@NotNull(message = "SMTP 服务器域名不能为空")
|
||||
private String host;
|
||||
|
||||
@Schema(description = "SMTP 服务器端口", requiredMode = Schema.RequiredMode.REQUIRED, example = "80")
|
||||
@NotNull(message = "SMTP 服务器端口不能为空")
|
||||
private Integer port;
|
||||
|
||||
@Schema(description = "是否开启 ssl", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
|
||||
@NotNull(message = "是否开启 ssl 必填")
|
||||
private Boolean sslEnable;
|
||||
|
||||
@Schema(description = "是否开启 starttls", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
|
||||
@NotNull(message = "是否开启 starttls 必填")
|
||||
private Boolean starttlsEnable;
|
||||
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
package com.njcn.rdms.module.system.controller.admin.mail.vo.account;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
@Schema(description = "管理后台 - 邮箱账号的精简 Response VO")
|
||||
@Data
|
||||
public class MailAccountSimpleRespVO {
|
||||
|
||||
@Schema(description = "邮箱编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "邮箱", requiredMode = Schema.RequiredMode.REQUIRED, example = "768541388@qq.com")
|
||||
private String mail;
|
||||
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
package com.njcn.rdms.module.system.controller.admin.mail.vo.log;
|
||||
|
||||
import com.njcn.rdms.framework.common.pojo.PageParam;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import static com.njcn.rdms.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||
|
||||
@Schema(description = "管理后台 - 邮箱日志分页 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class MailLogPageReqVO extends PageParam {
|
||||
|
||||
@Schema(description = "用户编号", example = "30883")
|
||||
private Long userId;
|
||||
|
||||
@Schema(description = "用户类型,参见 UserTypeEnum 枚举", example = "2")
|
||||
private Integer userType;
|
||||
|
||||
@Schema(description = "接收邮箱地址,模糊匹配", example = "76854@qq.com")
|
||||
private String toMail;
|
||||
|
||||
@Schema(description = "邮箱账号编号", example = "18107")
|
||||
private Long accountId;
|
||||
|
||||
@Schema(description = "模板编号", example = "5678")
|
||||
private Long templateId;
|
||||
|
||||
@Schema(description = "发送状态,参见 MailSendStatusEnum 枚举", example = "1")
|
||||
private Integer sendStatus;
|
||||
|
||||
@Schema(description = "发送时间")
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
private LocalDateTime[] sendTime;
|
||||
|
||||
}
|
||||
@@ -1,71 +0,0 @@
|
||||
package com.njcn.rdms.module.system.controller.admin.mail.vo.log;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Schema(description = "管理后台 - 邮件日志 Response VO")
|
||||
@Data
|
||||
public class MailLogRespVO {
|
||||
|
||||
@Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "31020")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "用户编号", example = "30883")
|
||||
private Long userId;
|
||||
|
||||
@Schema(description = "用户类型,参见 UserTypeEnum 枚举", example = "2")
|
||||
private Byte userType;
|
||||
|
||||
@Schema(description = "接收邮箱地址", requiredMode = Schema.RequiredMode.REQUIRED, example = "user1@example.com, user2@example.com")
|
||||
private List<String> toMails;
|
||||
|
||||
@Schema(description = "抄送邮箱地址", requiredMode = Schema.RequiredMode.REQUIRED, example = "user3@example.com, user4@example.com")
|
||||
private List<String> ccMails;
|
||||
|
||||
@Schema(description = "密送邮箱地址", requiredMode = Schema.RequiredMode.REQUIRED, example = "user5@example.com, user6@example.com")
|
||||
private List<String> bccMails;
|
||||
|
||||
@Schema(description = "邮箱账号编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "18107")
|
||||
private Long accountId;
|
||||
|
||||
@Schema(description = "发送邮箱地址", requiredMode = Schema.RequiredMode.REQUIRED, example = "85757@qq.com")
|
||||
private String fromMail;
|
||||
|
||||
@Schema(description = "模板编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "5678")
|
||||
private Long templateId;
|
||||
|
||||
@Schema(description = "模板编码", requiredMode = Schema.RequiredMode.REQUIRED, example = "test_01")
|
||||
private String templateCode;
|
||||
|
||||
@Schema(description = "模版发送人名称", example = "李四")
|
||||
private String templateNickname;
|
||||
|
||||
@Schema(description = "邮件标题", requiredMode = Schema.RequiredMode.REQUIRED, example = "测试标题")
|
||||
private String templateTitle;
|
||||
|
||||
@Schema(description = "邮件内容", requiredMode = Schema.RequiredMode.REQUIRED, example = "测试内容")
|
||||
private String templateContent;
|
||||
|
||||
@Schema(description = "邮件参数", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private Map<String, Object> templateParams;
|
||||
|
||||
@Schema(description = "发送状态,参见 MailSendStatusEnum 枚举", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private Byte sendStatus;
|
||||
|
||||
@Schema(description = "发送时间")
|
||||
private LocalDateTime sendTime;
|
||||
|
||||
@Schema(description = "发送返回的消息 ID", example = "28568")
|
||||
private String sendMessageId;
|
||||
|
||||
@Schema(description = "发送异常")
|
||||
private String sendException;
|
||||
|
||||
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private LocalDateTime createTime;
|
||||
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
package com.njcn.rdms.module.system.controller.admin.mail.vo.template;
|
||||
|
||||
import com.njcn.rdms.framework.common.pojo.PageParam;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import static com.njcn.rdms.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||
|
||||
@Schema(description = "管理后台 - 邮件模版分页 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class MailTemplatePageReqVO extends PageParam {
|
||||
|
||||
@Schema(description = "状态,参见 CommonStatusEnum 枚举", example = "1")
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "标识,模糊匹配", example = "code_1024")
|
||||
private String code;
|
||||
|
||||
@Schema(description = "名称,模糊匹配", example = "芋头")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "账号编号", example = "2048")
|
||||
private Long accountId;
|
||||
|
||||
@Schema(description = "创建时间")
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
private LocalDateTime[] createTime;
|
||||
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
package com.njcn.rdms.module.system.controller.admin.mail.vo.template;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
@Schema(description = "管理后台 - 邮件末班 Response VO")
|
||||
@Data
|
||||
public class MailTemplateRespVO {
|
||||
|
||||
@Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "模版名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "测试名字")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "模版编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "test")
|
||||
private String code;
|
||||
|
||||
@Schema(description = "发送的邮箱账号编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private Long accountId;
|
||||
|
||||
@Schema(description = "发送人名称", example = "芋头")
|
||||
private String nickname;
|
||||
|
||||
@Schema(description = "标题", requiredMode = Schema.RequiredMode.REQUIRED, example = "注册成功")
|
||||
private String title;
|
||||
|
||||
@Schema(description = "内容", requiredMode = Schema.RequiredMode.REQUIRED, example = "你好,注册成功啦")
|
||||
private String content;
|
||||
|
||||
@Schema(description = "参数数组", example = "name,code")
|
||||
private List<String> params;
|
||||
|
||||
@Schema(description = "状态,参见 CommonStatusEnum 枚举", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "备注", example = "奥特曼")
|
||||
private String remark;
|
||||
|
||||
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private LocalDateTime createTime;
|
||||
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
package com.njcn.rdms.module.system.controller.admin.mail.vo.template;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
|
||||
@Schema(description = "管理后台 - 邮件模版创建/修改 Request VO")
|
||||
@Data
|
||||
public class MailTemplateSaveReqVO {
|
||||
|
||||
@Schema(description = "编号", example = "1024")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "模版名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "测试名字")
|
||||
@NotNull(message = "名称不能为空")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "模版编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "test")
|
||||
@NotNull(message = "模版编号不能为空")
|
||||
private String code;
|
||||
|
||||
@Schema(description = "发送的邮箱账号编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@NotNull(message = "发送的邮箱账号编号不能为空")
|
||||
private Long accountId;
|
||||
|
||||
@Schema(description = "发送人名称", example = "芋头")
|
||||
private String nickname;
|
||||
|
||||
@Schema(description = "标题", requiredMode = Schema.RequiredMode.REQUIRED, example = "注册成功")
|
||||
@NotEmpty(message = "标题不能为空")
|
||||
private String title;
|
||||
|
||||
@Schema(description = "内容", requiredMode = Schema.RequiredMode.REQUIRED, example = "你好,注册成功啦")
|
||||
@NotEmpty(message = "内容不能为空")
|
||||
private String content;
|
||||
|
||||
@Schema(description = "状态,参见 CommonStatusEnum 枚举", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@NotNull(message = "状态不能为空")
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "备注", example = "奥特曼")
|
||||
private String remark;
|
||||
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
package com.njcn.rdms.module.system.controller.admin.mail.vo.template;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Schema(description = "管理后台 - 邮件发送 Req VO")
|
||||
@Data
|
||||
public class MailTemplateSendReqVO {
|
||||
|
||||
@Schema(description = "接收邮箱", requiredMode = Schema.RequiredMode.REQUIRED, example = "[user1@example.com, user2@example.com]")
|
||||
@NotEmpty(message = "接收邮箱不能为空")
|
||||
private List<String> toMails;
|
||||
|
||||
@Schema(description = "抄送邮箱", requiredMode = Schema.RequiredMode.REQUIRED, example = "[user3@example.com, user4@example.com]")
|
||||
private List<String> ccMails;
|
||||
|
||||
@Schema(description = "密送邮箱", requiredMode = Schema.RequiredMode.REQUIRED, example = "[user5@example.com, user6@example.com]")
|
||||
private List<String> bccMails;
|
||||
|
||||
@Schema(description = "模板编码", requiredMode = Schema.RequiredMode.REQUIRED, example = "test_01")
|
||||
@NotNull(message = "模板编码不能为空")
|
||||
private String templateCode;
|
||||
|
||||
@Schema(description = "模板参数")
|
||||
private Map<String, Object> templateParams;
|
||||
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
package com.njcn.rdms.module.system.controller.admin.mail.vo.template;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
@Schema(description = "管理后台 - 邮件模版的精简 Response VO")
|
||||
@Data
|
||||
public class MailTemplateSimpleRespVO {
|
||||
|
||||
@Schema(description = "模版编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "模版名字", requiredMode = Schema.RequiredMode.REQUIRED, example = "哒哒哒")
|
||||
private String name;
|
||||
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
### 请求 /infra/redis/get-monitor-info 接口 => 成功
|
||||
GET {{baseUrl}}/infra/redis/get-monitor-info
|
||||
### 请求 /system/redis/get-monitor-info 接口 => 成功
|
||||
GET {{baseUrl}}/system/redis/get-monitor-info
|
||||
Authorization: Bearer {{token}}
|
||||
tenant-id: {{adminTenantId}}
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ import static com.njcn.rdms.framework.common.pojo.CommonResult.success;
|
||||
|
||||
@Tag(name = "管理后台 - Redis 监控")
|
||||
@RestController
|
||||
@RequestMapping("/infra/redis")
|
||||
@RequestMapping("/system/redis")
|
||||
public class RedisController {
|
||||
|
||||
@Resource
|
||||
@@ -28,7 +28,7 @@ public class RedisController {
|
||||
|
||||
@GetMapping("/get-monitor-info")
|
||||
@Operation(summary = "获得 Redis 监控信息")
|
||||
@PreAuthorize("@ss.hasPermission('infra:redis:get-monitor-info')")
|
||||
@PreAuthorize("@ss.hasPermission('system:redis:get-monitor-info')")
|
||||
public CommonResult<RedisMonitorRespVO> getRedisMonitorInfo() {
|
||||
// 获得 Redis 统计信息
|
||||
Properties info = stringRedisTemplate.execute((RedisCallback<Properties>) RedisServerCommands::info);
|
||||
@@ -41,3 +41,4 @@ public class RedisController {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
### 请求 /system/social-client/send-subscribe-message 接口 => 发送测试订阅消息
|
||||
POST {{baseUrl}}/system/social-client/send-subscribe-message
|
||||
Authorization: Bearer {{token}}
|
||||
Content-Type: application/json
|
||||
#Authorization: Bearer test100
|
||||
tenant-id: {{adminTenantId}}
|
||||
|
||||
{
|
||||
"userId": 247,
|
||||
"userType": 1,
|
||||
"socialType": 34,
|
||||
"templateTitle": "充值成功通知",
|
||||
"page": "",
|
||||
"messages": {
|
||||
"character_string1":"5616122165165",
|
||||
"amount2":"1000.00",
|
||||
"time3":"2024-01-01 10:10:10",
|
||||
"phrase4": "充值成功"
|
||||
}
|
||||
}
|
||||
@@ -1,83 +0,0 @@
|
||||
package com.njcn.rdms.module.system.controller.admin.socail;
|
||||
|
||||
import com.njcn.rdms.framework.common.pojo.CommonResult;
|
||||
import com.njcn.rdms.framework.common.pojo.PageResult;
|
||||
import com.njcn.rdms.framework.common.util.object.BeanUtils;
|
||||
import com.njcn.rdms.module.system.controller.admin.socail.vo.client.SocialClientPageReqVO;
|
||||
import com.njcn.rdms.module.system.controller.admin.socail.vo.client.SocialClientRespVO;
|
||||
import com.njcn.rdms.module.system.controller.admin.socail.vo.client.SocialClientSaveReqVO;
|
||||
import com.njcn.rdms.module.system.dal.dataobject.social.SocialClientDO;
|
||||
import com.njcn.rdms.module.system.service.social.SocialClientService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.validation.Valid;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static com.njcn.rdms.framework.common.pojo.CommonResult.success;
|
||||
|
||||
@Tag(name = "管理后台 - 社交客户端")
|
||||
@RestController
|
||||
@RequestMapping("/system/social-client")
|
||||
@Validated
|
||||
public class SocialClientController {
|
||||
|
||||
@Resource
|
||||
private SocialClientService socialClientService;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(summary = "创建社交客户端")
|
||||
@PreAuthorize("@ss.hasPermission('system:social-client:create')")
|
||||
public CommonResult<Long> createSocialClient(@Valid @RequestBody SocialClientSaveReqVO createReqVO) {
|
||||
return success(socialClientService.createSocialClient(createReqVO));
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@Operation(summary = "更新社交客户端")
|
||||
@PreAuthorize("@ss.hasPermission('system:social-client:update')")
|
||||
public CommonResult<Boolean> updateSocialClient(@Valid @RequestBody SocialClientSaveReqVO updateReqVO) {
|
||||
socialClientService.updateSocialClient(updateReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(summary = "删除社交客户端")
|
||||
@Parameter(name = "id", description = "编号", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('system:social-client:delete')")
|
||||
public CommonResult<Boolean> deleteSocialClient(@RequestParam("id") Long id) {
|
||||
socialClientService.deleteSocialClient(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete-list")
|
||||
@Parameter(name = "ids", description = "编号列表", required = true)
|
||||
@Operation(summary = "批量删除社交客户端")
|
||||
@PreAuthorize("@ss.hasPermission('system:social-client:delete')")
|
||||
public CommonResult<Boolean> deleteSocialClientList(@RequestParam("ids") List<Long> ids) {
|
||||
socialClientService.deleteSocialClientList(ids);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@Operation(summary = "获得社交客户端")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('system:social-client:query')")
|
||||
public CommonResult<SocialClientRespVO> getSocialClient(@RequestParam("id") Long id) {
|
||||
SocialClientDO client = socialClientService.getSocialClient(id);
|
||||
return success(BeanUtils.toBean(client, SocialClientRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(summary = "获得社交客户端分页")
|
||||
@PreAuthorize("@ss.hasPermission('system:social-client:query')")
|
||||
public CommonResult<PageResult<SocialClientRespVO>> getSocialClientPage(@Valid SocialClientPageReqVO pageVO) {
|
||||
PageResult<SocialClientDO> pageResult = socialClientService.getSocialClientPage(pageVO);
|
||||
return success(BeanUtils.toBean(pageResult, SocialClientRespVO.class));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
package com.njcn.rdms.module.system.controller.admin.socail.vo.client;
|
||||
|
||||
import com.njcn.rdms.framework.common.pojo.PageParam;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
@Schema(description = "管理后台 - 社交客户端分页 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class SocialClientPageReqVO extends PageParam {
|
||||
|
||||
@Schema(description = "应用名", example = "rdms商城")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "社交平台的类型", example = "31")
|
||||
private Integer socialType;
|
||||
|
||||
@Schema(description = "用户类型", example = "2")
|
||||
private Integer userType;
|
||||
|
||||
@Schema(description = "客户端编号", example = "145442115")
|
||||
private String clientId;
|
||||
|
||||
@Schema(description = "状态", example = "1")
|
||||
private Integer status;
|
||||
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
package com.njcn.rdms.module.system.controller.admin.socail.vo.client;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Schema(description = "管理后台 - 社交客户端 Response VO")
|
||||
@Data
|
||||
public class SocialClientRespVO {
|
||||
|
||||
@Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "27162")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "应用名", requiredMode = Schema.RequiredMode.REQUIRED, example = "rdms商城")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "社交平台的类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "31")
|
||||
private Integer socialType;
|
||||
|
||||
@Schema(description = "用户类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
|
||||
private Integer userType;
|
||||
|
||||
@Schema(description = "客户端编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "wwd411c69a39ad2e54")
|
||||
private String clientId;
|
||||
|
||||
@Schema(description = "客户端密钥", requiredMode = Schema.RequiredMode.REQUIRED, example = "peter")
|
||||
private String clientSecret;
|
||||
|
||||
@Schema(description = "授权方的网页应用编号", example = "2000045")
|
||||
private String agentId;
|
||||
|
||||
@Schema(description = "publicKey 公钥", example = "2000045")
|
||||
private String publicKey;
|
||||
|
||||
@Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private LocalDateTime createTime;
|
||||
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
package com.njcn.rdms.module.system.controller.admin.socail.vo.client;
|
||||
|
||||
import com.njcn.rdms.framework.common.enums.CommonStatusEnum;
|
||||
import com.njcn.rdms.framework.common.enums.UserTypeEnum;
|
||||
import com.njcn.rdms.framework.common.validation.InEnum;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
|
||||
@Schema(description = "管理后台 - 社交客户端创建/修改 Request VO")
|
||||
@Data
|
||||
public class SocialClientSaveReqVO {
|
||||
|
||||
@Schema(description = "编号", example = "27162")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "应用名", requiredMode = Schema.RequiredMode.REQUIRED, example = "rdms商城")
|
||||
@NotNull(message = "应用名不能为空")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "社交平台的类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "31")
|
||||
@NotNull(message = "社交平台的类型不能为空")
|
||||
private Integer socialType;
|
||||
|
||||
@Schema(description = "用户类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
|
||||
@NotNull(message = "用户类型不能为空")
|
||||
@InEnum(UserTypeEnum.class)
|
||||
private Integer userType;
|
||||
|
||||
@Schema(description = "客户端编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "wwd411c69a39ad2e54")
|
||||
@NotNull(message = "客户端编号不能为空")
|
||||
private String clientId;
|
||||
|
||||
@Schema(description = "客户端密钥", requiredMode = Schema.RequiredMode.REQUIRED, example = "peter")
|
||||
@NotNull(message = "客户端密钥不能为空")
|
||||
private String clientSecret;
|
||||
|
||||
@Schema(description = "授权方的网页应用编号", example = "2000045")
|
||||
private String agentId;
|
||||
|
||||
@Schema(description = "publicKey 公钥", example = "2000045")
|
||||
private String publicKey;
|
||||
|
||||
@Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@NotNull(message = "状态不能为空")
|
||||
@InEnum(CommonStatusEnum.class)
|
||||
private Integer status;
|
||||
|
||||
}
|
||||
@@ -23,7 +23,7 @@ import static com.njcn.rdms.framework.common.pojo.CommonResult.success;
|
||||
|
||||
@Tag(name = "用户 App - 文件存储")
|
||||
@RestController
|
||||
@RequestMapping("/infra/file")
|
||||
@RequestMapping("/system/file")
|
||||
@Validated
|
||||
@Slf4j
|
||||
public class AppFileController {
|
||||
@@ -63,3 +63,4 @@ public class AppFileController {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,68 +0,0 @@
|
||||
package com.njcn.rdms.module.system.convert.codegen;
|
||||
|
||||
import com.baomidou.mybatisplus.generator.config.po.TableField;
|
||||
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
|
||||
import com.njcn.rdms.framework.common.util.collection.CollectionUtils;
|
||||
import com.njcn.rdms.framework.common.util.object.BeanUtils;
|
||||
import com.njcn.rdms.module.system.controller.admin.codegen.vo.CodegenDetailRespVO;
|
||||
import com.njcn.rdms.module.system.controller.admin.codegen.vo.CodegenPreviewRespVO;
|
||||
import com.njcn.rdms.module.system.controller.admin.codegen.vo.column.CodegenColumnRespVO;
|
||||
import com.njcn.rdms.module.system.controller.admin.codegen.vo.table.CodegenTableRespVO;
|
||||
import com.njcn.rdms.module.system.dal.dataobject.codegen.CodegenColumnDO;
|
||||
import com.njcn.rdms.module.system.dal.dataobject.codegen.CodegenTableDO;
|
||||
import org.apache.ibatis.type.JdbcType;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.Mapping;
|
||||
import org.mapstruct.Mappings;
|
||||
import org.mapstruct.Named;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Mapper
|
||||
public interface CodegenConvert {
|
||||
|
||||
CodegenConvert INSTANCE = Mappers.getMapper(CodegenConvert.class);
|
||||
|
||||
// ========== TableInfo 相关 ==========
|
||||
|
||||
@Mappings({
|
||||
@Mapping(source = "name", target = "tableName"),
|
||||
@Mapping(source = "comment", target = "tableComment"),
|
||||
})
|
||||
CodegenTableDO convert(TableInfo bean);
|
||||
|
||||
List<CodegenColumnDO> convertList(List<TableField> list);
|
||||
|
||||
@Mappings({
|
||||
@Mapping(source = "name", target = "columnName"),
|
||||
@Mapping(source = "metaInfo.jdbcType", target = "dataType", qualifiedByName = "getDataType"),
|
||||
@Mapping(source = "comment", target = "columnComment"),
|
||||
@Mapping(source = "metaInfo.nullable", target = "nullable"),
|
||||
@Mapping(source = "keyFlag", target = "primaryKey"),
|
||||
@Mapping(source = "columnType.type", target = "javaType"),
|
||||
@Mapping(source = "propertyName", target = "javaField"),
|
||||
})
|
||||
CodegenColumnDO convert(TableField bean);
|
||||
|
||||
@Named("getDataType")
|
||||
default String getDataType(JdbcType jdbcType) {
|
||||
return jdbcType.name();
|
||||
}
|
||||
|
||||
// ========== 其它 ==========
|
||||
|
||||
default CodegenDetailRespVO convert(CodegenTableDO table, List<CodegenColumnDO> columns) {
|
||||
CodegenDetailRespVO respVO = new CodegenDetailRespVO();
|
||||
respVO.setTable(BeanUtils.toBean(table, CodegenTableRespVO.class));
|
||||
respVO.setColumns(BeanUtils.toBean(columns, CodegenColumnRespVO.class));
|
||||
return respVO;
|
||||
}
|
||||
|
||||
default List<CodegenPreviewRespVO> convert(Map<String, String> codes) {
|
||||
return CollectionUtils.convertList(codes.entrySet(),
|
||||
entry -> new CodegenPreviewRespVO().setFilePath(entry.getKey()).setCode(entry.getValue()));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,133 +0,0 @@
|
||||
package com.njcn.rdms.module.system.dal.dataobject.codegen;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.KeySequence;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.baomidou.mybatisplus.generator.config.po.TableField;
|
||||
import com.njcn.rdms.framework.mybatis.core.dataobject.BaseDO;
|
||||
import com.njcn.rdms.module.system.enums.codegen.CodegenColumnHtmlTypeEnum;
|
||||
import com.njcn.rdms.module.system.enums.codegen.CodegenColumnListConditionEnum;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 代码生成 column 字段定义
|
||||
*
|
||||
* @author hongawen
|
||||
*/
|
||||
@TableName(value = "infra_codegen_column", autoResultMap = true)
|
||||
@KeySequence("infra_codegen_column_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
|
||||
@Data
|
||||
|
||||
public class CodegenColumnDO extends BaseDO {
|
||||
|
||||
/**
|
||||
* ID 编号
|
||||
*/
|
||||
@TableId
|
||||
private Long id;
|
||||
/**
|
||||
* 表编号
|
||||
* <p>
|
||||
* 关联 {@link CodegenTableDO#getId()}
|
||||
*/
|
||||
private Long tableId;
|
||||
|
||||
// ========== 表相关字段 ==========
|
||||
|
||||
/**
|
||||
* 字段名
|
||||
*
|
||||
* 关联 {@link TableField#getName()}
|
||||
*/
|
||||
private String columnName;
|
||||
/**
|
||||
* 数据库字段类型
|
||||
*
|
||||
* 关联 {@link TableField.MetaInfo#getJdbcType()}
|
||||
*/
|
||||
private String dataType;
|
||||
/**
|
||||
* 字段描述
|
||||
*
|
||||
* 关联 {@link TableField#getComment()}
|
||||
*/
|
||||
private String columnComment;
|
||||
/**
|
||||
* 是否允许为空
|
||||
*
|
||||
* 关联 {@link TableField.MetaInfo#isNullable()}
|
||||
*/
|
||||
private Boolean nullable;
|
||||
/**
|
||||
* 是否主键
|
||||
*
|
||||
* 关联 {@link TableField#isKeyFlag()}
|
||||
*/
|
||||
private Boolean primaryKey;
|
||||
/**
|
||||
* 排序
|
||||
*/
|
||||
private Integer ordinalPosition;
|
||||
|
||||
// ========== Java 相关字段 ==========
|
||||
|
||||
/**
|
||||
* Java 属性类型
|
||||
*
|
||||
* 例如说 String、Boolean 等等
|
||||
*
|
||||
* 关联 {@link TableField#getColumnType()}
|
||||
*/
|
||||
private String javaType;
|
||||
/**
|
||||
* Java 属性名
|
||||
*
|
||||
* 关联 {@link TableField#getPropertyName()}
|
||||
*/
|
||||
private String javaField;
|
||||
/**
|
||||
* 字典类型
|
||||
* <p>
|
||||
* 关联 DictTypeDO 的 type 属性
|
||||
*/
|
||||
private String dictType;
|
||||
/**
|
||||
* 数据示例,主要用于生成 Swagger 注解的 example 字段
|
||||
*/
|
||||
private String example;
|
||||
|
||||
// ========== CRUD 相关字段 ==========
|
||||
|
||||
/**
|
||||
* 是否为 Create 创建操作的字段
|
||||
*/
|
||||
private Boolean createOperation;
|
||||
/**
|
||||
* 是否为 Update 更新操作的字段
|
||||
*/
|
||||
private Boolean updateOperation;
|
||||
/**
|
||||
* 是否为 List 查询操作的字段
|
||||
*/
|
||||
private Boolean listOperation;
|
||||
/**
|
||||
* List 查询操作的条件类型
|
||||
* <p>
|
||||
* 枚举 {@link CodegenColumnListConditionEnum}
|
||||
*/
|
||||
private String listOperationCondition;
|
||||
/**
|
||||
* 是否为 List 查询操作的返回字段
|
||||
*/
|
||||
private Boolean listOperationResult;
|
||||
|
||||
// ========== UI 相关字段 ==========
|
||||
|
||||
/**
|
||||
* 显示类型
|
||||
* <p>
|
||||
* 枚举 {@link CodegenColumnHtmlTypeEnum}
|
||||
*/
|
||||
private String htmlType;
|
||||
|
||||
}
|
||||
@@ -1,155 +0,0 @@
|
||||
package com.njcn.rdms.module.system.dal.dataobject.codegen;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.KeySequence;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
|
||||
import com.njcn.rdms.framework.mybatis.core.dataobject.BaseDO;
|
||||
import com.njcn.rdms.module.system.dal.dataobject.db.DataSourceConfigDO;
|
||||
import com.njcn.rdms.module.system.enums.codegen.CodegenFrontTypeEnum;
|
||||
import com.njcn.rdms.module.system.enums.codegen.CodegenSceneEnum;
|
||||
import com.njcn.rdms.module.system.enums.codegen.CodegenTemplateTypeEnum;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 代码生成 table 表定义
|
||||
*
|
||||
* @author hongawen
|
||||
*/
|
||||
@TableName(value = "infra_codegen_table", autoResultMap = true)
|
||||
@KeySequence("infra_codegen_table_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
|
||||
@Data
|
||||
|
||||
public class CodegenTableDO extends BaseDO {
|
||||
|
||||
/**
|
||||
* ID 编号
|
||||
*/
|
||||
@TableId
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 数据源编号
|
||||
*
|
||||
* 关联 {@link DataSourceConfigDO#getId()}
|
||||
*/
|
||||
private Long dataSourceConfigId;
|
||||
/**
|
||||
* 生成场景
|
||||
*
|
||||
* 枚举 {@link CodegenSceneEnum}
|
||||
*/
|
||||
private Integer scene;
|
||||
|
||||
// ========== 表相关字段 ==========
|
||||
|
||||
/**
|
||||
* 表名称
|
||||
*
|
||||
* 关联 {@link TableInfo#getName()}
|
||||
*/
|
||||
private String tableName;
|
||||
/**
|
||||
* 表描述
|
||||
*
|
||||
* 关联 {@link TableInfo#getComment()}
|
||||
*/
|
||||
private String tableComment;
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
private String remark;
|
||||
|
||||
// ========== 类相关字段 ==========
|
||||
|
||||
/**
|
||||
* 模块名,即一级目录
|
||||
*
|
||||
* 例如说,system、infra、tool 等等
|
||||
*/
|
||||
private String moduleName;
|
||||
/**
|
||||
* 业务名,即二级目录
|
||||
*
|
||||
* 例如说,user、permission、dict 等等
|
||||
*/
|
||||
private String businessName;
|
||||
/**
|
||||
* 类名称(首字母大写)
|
||||
*
|
||||
* 例如说,SysUser、SysMenu、SysDictData 等等
|
||||
*/
|
||||
private String className;
|
||||
/**
|
||||
* 类描述
|
||||
*/
|
||||
private String classComment;
|
||||
/**
|
||||
* 作者
|
||||
*/
|
||||
private String author;
|
||||
|
||||
// ========== 生成相关字段 ==========
|
||||
|
||||
/**
|
||||
* 模板类型
|
||||
*
|
||||
* 枚举 {@link CodegenTemplateTypeEnum}
|
||||
*/
|
||||
private Integer templateType;
|
||||
/**
|
||||
* 代码生成的前端类型
|
||||
*
|
||||
* 枚举 {@link CodegenFrontTypeEnum}
|
||||
*/
|
||||
private Integer frontType;
|
||||
|
||||
// ========== 菜单相关字段 ==========
|
||||
|
||||
/**
|
||||
* 父菜单编号
|
||||
*
|
||||
* 关联 MenuDO 的 id 属性
|
||||
*/
|
||||
private Long parentMenuId;
|
||||
|
||||
// ========== 主子表相关字段 ==========
|
||||
|
||||
/**
|
||||
* 主表的编号
|
||||
*
|
||||
* 关联 {@link CodegenTableDO#getId()}
|
||||
*/
|
||||
private Long masterTableId;
|
||||
/**
|
||||
* 【自己】子表关联主表的字段编号
|
||||
*
|
||||
* 关联 {@link CodegenColumnDO#getId()}
|
||||
*/
|
||||
private Long subJoinColumnId;
|
||||
/**
|
||||
* 主表与子表是否一对多
|
||||
*
|
||||
* true:一对多
|
||||
* false:一对一
|
||||
*/
|
||||
private Boolean subJoinMany;
|
||||
|
||||
// ========== 树表相关字段 ==========
|
||||
|
||||
/**
|
||||
* 树表的父字段编号
|
||||
*
|
||||
* 关联 {@link CodegenColumnDO#getId()}
|
||||
*/
|
||||
private Long treeParentColumnId;
|
||||
/**
|
||||
* 树表的名字字段编号
|
||||
*
|
||||
* 名字的用途:新增或修改时,select 框展示的字段
|
||||
*
|
||||
* 关联 {@link CodegenColumnDO#getId()}
|
||||
*/
|
||||
private Long treeNameColumnId;
|
||||
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
package com.njcn.rdms.module.system.dal.dataobject.db;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.KeySequence;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.njcn.rdms.framework.mybatis.core.dataobject.BaseDO;
|
||||
import com.njcn.rdms.framework.mybatis.core.type.EncryptTypeHandler;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 数据源配置
|
||||
*
|
||||
* @author hongawen
|
||||
*/
|
||||
@TableName(value = "infra_data_source_config", autoResultMap = true)
|
||||
@KeySequence("infra_data_source_config_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
|
||||
@Data
|
||||
|
||||
public class DataSourceConfigDO extends BaseDO {
|
||||
|
||||
/**
|
||||
* 主键编号 - Master 数据源
|
||||
*/
|
||||
public static final Long ID_MASTER = 0L;
|
||||
|
||||
/**
|
||||
* 主键编号
|
||||
*/
|
||||
private Long id;
|
||||
/**
|
||||
* 连接名
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 数据源连接
|
||||
*/
|
||||
private String url;
|
||||
/**
|
||||
* 用户名
|
||||
*/
|
||||
private String username;
|
||||
/**
|
||||
* 密码
|
||||
*/
|
||||
@TableField(typeHandler = EncryptTypeHandler.class)
|
||||
private String password;
|
||||
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
package com.njcn.rdms.module.system.dal.dataobject.mail;
|
||||
|
||||
import com.njcn.rdms.framework.mybatis.core.dataobject.BaseDO;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.KeySequence;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
/**
|
||||
* 邮箱账号 DO
|
||||
*
|
||||
* 用途:配置发送邮箱的账号
|
||||
*
|
||||
* @author hongawen
|
||||
*
|
||||
*/
|
||||
@TableName(value = "system_mail_account", autoResultMap = true)
|
||||
@KeySequence("system_mail_account_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
|
||||
public class MailAccountDO extends BaseDO {
|
||||
|
||||
/**
|
||||
* 主键
|
||||
*/
|
||||
@TableId
|
||||
private Long id;
|
||||
/**
|
||||
* 邮箱
|
||||
*/
|
||||
private String mail;
|
||||
|
||||
/**
|
||||
* 用户名
|
||||
*/
|
||||
private String username;
|
||||
/**
|
||||
* 密码
|
||||
*/
|
||||
private String password;
|
||||
/**
|
||||
* SMTP 服务器域名
|
||||
*/
|
||||
private String host;
|
||||
/**
|
||||
* SMTP 服务器端口
|
||||
*/
|
||||
private Integer port;
|
||||
/**
|
||||
* 是否开启 SSL
|
||||
*/
|
||||
private Boolean sslEnable;
|
||||
/**
|
||||
* 是否开启 STARTTLS
|
||||
*/
|
||||
private Boolean starttlsEnable;
|
||||
|
||||
}
|
||||
@@ -1,139 +0,0 @@
|
||||
package com.njcn.rdms.module.system.dal.dataobject.mail;
|
||||
|
||||
import com.njcn.rdms.framework.common.enums.UserTypeEnum;
|
||||
import com.njcn.rdms.framework.mybatis.core.dataobject.BaseDO;
|
||||
import com.njcn.rdms.framework.mybatis.core.type.StringListTypeHandler;
|
||||
|
||||
import com.njcn.rdms.module.system.enums.mail.MailSendStatusEnum;
|
||||
import com.baomidou.mybatisplus.annotation.KeySequence;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
|
||||
import lombok.*;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 邮箱日志 DO
|
||||
* 记录每一次邮件的发送
|
||||
*
|
||||
* @author hongawen
|
||||
*
|
||||
*/
|
||||
@TableName(value = "system_mail_log", autoResultMap = true)
|
||||
@KeySequence("system_mail_log_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
|
||||
public class MailLogDO extends BaseDO implements Serializable {
|
||||
|
||||
/**
|
||||
* 日志编号,自增
|
||||
*/
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 用户编码
|
||||
*/
|
||||
private Long userId;
|
||||
/**
|
||||
* 用户类型
|
||||
*
|
||||
* 枚举 {@link UserTypeEnum}
|
||||
*/
|
||||
private Integer userType;
|
||||
|
||||
/**
|
||||
* 接收邮箱地址
|
||||
*/
|
||||
@TableField(typeHandler = StringListTypeHandler.class)
|
||||
private List<String> toMails;
|
||||
/**
|
||||
* 接收邮箱地址
|
||||
*/
|
||||
@TableField(typeHandler = StringListTypeHandler.class)
|
||||
private List<String> ccMails;
|
||||
/**
|
||||
* 密送邮箱地址
|
||||
*/
|
||||
@TableField(typeHandler = StringListTypeHandler.class)
|
||||
private List<String> bccMails;
|
||||
|
||||
/**
|
||||
* 邮箱账号编号
|
||||
*
|
||||
* 关联 {@link MailAccountDO#getId()}
|
||||
*/
|
||||
private Long accountId;
|
||||
/**
|
||||
* 发送邮箱地址
|
||||
*
|
||||
* 冗余 {@link MailAccountDO#getMail()}
|
||||
*/
|
||||
private String fromMail;
|
||||
|
||||
// ========= 模板相关字段 =========
|
||||
/**
|
||||
* 模版编号
|
||||
*
|
||||
* 关联 {@link MailTemplateDO#getId()}
|
||||
*/
|
||||
private Long templateId;
|
||||
/**
|
||||
* 模版编码
|
||||
*
|
||||
* 冗余 {@link MailTemplateDO#getCode()}
|
||||
*/
|
||||
private String templateCode;
|
||||
/**
|
||||
* 模版发送人名称
|
||||
*
|
||||
* 冗余 {@link MailTemplateDO#getNickname()}
|
||||
*/
|
||||
private String templateNickname;
|
||||
/**
|
||||
* 模版标题
|
||||
*/
|
||||
private String templateTitle;
|
||||
/**
|
||||
* 模版内容
|
||||
*
|
||||
* 基于 {@link MailTemplateDO#getContent()} 格式化后的内容
|
||||
*/
|
||||
private String templateContent;
|
||||
/**
|
||||
* 模版参数
|
||||
*
|
||||
* 基于 {@link MailTemplateDO#getParams()} 输入后的参数
|
||||
*/
|
||||
@TableField(typeHandler = JacksonTypeHandler.class)
|
||||
private Map<String, Object> templateParams;
|
||||
|
||||
// ========= 发送相关字段 =========
|
||||
/**
|
||||
* 发送状态
|
||||
*
|
||||
* 枚举 {@link MailSendStatusEnum}
|
||||
*/
|
||||
private Integer sendStatus;
|
||||
/**
|
||||
* 发送时间
|
||||
*/
|
||||
private LocalDateTime sendTime;
|
||||
/**
|
||||
* 发送返回的消息 ID
|
||||
*/
|
||||
private String sendMessageId;
|
||||
/**
|
||||
* 发送异常
|
||||
*/
|
||||
private String sendException;
|
||||
|
||||
}
|
||||
@@ -1,75 +0,0 @@
|
||||
package com.njcn.rdms.module.system.dal.dataobject.mail;
|
||||
|
||||
import com.njcn.rdms.framework.common.enums.CommonStatusEnum;
|
||||
import com.njcn.rdms.framework.mybatis.core.dataobject.BaseDO;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.KeySequence;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 邮件模版 DO
|
||||
*
|
||||
* @author hongawen
|
||||
*
|
||||
*/
|
||||
@TableName(value = "system_mail_template", autoResultMap = true)
|
||||
@KeySequence("system_mail_template_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
|
||||
public class MailTemplateDO extends BaseDO {
|
||||
|
||||
/**
|
||||
* 主键
|
||||
*/
|
||||
private Long id;
|
||||
/**
|
||||
* 模版名称
|
||||
*/
|
||||
private String name;
|
||||
/**
|
||||
* 模版编号
|
||||
*/
|
||||
private String code;
|
||||
/**
|
||||
* 发送的邮箱账号编号
|
||||
*
|
||||
* 关联 {@link MailAccountDO#getId()}
|
||||
*/
|
||||
private Long accountId;
|
||||
|
||||
/**
|
||||
* 发送人名称
|
||||
*/
|
||||
private String nickname;
|
||||
/**
|
||||
* 标题
|
||||
*/
|
||||
private String title;
|
||||
/**
|
||||
* 内容
|
||||
*/
|
||||
private String content;
|
||||
/**
|
||||
* 参数数组(自动根据内容生成)
|
||||
*/
|
||||
@TableField(typeHandler = JacksonTypeHandler.class)
|
||||
private List<String> params;
|
||||
/**
|
||||
* 状态
|
||||
*
|
||||
* 枚举 {@link CommonStatusEnum}
|
||||
*/
|
||||
private Integer status;
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
private String remark;
|
||||
|
||||
}
|
||||
@@ -1,56 +0,0 @@
|
||||
package com.njcn.rdms.module.system.dal.dataobject.social;
|
||||
|
||||
import com.njcn.rdms.framework.common.enums.CommonStatusEnum;
|
||||
import com.njcn.rdms.framework.common.enums.UserTypeEnum;
|
||||
import com.njcn.rdms.framework.mybatis.core.dataobject.BaseDO;
|
||||
import com.baomidou.mybatisplus.annotation.KeySequence;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.*;
|
||||
|
||||
/**
|
||||
* 社交客户端 DO
|
||||
*
|
||||
* @author hongawen
|
||||
*/
|
||||
@TableName(value = "system_social_client", autoResultMap = true)
|
||||
@KeySequence("system_social_client_seq")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class SocialClientDO extends BaseDO {
|
||||
|
||||
@TableId
|
||||
private Long id;
|
||||
/** 应用名 */
|
||||
private String name;
|
||||
/**
|
||||
* 社交类型
|
||||
*
|
||||
* 枚举 {@link UserTypeEnum}
|
||||
*/
|
||||
private Integer socialType;
|
||||
/**
|
||||
* 用户类型
|
||||
*
|
||||
* 枚举 {@link UserTypeEnum}
|
||||
*/
|
||||
private Integer userType;
|
||||
/**
|
||||
* 状态
|
||||
*
|
||||
* 枚举 {@link CommonStatusEnum}
|
||||
*/
|
||||
private Integer status;
|
||||
/** 客户端 id */
|
||||
private String clientId;
|
||||
/** 客户端 Secret */
|
||||
private String clientSecret;
|
||||
/** 代理编号 */
|
||||
private String agentId;
|
||||
/** publicKey 公钥 */
|
||||
private String publicKey;
|
||||
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
package com.njcn.rdms.module.system.dal.mysql.codegen;
|
||||
|
||||
import com.njcn.rdms.framework.mybatis.core.mapper.BaseMapperX;
|
||||
import com.njcn.rdms.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||
import com.njcn.rdms.module.system.dal.dataobject.codegen.CodegenColumnDO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
@Mapper
|
||||
public interface CodegenColumnMapper extends BaseMapperX<CodegenColumnDO> {
|
||||
|
||||
default List<CodegenColumnDO> selectListByTableId(Long tableId) {
|
||||
return selectList(new LambdaQueryWrapperX<CodegenColumnDO>()
|
||||
.eq(CodegenColumnDO::getTableId, tableId)
|
||||
.orderByAsc(CodegenColumnDO::getOrdinalPosition));
|
||||
}
|
||||
|
||||
default void deleteListByTableId(Long tableId) {
|
||||
delete(CodegenColumnDO::getTableId, tableId);
|
||||
}
|
||||
|
||||
default void deleteListByTableId(Collection<Long> tableIds) {
|
||||
delete(new LambdaQueryWrapperX<CodegenColumnDO>()
|
||||
.in(CodegenColumnDO::getTableId, tableIds));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
package com.njcn.rdms.module.system.dal.mysql.codegen;
|
||||
|
||||
import com.njcn.rdms.framework.common.pojo.PageResult;
|
||||
import com.njcn.rdms.framework.mybatis.core.mapper.BaseMapperX;
|
||||
import com.njcn.rdms.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||
import com.njcn.rdms.module.system.controller.admin.codegen.vo.table.CodegenTablePageReqVO;
|
||||
import com.njcn.rdms.module.system.dal.dataobject.codegen.CodegenTableDO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Mapper
|
||||
public interface CodegenTableMapper extends BaseMapperX<CodegenTableDO> {
|
||||
|
||||
default CodegenTableDO selectByTableNameAndDataSourceConfigId(String tableName, Long dataSourceConfigId) {
|
||||
return selectOne(CodegenTableDO::getTableName, tableName,
|
||||
CodegenTableDO::getDataSourceConfigId, dataSourceConfigId);
|
||||
}
|
||||
|
||||
default PageResult<CodegenTableDO> selectPage(CodegenTablePageReqVO pageReqVO) {
|
||||
return selectPage(pageReqVO, new LambdaQueryWrapperX<CodegenTableDO>()
|
||||
.likeIfPresent(CodegenTableDO::getTableName, pageReqVO.getTableName())
|
||||
.likeIfPresent(CodegenTableDO::getTableComment, pageReqVO.getTableComment())
|
||||
.likeIfPresent(CodegenTableDO::getClassName, pageReqVO.getClassName())
|
||||
.betweenIfPresent(CodegenTableDO::getCreateTime, pageReqVO.getCreateTime())
|
||||
.orderByDesc(CodegenTableDO::getUpdateTime)
|
||||
);
|
||||
}
|
||||
|
||||
default List<CodegenTableDO> selectListByDataSourceConfigId(Long dataSourceConfigId) {
|
||||
return selectList(CodegenTableDO::getDataSourceConfigId, dataSourceConfigId);
|
||||
}
|
||||
|
||||
default List<CodegenTableDO> selectListByTemplateTypeAndMasterTableId(Integer templateType, Long masterTableId) {
|
||||
return selectList(CodegenTableDO::getTemplateType, templateType,
|
||||
CodegenTableDO::getMasterTableId, masterTableId);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
package com.njcn.rdms.module.system.dal.mysql.db;
|
||||
|
||||
import com.njcn.rdms.framework.mybatis.core.mapper.BaseMapperX;
|
||||
import com.njcn.rdms.module.system.dal.dataobject.db.DataSourceConfigDO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
/**
|
||||
* 数据源配置 Mapper
|
||||
*
|
||||
* @author hongawen
|
||||
*/
|
||||
@Mapper
|
||||
public interface DataSourceConfigMapper extends BaseMapperX<DataSourceConfigDO> {
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
package com.njcn.rdms.module.system.dal.mysql.mail;
|
||||
|
||||
import com.njcn.rdms.framework.common.pojo.PageResult;
|
||||
import com.njcn.rdms.framework.mybatis.core.mapper.BaseMapperX;
|
||||
import com.njcn.rdms.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||
import com.njcn.rdms.module.system.controller.admin.mail.vo.account.MailAccountPageReqVO;
|
||||
import com.njcn.rdms.module.system.dal.dataobject.mail.MailAccountDO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
@Mapper
|
||||
public interface MailAccountMapper extends BaseMapperX<MailAccountDO> {
|
||||
|
||||
default PageResult<MailAccountDO> selectPage(MailAccountPageReqVO pageReqVO) {
|
||||
return selectPage(pageReqVO, new LambdaQueryWrapperX<MailAccountDO>()
|
||||
.likeIfPresent(MailAccountDO::getMail, pageReqVO.getMail())
|
||||
.likeIfPresent(MailAccountDO::getUsername , pageReqVO.getUsername())
|
||||
.orderByDesc(MailAccountDO::getId));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
package com.njcn.rdms.module.system.dal.mysql.mail;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.njcn.rdms.framework.common.pojo.PageResult;
|
||||
import com.njcn.rdms.framework.mybatis.core.mapper.BaseMapperX;
|
||||
import com.njcn.rdms.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||
import com.njcn.rdms.framework.mybatis.core.util.MyBatisUtils;
|
||||
import com.njcn.rdms.module.system.controller.admin.mail.vo.log.MailLogPageReqVO;
|
||||
import com.njcn.rdms.module.system.dal.dataobject.mail.MailLogDO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
@Mapper
|
||||
public interface MailLogMapper extends BaseMapperX<MailLogDO> {
|
||||
|
||||
default PageResult<MailLogDO> selectPage(MailLogPageReqVO reqVO) {
|
||||
return selectPage(reqVO, new LambdaQueryWrapperX<MailLogDO>()
|
||||
.eqIfPresent(MailLogDO::getUserId, reqVO.getUserId())
|
||||
.eqIfPresent(MailLogDO::getUserType, reqVO.getUserType())
|
||||
.eqIfPresent(MailLogDO::getAccountId, reqVO.getAccountId())
|
||||
.eqIfPresent(MailLogDO::getTemplateId, reqVO.getTemplateId())
|
||||
.eqIfPresent(MailLogDO::getSendStatus, reqVO.getSendStatus())
|
||||
.betweenIfPresent(MailLogDO::getSendTime, reqVO.getSendTime())
|
||||
.apply(StrUtil.isNotBlank(reqVO.getToMail()),
|
||||
MyBatisUtils.findInSet("to_mails", reqVO.getToMail()))
|
||||
.orderByDesc(MailLogDO::getId));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
package com.njcn.rdms.module.system.dal.mysql.mail;
|
||||
|
||||
import com.njcn.rdms.framework.common.pojo.PageResult;
|
||||
import com.njcn.rdms.framework.mybatis.core.mapper.BaseMapperX;
|
||||
import com.njcn.rdms.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||
import com.njcn.rdms.module.system.controller.admin.mail.vo.template.MailTemplatePageReqVO;
|
||||
import com.njcn.rdms.module.system.dal.dataobject.mail.MailTemplateDO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
@Mapper
|
||||
public interface MailTemplateMapper extends BaseMapperX<MailTemplateDO> {
|
||||
|
||||
default PageResult<MailTemplateDO> selectPage(MailTemplatePageReqVO pageReqVO){
|
||||
return selectPage(pageReqVO , new LambdaQueryWrapperX<MailTemplateDO>()
|
||||
.eqIfPresent(MailTemplateDO::getStatus, pageReqVO.getStatus())
|
||||
.likeIfPresent(MailTemplateDO::getCode, pageReqVO.getCode())
|
||||
.likeIfPresent(MailTemplateDO::getName, pageReqVO.getName())
|
||||
.eqIfPresent(MailTemplateDO::getAccountId, pageReqVO.getAccountId())
|
||||
.betweenIfPresent(MailTemplateDO::getCreateTime, pageReqVO.getCreateTime())
|
||||
.orderByDesc(MailTemplateDO::getId));
|
||||
}
|
||||
|
||||
default Long selectCountByAccountId(Long accountId) {
|
||||
return selectCount(MailTemplateDO::getAccountId, accountId);
|
||||
}
|
||||
|
||||
default MailTemplateDO selectByCode(String code) {
|
||||
return selectOne(MailTemplateDO::getCode, code);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
package com.njcn.rdms.module.system.dal.mysql.social;
|
||||
|
||||
import com.njcn.rdms.framework.common.pojo.PageResult;
|
||||
import com.njcn.rdms.framework.mybatis.core.mapper.BaseMapperX;
|
||||
import com.njcn.rdms.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||
import com.njcn.rdms.module.system.controller.admin.socail.vo.client.SocialClientPageReqVO;
|
||||
import com.njcn.rdms.module.system.dal.dataobject.social.SocialClientDO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
@Mapper
|
||||
public interface SocialClientMapper extends BaseMapperX<SocialClientDO> {
|
||||
|
||||
default SocialClientDO selectBySocialTypeAndUserType(Integer socialType, Integer userType) {
|
||||
return selectOne(SocialClientDO::getSocialType, socialType,
|
||||
SocialClientDO::getUserType, userType);
|
||||
}
|
||||
|
||||
default PageResult<SocialClientDO> selectPage(SocialClientPageReqVO reqVO) {
|
||||
return selectPage(reqVO, new LambdaQueryWrapperX<SocialClientDO>()
|
||||
.likeIfPresent(SocialClientDO::getName, reqVO.getName())
|
||||
.eqIfPresent(SocialClientDO::getSocialType, reqVO.getSocialType())
|
||||
.eqIfPresent(SocialClientDO::getUserType, reqVO.getUserType())
|
||||
.likeIfPresent(SocialClientDO::getClientId, reqVO.getClientId())
|
||||
.eqIfPresent(SocialClientDO::getStatus, reqVO.getStatus())
|
||||
.orderByDesc(SocialClientDO::getId));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -27,8 +27,4 @@ public interface RedisKeyConstants {
|
||||
|
||||
String NOTIFY_TEMPLATE = "notify_template";
|
||||
|
||||
String MAIL_ACCOUNT = "mail_account";
|
||||
|
||||
String MAIL_TEMPLATE = "mail_template";
|
||||
|
||||
}
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
package com.njcn.rdms.module.system.framework.codegen.config;
|
||||
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@EnableConfigurationProperties(CodegenProperties.class)
|
||||
public class CodegenConfiguration {
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
package com.njcn.rdms.module.system.framework.codegen.config;
|
||||
|
||||
import com.njcn.rdms.module.system.enums.codegen.CodegenFrontTypeEnum;
|
||||
import com.njcn.rdms.module.system.enums.codegen.CodegenVOTypeEnum;
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
@ConfigurationProperties(prefix = "rdms.codegen")
|
||||
@Validated
|
||||
@Data
|
||||
public class CodegenProperties {
|
||||
|
||||
/**
|
||||
* 生成的 Java 代码的基础包
|
||||
*/
|
||||
@NotNull(message = "Java 代码的基础包不能为空")
|
||||
private String basePackage;
|
||||
|
||||
/**
|
||||
* 数据库名数组
|
||||
*/
|
||||
@NotEmpty(message = "数据库不能为空")
|
||||
private Collection<String> dbSchemas;
|
||||
|
||||
/**
|
||||
* 代码生成的前端类型(默认)
|
||||
*
|
||||
* 枚举 {@link CodegenFrontTypeEnum#getType()}
|
||||
*/
|
||||
@NotNull(message = "代码生成的前端类型不能为空")
|
||||
private Integer frontType;
|
||||
|
||||
/**
|
||||
* 代码生成的 VO 类型
|
||||
*
|
||||
* 枚举 {@link CodegenVOTypeEnum#getType()}
|
||||
*/
|
||||
@NotNull(message = "代码生成的 VO 类型不能为空")
|
||||
private Integer voType;
|
||||
|
||||
/**
|
||||
* 是否生成批量删除接口
|
||||
*/
|
||||
@NotNull(message = "是否生成批量删除接口不能为空")
|
||||
private Boolean deleteBatchEnable;
|
||||
|
||||
/**
|
||||
* 是否生成单元测试
|
||||
*/
|
||||
@NotNull(message = "是否生成单元测试不能为空")
|
||||
private Boolean unitTestEnable;
|
||||
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
/**
|
||||
* 代码生成器
|
||||
*/
|
||||
package com.njcn.rdms.module.system.framework.codegen;
|
||||
@@ -72,7 +72,8 @@ public abstract class AbstractFileClient<Config extends FileClientConfig> implem
|
||||
* @return URL 访问地址
|
||||
*/
|
||||
protected String formatFileUrl(String domain, String path) {
|
||||
return StrUtil.format("{}/admin-api/infra/file/{}/get/{}", domain, getId(), path);
|
||||
return StrUtil.format("{}/admin-api/system/file/{}/get/{}", domain, getId(), path);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
package com.njcn.rdms.module.system.mq.consumer.mail;
|
||||
|
||||
import com.njcn.rdms.module.system.mq.message.mail.MailSendMessage;
|
||||
import com.njcn.rdms.module.system.service.mail.MailSendService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.context.event.EventListener;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
|
||||
/**
|
||||
* 针对 {@link MailSendMessage} 的消费者
|
||||
*
|
||||
* @author hongawen
|
||||
*/
|
||||
@Component
|
||||
@Slf4j
|
||||
public class MailSendConsumer {
|
||||
|
||||
@Resource
|
||||
private MailSendService mailSendService;
|
||||
|
||||
@EventListener
|
||||
@Async // Spring Event 默认在 Producer 发送的线程,通过 @Async 实现异步
|
||||
public void onMessage(MailSendMessage message) {
|
||||
log.info("[onMessage][消息内容({})]", message);
|
||||
mailSendService.doSendMail(message);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
package com.njcn.rdms.module.system.mq.message.mail;
|
||||
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* 邮箱发送消息
|
||||
*
|
||||
* @author hongawen
|
||||
*/
|
||||
@Data
|
||||
public class MailSendMessage {
|
||||
|
||||
/**
|
||||
* 邮件日志编号
|
||||
*/
|
||||
@NotNull(message = "邮件日志编号不能为空")
|
||||
private Long logId;
|
||||
/**
|
||||
* 接收邮件地址
|
||||
*/
|
||||
@NotEmpty(message = "接收邮件地址不能为空")
|
||||
private Collection<String> toMails;
|
||||
/**
|
||||
* 抄送邮件地址
|
||||
*/
|
||||
private Collection<String> ccMails;
|
||||
/**
|
||||
* 密送邮件地址
|
||||
*/
|
||||
private Collection<String> bccMails;
|
||||
/**
|
||||
* 邮件账号编号
|
||||
*/
|
||||
@NotNull(message = "邮件账号编号不能为空")
|
||||
private Long accountId;
|
||||
|
||||
/**
|
||||
* 邮件发件人
|
||||
*/
|
||||
private String nickname;
|
||||
/**
|
||||
* 邮件标题
|
||||
*/
|
||||
@NotEmpty(message = "邮件标题不能为空")
|
||||
private String title;
|
||||
/**
|
||||
* 邮件内容
|
||||
*/
|
||||
@NotEmpty(message = "邮件内容不能为空")
|
||||
private String content;
|
||||
|
||||
/**
|
||||
* 附件
|
||||
*/
|
||||
private File[] attachments;
|
||||
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
package com.njcn.rdms.module.system.mq.producer.mail;
|
||||
|
||||
import com.njcn.rdms.module.system.mq.message.mail.MailSendMessage;
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* Mail 邮件相关消息的 Producer
|
||||
*
|
||||
* @author hongawen
|
||||
* @since 2021/4/19 13:33
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class MailProducer {
|
||||
|
||||
@Resource
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
/**
|
||||
* 发送 {@link MailSendMessage} 消息
|
||||
*
|
||||
* @param sendLogId 发送日志编码
|
||||
* @param toMails 接收邮件地址
|
||||
* @param ccMails 抄送邮件地址
|
||||
* @param bccMails 密送邮件地址
|
||||
* @param accountId 邮件账号编号
|
||||
* @param nickname 邮件发件人
|
||||
* @param title 邮件标题
|
||||
* @param content 邮件内容
|
||||
* @param attachments 附件
|
||||
*/
|
||||
public void sendMailSendMessage(Long sendLogId,
|
||||
Collection<String> toMails, Collection<String> ccMails, Collection<String> bccMails,
|
||||
Long accountId, String nickname, String title, String content,
|
||||
File[] attachments) {
|
||||
MailSendMessage message = new MailSendMessage()
|
||||
.setLogId(sendLogId)
|
||||
.setToMails(toMails).setCcMails(ccMails).setBccMails(bccMails)
|
||||
.setAccountId(accountId).setNickname(nickname)
|
||||
.setTitle(title).setContent(content).setAttachments(attachments);
|
||||
applicationContext.publishEvent(message);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,108 +0,0 @@
|
||||
package com.njcn.rdms.module.system.service.codegen;
|
||||
|
||||
import com.njcn.rdms.framework.common.pojo.PageResult;
|
||||
import com.njcn.rdms.module.system.controller.admin.codegen.vo.CodegenCreateListReqVO;
|
||||
import com.njcn.rdms.module.system.controller.admin.codegen.vo.CodegenUpdateReqVO;
|
||||
import com.njcn.rdms.module.system.controller.admin.codegen.vo.table.CodegenTablePageReqVO;
|
||||
import com.njcn.rdms.module.system.controller.admin.codegen.vo.table.DatabaseTableRespVO;
|
||||
import com.njcn.rdms.module.system.dal.dataobject.codegen.CodegenColumnDO;
|
||||
import com.njcn.rdms.module.system.dal.dataobject.codegen.CodegenTableDO;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 代码生成 Service 接口
|
||||
*
|
||||
* @author hongawen
|
||||
*/
|
||||
public interface CodegenService {
|
||||
|
||||
/**
|
||||
* 基于数据库的表结构,创建代码生成器的表定义
|
||||
*
|
||||
* @param author 作者
|
||||
* @param reqVO 表信息
|
||||
* @return 创建的表定义的编号数组
|
||||
*/
|
||||
List<Long> createCodegenList(String author, CodegenCreateListReqVO reqVO);
|
||||
|
||||
/**
|
||||
* 更新数据库的表和字段定义
|
||||
*
|
||||
* @param updateReqVO 更新信息
|
||||
*/
|
||||
void updateCodegen(CodegenUpdateReqVO updateReqVO);
|
||||
|
||||
/**
|
||||
* 基于数据库的表结构,同步数据库的表和字段定义
|
||||
*
|
||||
* @param tableId 表编号
|
||||
*/
|
||||
void syncCodegenFromDB(Long tableId);
|
||||
|
||||
/**
|
||||
* 删除数据库的表和字段定义
|
||||
*
|
||||
* @param tableId 数据编号
|
||||
*/
|
||||
void deleteCodegen(Long tableId);
|
||||
|
||||
/**
|
||||
* 批量删除数据库的表和字段定义
|
||||
*
|
||||
* @param tableIds 数据编号列表
|
||||
*/
|
||||
void deleteCodegenList(List<Long> tableIds);
|
||||
|
||||
/**
|
||||
* 获得表定义列表
|
||||
*
|
||||
* @param dataSourceConfigId 数据源配置的编号
|
||||
* @return 表定义列表
|
||||
*/
|
||||
List<CodegenTableDO> getCodegenTableList(Long dataSourceConfigId);
|
||||
|
||||
/**
|
||||
* 获得表定义分页
|
||||
*
|
||||
* @param pageReqVO 分页条件
|
||||
* @return 表定义分页
|
||||
*/
|
||||
PageResult<CodegenTableDO> getCodegenTablePage(CodegenTablePageReqVO pageReqVO);
|
||||
|
||||
/**
|
||||
* 获得表定义
|
||||
*
|
||||
* @param id 表编号
|
||||
* @return 表定义
|
||||
*/
|
||||
CodegenTableDO getCodegenTable(Long id);
|
||||
|
||||
/**
|
||||
* 获得指定表的字段定义数组
|
||||
*
|
||||
* @param tableId 表编号
|
||||
* @return 字段定义数组
|
||||
*/
|
||||
List<CodegenColumnDO> getCodegenColumnListByTableId(Long tableId);
|
||||
|
||||
/**
|
||||
* 执行指定表的代码生成
|
||||
*
|
||||
* @param tableId 表编号
|
||||
* @return 生成结果。key 为文件路径,value 为对应的代码内容
|
||||
*/
|
||||
Map<String, String> generationCodes(Long tableId);
|
||||
|
||||
/**
|
||||
* 获得数据库自带的表定义列表
|
||||
*
|
||||
* @param dataSourceConfigId 数据源的配置编号
|
||||
* @param name 表名称
|
||||
* @param comment 表描述
|
||||
* @return 表定义列表
|
||||
*/
|
||||
List<DatabaseTableRespVO> getDatabaseTableList(Long dataSourceConfigId, String name, String comment);
|
||||
|
||||
}
|
||||
@@ -1,310 +0,0 @@
|
||||
package com.njcn.rdms.module.system.service.codegen;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.baomidou.mybatisplus.annotation.DbType;
|
||||
import com.baomidou.mybatisplus.generator.config.po.TableField;
|
||||
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.njcn.rdms.framework.common.pojo.PageResult;
|
||||
import com.njcn.rdms.framework.common.util.object.BeanUtils;
|
||||
import com.njcn.rdms.framework.mybatis.core.util.JdbcUtils;
|
||||
import com.njcn.rdms.module.system.controller.admin.codegen.vo.CodegenCreateListReqVO;
|
||||
import com.njcn.rdms.module.system.controller.admin.codegen.vo.CodegenUpdateReqVO;
|
||||
import com.njcn.rdms.module.system.controller.admin.codegen.vo.table.CodegenTablePageReqVO;
|
||||
import com.njcn.rdms.module.system.controller.admin.codegen.vo.table.DatabaseTableRespVO;
|
||||
import com.njcn.rdms.module.system.dal.dataobject.codegen.CodegenColumnDO;
|
||||
import com.njcn.rdms.module.system.dal.dataobject.codegen.CodegenTableDO;
|
||||
import com.njcn.rdms.module.system.dal.dataobject.db.DataSourceConfigDO;
|
||||
import com.njcn.rdms.module.system.dal.mysql.codegen.CodegenColumnMapper;
|
||||
import com.njcn.rdms.module.system.dal.mysql.codegen.CodegenTableMapper;
|
||||
import com.njcn.rdms.module.system.enums.codegen.CodegenSceneEnum;
|
||||
import com.njcn.rdms.module.system.enums.codegen.CodegenTemplateTypeEnum;
|
||||
import com.njcn.rdms.module.system.framework.codegen.config.CodegenProperties;
|
||||
import com.njcn.rdms.module.system.service.codegen.inner.CodegenBuilder;
|
||||
import com.njcn.rdms.module.system.service.codegen.inner.CodegenEngine;
|
||||
import com.njcn.rdms.module.system.service.db.DataSourceConfigService;
|
||||
import com.njcn.rdms.module.system.service.db.DatabaseTableService;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.BiPredicate;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
import static com.njcn.rdms.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static com.njcn.rdms.framework.common.util.collection.CollectionUtils.convertMap;
|
||||
import static com.njcn.rdms.framework.common.util.collection.CollectionUtils.convertSet;
|
||||
import static com.njcn.rdms.module.system.enums.ErrorCodeConstants.*;
|
||||
|
||||
/**
|
||||
* 代码生成 Service 实现类
|
||||
*
|
||||
* @author hongawen
|
||||
*/
|
||||
@Service
|
||||
public class CodegenServiceImpl implements CodegenService {
|
||||
|
||||
@Resource
|
||||
private DatabaseTableService databaseTableService;
|
||||
@Resource
|
||||
private DataSourceConfigService dataSourceConfigService;
|
||||
|
||||
@Resource
|
||||
private CodegenTableMapper codegenTableMapper;
|
||||
@Resource
|
||||
private CodegenColumnMapper codegenColumnMapper;
|
||||
|
||||
@Resource
|
||||
private CodegenBuilder codegenBuilder;
|
||||
@Resource
|
||||
private CodegenEngine codegenEngine;
|
||||
|
||||
@Resource
|
||||
private CodegenProperties codegenProperties;
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public List<Long> createCodegenList(String author, CodegenCreateListReqVO reqVO) {
|
||||
List<Long> ids = new ArrayList<>(reqVO.getTableNames().size());
|
||||
// 遍历添加。虽然效率会低一点,但是没必要做成完全批量,因为不会这么大量
|
||||
reqVO.getTableNames().forEach(tableName -> ids.add(createCodegen(author, reqVO.getDataSourceConfigId(), tableName)));
|
||||
return ids;
|
||||
}
|
||||
|
||||
private Long createCodegen(String author, Long dataSourceConfigId, String tableName) {
|
||||
// 从数据库中,获得数据库表结构
|
||||
TableInfo tableInfo = databaseTableService.getTable(dataSourceConfigId, tableName);
|
||||
// 导入
|
||||
return createCodegen0(author, dataSourceConfigId, tableInfo);
|
||||
}
|
||||
|
||||
private Long createCodegen0(String author, Long dataSourceConfigId, TableInfo tableInfo) {
|
||||
// 校验导入的表和字段非空
|
||||
validateTableInfo(tableInfo);
|
||||
// 校验是否已经存在
|
||||
if (codegenTableMapper.selectByTableNameAndDataSourceConfigId(tableInfo.getName(),
|
||||
dataSourceConfigId) != null) {
|
||||
throw exception(CODEGEN_TABLE_EXISTS);
|
||||
}
|
||||
|
||||
// 构建 CodegenTableDO 对象,插入到 DB 中
|
||||
CodegenTableDO table = codegenBuilder.buildTable(tableInfo);
|
||||
table.setDataSourceConfigId(dataSourceConfigId);
|
||||
table.setScene(CodegenSceneEnum.ADMIN.getScene()); // 默认配置下,使用管理后台的模板
|
||||
table.setFrontType(codegenProperties.getFrontType());
|
||||
table.setAuthor(author);
|
||||
codegenTableMapper.insert(table);
|
||||
|
||||
// 构建 CodegenColumnDO 数组,插入到 DB 中
|
||||
List<CodegenColumnDO> columns = codegenBuilder.buildColumns(table.getId(), tableInfo.getFields());
|
||||
// 如果没有主键,则使用第一个字段作为主键
|
||||
if (!tableInfo.isHavePrimaryKey()) {
|
||||
columns.get(0).setPrimaryKey(true);
|
||||
}
|
||||
codegenColumnMapper.insertBatch(columns);
|
||||
return table.getId();
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void validateTableInfo(TableInfo tableInfo) {
|
||||
if (tableInfo == null) {
|
||||
throw exception(CODEGEN_IMPORT_TABLE_NULL);
|
||||
}
|
||||
if (StrUtil.isEmpty(tableInfo.getComment())) {
|
||||
throw exception(CODEGEN_TABLE_INFO_TABLE_COMMENT_IS_NULL);
|
||||
}
|
||||
if (CollUtil.isEmpty(tableInfo.getFields())) {
|
||||
throw exception(CODEGEN_IMPORT_COLUMNS_NULL);
|
||||
}
|
||||
tableInfo.getFields().forEach(field -> {
|
||||
if (StrUtil.isEmpty(field.getComment())) {
|
||||
throw exception(CODEGEN_TABLE_INFO_COLUMN_COMMENT_IS_NULL, field.getName());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void updateCodegen(CodegenUpdateReqVO updateReqVO) {
|
||||
// 校验是否已经存在
|
||||
if (codegenTableMapper.selectById(updateReqVO.getTable().getId()) == null) {
|
||||
throw exception(CODEGEN_TABLE_NOT_EXISTS);
|
||||
}
|
||||
// 校验主表字段存在
|
||||
if (Objects.equals(updateReqVO.getTable().getTemplateType(), CodegenTemplateTypeEnum.SUB.getType())) {
|
||||
if (codegenTableMapper.selectById(updateReqVO.getTable().getMasterTableId()) == null) {
|
||||
throw exception(CODEGEN_MASTER_TABLE_NOT_EXISTS, updateReqVO.getTable().getMasterTableId());
|
||||
}
|
||||
if (CollUtil.findOne(updateReqVO.getColumns(), // 关联主表的字段不存在
|
||||
column -> column.getId().equals(updateReqVO.getTable().getSubJoinColumnId())) == null) {
|
||||
throw exception(CODEGEN_SUB_COLUMN_NOT_EXISTS, updateReqVO.getTable().getSubJoinColumnId());
|
||||
}
|
||||
}
|
||||
|
||||
// 更新 table 表定义
|
||||
CodegenTableDO updateTableObj = BeanUtils.toBean(updateReqVO.getTable(), CodegenTableDO.class);
|
||||
codegenTableMapper.updateById(updateTableObj);
|
||||
// 更新 column 字段定义
|
||||
List<CodegenColumnDO> updateColumnObjs = BeanUtils.toBean(updateReqVO.getColumns(), CodegenColumnDO.class);
|
||||
updateColumnObjs.forEach(updateColumnObj -> codegenColumnMapper.updateById(updateColumnObj));
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void syncCodegenFromDB(Long tableId) {
|
||||
// 校验是否已经存在
|
||||
CodegenTableDO table = codegenTableMapper.selectById(tableId);
|
||||
if (table == null) {
|
||||
throw exception(CODEGEN_TABLE_NOT_EXISTS);
|
||||
}
|
||||
// 从数据库中,获得数据库表结构
|
||||
TableInfo tableInfo = databaseTableService.getTable(table.getDataSourceConfigId(), table.getTableName());
|
||||
// 执行同步
|
||||
syncCodegen0(tableId, tableInfo);
|
||||
}
|
||||
|
||||
private void syncCodegen0(Long tableId, TableInfo tableInfo) {
|
||||
// 1. 校验导入的表和字段非空
|
||||
validateTableInfo(tableInfo);
|
||||
List<TableField> tableFields = tableInfo.getFields();
|
||||
|
||||
// 2. 构建 CodegenColumnDO 数组,只同步新增的字段
|
||||
List<CodegenColumnDO> codegenColumns = codegenColumnMapper.selectListByTableId(tableId);
|
||||
Set<String> codegenColumnNames = convertSet(codegenColumns, CodegenColumnDO::getColumnName);
|
||||
|
||||
// 3.1 计算需要【修改】的字段,插入时重新插入,删除时将原来的删除
|
||||
Map<String, CodegenColumnDO> codegenColumnDOMap = convertMap(codegenColumns, CodegenColumnDO::getColumnName);
|
||||
BiPredicate<TableField, CodegenColumnDO> primaryKeyPredicate =
|
||||
(tableField, codegenColumn) -> tableField.getMetaInfo().getJdbcType().name().equals(codegenColumn.getDataType())
|
||||
&& tableField.getMetaInfo().isNullable() == codegenColumn.getNullable()
|
||||
&& tableField.isKeyFlag() == codegenColumn.getPrimaryKey()
|
||||
&& tableField.getComment().equals(codegenColumn.getColumnComment());
|
||||
Set<String> modifyFieldNames = IntStream.range(0, tableFields.size()).mapToObj(index -> {
|
||||
TableField tableField = tableFields.get(index);
|
||||
String columnName = tableField.getColumnName();
|
||||
CodegenColumnDO codegenColumn = codegenColumnDOMap.get(columnName);
|
||||
if (codegenColumn == null) {
|
||||
return null;
|
||||
}
|
||||
if (!primaryKeyPredicate.test(tableField, codegenColumn) || codegenColumn.getOrdinalPosition() != index) {
|
||||
return columnName;
|
||||
}
|
||||
return null;
|
||||
}).filter(Objects::nonNull).collect(Collectors.toSet());
|
||||
// 3.2 计算需要【删除】的字段
|
||||
Set<String> tableFieldNames = convertSet(tableFields, TableField::getName);
|
||||
Set<Long> deleteColumnIds = codegenColumns.stream()
|
||||
.filter(column -> (!tableFieldNames.contains(column.getColumnName())) || modifyFieldNames.contains(column.getColumnName()))
|
||||
.map(CodegenColumnDO::getId).collect(Collectors.toSet());
|
||||
// 移除已经存在的字段
|
||||
tableFields.removeIf(column -> codegenColumnNames.contains(column.getColumnName()) && (!modifyFieldNames.contains(column.getColumnName())));
|
||||
if (CollUtil.isEmpty(tableFields) && CollUtil.isEmpty(deleteColumnIds)) {
|
||||
throw exception(CODEGEN_SYNC_NONE_CHANGE);
|
||||
}
|
||||
|
||||
// 4.1 插入新增的字段
|
||||
List<CodegenColumnDO> columns = codegenBuilder.buildColumns(tableId, tableFields);
|
||||
codegenColumnMapper.insertBatch(columns);
|
||||
// 4.2 删除不存在的字段
|
||||
if (CollUtil.isNotEmpty(deleteColumnIds)) {
|
||||
codegenColumnMapper.deleteByIds(deleteColumnIds);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void deleteCodegen(Long tableId) {
|
||||
// 校验是否已经存在
|
||||
if (codegenTableMapper.selectById(tableId) == null) {
|
||||
throw exception(CODEGEN_TABLE_NOT_EXISTS);
|
||||
}
|
||||
|
||||
// 删除 table 表定义
|
||||
codegenTableMapper.deleteById(tableId);
|
||||
// 删除 column 字段定义
|
||||
codegenColumnMapper.deleteListByTableId(tableId);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void deleteCodegenList(List<Long> tableIds) {
|
||||
// 批量删除 table 表定义
|
||||
codegenTableMapper.deleteByIds(tableIds);
|
||||
// 批量删除 column 字段定义
|
||||
codegenColumnMapper.deleteListByTableId(tableIds);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CodegenTableDO> getCodegenTableList(Long dataSourceConfigId) {
|
||||
return codegenTableMapper.selectListByDataSourceConfigId(dataSourceConfigId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageResult<CodegenTableDO> getCodegenTablePage(CodegenTablePageReqVO pageReqVO) {
|
||||
return codegenTableMapper.selectPage(pageReqVO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CodegenTableDO getCodegenTable(Long id) {
|
||||
return codegenTableMapper.selectById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CodegenColumnDO> getCodegenColumnListByTableId(Long tableId) {
|
||||
return codegenColumnMapper.selectListByTableId(tableId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> generationCodes(Long tableId) {
|
||||
// 校验是否已经存在
|
||||
CodegenTableDO table = codegenTableMapper.selectById(tableId);
|
||||
if (table == null) {
|
||||
throw exception(CODEGEN_TABLE_NOT_EXISTS);
|
||||
}
|
||||
List<CodegenColumnDO> columns = codegenColumnMapper.selectListByTableId(tableId);
|
||||
if (CollUtil.isEmpty(columns)) {
|
||||
throw exception(CODEGEN_COLUMN_NOT_EXISTS);
|
||||
}
|
||||
|
||||
// 如果是主子表,则加载对应的子表信息
|
||||
List<CodegenTableDO> subTables = null;
|
||||
List<List<CodegenColumnDO>> subColumnsList = null;
|
||||
if (CodegenTemplateTypeEnum.isMaster(table.getTemplateType())) {
|
||||
// 校验子表存在
|
||||
subTables = codegenTableMapper.selectListByTemplateTypeAndMasterTableId(
|
||||
CodegenTemplateTypeEnum.SUB.getType(), tableId);
|
||||
if (CollUtil.isEmpty(subTables)) {
|
||||
throw exception(CODEGEN_MASTER_GENERATION_FAIL_NO_SUB_TABLE);
|
||||
}
|
||||
// 校验子表的关联字段存在
|
||||
subColumnsList = new ArrayList<>();
|
||||
for (CodegenTableDO subTable : subTables) {
|
||||
List<CodegenColumnDO> subColumns = codegenColumnMapper.selectListByTableId(subTable.getId());
|
||||
if (CollUtil.findOne(subColumns, column -> column.getId().equals(subTable.getSubJoinColumnId())) == null) {
|
||||
throw exception(CODEGEN_SUB_COLUMN_NOT_EXISTS, subTable.getId());
|
||||
}
|
||||
subColumnsList.add(subColumns);
|
||||
}
|
||||
}
|
||||
|
||||
// 获取数据源对应的数据库类型
|
||||
DataSourceConfigDO dataSourceConfig = dataSourceConfigService.getDataSourceConfig(table.getDataSourceConfigId());
|
||||
DbType dbType = JdbcUtils.getDbType(dataSourceConfig.getUrl());
|
||||
// 执行生成
|
||||
return codegenEngine.execute(dbType, table, columns, subTables, subColumnsList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DatabaseTableRespVO> getDatabaseTableList(Long dataSourceConfigId, String name, String comment) {
|
||||
List<TableInfo> tables = databaseTableService.getTableList(dataSourceConfigId, name, comment);
|
||||
// 移除在 Codegen 中,已经存在的
|
||||
Set<String> existsTables = convertSet(
|
||||
codegenTableMapper.selectListByDataSourceConfigId(dataSourceConfigId), CodegenTableDO::getTableName);
|
||||
tables.removeIf(table -> existsTables.contains(table.getName()));
|
||||
return BeanUtils.toBean(tables, DatabaseTableRespVO.class);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,220 +0,0 @@
|
||||
package com.njcn.rdms.module.system.service.codegen.inner;
|
||||
|
||||
import cn.hutool.core.map.MapUtil;
|
||||
import cn.hutool.core.util.ReflectUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.baomidou.mybatisplus.generator.config.po.TableField;
|
||||
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.njcn.rdms.framework.mybatis.core.dataobject.BaseDO;
|
||||
import com.njcn.rdms.module.system.convert.codegen.CodegenConvert;
|
||||
import com.njcn.rdms.module.system.dal.dataobject.codegen.CodegenColumnDO;
|
||||
import com.njcn.rdms.module.system.dal.dataobject.codegen.CodegenTableDO;
|
||||
import com.njcn.rdms.module.system.enums.codegen.CodegenColumnHtmlTypeEnum;
|
||||
import com.njcn.rdms.module.system.enums.codegen.CodegenColumnListConditionEnum;
|
||||
import com.njcn.rdms.module.system.enums.codegen.CodegenTemplateTypeEnum;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.*;
|
||||
|
||||
import static cn.hutool.core.text.CharSequenceUtil.*;
|
||||
import static cn.hutool.core.util.RandomUtil.randomEle;
|
||||
import static cn.hutool.core.util.RandomUtil.randomInt;
|
||||
|
||||
/**
|
||||
* 代码生成器的 Builder,负责:
|
||||
* 1. 将数据库的表 {@link TableInfo} 定义,构建成 {@link CodegenTableDO}
|
||||
* 2. 将数据库的列 {@link TableField} 构定义,建成 {@link CodegenColumnDO}
|
||||
*/
|
||||
@Component
|
||||
public class CodegenBuilder {
|
||||
|
||||
/**
|
||||
* 字段名与 {@link CodegenColumnListConditionEnum} 的默认映射
|
||||
* 注意,字段的匹配以后缀的方式
|
||||
*/
|
||||
private static final Map<String, CodegenColumnListConditionEnum> COLUMN_LIST_OPERATION_CONDITION_MAPPINGS =
|
||||
MapUtil.<String, CodegenColumnListConditionEnum>builder()
|
||||
.put("name", CodegenColumnListConditionEnum.LIKE)
|
||||
.put("time", CodegenColumnListConditionEnum.BETWEEN)
|
||||
.put("date", CodegenColumnListConditionEnum.BETWEEN)
|
||||
.build();
|
||||
|
||||
/**
|
||||
* 字段名与 {@link CodegenColumnHtmlTypeEnum} 的默认映射
|
||||
* 注意,字段的匹配以后缀的方式
|
||||
*/
|
||||
private static final Map<String, CodegenColumnHtmlTypeEnum> COLUMN_HTML_TYPE_MAPPINGS =
|
||||
MapUtil.<String, CodegenColumnHtmlTypeEnum>builder()
|
||||
.put("status", CodegenColumnHtmlTypeEnum.RADIO)
|
||||
.put("sex", CodegenColumnHtmlTypeEnum.RADIO)
|
||||
.put("type", CodegenColumnHtmlTypeEnum.SELECT)
|
||||
.put("image", CodegenColumnHtmlTypeEnum.IMAGE_UPLOAD)
|
||||
.put("file", CodegenColumnHtmlTypeEnum.FILE_UPLOAD)
|
||||
.put("content", CodegenColumnHtmlTypeEnum.EDITOR)
|
||||
.put("description", CodegenColumnHtmlTypeEnum.EDITOR)
|
||||
.put("demo", CodegenColumnHtmlTypeEnum.EDITOR)
|
||||
.put("time", CodegenColumnHtmlTypeEnum.DATETIME)
|
||||
.put("date", CodegenColumnHtmlTypeEnum.DATETIME)
|
||||
.build();
|
||||
|
||||
/**
|
||||
* 多租户编号的字段名
|
||||
*/
|
||||
public static final String TENANT_ID_FIELD = "tenantId";
|
||||
/**
|
||||
* {@link BaseDO} 的字段
|
||||
*/
|
||||
public static final Set<String> BASE_DO_FIELDS = new HashSet<>();
|
||||
/**
|
||||
* 新增操作,不需要传递的字段
|
||||
*/
|
||||
private static final Set<String> CREATE_OPERATION_EXCLUDE_COLUMN = Sets.newHashSet("id");
|
||||
/**
|
||||
* 修改操作,不需要传递的字段
|
||||
*/
|
||||
private static final Set<String> UPDATE_OPERATION_EXCLUDE_COLUMN = Sets.newHashSet();
|
||||
/**
|
||||
* 列表操作的条件,不需要传递的字段
|
||||
*/
|
||||
private static final Set<String> LIST_OPERATION_EXCLUDE_COLUMN = Sets.newHashSet("id");
|
||||
/**
|
||||
* 列表操作的结果,不需要返回的字段
|
||||
*/
|
||||
private static final Set<String> LIST_OPERATION_RESULT_EXCLUDE_COLUMN = Sets.newHashSet();
|
||||
|
||||
static {
|
||||
Arrays.stream(ReflectUtil.getFields(BaseDO.class)).forEach(field -> BASE_DO_FIELDS.add(field.getName()));
|
||||
BASE_DO_FIELDS.add(TENANT_ID_FIELD);
|
||||
// 处理 OPERATION 相关的字段
|
||||
CREATE_OPERATION_EXCLUDE_COLUMN.addAll(BASE_DO_FIELDS);
|
||||
UPDATE_OPERATION_EXCLUDE_COLUMN.addAll(BASE_DO_FIELDS);
|
||||
LIST_OPERATION_EXCLUDE_COLUMN.addAll(BASE_DO_FIELDS);
|
||||
LIST_OPERATION_EXCLUDE_COLUMN.remove("createTime"); // 创建时间,还是可能需要传递的
|
||||
LIST_OPERATION_RESULT_EXCLUDE_COLUMN.addAll(BASE_DO_FIELDS);
|
||||
LIST_OPERATION_RESULT_EXCLUDE_COLUMN.remove("createTime"); // 创建时间,还是需要返回的
|
||||
}
|
||||
|
||||
public CodegenTableDO buildTable(TableInfo tableInfo) {
|
||||
CodegenTableDO table = CodegenConvert.INSTANCE.convert(tableInfo);
|
||||
initTableDefault(table);
|
||||
return table;
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化 Table 表的默认字段
|
||||
*
|
||||
* @param table 表定义
|
||||
*/
|
||||
private void initTableDefault(CodegenTableDO table) {
|
||||
// 以 system_dept 举例子。moduleName 为 system、businessName 为 dept、className 为 Dept
|
||||
// 如果希望以 System 前缀,则可以手动在【代码生成 - 修改生成配置 - 基本信息】,将实体类名称改为 SystemDept 即可
|
||||
String tableName = table.getTableName().toLowerCase();
|
||||
// 第一步,_ 前缀的前面,作为 module 名字;第二步,moduleName 必须小写;
|
||||
table.setModuleName(subBefore(tableName, '_', false).toLowerCase());
|
||||
// 第一步,第一个 _ 前缀的后面,作为 module 名字; 第二步,可能存在多个 _ 的情况,转换成驼峰; 第三步,businessName 必须小写;
|
||||
table.setBusinessName(toCamelCase(subAfter(tableName, '_', false)).toLowerCase());
|
||||
// 驼峰 + 首字母大写;第一步,第一个 _ 前缀的后面,作为 class 名字;第二步,驼峰命名
|
||||
table.setClassName(upperFirst(toCamelCase(subAfter(tableName, '_', false))));
|
||||
// 去除结尾的表,作为类描述
|
||||
table.setClassComment(StrUtil.removeSuffixIgnoreCase(table.getTableComment(), "表"));
|
||||
table.setTemplateType(CodegenTemplateTypeEnum.ONE.getType());
|
||||
}
|
||||
|
||||
public List<CodegenColumnDO> buildColumns(Long tableId, List<TableField> tableFields) {
|
||||
List<CodegenColumnDO> columns = CodegenConvert.INSTANCE.convertList(tableFields);
|
||||
int index = 1;
|
||||
for (CodegenColumnDO column : columns) {
|
||||
column.setTableId(tableId);
|
||||
column.setOrdinalPosition(index++);
|
||||
// 特殊处理:Byte => Integer
|
||||
if (Byte.class.getSimpleName().equals(column.getJavaType())) {
|
||||
column.setJavaType(Integer.class.getSimpleName());
|
||||
}
|
||||
// 初始化 Column 列的默认字段
|
||||
processColumnOperation(column); // 处理 CRUD 相关的字段的默认值
|
||||
processColumnUI(column); // 处理 UI 相关的字段的默认值
|
||||
processColumnExample(column); // 处理字段的 swagger example 示例
|
||||
}
|
||||
return columns;
|
||||
}
|
||||
|
||||
private void processColumnOperation(CodegenColumnDO column) {
|
||||
// 处理 createOperation 字段
|
||||
column.setCreateOperation(!CREATE_OPERATION_EXCLUDE_COLUMN.contains(column.getJavaField())
|
||||
&& !column.getPrimaryKey()); // 对于主键,创建时无需传递
|
||||
// 处理 updateOperation 字段
|
||||
column.setUpdateOperation(!UPDATE_OPERATION_EXCLUDE_COLUMN.contains(column.getJavaField())
|
||||
|| column.getPrimaryKey()); // 对于主键,更新时需要传递
|
||||
// 处理 listOperation 字段
|
||||
column.setListOperation(!LIST_OPERATION_EXCLUDE_COLUMN.contains(column.getJavaField())
|
||||
&& !column.getPrimaryKey()); // 对于主键,列表过滤不需要传递
|
||||
// 处理 listOperationCondition 字段
|
||||
COLUMN_LIST_OPERATION_CONDITION_MAPPINGS.entrySet().stream()
|
||||
.filter(entry -> StrUtil.endWithIgnoreCase(column.getJavaField(), entry.getKey()))
|
||||
.findFirst().ifPresent(entry -> column.setListOperationCondition(entry.getValue().getCondition()));
|
||||
if (column.getListOperationCondition() == null) {
|
||||
column.setListOperationCondition(CodegenColumnListConditionEnum.EQ.getCondition());
|
||||
}
|
||||
// 处理 listOperationResult 字段
|
||||
column.setListOperationResult(!LIST_OPERATION_RESULT_EXCLUDE_COLUMN.contains(column.getJavaField()));
|
||||
}
|
||||
|
||||
private void processColumnUI(CodegenColumnDO column) {
|
||||
// 基于后缀进行匹配
|
||||
COLUMN_HTML_TYPE_MAPPINGS.entrySet().stream()
|
||||
.filter(entry -> StrUtil.endWithIgnoreCase(column.getJavaField(), entry.getKey()))
|
||||
.findFirst().ifPresent(entry -> column.setHtmlType(entry.getValue().getType()));
|
||||
// 如果是 Boolean 类型时,设置为 radio 类型.
|
||||
if (Boolean.class.getSimpleName().equals(column.getJavaType())) {
|
||||
column.setHtmlType(CodegenColumnHtmlTypeEnum.RADIO.getType());
|
||||
}
|
||||
// 如果是 LocalDateTime 类型,则设置为 datetime 类型
|
||||
if (LocalDateTime.class.getSimpleName().equals(column.getJavaType())) {
|
||||
column.setHtmlType(CodegenColumnHtmlTypeEnum.DATETIME.getType());
|
||||
}
|
||||
// 兜底,设置默认为 input 类型
|
||||
if (column.getHtmlType() == null) {
|
||||
column.setHtmlType(CodegenColumnHtmlTypeEnum.INPUT.getType());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理字段的 swagger example 示例
|
||||
*
|
||||
* @param column 字段
|
||||
*/
|
||||
private void processColumnExample(CodegenColumnDO column) {
|
||||
// id、price、count 等可能是整数的后缀
|
||||
if (StrUtil.endWithAnyIgnoreCase(column.getJavaField(), "id", "price", "count")) {
|
||||
column.setExample(String.valueOf(randomInt(1, Short.MAX_VALUE)));
|
||||
return;
|
||||
}
|
||||
// name
|
||||
if (StrUtil.endWithIgnoreCase(column.getJavaField(), "name")) {
|
||||
column.setExample(randomEle(new String[]{"张三", "李四", "王五", "赵六", "芋艿"}));
|
||||
return;
|
||||
}
|
||||
// status
|
||||
if (StrUtil.endWithAnyIgnoreCase(column.getJavaField(), "status", "type")) {
|
||||
column.setExample(randomEle(new String[]{"1", "2"}));
|
||||
return;
|
||||
}
|
||||
// url
|
||||
if (StrUtil.endWithIgnoreCase(column.getColumnName(), "url")) {
|
||||
column.setExample("https://www.iocoder.cn");
|
||||
return;
|
||||
}
|
||||
// reason
|
||||
if (StrUtil.endWithIgnoreCase(column.getColumnName(), "reason")) {
|
||||
column.setExample(randomEle(new String[]{"不喜欢", "不对", "不好", "不香"}));
|
||||
return;
|
||||
}
|
||||
// description、memo、remark
|
||||
if (StrUtil.endWithAnyIgnoreCase(column.getColumnName(), "description", "memo", "remark")) {
|
||||
column.setExample(randomEle(new String[]{"你猜", "随便", "你说的对"}));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,679 +0,0 @@
|
||||
package com.njcn.rdms.module.system.service.codegen.inner;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.map.MapUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.extra.template.TemplateConfig;
|
||||
import cn.hutool.extra.template.TemplateEngine;
|
||||
import cn.hutool.extra.template.engine.velocity.VelocityEngine;
|
||||
import cn.hutool.system.SystemUtil;
|
||||
import com.baomidou.mybatisplus.annotation.DbType;
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.collect.ImmutableTable;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Table;
|
||||
import com.njcn.rdms.framework.apilog.core.annotation.ApiAccessLog;
|
||||
import com.njcn.rdms.framework.apilog.core.enums.OperateTypeEnum;
|
||||
import com.njcn.rdms.framework.common.exception.util.ServiceExceptionUtil;
|
||||
import com.njcn.rdms.framework.common.pojo.CommonResult;
|
||||
import com.njcn.rdms.framework.common.pojo.PageParam;
|
||||
import com.njcn.rdms.framework.common.pojo.PageResult;
|
||||
import com.njcn.rdms.framework.common.util.collection.CollectionUtils;
|
||||
import com.njcn.rdms.framework.common.util.date.DateUtils;
|
||||
import com.njcn.rdms.framework.common.util.date.LocalDateTimeUtils;
|
||||
import com.njcn.rdms.framework.common.util.object.BeanUtils;
|
||||
import com.njcn.rdms.framework.common.util.object.ObjectUtils;
|
||||
import com.njcn.rdms.framework.common.util.string.StrUtils;
|
||||
import com.njcn.rdms.framework.excel.core.annotations.DictFormat;
|
||||
import com.njcn.rdms.framework.excel.core.convert.DictConvert;
|
||||
import com.njcn.rdms.framework.excel.core.util.ExcelUtils;
|
||||
import com.njcn.rdms.framework.mybatis.core.dataobject.BaseDO;
|
||||
import com.njcn.rdms.framework.mybatis.core.mapper.BaseMapperX;
|
||||
import com.njcn.rdms.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||
import com.njcn.rdms.module.system.dal.dataobject.codegen.CodegenColumnDO;
|
||||
import com.njcn.rdms.module.system.dal.dataobject.codegen.CodegenTableDO;
|
||||
import com.njcn.rdms.module.system.enums.codegen.CodegenFrontTypeEnum;
|
||||
import com.njcn.rdms.module.system.enums.codegen.CodegenSceneEnum;
|
||||
import com.njcn.rdms.module.system.enums.codegen.CodegenTemplateTypeEnum;
|
||||
import com.njcn.rdms.module.system.enums.codegen.CodegenVOTypeEnum;
|
||||
import com.njcn.rdms.module.system.framework.codegen.config.CodegenProperties;
|
||||
import jakarta.annotation.PostConstruct;
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.Setter;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static cn.hutool.core.map.MapUtil.getStr;
|
||||
import static cn.hutool.core.text.CharSequenceUtil.*;
|
||||
|
||||
/**
|
||||
* 代码生成的引擎,用于具体生成代码
|
||||
* 目前基于 {@link org.apache.velocity.app.Velocity} 模板引擎实现
|
||||
*
|
||||
* 考虑到 Java 模板引擎的框架非常多,Freemarker、Velocity、Thymeleaf 等等,所以我们采用 hutool 封装的 {@link cn.hutool.extra.template.Template} 抽象
|
||||
*
|
||||
* @author hongawen
|
||||
*/
|
||||
@Component
|
||||
public class CodegenEngine {
|
||||
|
||||
/**
|
||||
* 后端的模板配置
|
||||
*
|
||||
* key:模板在 resources 的地址
|
||||
* value:生成的路径
|
||||
*/
|
||||
private static final Map<String, String> SERVER_TEMPLATES = MapUtil.<String, String>builder(new LinkedHashMap<>()) // 有序
|
||||
// Java module-biz(server) Main
|
||||
.put(javaTemplatePath("controller/vo/pageReqVO"), javaModuleImplVOFilePath("PageReqVO"))
|
||||
.put(javaTemplatePath("controller/vo/listReqVO"), javaModuleImplVOFilePath("ListReqVO"))
|
||||
.put(javaTemplatePath("controller/vo/respVO"), javaModuleImplVOFilePath("RespVO"))
|
||||
.put(javaTemplatePath("controller/vo/saveReqVO"), javaModuleImplVOFilePath("SaveReqVO"))
|
||||
.put(javaTemplatePath("controller/controller"), javaModuleImplControllerFilePath())
|
||||
.put(javaTemplatePath("dal/do"),
|
||||
javaModuleImplMainFilePath("dal/dataobject/${table.businessName}/${table.className}DO"))
|
||||
.put(javaTemplatePath("dal/do_sub"), // 特殊:主子表专属逻辑
|
||||
javaModuleImplMainFilePath("dal/dataobject/${table.businessName}/${subTable.className}DO"))
|
||||
.put(javaTemplatePath("dal/mapper"),
|
||||
javaModuleImplMainFilePath("dal/mysql/${table.businessName}/${table.className}Mapper"))
|
||||
.put(javaTemplatePath("dal/mapper_sub"), // 特殊:主子表专属逻辑
|
||||
javaModuleImplMainFilePath("dal/mysql/${table.businessName}/${subTable.className}Mapper"))
|
||||
.put(javaTemplatePath("dal/mapper.xml"), mapperXmlFilePath())
|
||||
.put(javaTemplatePath("service/serviceImpl"),
|
||||
javaModuleImplMainFilePath("service/${table.businessName}/${table.className}ServiceImpl"))
|
||||
.put(javaTemplatePath("service/service"),
|
||||
javaModuleImplMainFilePath("service/${table.businessName}/${table.className}Service"))
|
||||
// Java module-biz(server) Test
|
||||
.put(javaTemplatePath("test/serviceTest"),
|
||||
javaModuleImplTestFilePath("service/${table.businessName}/${table.className}ServiceImplTest"))
|
||||
// Java module-api Main
|
||||
.put(javaTemplatePath("enums/errorcode"), javaModuleApiMainFilePath("enums/ErrorCodeConstants_手动操作"))
|
||||
// SQL
|
||||
.put("codegen/sql/sql.vm", "sql/sql.sql")
|
||||
.put("codegen/sql/h2.vm", "sql/h2.sql")
|
||||
.build();
|
||||
|
||||
/**
|
||||
* 前端的配置模版
|
||||
*
|
||||
* key1:UI 模版的类型 {@link CodegenFrontTypeEnum#getType()}
|
||||
* key2:模板在 resources 的地址
|
||||
* value:生成的路径
|
||||
*/
|
||||
private static final Table<Integer, String, String> FRONT_TEMPLATES = ImmutableTable.<Integer, String, String>builder()
|
||||
// VUE2_ELEMENT_UI
|
||||
.put(CodegenFrontTypeEnum.VUE2_ELEMENT_UI.getType(), vueTemplatePath("views/index.vue"),
|
||||
vueFilePath("views/${table.moduleName}/${table.businessName}/index.vue"))
|
||||
.put(CodegenFrontTypeEnum.VUE2_ELEMENT_UI.getType(), vueTemplatePath("api/api.js"),
|
||||
vueFilePath("api/${table.moduleName}/${table.businessName}/index.js"))
|
||||
.put(CodegenFrontTypeEnum.VUE2_ELEMENT_UI.getType(), vueTemplatePath("views/form.vue"),
|
||||
vueFilePath("views/${table.moduleName}/${table.businessName}/${simpleClassName}Form.vue"))
|
||||
.put(CodegenFrontTypeEnum.VUE2_ELEMENT_UI.getType(), vueTemplatePath("views/components/form_sub_normal.vue"), // 特殊:主子表专属逻辑
|
||||
vueFilePath("views/${table.moduleName}/${table.businessName}/components/${subSimpleClassName}Form.vue"))
|
||||
.put(CodegenFrontTypeEnum.VUE2_ELEMENT_UI.getType(), vueTemplatePath("views/components/form_sub_inner.vue"), // 特殊:主子表专属逻辑
|
||||
vueFilePath("views/${table.moduleName}/${table.businessName}/components/${subSimpleClassName}Form.vue"))
|
||||
.put(CodegenFrontTypeEnum.VUE2_ELEMENT_UI.getType(), vueTemplatePath("views/components/form_sub_erp.vue"), // 特殊:主子表专属逻辑
|
||||
vueFilePath("views/${table.moduleName}/${table.businessName}/components/${subSimpleClassName}Form.vue"))
|
||||
.put(CodegenFrontTypeEnum.VUE2_ELEMENT_UI.getType(), vueTemplatePath("views/components/list_sub_inner.vue"), // 特殊:主子表专属逻辑
|
||||
vueFilePath("views/${table.moduleName}/${table.businessName}/components/${subSimpleClassName}List.vue"))
|
||||
.put(CodegenFrontTypeEnum.VUE2_ELEMENT_UI.getType(), vueTemplatePath("views/components/list_sub_erp.vue"), // 特殊:主子表专属逻辑
|
||||
vueFilePath("views/${table.moduleName}/${table.businessName}/components/${subSimpleClassName}List.vue"))
|
||||
// VUE3_ELEMENT_PLUS
|
||||
.put(CodegenFrontTypeEnum.VUE3_ELEMENT_PLUS.getType(), vue3TemplatePath("views/index.vue"),
|
||||
vue3FilePath("views/${table.moduleName}/${table.businessName}/index.vue"))
|
||||
.put(CodegenFrontTypeEnum.VUE3_ELEMENT_PLUS.getType(), vue3TemplatePath("views/form.vue"),
|
||||
vue3FilePath("views/${table.moduleName}/${table.businessName}/${simpleClassName}Form.vue"))
|
||||
.put(CodegenFrontTypeEnum.VUE3_ELEMENT_PLUS.getType(), vue3TemplatePath("views/components/form_sub_normal.vue"), // 特殊:主子表专属逻辑
|
||||
vue3FilePath("views/${table.moduleName}/${table.businessName}/components/${subSimpleClassName}Form.vue"))
|
||||
.put(CodegenFrontTypeEnum.VUE3_ELEMENT_PLUS.getType(), vue3TemplatePath("views/components/form_sub_inner.vue"), // 特殊:主子表专属逻辑
|
||||
vue3FilePath("views/${table.moduleName}/${table.businessName}/components/${subSimpleClassName}Form.vue"))
|
||||
.put(CodegenFrontTypeEnum.VUE3_ELEMENT_PLUS.getType(), vue3TemplatePath("views/components/form_sub_erp.vue"), // 特殊:主子表专属逻辑
|
||||
vue3FilePath("views/${table.moduleName}/${table.businessName}/components/${subSimpleClassName}Form.vue"))
|
||||
.put(CodegenFrontTypeEnum.VUE3_ELEMENT_PLUS.getType(), vue3TemplatePath("views/components/list_sub_inner.vue"), // 特殊:主子表专属逻辑
|
||||
vue3FilePath("views/${table.moduleName}/${table.businessName}/components/${subSimpleClassName}List.vue"))
|
||||
.put(CodegenFrontTypeEnum.VUE3_ELEMENT_PLUS.getType(), vue3TemplatePath("views/components/list_sub_erp.vue"), // 特殊:主子表专属逻辑
|
||||
vue3FilePath("views/${table.moduleName}/${table.businessName}/components/${subSimpleClassName}List.vue"))
|
||||
.put(CodegenFrontTypeEnum.VUE3_ELEMENT_PLUS.getType(), vue3TemplatePath("api/api.ts"),
|
||||
vue3FilePath("api/${table.moduleName}/${table.businessName}/index.ts"))
|
||||
.put(CodegenFrontTypeEnum.VUE3_ADMIN_UNIAPP_WOT.getType(), vue3AdminUniappTemplatePath("api/api.ts"),
|
||||
vue3UniappFilePath("api/${table.moduleName}/${table.businessName}/index.ts"))
|
||||
.put(CodegenFrontTypeEnum.VUE3_ADMIN_UNIAPP_WOT.getType(), vue3AdminUniappTemplatePath("views/index.vue"),
|
||||
vue3UniappFilePath("pages-${table.moduleName}/${table.businessName}/index.vue"))
|
||||
.put(CodegenFrontTypeEnum.VUE3_ADMIN_UNIAPP_WOT.getType(), vue3AdminUniappTemplatePath("components/search-form.vue"),
|
||||
vue3UniappFilePath("pages-${table.moduleName}/${table.businessName}/components/search-form.vue"))
|
||||
.put(CodegenFrontTypeEnum.VUE3_ADMIN_UNIAPP_WOT.getType(), vue3AdminUniappTemplatePath("views/form/index.vue"),
|
||||
vue3UniappFilePath("pages-${table.moduleName}/${table.businessName}/form/index.vue"))
|
||||
.put(CodegenFrontTypeEnum.VUE3_ADMIN_UNIAPP_WOT.getType(), vue3AdminUniappTemplatePath("views/detail/index.vue"),
|
||||
vue3UniappFilePath("pages-${table.moduleName}/${table.businessName}/detail/index.vue"))
|
||||
// VUE3_VBEN2_ANTD_SCHEMA
|
||||
.put(CodegenFrontTypeEnum.VUE3_VBEN2_ANTD_SCHEMA.getType(), vue3VbenTemplatePath("views/data.ts"),
|
||||
vue3VbenFilePath("views/${table.moduleName}/${table.businessName}/${classNameVar}.data.ts"))
|
||||
.put(CodegenFrontTypeEnum.VUE3_VBEN2_ANTD_SCHEMA.getType(), vue3VbenTemplatePath("views/index.vue"),
|
||||
vue3VbenFilePath("views/${table.moduleName}/${table.businessName}/index.vue"))
|
||||
.put(CodegenFrontTypeEnum.VUE3_VBEN2_ANTD_SCHEMA.getType(), vue3VbenTemplatePath("views/form.vue"),
|
||||
vue3VbenFilePath("views/${table.moduleName}/${table.businessName}/${simpleClassName}Modal.vue"))
|
||||
.put(CodegenFrontTypeEnum.VUE3_VBEN2_ANTD_SCHEMA.getType(), vue3VbenTemplatePath("api/api.ts"),
|
||||
vue3VbenFilePath("api/${table.moduleName}/${table.businessName}/index.ts"))
|
||||
// VUE3_VBEN5_ANTD_SCHEMA
|
||||
.put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD_SCHEMA.getType(), vue3Vben5AntdSchemaTemplatePath("views/data.ts"),
|
||||
vue3VbenFilePath("views/${table.moduleName}/${table.businessName}/data.ts"))
|
||||
.put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD_SCHEMA.getType(), vue3Vben5AntdSchemaTemplatePath("views/index.vue"),
|
||||
vue3VbenFilePath("views/${table.moduleName}/${table.businessName}/index.vue"))
|
||||
.put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD_SCHEMA.getType(), vue3Vben5AntdSchemaTemplatePath("views/form.vue"),
|
||||
vue3VbenFilePath("views/${table.moduleName}/${table.businessName}/modules/form.vue"))
|
||||
.put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD_SCHEMA.getType(), vue3Vben5AntdSchemaTemplatePath("api/api.ts"),
|
||||
vue3VbenFilePath("api/${table.moduleName}/${table.businessName}/index.ts"))
|
||||
.put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD_SCHEMA.getType(), vue3Vben5AntdSchemaTemplatePath("views/modules/form_sub_normal.vue"), // 特殊:主子表专属逻辑
|
||||
vue3VbenFilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-form.vue"))
|
||||
.put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD_SCHEMA.getType(), vue3Vben5AntdSchemaTemplatePath("views/modules/form_sub_inner.vue"), // 特殊:主子表专属逻辑
|
||||
vue3VbenFilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-form.vue"))
|
||||
.put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD_SCHEMA.getType(), vue3Vben5AntdSchemaTemplatePath("views/modules/form_sub_erp.vue"), // 特殊:主子表专属逻辑
|
||||
vue3VbenFilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-form.vue"))
|
||||
.put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD_SCHEMA.getType(), vue3Vben5AntdSchemaTemplatePath("views/modules/list_sub_inner.vue"), // 特殊:主子表专属逻辑
|
||||
vue3VbenFilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-list.vue"))
|
||||
.put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD_SCHEMA.getType(), vue3Vben5AntdSchemaTemplatePath("views/modules/list_sub_erp.vue"), // 特殊:主子表专属逻辑
|
||||
vue3VbenFilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-list.vue"))
|
||||
// VUE3_VBEN5_ANTD
|
||||
.put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD_GENERAL.getType(), vue3Vben5AntdGeneralTemplatePath("views/index.vue"),
|
||||
vue3VbenFilePath("views/${table.moduleName}/${table.businessName}/index.vue"))
|
||||
.put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD_GENERAL.getType(), vue3Vben5AntdGeneralTemplatePath("views/form.vue"),
|
||||
vue3VbenFilePath("views/${table.moduleName}/${table.businessName}/modules/form.vue"))
|
||||
.put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD_GENERAL.getType(), vue3Vben5AntdGeneralTemplatePath("api/api.ts"),
|
||||
vue3VbenFilePath("api/${table.moduleName}/${table.businessName}/index.ts"))
|
||||
.put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD_GENERAL.getType(), vue3Vben5AntdGeneralTemplatePath("views/modules/form_sub_normal.vue"), // 特殊:主子表专属逻辑
|
||||
vue3VbenFilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-form.vue"))
|
||||
.put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD_GENERAL.getType(), vue3Vben5AntdGeneralTemplatePath("views/modules/form_sub_inner.vue"), // 特殊:主子表专属逻辑
|
||||
vue3VbenFilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-form.vue"))
|
||||
.put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD_GENERAL.getType(), vue3Vben5AntdGeneralTemplatePath("views/modules/form_sub_erp.vue"), // 特殊:主子表专属逻辑
|
||||
vue3VbenFilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-form.vue"))
|
||||
.put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD_GENERAL.getType(), vue3Vben5AntdGeneralTemplatePath("views/modules/list_sub_inner.vue"), // 特殊:主子表专属逻辑
|
||||
vue3VbenFilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-list.vue"))
|
||||
.put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD_GENERAL.getType(), vue3Vben5AntdGeneralTemplatePath("views/modules/list_sub_erp.vue"), // 特殊:主子表专属逻辑
|
||||
vue3VbenFilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-list.vue"))
|
||||
// VUE3_VBEN5_EP_SCHEMA
|
||||
.put(CodegenFrontTypeEnum.VUE3_VBEN5_EP_SCHEMA.getType(), vue3Vben5EpSchemaTemplatePath("views/data.ts"),
|
||||
vue3VbenFilePath("views/${table.moduleName}/${table.businessName}/data.ts"))
|
||||
.put(CodegenFrontTypeEnum.VUE3_VBEN5_EP_SCHEMA.getType(), vue3Vben5EpSchemaTemplatePath("views/index.vue"),
|
||||
vue3VbenFilePath("views/${table.moduleName}/${table.businessName}/index.vue"))
|
||||
.put(CodegenFrontTypeEnum.VUE3_VBEN5_EP_SCHEMA.getType(), vue3Vben5EpSchemaTemplatePath("views/form.vue"),
|
||||
vue3VbenFilePath("views/${table.moduleName}/${table.businessName}/modules/form.vue"))
|
||||
.put(CodegenFrontTypeEnum.VUE3_VBEN5_EP_SCHEMA.getType(), vue3Vben5EpSchemaTemplatePath("api/api.ts"),
|
||||
vue3VbenFilePath("api/${table.moduleName}/${table.businessName}/index.ts"))
|
||||
.put(CodegenFrontTypeEnum.VUE3_VBEN5_EP_SCHEMA.getType(), vue3Vben5EpSchemaTemplatePath("views/modules/form_sub_normal.vue"), // 特殊:主子表专属逻辑
|
||||
vue3VbenFilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-form.vue"))
|
||||
.put(CodegenFrontTypeEnum.VUE3_VBEN5_EP_SCHEMA.getType(), vue3Vben5EpSchemaTemplatePath("views/modules/form_sub_inner.vue"), // 特殊:主子表专属逻辑
|
||||
vue3VbenFilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-form.vue"))
|
||||
.put(CodegenFrontTypeEnum.VUE3_VBEN5_EP_SCHEMA.getType(), vue3Vben5EpSchemaTemplatePath("views/modules/form_sub_erp.vue"), // 特殊:主子表专属逻辑
|
||||
vue3VbenFilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-form.vue"))
|
||||
.put(CodegenFrontTypeEnum.VUE3_VBEN5_EP_SCHEMA.getType(), vue3Vben5EpSchemaTemplatePath("views/modules/list_sub_inner.vue"), // 特殊:主子表专属逻辑
|
||||
vue3VbenFilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-list.vue"))
|
||||
.put(CodegenFrontTypeEnum.VUE3_VBEN5_EP_SCHEMA.getType(), vue3Vben5EpSchemaTemplatePath("views/modules/list_sub_erp.vue"), // 特殊:主子表专属逻辑
|
||||
vue3VbenFilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-list.vue"))
|
||||
// VUE3_VBEN5_EP
|
||||
.put(CodegenFrontTypeEnum.VUE3_VBEN5_EP_GENERAL.getType(), vue3Vben5EpGeneralTemplatePath("views/index.vue"),
|
||||
vue3VbenFilePath("views/${table.moduleName}/${table.businessName}/index.vue"))
|
||||
.put(CodegenFrontTypeEnum.VUE3_VBEN5_EP_GENERAL.getType(), vue3Vben5EpGeneralTemplatePath("views/form.vue"),
|
||||
vue3VbenFilePath("views/${table.moduleName}/${table.businessName}/modules/form.vue"))
|
||||
.put(CodegenFrontTypeEnum.VUE3_VBEN5_EP_GENERAL.getType(), vue3Vben5EpGeneralTemplatePath("api/api.ts"),
|
||||
vue3VbenFilePath("api/${table.moduleName}/${table.businessName}/index.ts"))
|
||||
.put(CodegenFrontTypeEnum.VUE3_VBEN5_EP_GENERAL.getType(), vue3Vben5EpGeneralTemplatePath("views/modules/form_sub_normal.vue"), // 特殊:主子表专属逻辑
|
||||
vue3VbenFilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-form.vue"))
|
||||
.put(CodegenFrontTypeEnum.VUE3_VBEN5_EP_GENERAL.getType(), vue3Vben5EpGeneralTemplatePath("views/modules/form_sub_inner.vue"), // 特殊:主子表专属逻辑
|
||||
vue3VbenFilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-form.vue"))
|
||||
.put(CodegenFrontTypeEnum.VUE3_VBEN5_EP_GENERAL.getType(), vue3Vben5EpGeneralTemplatePath("views/modules/form_sub_erp.vue"), // 特殊:主子表专属逻辑
|
||||
vue3VbenFilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-form.vue"))
|
||||
.put(CodegenFrontTypeEnum.VUE3_VBEN5_EP_GENERAL.getType(), vue3Vben5EpGeneralTemplatePath("views/modules/list_sub_inner.vue"), // 特殊:主子表专属逻辑
|
||||
vue3VbenFilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-list.vue"))
|
||||
.put(CodegenFrontTypeEnum.VUE3_VBEN5_EP_GENERAL.getType(), vue3Vben5EpGeneralTemplatePath("views/modules/list_sub_erp.vue"), // 特殊:主子表专属逻辑
|
||||
vue3VbenFilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-list.vue"))
|
||||
.build();
|
||||
|
||||
@Resource
|
||||
private CodegenProperties codegenProperties;
|
||||
|
||||
/**
|
||||
* 是否使用 jakarta 包,用于解决 Spring Boot 2.X 和 3.X 的兼容性问题
|
||||
*
|
||||
* true - 使用 jakarta.validation.constraints.*
|
||||
* false - 使用 javax.validation.constraints.*
|
||||
*/
|
||||
@Setter // 允许设置的原因,是因为单测需要手动改变
|
||||
private Boolean jakartaEnable;
|
||||
|
||||
/**
|
||||
* 是否为 rdms-cloud 项目,用于解决 Boot 和 Cloud 的 api 模块兼容性问题
|
||||
*
|
||||
* true - 需要有 rdms-module-xxx-api 模块
|
||||
* false - 不需要有,使用 api、enum 包即可
|
||||
*/
|
||||
@Setter
|
||||
private Boolean cloudEnable;
|
||||
|
||||
/**
|
||||
* 模板引擎,由 hutool 实现
|
||||
*/
|
||||
private final TemplateEngine templateEngine;
|
||||
/**
|
||||
* 全局通用变量映射
|
||||
*/
|
||||
private final Map<String, Object> globalBindingMap = new HashMap<>();
|
||||
|
||||
public CodegenEngine() {
|
||||
// 初始化 TemplateEngine 属性
|
||||
TemplateConfig config = new TemplateConfig();
|
||||
config.setResourceMode(TemplateConfig.ResourceMode.CLASSPATH);
|
||||
this.templateEngine = new VelocityEngine(config);
|
||||
// 设置 javaxEnable,按照是否使用 JDK17 来判断
|
||||
this.jakartaEnable = SystemUtil.getJavaInfo().isJavaVersionAtLeast(1700) // 17.00 * 100
|
||||
&& ClassUtils.isPresent("jakarta.annotation.Resource", ClassUtils.getDefaultClassLoader());
|
||||
// 设置 cloudEnable,按照是否使用 Spring Cloud 来判断
|
||||
this.cloudEnable = ClassUtils.isPresent("com.njcn.rdms.module.infra.framework.rpc.config.RpcConfiguration",
|
||||
ClassUtils.getDefaultClassLoader());
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
@VisibleForTesting
|
||||
void initGlobalBindingMap() {
|
||||
// 全局配置
|
||||
globalBindingMap.put("basePackage", codegenProperties.getBasePackage());
|
||||
globalBindingMap.put("baseFrameworkPackage", codegenProperties.getBasePackage()
|
||||
+ '.' + "framework"); // 用于后续获取测试类的 package 地址
|
||||
globalBindingMap.put("jakartaPackage", jakartaEnable ? "jakarta" : "javax");
|
||||
globalBindingMap.put("voType", codegenProperties.getVoType());
|
||||
globalBindingMap.put("deleteBatchEnable", codegenProperties.getDeleteBatchEnable());
|
||||
// 全局 Java Bean
|
||||
globalBindingMap.put("CommonResultClassName", CommonResult.class.getName());
|
||||
globalBindingMap.put("PageResultClassName", PageResult.class.getName());
|
||||
// VO 类,独有字段
|
||||
globalBindingMap.put("PageParamClassName", PageParam.class.getName());
|
||||
globalBindingMap.put("DictFormatClassName", DictFormat.class.getName());
|
||||
// DO 类,独有字段
|
||||
globalBindingMap.put("BaseDOClassName", BaseDO.class.getName());
|
||||
globalBindingMap.put("baseDOFields", CodegenBuilder.BASE_DO_FIELDS);
|
||||
globalBindingMap.put("QueryWrapperClassName", LambdaQueryWrapperX.class.getName());
|
||||
globalBindingMap.put("BaseMapperClassName", BaseMapperX.class.getName());
|
||||
// Util 工具类
|
||||
globalBindingMap.put("ServiceExceptionUtilClassName", ServiceExceptionUtil.class.getName());
|
||||
globalBindingMap.put("DateUtilsClassName", DateUtils.class.getName());
|
||||
globalBindingMap.put("ExcelUtilsClassName", ExcelUtils.class.getName());
|
||||
globalBindingMap.put("LocalDateTimeUtilsClassName", LocalDateTimeUtils.class.getName());
|
||||
globalBindingMap.put("ObjectUtilsClassName", ObjectUtils.class.getName());
|
||||
globalBindingMap.put("DictConvertClassName", DictConvert.class.getName());
|
||||
globalBindingMap.put("ApiAccessLogClassName", ApiAccessLog.class.getName());
|
||||
globalBindingMap.put("OperateTypeEnumClassName", OperateTypeEnum.class.getName());
|
||||
globalBindingMap.put("BeanUtils", BeanUtils.class.getName());
|
||||
globalBindingMap.put("CollectionUtilsClassName", CollectionUtils.class.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成代码
|
||||
*
|
||||
* @param dbType 数据库类型
|
||||
* @param table 表定义
|
||||
* @param columns table 的字段定义数组
|
||||
* @param subTables 子表数组,当且仅当主子表时使用
|
||||
* @param subColumnsList subTables 的字段定义数组
|
||||
* @return 生成的代码,key 是路径,value 是对应代码
|
||||
*/
|
||||
public Map<String, String> execute(DbType dbType, CodegenTableDO table, List<CodegenColumnDO> columns,
|
||||
List<CodegenTableDO> subTables, List<List<CodegenColumnDO>> subColumnsList) {
|
||||
// 1.1 初始化 bindMap 上下文
|
||||
Map<String, Object> bindingMap = initBindingMap(dbType, table, columns, subTables, subColumnsList);
|
||||
// 1.2 获得模版
|
||||
Map<String, String> templates = getTemplates(table.getFrontType());
|
||||
|
||||
// 2. 执行生成
|
||||
Map<String, String> result = Maps.newLinkedHashMapWithExpectedSize(templates.size()); // 有序
|
||||
templates.forEach((vmPath, filePath) -> {
|
||||
// 2.1 特殊:主子表专属逻辑
|
||||
if (isSubTemplate(vmPath)) {
|
||||
generateSubCode(table, subTables, result, vmPath, filePath, bindingMap);
|
||||
return;
|
||||
// 2.2 特殊:树表专属逻辑
|
||||
} else if (isPageReqVOTemplate(vmPath)) {
|
||||
// 减少多余的类生成,例如说 PageVO.java 类
|
||||
if (CodegenTemplateTypeEnum.isTree(table.getTemplateType())) {
|
||||
return;
|
||||
}
|
||||
} else if (isListReqVOTemplate(vmPath)) {
|
||||
// 减少多余的类生成,例如说 ListVO.java 类
|
||||
if (!CodegenTemplateTypeEnum.isTree(table.getTemplateType())) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
// 2.3 默认生成
|
||||
generateCode(result, vmPath, filePath, bindingMap);
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
private void generateCode(Map<String, String> result, String vmPath,
|
||||
String filePath, Map<String, Object> bindingMap) {
|
||||
filePath = formatFilePath(filePath, bindingMap);
|
||||
String content = templateEngine.getTemplate(vmPath).render(bindingMap);
|
||||
// 格式化代码
|
||||
content = prettyCode(content, vmPath);
|
||||
result.put(filePath, content);
|
||||
}
|
||||
|
||||
private void generateSubCode(CodegenTableDO table, List<CodegenTableDO> subTables,
|
||||
Map<String, String> result, String vmPath,
|
||||
String filePath, Map<String, Object> bindingMap) {
|
||||
// 没有子表,所以不生成
|
||||
if (CollUtil.isEmpty(subTables)) {
|
||||
return;
|
||||
}
|
||||
// 主子表的模式匹配。目的:过滤掉个性化的模版
|
||||
if (vmPath.contains("_normal")
|
||||
&& ObjectUtil.notEqual(table.getTemplateType(), CodegenTemplateTypeEnum.MASTER_NORMAL.getType())) {
|
||||
return;
|
||||
}
|
||||
if (vmPath.contains("_erp")
|
||||
&& ObjectUtil.notEqual(table.getTemplateType(), CodegenTemplateTypeEnum.MASTER_ERP.getType())) {
|
||||
return;
|
||||
}
|
||||
if (vmPath.contains("_inner")
|
||||
&& ObjectUtil.notEqual(table.getTemplateType(), CodegenTemplateTypeEnum.MASTER_INNER.getType())) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 逐个生成
|
||||
for (int i = 0; i < subTables.size(); i++) {
|
||||
bindingMap.put("subIndex", i);
|
||||
generateCode(result, vmPath, filePath, bindingMap);
|
||||
}
|
||||
bindingMap.remove("subIndex");
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化生成后的代码
|
||||
*
|
||||
* 因为尽量让 vm 模版简单,所以统一的处理都在这个方法。
|
||||
* 如果不处理,Vue 的 Pretty 格式校验可能会报错
|
||||
*
|
||||
* @param content 格式化前的代码
|
||||
* @param vmPath 模板路径
|
||||
* @return 格式化后的代码
|
||||
*/
|
||||
private String prettyCode(String content, String vmPath) {
|
||||
// Vue 界面:去除字段后面多余的 , 逗号,解决前端的 Pretty 代码格式检查的报错(需要排除 vben5、vue3_admin_uniapp)
|
||||
if (!StrUtil.containsAny(vmPath, "vben5", "vue3_admin_uniapp")) {
|
||||
content = content.replaceAll(",\n}", "\n}").replaceAll(",\n }", "\n }");
|
||||
}
|
||||
// Vue 界面:去除多的 dateFormatter,只有一个的情况下,说明没使用到
|
||||
if (StrUtil.count(content, "dateFormatter") == 1) {
|
||||
content = StrUtils.removeLineContains(content, "dateFormatter");
|
||||
}
|
||||
// Vue2 界面:修正 $refs
|
||||
if (StrUtil.count(content, "this.refs") >= 1) {
|
||||
content = content.replace("this.refs", "this.$refs");
|
||||
}
|
||||
// Vue 界面:去除多的 dict 相关,只有一个的情况下,说明没使用到
|
||||
if (StrUtil.count(content, "getIntDictOptions") == 1) {
|
||||
content = content.replace("getIntDictOptions, ", "");
|
||||
}
|
||||
if (StrUtil.count(content, "getStrDictOptions") == 1) {
|
||||
content = content.replace("getStrDictOptions, ", "");
|
||||
}
|
||||
if (StrUtil.count(content, "getBoolDictOptions") == 1) {
|
||||
content = content.replace("getBoolDictOptions, ", "");
|
||||
}
|
||||
if (StrUtil.count(content, "DICT_TYPE.") == 0) {
|
||||
content = StrUtils.removeLineContains(content, "DICT_TYPE");
|
||||
}
|
||||
return content;
|
||||
}
|
||||
|
||||
private Map<String, Object> initBindingMap(DbType dbType, CodegenTableDO table, List<CodegenColumnDO> columns,
|
||||
List<CodegenTableDO> subTables, List<List<CodegenColumnDO>> subColumnsList) {
|
||||
// 创建 bindingMap
|
||||
Map<String, Object> bindingMap = new HashMap<>(globalBindingMap);
|
||||
bindingMap.put("dbType", dbType);
|
||||
bindingMap.put("table", table);
|
||||
bindingMap.put("columns", columns);
|
||||
bindingMap.put("primaryColumn", CollectionUtils.findFirst(columns, CodegenColumnDO::getPrimaryKey)); // 主键字段
|
||||
bindingMap.put("sceneEnum", CodegenSceneEnum.valueOf(table.getScene()));
|
||||
// className 相关
|
||||
// 去掉指定前缀,将 TestDictType 转换成 DictType. 因为在 create 等方法后,不需要带上 Test 前缀
|
||||
String className = table.getClassName();
|
||||
String simpleClassName = equalsAnyIgnoreCase(table.getClassName(), table.getModuleName()) ? table.getClassName()
|
||||
: removePrefix(table.getClassName(), upperFirst(table.getModuleName()));
|
||||
String classNameVar = lowerFirst(simpleClassName);
|
||||
bindingMap.put("simpleClassName", simpleClassName);
|
||||
bindingMap.put("simpleClassName_underlineCase", toUnderlineCase(simpleClassName)); // 将 DictType 转换成 dict_type
|
||||
bindingMap.put("classNameVar", classNameVar); // 将 DictType 转换成 dictType,用于变量
|
||||
// 将 DictType 转换成 dict-type
|
||||
String simpleClassNameStrikeCase = toSymbolCase(simpleClassName, '-');
|
||||
bindingMap.put("simpleClassName_strikeCase", simpleClassNameStrikeCase);
|
||||
// permission 前缀
|
||||
bindingMap.put("permissionPrefix", table.getModuleName() + ":" + simpleClassNameStrikeCase);
|
||||
|
||||
// 特殊:树表专属逻辑
|
||||
if (CodegenTemplateTypeEnum.isTree(table.getTemplateType())) {
|
||||
CodegenColumnDO treeParentColumn = CollUtil.findOne(columns,
|
||||
column -> Objects.equals(column.getId(), table.getTreeParentColumnId()));
|
||||
bindingMap.put("treeParentColumn", treeParentColumn);
|
||||
bindingMap.put("treeParentColumn_javaField_underlineCase", toUnderlineCase(treeParentColumn.getJavaField()));
|
||||
CodegenColumnDO treeNameColumn = CollUtil.findOne(columns,
|
||||
column -> Objects.equals(column.getId(), table.getTreeNameColumnId()));
|
||||
bindingMap.put("treeNameColumn", treeNameColumn);
|
||||
bindingMap.put("treeNameColumn_javaField_underlineCase", toUnderlineCase(treeNameColumn.getJavaField()));
|
||||
}
|
||||
|
||||
// 特殊:主子表专属逻辑
|
||||
if (CollUtil.isNotEmpty(subTables)) {
|
||||
// 创建 bindingMap
|
||||
bindingMap.put("subTables", subTables);
|
||||
bindingMap.put("subColumnsList", subColumnsList);
|
||||
List<CodegenColumnDO> subPrimaryColumns = new ArrayList<>();
|
||||
List<CodegenColumnDO> subJoinColumns = new ArrayList<>();
|
||||
List<String> subJoinColumnStrikeCases = new ArrayList<>();
|
||||
List<String> subSimpleClassNames = new ArrayList<>();
|
||||
List<String> subClassNameVars = new ArrayList<>();
|
||||
List<String> simpleClassNameUnderlineCases = new ArrayList<>();
|
||||
List<String> subSimpleClassNameStrikeCases = new ArrayList<>();
|
||||
for (int i = 0; i < subTables.size(); i++) {
|
||||
CodegenTableDO subTable = subTables.get(i);
|
||||
List<CodegenColumnDO> subColumns = subColumnsList.get(i);
|
||||
subPrimaryColumns.add(CollectionUtils.findFirst(subColumns, CodegenColumnDO::getPrimaryKey)); //
|
||||
CodegenColumnDO subColumn = CollectionUtils.findFirst(subColumns, // 关联的字段
|
||||
column -> Objects.equals(column.getId(), subTable.getSubJoinColumnId()));
|
||||
subJoinColumns.add(subColumn);
|
||||
subJoinColumnStrikeCases.add(toSymbolCase(subColumn.getJavaField(), '-')); // 将 DictType 转换成 dict-type
|
||||
// className 相关
|
||||
String subSimpleClassName = removePrefix(subTable.getClassName(), upperFirst(subTable.getModuleName()));
|
||||
subSimpleClassNames.add(subSimpleClassName);
|
||||
simpleClassNameUnderlineCases.add(toUnderlineCase(subSimpleClassName)); // 将 DictType 转换成 dict_type
|
||||
subClassNameVars.add(lowerFirst(subSimpleClassName)); // 将 DictType 转换成 dictType,用于变量
|
||||
subSimpleClassNameStrikeCases.add(toSymbolCase(subSimpleClassName, '-')); // 将 DictType 转换成 dict-type
|
||||
}
|
||||
bindingMap.put("subPrimaryColumns", subPrimaryColumns);
|
||||
bindingMap.put("subJoinColumns", subJoinColumns);
|
||||
bindingMap.put("subJoinColumn_strikeCases", subJoinColumnStrikeCases);
|
||||
bindingMap.put("subSimpleClassNames", subSimpleClassNames);
|
||||
bindingMap.put("simpleClassNameUnderlineCases", simpleClassNameUnderlineCases);
|
||||
bindingMap.put("subClassNameVars", subClassNameVars);
|
||||
bindingMap.put("subSimpleClassName_strikeCases", subSimpleClassNameStrikeCases);
|
||||
}
|
||||
|
||||
// 多个 vm 公用的 VO 变量
|
||||
if (ObjectUtil.equal(codegenProperties.getVoType(), CodegenVOTypeEnum.VO.getType())) {
|
||||
String prefixClass = CodegenSceneEnum.valueOf(table.getScene()).getPrefixClass();
|
||||
bindingMap.put("saveReqVOClass", prefixClass + className + "SaveReqVO");
|
||||
bindingMap.put("updateReqVOClass", prefixClass + className + "SaveReqVO");
|
||||
bindingMap.put("respVOClass", prefixClass + className + "RespVO");
|
||||
bindingMap.put("saveReqVOVar", "createReqVO");
|
||||
bindingMap.put("updateReqVOVar", "updateReqVO");
|
||||
} else if (ObjectUtil.equal(codegenProperties.getVoType(), CodegenVOTypeEnum.DO.getType())) {
|
||||
bindingMap.put("saveReqVOClass", className + "DO");
|
||||
bindingMap.put("updateReqVOClass", className + "DO");
|
||||
bindingMap.put("respVOClass", className + "DO");
|
||||
bindingMap.put("saveReqVOVar", classNameVar);
|
||||
bindingMap.put("updateReqVOVar", classNameVar);
|
||||
}
|
||||
return bindingMap;
|
||||
}
|
||||
|
||||
private Map<String, String> getTemplates(Integer frontType) {
|
||||
Map<String, String> templates = new LinkedHashMap<>();
|
||||
templates.putAll(SERVER_TEMPLATES);
|
||||
templates.putAll(FRONT_TEMPLATES.row(frontType));
|
||||
// 如果是 Boot 项目,则不使用 api/server 模块
|
||||
if (Boolean.FALSE.equals(cloudEnable)) {
|
||||
SERVER_TEMPLATES.forEach((templatePath, filePath) -> {
|
||||
filePath = StrUtil.replace(filePath, "/rdms-module-${table.moduleName}-api", "");
|
||||
filePath = StrUtil.replace(filePath, "/rdms-module-${table.moduleName}-server", "");
|
||||
templates.put(templatePath, filePath);
|
||||
});
|
||||
}
|
||||
// 如果禁用单元测试,则移除对应的模版
|
||||
if (Boolean.FALSE.equals(codegenProperties.getUnitTestEnable())) {
|
||||
templates.remove(javaTemplatePath("test/serviceTest"));
|
||||
templates.remove("codegen/sql/h2.vm");
|
||||
}
|
||||
// 如果禁用 VO 类型,则移除对应的模版
|
||||
if (ObjectUtil.notEqual(codegenProperties.getVoType(), CodegenVOTypeEnum.VO.getType())) {
|
||||
templates.remove(javaTemplatePath("controller/vo/respVO"));
|
||||
templates.remove(javaTemplatePath("controller/vo/saveReqVO"));
|
||||
}
|
||||
return templates;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private String formatFilePath(String filePath, Map<String, Object> bindingMap) {
|
||||
filePath = StrUtil.replace(filePath, "${basePackage}",
|
||||
getStr(bindingMap, "basePackage").replaceAll("\\.", "/"));
|
||||
filePath = StrUtil.replace(filePath, "${classNameVar}",
|
||||
getStr(bindingMap, "classNameVar"));
|
||||
filePath = StrUtil.replace(filePath, "${simpleClassName}",
|
||||
getStr(bindingMap, "simpleClassName"));
|
||||
// sceneEnum 包含的字段
|
||||
CodegenSceneEnum sceneEnum = (CodegenSceneEnum) bindingMap.get("sceneEnum");
|
||||
filePath = StrUtil.replace(filePath, "${sceneEnum.prefixClass}", sceneEnum.getPrefixClass());
|
||||
filePath = StrUtil.replace(filePath, "${sceneEnum.basePackage}", sceneEnum.getBasePackage());
|
||||
// table 包含的字段
|
||||
CodegenTableDO table = (CodegenTableDO) bindingMap.get("table");
|
||||
filePath = StrUtil.replace(filePath, "${table.moduleName}", table.getModuleName());
|
||||
filePath = StrUtil.replace(filePath, "${table.businessName}", table.getBusinessName());
|
||||
filePath = StrUtil.replace(filePath, "${table.className}", table.getClassName());
|
||||
// 特殊:主子表专属逻辑
|
||||
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());
|
||||
filePath = StrUtil.replace(filePath, "${subSimpleClassName}",
|
||||
((List<String>) bindingMap.get("subSimpleClassNames")).get(subIndex));
|
||||
filePath = StrUtil.replace(filePath, "${subSimpleClassName_strikeCase}",
|
||||
((List<String>) bindingMap.get("subSimpleClassName_strikeCases")).get(subIndex));
|
||||
}
|
||||
return filePath;
|
||||
}
|
||||
|
||||
private static String javaTemplatePath(String path) {
|
||||
return "codegen/java/" + path + ".vm";
|
||||
}
|
||||
|
||||
private static String javaModuleImplVOFilePath(String path) {
|
||||
return javaModuleFilePath("controller/${sceneEnum.basePackage}/${table.businessName}/" +
|
||||
"vo/${sceneEnum.prefixClass}${table.className}" + path, "server", "main");
|
||||
}
|
||||
|
||||
private static String javaModuleImplControllerFilePath() {
|
||||
return javaModuleFilePath("controller/${sceneEnum.basePackage}/${table.businessName}/" +
|
||||
"${sceneEnum.prefixClass}${table.className}Controller", "server", "main");
|
||||
}
|
||||
|
||||
private static String javaModuleImplMainFilePath(String path) {
|
||||
return javaModuleFilePath(path, "server", "main");
|
||||
}
|
||||
|
||||
private static String javaModuleApiMainFilePath(String path) {
|
||||
return javaModuleFilePath(path, "api", "main");
|
||||
}
|
||||
|
||||
private static String javaModuleImplTestFilePath(String path) {
|
||||
return javaModuleFilePath(path, "server", "test");
|
||||
}
|
||||
|
||||
private static String javaModuleFilePath(String path, String module, String src) {
|
||||
return "rdms-module-${table.moduleName}/" + // 顶级模块
|
||||
"rdms-module-${table.moduleName}-" + module + "/" + // 子模块
|
||||
"src/" + src + "/java/${basePackage}/module/${table.moduleName}/" + path + ".java";
|
||||
}
|
||||
|
||||
private static String mapperXmlFilePath() {
|
||||
return "rdms-module-${table.moduleName}/" + // 顶级模块
|
||||
"rdms-module-${table.moduleName}-server/" + // 子模块
|
||||
"src/main/resources/mapper/${table.businessName}/${table.className}Mapper.xml";
|
||||
}
|
||||
|
||||
private static String vueTemplatePath(String path) {
|
||||
return "codegen/vue/" + path + ".vm";
|
||||
}
|
||||
|
||||
private static String vueFilePath(String path) {
|
||||
return "rdms-ui-${sceneEnum.basePackage}-vue2/" + // 顶级目录
|
||||
"src/" + path;
|
||||
}
|
||||
|
||||
private static String vue3TemplatePath(String path) {
|
||||
return "codegen/vue3/" + path + ".vm";
|
||||
}
|
||||
|
||||
private static String vue3FilePath(String path) {
|
||||
return "rdms-ui-${sceneEnum.basePackage}-vue3/" + // 顶级目录
|
||||
"src/" + path;
|
||||
}
|
||||
|
||||
private static String vue3AdminUniappTemplatePath(String path) {
|
||||
return "codegen/vue3_admin_uniapp/" + path + ".vm";
|
||||
}
|
||||
|
||||
private static String vue3UniappFilePath(String path) {
|
||||
return "rdms-ui-${sceneEnum.basePackage}-uniapp/" + // 顶级目录
|
||||
"src/" + path;
|
||||
}
|
||||
|
||||
private static String vue3VbenFilePath(String path) {
|
||||
return "rdms-ui-${sceneEnum.basePackage}-vben/" + // 顶级目录
|
||||
"src/" + path;
|
||||
}
|
||||
|
||||
private static String vue3VbenTemplatePath(String path) {
|
||||
return "codegen/vue3_vben/" + path + ".vm";
|
||||
}
|
||||
|
||||
private static String vue3Vben5AntdSchemaTemplatePath(String path) {
|
||||
return "codegen/vue3_vben5_antd/schema/" + path + ".vm";
|
||||
}
|
||||
|
||||
private static String vue3Vben5AntdGeneralTemplatePath(String path) {
|
||||
return "codegen/vue3_vben5_antd/general/" + path + ".vm";
|
||||
}
|
||||
|
||||
private static String vue3Vben5EpSchemaTemplatePath(String path) {
|
||||
return "codegen/vue3_vben5_ele/schema/" + path + ".vm";
|
||||
}
|
||||
|
||||
private static String vue3Vben5EpGeneralTemplatePath(String path) {
|
||||
return "codegen/vue3_vben5_ele/general/" + path + ".vm";
|
||||
}
|
||||
|
||||
private static boolean isSubTemplate(String path) {
|
||||
return path.contains("_sub");
|
||||
}
|
||||
|
||||
private static boolean isPageReqVOTemplate(String path) {
|
||||
return path.contains("pageReqVO");
|
||||
}
|
||||
|
||||
private static boolean isListReqVOTemplate(String path) {
|
||||
return path.contains("listReqVO");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
package com.njcn.rdms.module.system.service.db;
|
||||
|
||||
import com.njcn.rdms.module.system.controller.admin.db.vo.DataSourceConfigSaveReqVO;
|
||||
import com.njcn.rdms.module.system.dal.dataobject.db.DataSourceConfigDO;
|
||||
import jakarta.validation.Valid;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 数据源配置 Service 接口
|
||||
*
|
||||
* @author hongawen
|
||||
*/
|
||||
public interface DataSourceConfigService {
|
||||
|
||||
/**
|
||||
* 创建数据源配置
|
||||
*
|
||||
* @param createReqVO 创建信息
|
||||
* @return 编号
|
||||
*/
|
||||
Long createDataSourceConfig(@Valid DataSourceConfigSaveReqVO createReqVO);
|
||||
|
||||
/**
|
||||
* 更新数据源配置
|
||||
*
|
||||
* @param updateReqVO 更新信息
|
||||
*/
|
||||
void updateDataSourceConfig(@Valid DataSourceConfigSaveReqVO updateReqVO);
|
||||
|
||||
/**
|
||||
* 删除数据源配置
|
||||
*
|
||||
* @param id 编号
|
||||
*/
|
||||
void deleteDataSourceConfig(Long id);
|
||||
|
||||
/**
|
||||
* 批量删除数据源配置
|
||||
*
|
||||
* @param ids 编号列表
|
||||
*/
|
||||
void deleteDataSourceConfigList(List<Long> ids);
|
||||
|
||||
/**
|
||||
* 获得数据源配置
|
||||
*
|
||||
* @param id 编号
|
||||
* @return 数据源配置
|
||||
*/
|
||||
DataSourceConfigDO getDataSourceConfig(Long id);
|
||||
|
||||
/**
|
||||
* 获得数据源配置列表
|
||||
*
|
||||
* @return 数据源配置列表
|
||||
*/
|
||||
List<DataSourceConfigDO> getDataSourceConfigList();
|
||||
|
||||
}
|
||||
@@ -1,111 +0,0 @@
|
||||
package com.njcn.rdms.module.system.service.db;
|
||||
|
||||
import com.baomidou.dynamic.datasource.creator.DataSourceProperty;
|
||||
import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DynamicDataSourceProperties;
|
||||
import com.njcn.rdms.framework.common.util.object.BeanUtils;
|
||||
import com.njcn.rdms.framework.mybatis.core.util.JdbcUtils;
|
||||
import com.njcn.rdms.module.system.controller.admin.db.vo.DataSourceConfigSaveReqVO;
|
||||
import com.njcn.rdms.module.system.dal.dataobject.db.DataSourceConfigDO;
|
||||
import com.njcn.rdms.module.system.dal.mysql.db.DataSourceConfigMapper;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import static com.njcn.rdms.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static com.njcn.rdms.module.system.enums.ErrorCodeConstants.DATA_SOURCE_CONFIG_NOT_EXISTS;
|
||||
import static com.njcn.rdms.module.system.enums.ErrorCodeConstants.DATA_SOURCE_CONFIG_NOT_OK;
|
||||
|
||||
/**
|
||||
* 数据源配置 Service 实现类
|
||||
*
|
||||
* @author hongawen
|
||||
*/
|
||||
@Service
|
||||
@Validated
|
||||
public class DataSourceConfigServiceImpl implements DataSourceConfigService {
|
||||
|
||||
@Resource
|
||||
private DataSourceConfigMapper dataSourceConfigMapper;
|
||||
|
||||
@Resource
|
||||
private DynamicDataSourceProperties dynamicDataSourceProperties;
|
||||
|
||||
@Override
|
||||
public Long createDataSourceConfig(DataSourceConfigSaveReqVO createReqVO) {
|
||||
DataSourceConfigDO config = BeanUtils.toBean(createReqVO, DataSourceConfigDO.class);
|
||||
validateConnectionOK(config);
|
||||
|
||||
// 插入
|
||||
dataSourceConfigMapper.insert(config);
|
||||
// 返回
|
||||
return config.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateDataSourceConfig(DataSourceConfigSaveReqVO updateReqVO) {
|
||||
// 校验存在
|
||||
validateDataSourceConfigExists(updateReqVO.getId());
|
||||
DataSourceConfigDO updateObj = BeanUtils.toBean(updateReqVO, DataSourceConfigDO.class);
|
||||
validateConnectionOK(updateObj);
|
||||
|
||||
// 更新
|
||||
dataSourceConfigMapper.updateById(updateObj);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteDataSourceConfig(Long id) {
|
||||
// 校验存在
|
||||
validateDataSourceConfigExists(id);
|
||||
// 删除
|
||||
dataSourceConfigMapper.deleteById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteDataSourceConfigList(List<Long> ids) {
|
||||
dataSourceConfigMapper.deleteByIds(ids);
|
||||
}
|
||||
|
||||
private void validateDataSourceConfigExists(Long id) {
|
||||
if (dataSourceConfigMapper.selectById(id) == null) {
|
||||
throw exception(DATA_SOURCE_CONFIG_NOT_EXISTS);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataSourceConfigDO getDataSourceConfig(Long id) {
|
||||
// 如果 id 为 0,默认为 master 的数据源
|
||||
if (Objects.equals(id, DataSourceConfigDO.ID_MASTER)) {
|
||||
return buildMasterDataSourceConfig();
|
||||
}
|
||||
// 从 DB 中读取
|
||||
return dataSourceConfigMapper.selectById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DataSourceConfigDO> getDataSourceConfigList() {
|
||||
List<DataSourceConfigDO> result = dataSourceConfigMapper.selectList();
|
||||
// 补充 master 数据源
|
||||
result.add(0, buildMasterDataSourceConfig());
|
||||
return result;
|
||||
}
|
||||
|
||||
private void validateConnectionOK(DataSourceConfigDO config) {
|
||||
boolean success = JdbcUtils.isConnectionOK(config.getUrl(), config.getUsername(), config.getPassword());
|
||||
if (!success) {
|
||||
throw exception(DATA_SOURCE_CONFIG_NOT_OK);
|
||||
}
|
||||
}
|
||||
|
||||
private DataSourceConfigDO buildMasterDataSourceConfig() {
|
||||
String primary = dynamicDataSourceProperties.getPrimary();
|
||||
DataSourceProperty dataSourceProperty = dynamicDataSourceProperties.getDatasource().get(primary);
|
||||
return new DataSourceConfigDO().setId(DataSourceConfigDO.ID_MASTER).setName(primary)
|
||||
.setUrl(dataSourceProperty.getUrl())
|
||||
.setUsername(dataSourceProperty.getUsername())
|
||||
.setPassword(dataSourceProperty.getPassword());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
package com.njcn.rdms.module.system.service.db;
|
||||
|
||||
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 数据库表 Service
|
||||
*
|
||||
* @author hongawen
|
||||
*/
|
||||
public interface DatabaseTableService {
|
||||
|
||||
/**
|
||||
* 获得表列表,基于表名称 + 表描述进行模糊匹配
|
||||
*
|
||||
* @param dataSourceConfigId 数据源配置的编号
|
||||
* @param nameLike 表名称,模糊匹配
|
||||
* @param commentLike 表描述,模糊匹配
|
||||
* @return 表列表
|
||||
*/
|
||||
List<TableInfo> getTableList(Long dataSourceConfigId, String nameLike, String commentLike);
|
||||
|
||||
/**
|
||||
* 获得指定表名
|
||||
*
|
||||
* @param dataSourceConfigId 数据源配置的编号
|
||||
* @param tableName 表名称
|
||||
* @return 表
|
||||
*/
|
||||
TableInfo getTable(Long dataSourceConfigId, String tableName);
|
||||
|
||||
}
|
||||
@@ -1,77 +0,0 @@
|
||||
package com.njcn.rdms.module.system.service.db;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
|
||||
import com.baomidou.mybatisplus.generator.config.GlobalConfig;
|
||||
import com.baomidou.mybatisplus.generator.config.StrategyConfig;
|
||||
import com.baomidou.mybatisplus.generator.config.builder.ConfigBuilder;
|
||||
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
|
||||
import com.baomidou.mybatisplus.generator.config.rules.DateType;
|
||||
import com.baomidou.mybatisplus.generator.query.SQLQuery;
|
||||
import com.njcn.rdms.framework.mybatis.core.util.JdbcUtils;
|
||||
import com.njcn.rdms.module.system.dal.dataobject.db.DataSourceConfigDO;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 数据库表 Service 实现类
|
||||
*
|
||||
* @author hongawen
|
||||
*/
|
||||
@Service
|
||||
public class DatabaseTableServiceImpl implements DatabaseTableService {
|
||||
|
||||
@Resource
|
||||
private DataSourceConfigService dataSourceConfigService;
|
||||
|
||||
@Override
|
||||
public List<TableInfo> getTableList(Long dataSourceConfigId, String nameLike, String commentLike) {
|
||||
List<TableInfo> tables = getTableList0(dataSourceConfigId, null);
|
||||
return tables.stream().filter(tableInfo -> (StrUtil.isEmpty(nameLike) || tableInfo.getName().contains(nameLike))
|
||||
&& (StrUtil.isEmpty(commentLike) || tableInfo.getComment().contains(commentLike)))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public TableInfo getTable(Long dataSourceConfigId, String name) {
|
||||
return CollUtil.getFirst(getTableList0(dataSourceConfigId, name));
|
||||
}
|
||||
|
||||
private List<TableInfo> getTableList0(Long dataSourceConfigId, String name) {
|
||||
// 获得数据源配置
|
||||
DataSourceConfigDO config = dataSourceConfigService.getDataSourceConfig(dataSourceConfigId);
|
||||
Assert.notNull(config, "数据源({}) 不存在!", dataSourceConfigId);
|
||||
|
||||
// 使用 MyBatis Plus Generator 解析表结构
|
||||
DataSourceConfig.Builder dataSourceConfigBuilder = new DataSourceConfig.Builder(config.getUrl(), config.getUsername(),
|
||||
config.getPassword());
|
||||
if (JdbcUtils.isSQLServer(config.getUrl())) { // 特殊:SQLServer jdbc 非标准,参见 https://github.com/baomidou/mybatis-plus/issues/5419
|
||||
dataSourceConfigBuilder.databaseQueryClass(SQLQuery.class);
|
||||
}
|
||||
StrategyConfig.Builder strategyConfig = new StrategyConfig.Builder().enableSkipView(); // 忽略视图,业务上一般用不到
|
||||
if (StrUtil.isNotEmpty(name)) {
|
||||
strategyConfig.addInclude(name);
|
||||
} else {
|
||||
// 移除工作流和定时任务前缀的表名
|
||||
strategyConfig.addExclude("ACT_[\\S\\s]+|QRTZ_[\\S\\s]+|FLW_[\\S\\s]+|act_[\\S\\s]+|qrtz_[\\S\\s]+|flw_[\\S\\s]+");
|
||||
// 移除 ORACLE 相关的系统表
|
||||
strategyConfig.addExclude("IMPDP_[\\S\\s]+|ALL_[\\S\\s]+|HS_[\\S\\s]+|impdp_[\\S\\s]+|all_[\\S\\s]+|hs_[\\S\\s]+");
|
||||
strategyConfig.addExclude("[\\S\\s]+\\$[\\S\\s]+|[\\S\\s]+\\$"); // 表里不能有 $,一般有都是系统的表
|
||||
}
|
||||
|
||||
GlobalConfig globalConfig = new GlobalConfig.Builder().dateType(DateType.TIME_PACK).build(); // 只使用 LocalDateTime 类型,不使用 LocalDate
|
||||
ConfigBuilder builder = new ConfigBuilder(null, dataSourceConfigBuilder.build(), strategyConfig.build(),
|
||||
null, globalConfig, null);
|
||||
// 按照名字排序
|
||||
List<TableInfo> tables = builder.getTableInfoList();
|
||||
tables.sort(Comparator.comparing(TableInfo::getName));
|
||||
return tables;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.njcn.rdms.module.system.service.logger;
|
||||
|
||||
import com.njcn.rdms.framework.common.biz.infra.logger.dto.ApiAccessLogCreateReqDTO;
|
||||
import com.njcn.rdms.framework.common.biz.system.logger.dto.ApiAccessLogCreateReqDTO;
|
||||
import com.njcn.rdms.framework.common.pojo.PageResult;
|
||||
import com.njcn.rdms.module.system.controller.admin.logger.vo.apiaccesslog.ApiAccessLogPageReqVO;
|
||||
import com.njcn.rdms.module.system.dal.dataobject.logger.ApiAccessLogDO;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.njcn.rdms.module.system.service.logger;
|
||||
|
||||
import com.njcn.rdms.framework.common.biz.infra.logger.dto.ApiAccessLogCreateReqDTO;
|
||||
import com.njcn.rdms.framework.common.biz.system.logger.dto.ApiAccessLogCreateReqDTO;
|
||||
import com.njcn.rdms.framework.common.pojo.PageResult;
|
||||
import com.njcn.rdms.framework.common.util.object.BeanUtils;
|
||||
import com.njcn.rdms.framework.common.util.string.StrUtils;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.njcn.rdms.module.system.service.logger;
|
||||
|
||||
import com.njcn.rdms.framework.common.biz.infra.logger.dto.ApiErrorLogCreateReqDTO;
|
||||
import com.njcn.rdms.framework.common.biz.system.logger.dto.ApiErrorLogCreateReqDTO;
|
||||
import com.njcn.rdms.framework.common.pojo.PageResult;
|
||||
import com.njcn.rdms.module.system.controller.admin.logger.vo.apierrorlog.ApiErrorLogPageReqVO;
|
||||
import com.njcn.rdms.module.system.dal.dataobject.logger.ApiErrorLogDO;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.njcn.rdms.module.system.service.logger;
|
||||
|
||||
import com.njcn.rdms.framework.common.biz.infra.logger.dto.ApiErrorLogCreateReqDTO;
|
||||
import com.njcn.rdms.framework.common.biz.system.logger.dto.ApiErrorLogCreateReqDTO;
|
||||
import com.njcn.rdms.framework.common.pojo.PageResult;
|
||||
import com.njcn.rdms.framework.common.util.object.BeanUtils;
|
||||
import com.njcn.rdms.framework.common.util.string.StrUtils;
|
||||
|
||||
@@ -1,79 +0,0 @@
|
||||
package com.njcn.rdms.module.system.service.mail;
|
||||
|
||||
import com.njcn.rdms.framework.common.pojo.PageResult;
|
||||
import com.njcn.rdms.module.system.controller.admin.mail.vo.account.MailAccountPageReqVO;
|
||||
import com.njcn.rdms.module.system.controller.admin.mail.vo.account.MailAccountSaveReqVO;
|
||||
import com.njcn.rdms.module.system.dal.dataobject.mail.MailAccountDO;
|
||||
import jakarta.validation.Valid;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 邮箱账号 Service 接口
|
||||
*
|
||||
* @author hongawen
|
||||
*
|
||||
*/
|
||||
public interface MailAccountService {
|
||||
|
||||
/**
|
||||
* 创建邮箱账号
|
||||
*
|
||||
* @param createReqVO 邮箱账号信息
|
||||
* @return 编号
|
||||
*/
|
||||
Long createMailAccount(@Valid MailAccountSaveReqVO createReqVO);
|
||||
|
||||
/**
|
||||
* 修改邮箱账号
|
||||
*
|
||||
* @param updateReqVO 邮箱账号信息
|
||||
*/
|
||||
void updateMailAccount(@Valid MailAccountSaveReqVO updateReqVO);
|
||||
|
||||
/**
|
||||
* 删除邮箱账号
|
||||
*
|
||||
* @param id 编号
|
||||
*/
|
||||
void deleteMailAccount(Long id);
|
||||
|
||||
/**
|
||||
* 批量删除邮箱账号
|
||||
*
|
||||
* @param ids 编号列表
|
||||
*/
|
||||
void deleteMailAccountList(List<Long> ids);
|
||||
|
||||
/**
|
||||
* 获取邮箱账号信息
|
||||
*
|
||||
* @param id 编号
|
||||
* @return 邮箱账号信息
|
||||
*/
|
||||
MailAccountDO getMailAccount(Long id);
|
||||
|
||||
/**
|
||||
* 从缓存中获取邮箱账号
|
||||
*
|
||||
* @param id 编号
|
||||
* @return 邮箱账号
|
||||
*/
|
||||
MailAccountDO getMailAccountFromCache(Long id);
|
||||
|
||||
/**
|
||||
* 获取邮箱账号分页信息
|
||||
*
|
||||
* @param pageReqVO 邮箱账号分页参数
|
||||
* @return 邮箱账号分页信息
|
||||
*/
|
||||
PageResult<MailAccountDO> getMailAccountPage(MailAccountPageReqVO pageReqVO);
|
||||
|
||||
/**
|
||||
* 获取邮箱数组信息
|
||||
*
|
||||
* @return 邮箱账号信息数组
|
||||
*/
|
||||
List<MailAccountDO> getMailAccountList();
|
||||
|
||||
}
|
||||
@@ -1,114 +0,0 @@
|
||||
package com.njcn.rdms.module.system.service.mail;
|
||||
|
||||
import com.njcn.rdms.framework.common.pojo.PageResult;
|
||||
import com.njcn.rdms.framework.common.util.object.BeanUtils;
|
||||
import com.njcn.rdms.module.system.controller.admin.mail.vo.account.MailAccountPageReqVO;
|
||||
import com.njcn.rdms.module.system.controller.admin.mail.vo.account.MailAccountSaveReqVO;
|
||||
import com.njcn.rdms.module.system.dal.dataobject.mail.MailAccountDO;
|
||||
import com.njcn.rdms.module.system.dal.mysql.mail.MailAccountMapper;
|
||||
import com.njcn.rdms.module.system.dal.redis.RedisKeyConstants;
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.cache.annotation.CacheEvict;
|
||||
import org.springframework.cache.annotation.Cacheable;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static com.njcn.rdms.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static com.njcn.rdms.module.system.enums.ErrorCodeConstants.MAIL_ACCOUNT_NOT_EXISTS;
|
||||
import static com.njcn.rdms.module.system.enums.ErrorCodeConstants.MAIL_ACCOUNT_RELATE_TEMPLATE_EXISTS;
|
||||
|
||||
/**
|
||||
* 邮箱账号 Service 实现类
|
||||
*
|
||||
* @author hongawen
|
||||
*
|
||||
*/
|
||||
@Service
|
||||
@Validated
|
||||
@Slf4j
|
||||
public class MailAccountServiceImpl implements MailAccountService {
|
||||
|
||||
@Resource
|
||||
private MailAccountMapper mailAccountMapper;
|
||||
|
||||
@Resource
|
||||
private MailTemplateService mailTemplateService;
|
||||
|
||||
@Override
|
||||
public Long createMailAccount(MailAccountSaveReqVO createReqVO) {
|
||||
MailAccountDO account = BeanUtils.toBean(createReqVO, MailAccountDO.class);
|
||||
mailAccountMapper.insert(account);
|
||||
return account.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
@CacheEvict(value = RedisKeyConstants.MAIL_ACCOUNT, key = "#updateReqVO.id")
|
||||
public void updateMailAccount(MailAccountSaveReqVO updateReqVO) {
|
||||
// 校验是否存在
|
||||
validateMailAccountExists(updateReqVO.getId());
|
||||
|
||||
// 更新
|
||||
MailAccountDO updateObj = BeanUtils.toBean(updateReqVO, MailAccountDO.class);
|
||||
mailAccountMapper.updateById(updateObj);
|
||||
}
|
||||
|
||||
@Override
|
||||
@CacheEvict(value = RedisKeyConstants.MAIL_ACCOUNT, key = "#id")
|
||||
public void deleteMailAccount(Long id) {
|
||||
// 校验是否存在账号
|
||||
validateMailAccountExists(id);
|
||||
// 校验是否存在关联模版
|
||||
if (mailTemplateService.getMailTemplateCountByAccountId(id) > 0) {
|
||||
throw exception(MAIL_ACCOUNT_RELATE_TEMPLATE_EXISTS);
|
||||
}
|
||||
|
||||
// 删除
|
||||
mailAccountMapper.deleteById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
@CacheEvict(value = RedisKeyConstants.MAIL_ACCOUNT,
|
||||
allEntries = true) // allEntries 清空所有缓存,因为 Spring Cache 不支持按照 ids 批量删除
|
||||
public void deleteMailAccountList(List<Long> ids) {
|
||||
// 1. 校验是否存在关联模版
|
||||
for (Long id : ids) {
|
||||
if (mailTemplateService.getMailTemplateCountByAccountId(id) > 0) {
|
||||
throw exception(MAIL_ACCOUNT_RELATE_TEMPLATE_EXISTS);
|
||||
}
|
||||
}
|
||||
|
||||
// 2. 批量删除
|
||||
mailAccountMapper.deleteByIds(ids);
|
||||
}
|
||||
|
||||
private void validateMailAccountExists(Long id) {
|
||||
if (mailAccountMapper.selectById(id) == null) {
|
||||
throw exception(MAIL_ACCOUNT_NOT_EXISTS);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public MailAccountDO getMailAccount(Long id) {
|
||||
return mailAccountMapper.selectById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Cacheable(value = RedisKeyConstants.MAIL_ACCOUNT, key = "#id", unless = "#result == null")
|
||||
public MailAccountDO getMailAccountFromCache(Long id) {
|
||||
return getMailAccount(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageResult<MailAccountDO> getMailAccountPage(MailAccountPageReqVO pageReqVO) {
|
||||
return mailAccountMapper.selectPage(pageReqVO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<MailAccountDO> getMailAccountList() {
|
||||
return mailAccountMapper.selectList();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,66 +0,0 @@
|
||||
package com.njcn.rdms.module.system.service.mail;
|
||||
|
||||
import com.njcn.rdms.framework.common.pojo.PageResult;
|
||||
import com.njcn.rdms.module.system.controller.admin.mail.vo.log.MailLogPageReqVO;
|
||||
import com.njcn.rdms.module.system.dal.dataobject.mail.MailAccountDO;
|
||||
import com.njcn.rdms.module.system.dal.dataobject.mail.MailLogDO;
|
||||
import com.njcn.rdms.module.system.dal.dataobject.mail.MailTemplateDO;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 邮件日志 Service 接口
|
||||
*
|
||||
* @author hongawen
|
||||
*
|
||||
*/
|
||||
public interface MailLogService {
|
||||
|
||||
/**
|
||||
* 邮件日志分页
|
||||
*
|
||||
* @param pageVO 分页参数
|
||||
* @return 分页结果
|
||||
*/
|
||||
PageResult<MailLogDO> getMailLogPage(MailLogPageReqVO pageVO);
|
||||
|
||||
/**
|
||||
* 获得指定编号的邮件日志
|
||||
*
|
||||
* @param id 日志编号
|
||||
* @return 邮件日志
|
||||
*/
|
||||
MailLogDO getMailLog(Long id);
|
||||
|
||||
/**
|
||||
* 创建邮件日志
|
||||
*
|
||||
* @param userId 用户编码
|
||||
* @param userType 用户类型
|
||||
* @param toMails 收件人邮件
|
||||
* @param ccMails 收件人邮件
|
||||
* @param bccMails 收件人邮件
|
||||
* @param account 邮件账号信息
|
||||
* @param template 模版信息
|
||||
* @param templateContent 模版内容
|
||||
* @param templateParams 模版参数
|
||||
* @param isSend 是否发送成功
|
||||
* @return 日志编号
|
||||
*/
|
||||
Long createMailLog(Long userId, Integer userType,
|
||||
Collection<String> toMails, Collection<String> ccMails, Collection<String> bccMails,
|
||||
MailAccountDO account, MailTemplateDO template,
|
||||
String templateContent, Map<String, Object> templateParams, Boolean isSend);
|
||||
|
||||
/**
|
||||
* 更新邮件发送结果
|
||||
*
|
||||
* @param logId 日志编号
|
||||
* @param messageId 发送后的消息编号
|
||||
* @param exception 发送异常
|
||||
*/
|
||||
void updateMailSendResult(Long logId, String messageId, Exception exception);
|
||||
|
||||
}
|
||||
@@ -1,80 +0,0 @@
|
||||
package com.njcn.rdms.module.system.service.mail;
|
||||
|
||||
import cn.hutool.core.collection.ListUtil;
|
||||
import com.njcn.rdms.framework.common.pojo.PageResult;
|
||||
import com.njcn.rdms.module.system.controller.admin.mail.vo.log.MailLogPageReqVO;
|
||||
import com.njcn.rdms.module.system.dal.dataobject.mail.MailAccountDO;
|
||||
import com.njcn.rdms.module.system.dal.dataobject.mail.MailLogDO;
|
||||
import com.njcn.rdms.module.system.dal.dataobject.mail.MailTemplateDO;
|
||||
import com.njcn.rdms.module.system.dal.mysql.mail.MailLogMapper;
|
||||
import com.njcn.rdms.module.system.enums.mail.MailSendStatusEnum;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.*;
|
||||
|
||||
import static cn.hutool.core.exceptions.ExceptionUtil.getRootCauseMessage;
|
||||
|
||||
/**
|
||||
* 邮件日志 Service 实现类
|
||||
*
|
||||
* @author hongawen
|
||||
*
|
||||
*/
|
||||
@Service
|
||||
@Validated
|
||||
public class MailLogServiceImpl implements MailLogService {
|
||||
|
||||
@Resource
|
||||
private MailLogMapper mailLogMapper;
|
||||
|
||||
@Override
|
||||
public PageResult<MailLogDO> getMailLogPage(MailLogPageReqVO pageVO) {
|
||||
return mailLogMapper.selectPage(pageVO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MailLogDO getMailLog(Long id) {
|
||||
return mailLogMapper.selectById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long createMailLog(Long userId, Integer userType,
|
||||
Collection<String> toMails, Collection<String> ccMails, Collection<String> bccMails,
|
||||
MailAccountDO account, MailTemplateDO template,
|
||||
String templateContent, Map<String, Object> templateParams, Boolean isSend) {
|
||||
MailLogDO.MailLogDOBuilder logDOBuilder = MailLogDO.builder();
|
||||
// 根据是否要发送,设置状态
|
||||
logDOBuilder.sendStatus(Objects.equals(isSend, true) ? MailSendStatusEnum.INIT.getStatus()
|
||||
: MailSendStatusEnum.IGNORE.getStatus())
|
||||
// 用户信息
|
||||
.userId(userId).userType(userType)
|
||||
.toMails(ListUtil.toList(toMails)).ccMails(ListUtil.toList(ccMails)).bccMails(ListUtil.toList(bccMails))
|
||||
.accountId(account.getId()).fromMail(account.getMail())
|
||||
// 模板相关字段
|
||||
.templateId(template.getId()).templateCode(template.getCode()).templateNickname(template.getNickname())
|
||||
.templateTitle(template.getTitle()).templateContent(templateContent).templateParams(templateParams);
|
||||
|
||||
// 插入数据库
|
||||
MailLogDO logDO = logDOBuilder.build();
|
||||
mailLogMapper.insert(logDO);
|
||||
return logDO.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateMailSendResult(Long logId, String messageId, Exception exception) {
|
||||
// 1. 成功
|
||||
if (exception == null) {
|
||||
mailLogMapper.updateById(new MailLogDO().setId(logId).setSendTime(LocalDateTime.now())
|
||||
.setSendStatus(MailSendStatusEnum.SUCCESS.getStatus()).setSendMessageId(messageId));
|
||||
return;
|
||||
}
|
||||
// 2. 失败
|
||||
mailLogMapper.updateById(new MailLogDO().setId(logId).setSendTime(LocalDateTime.now())
|
||||
.setSendStatus(MailSendStatusEnum.FAILURE.getStatus()).setSendException(getRootCauseMessage(exception)));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,84 +0,0 @@
|
||||
package com.njcn.rdms.module.system.service.mail;
|
||||
|
||||
import com.njcn.rdms.framework.common.enums.UserTypeEnum;
|
||||
import com.njcn.rdms.module.system.mq.message.mail.MailSendMessage;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 邮件发送 Service 接口
|
||||
*
|
||||
* @author hongawen
|
||||
*
|
||||
*/
|
||||
public interface MailSendService {
|
||||
|
||||
/**
|
||||
* 发送单条邮件给管理后台的用户
|
||||
*
|
||||
* @param userId 用户编码
|
||||
* @param toMails 收件邮箱
|
||||
* @param ccMails 抄送邮箱
|
||||
* @param bccMails 密送邮箱
|
||||
* @param templateCode 邮件模版编码
|
||||
* @param templateParams 邮件模版参数
|
||||
* @param attachments 附件
|
||||
* @return 发送日志编号
|
||||
*/
|
||||
default Long sendSingleMailToAdmin(Long userId,
|
||||
Collection<String> toMails, Collection<String> ccMails, Collection<String> bccMails,
|
||||
String templateCode, Map<String, Object> templateParams,
|
||||
File... attachments) {
|
||||
return sendSingleMail(toMails, ccMails, bccMails, userId, UserTypeEnum.ADMIN.getValue(),
|
||||
templateCode, templateParams, attachments);
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送单条邮件给用户 APP 的用户
|
||||
*
|
||||
* @param userId 用户编码
|
||||
* @param toMails 收件邮箱
|
||||
* @param ccMails 抄送邮箱
|
||||
* @param bccMails 密送邮箱
|
||||
* @param templateCode 邮件模版编码
|
||||
* @param templateParams 邮件模版参数
|
||||
* @param attachments 附件
|
||||
* @return 发送日志编号
|
||||
*/
|
||||
default Long sendSingleMailToMember(Long userId,
|
||||
Collection<String> toMails, Collection<String> ccMails, Collection<String> bccMails,
|
||||
String templateCode, Map<String, Object> templateParams,
|
||||
File... attachments) {
|
||||
return sendSingleMail(toMails, ccMails, bccMails, userId, UserTypeEnum.MEMBER.getValue(),
|
||||
templateCode, templateParams, attachments);
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送单条邮件
|
||||
*
|
||||
* @param toMails 收件邮箱
|
||||
* @param ccMails 抄送邮箱
|
||||
* @param bccMails 密送邮箱
|
||||
* @param userId 用户编号
|
||||
* @param userType 用户类型
|
||||
* @param templateCode 邮件模版编码
|
||||
* @param templateParams 邮件模版参数
|
||||
* @param attachments 附件
|
||||
* @return 发送日志编号
|
||||
*/
|
||||
Long sendSingleMail(Collection<String> toMails, Collection<String> ccMails, Collection<String> bccMails,
|
||||
Long userId, Integer userType,
|
||||
String templateCode, Map<String, Object> templateParams,
|
||||
File... attachments);
|
||||
|
||||
/**
|
||||
* 执行真正的邮件发送
|
||||
* 注意,该方法仅仅提供给 MQ Consumer 使用
|
||||
*
|
||||
* @param message 邮件
|
||||
*/
|
||||
void doSendMail(MailSendMessage message);
|
||||
|
||||
}
|
||||
@@ -1,183 +0,0 @@
|
||||
package com.njcn.rdms.module.system.service.mail;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.lang.Validator;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.njcn.rdms.framework.common.enums.CommonStatusEnum;
|
||||
import com.njcn.rdms.framework.common.enums.UserTypeEnum;
|
||||
import com.njcn.rdms.module.system.dal.dataobject.mail.MailAccountDO;
|
||||
import com.njcn.rdms.module.system.dal.dataobject.mail.MailTemplateDO;
|
||||
import com.njcn.rdms.module.system.dal.dataobject.user.AdminUserDO;
|
||||
import com.njcn.rdms.module.system.mq.message.mail.MailSendMessage;
|
||||
import com.njcn.rdms.module.system.mq.producer.mail.MailProducer;
|
||||
import com.njcn.rdms.module.system.service.member.MemberService;
|
||||
import com.njcn.rdms.module.system.service.user.AdminUserService;
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.dromara.hutool.extra.mail.MailAccount;
|
||||
import org.dromara.hutool.extra.mail.MailUtil;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Map;
|
||||
|
||||
import static com.njcn.rdms.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static com.njcn.rdms.module.system.enums.ErrorCodeConstants.*;
|
||||
|
||||
/**
|
||||
* 邮箱发送 Service 实现类
|
||||
*
|
||||
* @author hongawen
|
||||
*
|
||||
*/
|
||||
@Service
|
||||
@Validated
|
||||
@Slf4j
|
||||
public class MailSendServiceImpl implements MailSendService {
|
||||
|
||||
@Resource
|
||||
private AdminUserService adminUserService;
|
||||
@Resource
|
||||
private MemberService memberService;
|
||||
|
||||
@Resource
|
||||
private MailAccountService mailAccountService;
|
||||
@Resource
|
||||
private MailTemplateService mailTemplateService;
|
||||
|
||||
@Resource
|
||||
private MailLogService mailLogService;
|
||||
@Resource
|
||||
private MailProducer mailProducer;
|
||||
|
||||
@Override
|
||||
public Long sendSingleMail(Collection<String> toMails, Collection<String> ccMails, Collection<String> bccMails,
|
||||
Long userId, Integer userType,
|
||||
String templateCode, Map<String, Object> templateParams,
|
||||
File... attachments) {
|
||||
// 1.1 校验邮箱模版是否合法
|
||||
MailTemplateDO template = validateMailTemplate(templateCode);
|
||||
// 1.2 校验邮箱账号是否合法
|
||||
MailAccountDO account = validateMailAccount(template.getAccountId());
|
||||
// 1.3 校验邮件参数是否缺失
|
||||
validateTemplateParams(template, templateParams);
|
||||
|
||||
// 2. 组装邮箱
|
||||
String userMail = getUserMail(userId, userType);
|
||||
Collection<String> toMailSet = new LinkedHashSet<>();
|
||||
Collection<String> ccMailSet = new LinkedHashSet<>();
|
||||
Collection<String> bccMailSet = new LinkedHashSet<>();
|
||||
if (Validator.isEmail(userMail)) {
|
||||
toMailSet.add(userMail);
|
||||
}
|
||||
if (CollUtil.isNotEmpty(toMails)) {
|
||||
toMails.stream().filter(Validator::isEmail).forEach(toMailSet::add);
|
||||
}
|
||||
if (CollUtil.isNotEmpty(ccMails)) {
|
||||
ccMails.stream().filter(Validator::isEmail).forEach(ccMailSet::add);
|
||||
}
|
||||
if (CollUtil.isNotEmpty(bccMails)) {
|
||||
bccMails.stream().filter(Validator::isEmail).forEach(bccMailSet::add);
|
||||
}
|
||||
if (CollUtil.isEmpty(toMailSet)) {
|
||||
throw exception(MAIL_SEND_MAIL_NOT_EXISTS);
|
||||
}
|
||||
|
||||
// 创建发送日志。如果模板被禁用,则不发送邮件,只记录日志
|
||||
Boolean isSend = CommonStatusEnum.ENABLE.getStatus().equals(template.getStatus());
|
||||
String title = mailTemplateService.formatMailTemplateContent(template.getTitle(), templateParams);
|
||||
String content = mailTemplateService.formatMailTemplateContent(template.getContent(), templateParams);
|
||||
Long sendLogId = mailLogService.createMailLog(userId, userType, toMailSet, ccMailSet, bccMailSet,
|
||||
account, template, content, templateParams, isSend);
|
||||
// 发送 MQ 消息,异步执行发送邮件
|
||||
if (isSend) {
|
||||
mailProducer.sendMailSendMessage(sendLogId, toMailSet, ccMailSet, bccMailSet,
|
||||
account.getId(), template.getNickname(), title, content, attachments);
|
||||
}
|
||||
return sendLogId;
|
||||
}
|
||||
|
||||
private String getUserMail(Long userId, Integer userType) {
|
||||
if (userId == null || userType == null) {
|
||||
return null;
|
||||
}
|
||||
if (UserTypeEnum.ADMIN.getValue().equals(userType)) {
|
||||
AdminUserDO user = adminUserService.getUser(userId);
|
||||
if (user != null) {
|
||||
return user.getEmail();
|
||||
}
|
||||
}
|
||||
if (UserTypeEnum.MEMBER.getValue().equals(userType)) {
|
||||
return memberService.getMemberUserEmail(userId);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doSendMail(MailSendMessage message) {
|
||||
// 1. 创建发送账号
|
||||
MailAccountDO account = validateMailAccount(message.getAccountId());
|
||||
MailAccount mailAccount = buildMailAccount(account, message.getNickname());
|
||||
// 2. 发送邮件
|
||||
try {
|
||||
String messageId = MailUtil.send(mailAccount, message.getToMails(), message.getCcMails(), message.getBccMails(),
|
||||
message.getTitle(), message.getContent(), true, message.getAttachments());
|
||||
// 3. 更新结果(成功)
|
||||
mailLogService.updateMailSendResult(message.getLogId(), messageId, null);
|
||||
} catch (Exception e) {
|
||||
// 3. 更新结果(异常)
|
||||
mailLogService.updateMailSendResult(message.getLogId(), null, e);
|
||||
}
|
||||
}
|
||||
|
||||
private MailAccount buildMailAccount(MailAccountDO account, String nickname) {
|
||||
String from = StrUtil.isNotEmpty(nickname) ? nickname + " <" + account.getMail() + ">" : account.getMail();
|
||||
return new MailAccount().setFrom(from).setAuth(true)
|
||||
.setUser(account.getUsername()).setPass(account.getPassword().toCharArray())
|
||||
.setHost(account.getHost()).setPort(account.getPort())
|
||||
.setSslEnable(account.getSslEnable()).setStarttlsEnable(account.getStarttlsEnable());
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
MailTemplateDO validateMailTemplate(String templateCode) {
|
||||
// 获得邮件模板。考虑到效率,从缓存中获取
|
||||
MailTemplateDO template = mailTemplateService.getMailTemplateByCodeFromCache(templateCode);
|
||||
// 邮件模板不存在
|
||||
if (template == null) {
|
||||
throw exception(MAIL_TEMPLATE_NOT_EXISTS);
|
||||
}
|
||||
return template;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
MailAccountDO validateMailAccount(Long accountId) {
|
||||
// 获得邮箱账号。考虑到效率,从缓存中获取
|
||||
MailAccountDO account = mailAccountService.getMailAccountFromCache(accountId);
|
||||
// 邮箱账号不存在
|
||||
if (account == null) {
|
||||
throw exception(MAIL_ACCOUNT_NOT_EXISTS);
|
||||
}
|
||||
return account;
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验邮件参数是否缺失
|
||||
*
|
||||
* @param template 邮箱模板
|
||||
* @param templateParams 参数列表
|
||||
*/
|
||||
@VisibleForTesting
|
||||
void validateTemplateParams(MailTemplateDO template, Map<String, Object> templateParams) {
|
||||
template.getParams().forEach(key -> {
|
||||
Object value = templateParams.get(key);
|
||||
if (value == null) {
|
||||
throw exception(MAIL_SEND_TEMPLATE_PARAM_MISS, key);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,97 +0,0 @@
|
||||
package com.njcn.rdms.module.system.service.mail;
|
||||
|
||||
import com.njcn.rdms.framework.common.pojo.PageResult;
|
||||
import com.njcn.rdms.module.system.controller.admin.mail.vo.template.MailTemplatePageReqVO;
|
||||
import com.njcn.rdms.module.system.controller.admin.mail.vo.template.MailTemplateSaveReqVO;
|
||||
import com.njcn.rdms.module.system.dal.dataobject.mail.MailTemplateDO;
|
||||
import jakarta.validation.Valid;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 邮件模版 Service 接口
|
||||
*
|
||||
* @author hongawen
|
||||
*
|
||||
*/
|
||||
public interface MailTemplateService {
|
||||
|
||||
/**
|
||||
* 邮件模版创建
|
||||
*
|
||||
* @param createReqVO 邮件信息
|
||||
* @return 编号
|
||||
*/
|
||||
Long createMailTemplate(@Valid MailTemplateSaveReqVO createReqVO);
|
||||
|
||||
/**
|
||||
* 邮件模版修改
|
||||
*
|
||||
* @param updateReqVO 邮件信息
|
||||
*/
|
||||
void updateMailTemplate(@Valid MailTemplateSaveReqVO updateReqVO);
|
||||
|
||||
/**
|
||||
* 邮件模版删除
|
||||
*
|
||||
* @param id 编号
|
||||
*/
|
||||
void deleteMailTemplate(Long id);
|
||||
|
||||
/**
|
||||
* 批量删除邮件模版
|
||||
*
|
||||
* @param ids 编号列表
|
||||
*/
|
||||
void deleteMailTemplateList(List<Long> ids);
|
||||
|
||||
/**
|
||||
* 获取邮件模版
|
||||
*
|
||||
* @param id 编号
|
||||
* @return 邮件模版
|
||||
*/
|
||||
MailTemplateDO getMailTemplate(Long id);
|
||||
|
||||
/**
|
||||
* 获取邮件模版分页
|
||||
*
|
||||
* @param pageReqVO 模版信息
|
||||
* @return 邮件模版分页信息
|
||||
*/
|
||||
PageResult<MailTemplateDO> getMailTemplatePage(MailTemplatePageReqVO pageReqVO);
|
||||
|
||||
/**
|
||||
* 获取邮件模板数组
|
||||
*
|
||||
* @return 模版数组
|
||||
*/
|
||||
List<MailTemplateDO> getMailTemplateList();
|
||||
|
||||
/**
|
||||
* 从缓存中获取邮件模版
|
||||
*
|
||||
* @param code 模板编码
|
||||
* @return 邮件模板
|
||||
*/
|
||||
MailTemplateDO getMailTemplateByCodeFromCache(String code);
|
||||
|
||||
/**
|
||||
* 邮件模版内容合成
|
||||
*
|
||||
* @param content 邮件模版
|
||||
* @param params 合成参数
|
||||
* @return 格式化后的内容
|
||||
*/
|
||||
String formatMailTemplateContent(String content, Map<String, Object> params);
|
||||
|
||||
/**
|
||||
* 获得指定邮件账号下的邮件模板数量
|
||||
*
|
||||
* @param accountId 账号编号
|
||||
* @return 数量
|
||||
*/
|
||||
long getMailTemplateCountByAccountId(Long accountId);
|
||||
|
||||
}
|
||||
@@ -1,239 +0,0 @@
|
||||
package com.njcn.rdms.module.system.service.mail;
|
||||
|
||||
import cn.hutool.core.util.ObjUtil;
|
||||
import cn.hutool.core.util.ReUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.njcn.rdms.framework.common.pojo.PageResult;
|
||||
import com.njcn.rdms.framework.common.util.object.BeanUtils;
|
||||
import com.njcn.rdms.module.system.controller.admin.mail.vo.template.MailTemplatePageReqVO;
|
||||
import com.njcn.rdms.module.system.controller.admin.mail.vo.template.MailTemplateSaveReqVO;
|
||||
import com.njcn.rdms.module.system.dal.dataobject.mail.MailTemplateDO;
|
||||
import com.njcn.rdms.module.system.dal.mysql.mail.MailTemplateMapper;
|
||||
import com.njcn.rdms.module.system.dal.redis.RedisKeyConstants;
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.validation.Valid;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.cache.annotation.CacheEvict;
|
||||
import org.springframework.cache.annotation.Cacheable;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import static com.njcn.rdms.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static com.njcn.rdms.module.system.enums.ErrorCodeConstants.MAIL_TEMPLATE_CODE_EXISTS;
|
||||
import static com.njcn.rdms.module.system.enums.ErrorCodeConstants.MAIL_TEMPLATE_NOT_EXISTS;
|
||||
|
||||
/**
|
||||
* 邮箱模版 Service 实现类
|
||||
*
|
||||
* @author hongawen
|
||||
*
|
||||
*/
|
||||
@Service
|
||||
@Validated
|
||||
@Slf4j
|
||||
public class MailTemplateServiceImpl implements MailTemplateService {
|
||||
|
||||
/**
|
||||
* 正则表达式,匹配 {} 中的变量
|
||||
*/
|
||||
private static final Pattern PATTERN_PARAMS = Pattern.compile("\\{(.*?)}");
|
||||
|
||||
@Resource
|
||||
private MailTemplateMapper mailTemplateMapper;
|
||||
|
||||
@Override
|
||||
public Long createMailTemplate(MailTemplateSaveReqVO createReqVO) {
|
||||
// 校验 code 是否唯一
|
||||
validateCodeUnique(null, createReqVO.getCode());
|
||||
|
||||
// 插入
|
||||
MailTemplateDO template = BeanUtils.toBean(createReqVO, MailTemplateDO.class)
|
||||
.setParams(parseTemplateTitleAndContentParams(createReqVO.getTitle(), createReqVO.getContent()));
|
||||
mailTemplateMapper.insert(template);
|
||||
return template.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
@CacheEvict(cacheNames = RedisKeyConstants.MAIL_TEMPLATE,
|
||||
allEntries = true) // allEntries 清空所有缓存,因为可能修改到 code 字段,不好清理
|
||||
public void updateMailTemplate(@Valid MailTemplateSaveReqVO updateReqVO) {
|
||||
// 校验是否存在
|
||||
validateMailTemplateExists(updateReqVO.getId());
|
||||
// 校验 code 是否唯一
|
||||
validateCodeUnique(updateReqVO.getId(),updateReqVO.getCode());
|
||||
|
||||
// 更新
|
||||
MailTemplateDO updateObj = BeanUtils.toBean(updateReqVO, MailTemplateDO.class)
|
||||
.setParams(parseTemplateTitleAndContentParams(updateReqVO.getTitle(), updateReqVO.getContent()));
|
||||
mailTemplateMapper.updateById(updateObj);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void validateCodeUnique(Long id, String code) {
|
||||
MailTemplateDO template = mailTemplateMapper.selectByCode(code);
|
||||
if (template == null) {
|
||||
return;
|
||||
}
|
||||
// 存在 template 记录的情况下
|
||||
if (id == null // 新增时,说明重复
|
||||
|| ObjUtil.notEqual(id, template.getId())) { // 更新时,如果 id 不一致,说明重复
|
||||
throw exception(MAIL_TEMPLATE_CODE_EXISTS);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@CacheEvict(cacheNames = RedisKeyConstants.MAIL_TEMPLATE,
|
||||
allEntries = true) // allEntries 清空所有缓存,因为 id 不是直接的缓存 code,不好清理
|
||||
public void deleteMailTemplate(Long id) {
|
||||
// 校验是否存在
|
||||
validateMailTemplateExists(id);
|
||||
|
||||
// 删除
|
||||
mailTemplateMapper.deleteById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
@CacheEvict(cacheNames = RedisKeyConstants.MAIL_TEMPLATE,
|
||||
allEntries = true) // allEntries 清空所有缓存,因为 id 不是直接的缓存 code,不好清理
|
||||
public void deleteMailTemplateList(List<Long> ids) {
|
||||
mailTemplateMapper.deleteByIds(ids);
|
||||
}
|
||||
|
||||
private void validateMailTemplateExists(Long id) {
|
||||
if (mailTemplateMapper.selectById(id) == null) {
|
||||
throw exception(MAIL_TEMPLATE_NOT_EXISTS);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public MailTemplateDO getMailTemplate(Long id) {return mailTemplateMapper.selectById(id);}
|
||||
|
||||
@Override
|
||||
@Cacheable(value = RedisKeyConstants.MAIL_TEMPLATE, key = "#code", unless = "#result == null")
|
||||
public MailTemplateDO getMailTemplateByCodeFromCache(String code) {
|
||||
return mailTemplateMapper.selectByCode(code);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageResult<MailTemplateDO> getMailTemplatePage(MailTemplatePageReqVO pageReqVO) {
|
||||
return mailTemplateMapper.selectPage(pageReqVO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<MailTemplateDO> getMailTemplateList() {return mailTemplateMapper.selectList();}
|
||||
|
||||
@Override
|
||||
public String formatMailTemplateContent(String content, Map<String, Object> params) {
|
||||
// 1. 先替换模板变量
|
||||
String formattedContent = StrUtil.format(content, params);
|
||||
|
||||
// 关联 Pull Request:https://gitee.com/zhijiantianya/ruoyi-vue-pro/pulls/1461 讨论
|
||||
// 2.1 反转义HTML特殊字符
|
||||
formattedContent = unescapeHtml(formattedContent);
|
||||
// 2.2 处理代码块(确保<pre><code>标签格式正确)
|
||||
formattedContent = formatHtmlCodeBlocks(formattedContent);
|
||||
// 2.3 将最外层的 pre 标签替换为 div 标签
|
||||
formattedContent = replaceOuterPreWithDiv(formattedContent);
|
||||
return formattedContent;
|
||||
}
|
||||
|
||||
private String replaceOuterPreWithDiv(String content) {
|
||||
if (StrUtil.isEmpty(content)) {
|
||||
return content;
|
||||
}
|
||||
// 使用正则表达式匹配所有的 <pre> 标签,包括嵌套的 <code> 标签
|
||||
String regex = "(?s)<pre[^>]*>(.*?)</pre>";
|
||||
Pattern pattern = Pattern.compile(regex);
|
||||
Matcher matcher = pattern.matcher(content);
|
||||
StringBuilder sb = new StringBuilder();
|
||||
while (matcher.find()) {
|
||||
// 提取 <pre> 标签内的内容
|
||||
String innerContent = matcher.group(1);
|
||||
// 返回 div 标签包裹的内容
|
||||
matcher.appendReplacement(sb, "<div>" + innerContent + "</div>");
|
||||
}
|
||||
matcher.appendTail(sb);
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 反转义 HTML 特殊字符
|
||||
*
|
||||
* @param input 输入字符串
|
||||
* @return 反转义后的字符串
|
||||
*/
|
||||
private String unescapeHtml(String input) {
|
||||
if (StrUtil.isEmpty(input)) {
|
||||
return input;
|
||||
}
|
||||
return input
|
||||
.replace("&", "&")
|
||||
.replace("<", "<")
|
||||
.replace(">", ">")
|
||||
.replace(""", "\"")
|
||||
.replace("'", "'")
|
||||
.replace(" ", " ");
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化 HTML 中的代码块
|
||||
*
|
||||
* @param content 邮件内容
|
||||
* @return 格式化后的邮件内容
|
||||
*/
|
||||
private String formatHtmlCodeBlocks(String content) {
|
||||
// 匹配 <pre><code> 标签的代码块
|
||||
Pattern codeBlockPattern = Pattern.compile("<pre\\s*.*?><code\\s*.*?>(.*?)</code></pre>", Pattern.DOTALL);
|
||||
Matcher matcher = codeBlockPattern.matcher(content);
|
||||
StringBuilder sb = new StringBuilder();
|
||||
while (matcher.find()) {
|
||||
// 获取代码块内容
|
||||
String codeBlock = matcher.group(1);
|
||||
// 为代码块添加样式
|
||||
String replacement = "<pre style=\"background-color: #f5f5f5; padding: 10px; border-radius: 5px; overflow-x: auto;\"><code>" + codeBlock + "</code></pre>";
|
||||
matcher.appendReplacement(sb, replacement);
|
||||
}
|
||||
matcher.appendTail(sb);
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getMailTemplateCountByAccountId(Long accountId) {
|
||||
return mailTemplateMapper.selectCountByAccountId(accountId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析标题和内容中的参数
|
||||
*/
|
||||
@VisibleForTesting
|
||||
public List<String> parseTemplateTitleAndContentParams(String title, String content) {
|
||||
List<String> titleParams = ReUtil.findAllGroup1(PATTERN_PARAMS, title);
|
||||
List<String> contentParams = ReUtil.findAllGroup1(PATTERN_PARAMS, content);
|
||||
// 合并参数并去重
|
||||
List<String> allParams = new ArrayList<>(titleParams);
|
||||
for (String param : contentParams) {
|
||||
if (!allParams.contains(param)) {
|
||||
allParams.add(param);
|
||||
}
|
||||
}
|
||||
return allParams;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得邮件模板中的参数,形如 {key}
|
||||
*
|
||||
* @param content 内容
|
||||
* @return 参数列表
|
||||
*/
|
||||
List<String> parseTemplateContentParams(String content) {
|
||||
return ReUtil.findAllGroup1(PATTERN_PARAMS, content);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
package com.njcn.rdms.module.system.service.social;
|
||||
|
||||
import com.njcn.rdms.framework.common.pojo.PageResult;
|
||||
import com.njcn.rdms.module.system.controller.admin.socail.vo.client.SocialClientPageReqVO;
|
||||
import com.njcn.rdms.module.system.controller.admin.socail.vo.client.SocialClientSaveReqVO;
|
||||
import com.njcn.rdms.module.system.dal.dataobject.social.SocialClientDO;
|
||||
import jakarta.validation.Valid;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 社交应用 Service 接口
|
||||
*
|
||||
* @author hongawen
|
||||
*/
|
||||
public interface SocialClientService {
|
||||
|
||||
// =================== 客户端管理 ===================
|
||||
|
||||
Long createSocialClient(@Valid SocialClientSaveReqVO createReqVO);
|
||||
|
||||
void updateSocialClient(@Valid SocialClientSaveReqVO updateReqVO);
|
||||
|
||||
void deleteSocialClient(Long id);
|
||||
|
||||
void deleteSocialClientList(List<Long> ids);
|
||||
|
||||
SocialClientDO getSocialClient(Long id);
|
||||
|
||||
PageResult<SocialClientDO> getSocialClientPage(SocialClientPageReqVO pageReqVO);
|
||||
|
||||
}
|
||||
@@ -1,85 +0,0 @@
|
||||
package com.njcn.rdms.module.system.service.social;
|
||||
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import cn.hutool.core.util.ObjUtil;
|
||||
import com.njcn.rdms.framework.common.pojo.PageResult;
|
||||
import com.njcn.rdms.framework.common.util.object.BeanUtils;
|
||||
import com.njcn.rdms.module.system.controller.admin.socail.vo.client.SocialClientPageReqVO;
|
||||
import com.njcn.rdms.module.system.controller.admin.socail.vo.client.SocialClientSaveReqVO;
|
||||
import com.njcn.rdms.module.system.dal.dataobject.social.SocialClientDO;
|
||||
import com.njcn.rdms.module.system.dal.mysql.social.SocialClientMapper;
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static com.njcn.rdms.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static com.njcn.rdms.module.system.enums.ErrorCodeConstants.*;
|
||||
|
||||
/**
|
||||
* 社交应用 Service 实现类
|
||||
*
|
||||
* @author hongawen
|
||||
*/
|
||||
@Service
|
||||
@Slf4j
|
||||
public class SocialClientServiceImpl implements SocialClientService {
|
||||
|
||||
@Resource
|
||||
private SocialClientMapper socialClientMapper;
|
||||
|
||||
@Override
|
||||
public Long createSocialClient(SocialClientSaveReqVO createReqVO) {
|
||||
validateSocialClientUnique(null, createReqVO.getUserType(), createReqVO.getSocialType());
|
||||
SocialClientDO client = BeanUtils.toBean(createReqVO, SocialClientDO.class);
|
||||
socialClientMapper.insert(client);
|
||||
return client.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateSocialClient(SocialClientSaveReqVO updateReqVO) {
|
||||
validateSocialClientExists(updateReqVO.getId());
|
||||
validateSocialClientUnique(updateReqVO.getId(), updateReqVO.getUserType(), updateReqVO.getSocialType());
|
||||
SocialClientDO updateObj = BeanUtils.toBean(updateReqVO, SocialClientDO.class);
|
||||
socialClientMapper.updateById(updateObj);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteSocialClient(Long id) {
|
||||
validateSocialClientExists(id);
|
||||
socialClientMapper.deleteById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteSocialClientList(List<Long> ids) {
|
||||
socialClientMapper.deleteByIds(ids);
|
||||
}
|
||||
|
||||
private void validateSocialClientExists(Long id) {
|
||||
if (socialClientMapper.selectById(id) == null) {
|
||||
throw exception(SOCIAL_CLIENT_NOT_EXISTS);
|
||||
}
|
||||
}
|
||||
|
||||
private void validateSocialClientUnique(Long id, Integer userType, Integer socialType) {
|
||||
SocialClientDO client = socialClientMapper.selectBySocialTypeAndUserType(socialType, userType);
|
||||
if (client == null) {
|
||||
return;
|
||||
}
|
||||
if (id == null || ObjUtil.notEqual(id, client.getId())) {
|
||||
throw exception(SOCIAL_CLIENT_UNIQUE);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public SocialClientDO getSocialClient(Long id) {
|
||||
return socialClientMapper.selectById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageResult<SocialClientDO> getSocialClientPage(SocialClientPageReqVO pageReqVO) {
|
||||
return socialClientMapper.selectPage(pageReqVO);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
spring:
|
||||
spring:
|
||||
application:
|
||||
name: rdms-system-server
|
||||
profiles:
|
||||
@@ -116,16 +116,9 @@ rdms:
|
||||
title: 管理后台
|
||||
description: 提供管理员管理的所有功能
|
||||
version: ${rdms.info.version}
|
||||
codegen:
|
||||
base-package: com.njcn.rdms
|
||||
db-schemas: ${spring.datasource.dynamic.datasource.master.name}
|
||||
front-type: 20 # 前端模版的类型,参见 CodegenFrontTypeEnum 枚举类
|
||||
vo-type: 10 # VO 的类型,参见 CodegenVOTypeEnum 枚举类
|
||||
delete-batch-enable: true # 是否生成批量删除接口
|
||||
unit-test-enable: false # 是否生成单元测试
|
||||
websocket:
|
||||
enable: true # 是否开启 WebSocket
|
||||
sender-type: local # WebSocket 消息发送器类型:local(本地)、redis、rocketmq、rabbitmq、kafka
|
||||
path: /infra/ws # WebSocket 路径
|
||||
path: /system/ws # WebSocket 路径
|
||||
|
||||
debug: false
|
||||
|
||||
|
||||
@@ -1,271 +0,0 @@
|
||||
package ${basePackage}.module.${table.moduleName}.controller.${sceneEnum.basePackage}.${table.businessName};
|
||||
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import ${jakartaPackage}.annotation.Resource;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
#if ($sceneEnum.scene == 1)import org.springframework.security.access.prepost.PreAuthorize;#end
|
||||
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
|
||||
import ${jakartaPackage}.validation.constraints.*;
|
||||
import ${jakartaPackage}.validation.*;
|
||||
import ${jakartaPackage}.servlet.http.*;
|
||||
import java.util.*;
|
||||
import java.io.IOException;
|
||||
|
||||
import ${PageParamClassName};
|
||||
import ${PageResultClassName};
|
||||
import ${CommonResultClassName};
|
||||
import ${BeanUtils};
|
||||
import static ${CommonResultClassName}.success;
|
||||
|
||||
import ${ExcelUtilsClassName};
|
||||
|
||||
import ${ApiAccessLogClassName};
|
||||
import static ${OperateTypeEnumClassName}.*;
|
||||
|
||||
import ${basePackage}.module.${table.moduleName}.controller.${sceneEnum.basePackage}.${table.businessName}.vo.*;
|
||||
import ${basePackage}.module.${table.moduleName}.dal.dataobject.${table.businessName}.${table.className}DO;
|
||||
## 特殊:主子表专属逻辑
|
||||
#foreach ($subTable in $subTables)
|
||||
import ${basePackage}.module.${subTable.moduleName}.dal.dataobject.${subTable.businessName}.${subTable.className}DO;
|
||||
#end
|
||||
import ${basePackage}.module.${table.moduleName}.service.${table.businessName}.${table.className}Service;
|
||||
|
||||
@Tag(name = "${sceneEnum.name} - ${table.classComment}")
|
||||
@RestController
|
||||
##二级的 businessName 暂时不算在 HTTP 路径上,可以根据需要写
|
||||
@RequestMapping("/${table.moduleName}/${simpleClassName_strikeCase}")
|
||||
@Validated
|
||||
public class ${sceneEnum.prefixClass}${table.className}Controller {
|
||||
|
||||
@Resource
|
||||
private ${table.className}Service ${classNameVar}Service;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(summary = "创建${table.classComment}")
|
||||
#if ($sceneEnum.scene == 1)
|
||||
@PreAuthorize("@ss.hasPermission('${permissionPrefix}:create')")
|
||||
#end
|
||||
public CommonResult<${primaryColumn.javaType}> create${simpleClassName}(@Valid @RequestBody ${saveReqVOClass} ${saveReqVOVar}) {
|
||||
return success(${classNameVar}Service.create${simpleClassName}(${saveReqVOVar}));
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@Operation(summary = "更新${table.classComment}")
|
||||
#if ($sceneEnum.scene == 1)
|
||||
@PreAuthorize("@ss.hasPermission('${permissionPrefix}:update')")
|
||||
#end
|
||||
public CommonResult<Boolean> update${simpleClassName}(@Valid @RequestBody ${updateReqVOClass} ${updateReqVOVar}) {
|
||||
${classNameVar}Service.update${simpleClassName}(${updateReqVOVar});
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(summary = "删除${table.classComment}")
|
||||
@Parameter(name = "id", description = "编号", required = true)
|
||||
#if ($sceneEnum.scene == 1)
|
||||
@PreAuthorize("@ss.hasPermission('${permissionPrefix}:delete')")
|
||||
#end
|
||||
public CommonResult<Boolean> delete${simpleClassName}(@RequestParam("id") ${primaryColumn.javaType} id) {
|
||||
${classNameVar}Service.delete${simpleClassName}(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
#if ( $table.templateType != 2 && $deleteBatchEnable)
|
||||
@DeleteMapping("/delete-list")
|
||||
@Parameter(name = "ids", description = "编号", required = true)
|
||||
@Operation(summary = "批量删除${table.classComment}")
|
||||
#if ($sceneEnum.scene == 1)
|
||||
@PreAuthorize("@ss.hasPermission('${permissionPrefix}:delete')")
|
||||
#end
|
||||
public CommonResult<Boolean> delete${simpleClassName}List(@RequestParam("ids") List<${primaryColumn.javaType}> ids) {
|
||||
${classNameVar}Service.delete${simpleClassName}ListByIds(ids);
|
||||
return success(true);
|
||||
}
|
||||
#end
|
||||
|
||||
@GetMapping("/get")
|
||||
@Operation(summary = "获得${table.classComment}")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||
#if ($sceneEnum.scene == 1)
|
||||
@PreAuthorize("@ss.hasPermission('${permissionPrefix}:query')")
|
||||
#end
|
||||
public CommonResult<${respVOClass}> get${simpleClassName}(@RequestParam("id") ${primaryColumn.javaType} id) {
|
||||
${table.className}DO ${classNameVar} = ${classNameVar}Service.get${simpleClassName}(id);
|
||||
#if ($voType == 10)
|
||||
return success(BeanUtils.toBean(${classNameVar}, ${respVOClass}.class));
|
||||
#else
|
||||
return success(${classNameVar});
|
||||
#end
|
||||
}
|
||||
|
||||
#if ( $table.templateType != 2 )
|
||||
@GetMapping("/page")
|
||||
@Operation(summary = "获得${table.classComment}分页")
|
||||
#if ($sceneEnum.scene == 1)
|
||||
@PreAuthorize("@ss.hasPermission('${permissionPrefix}:query')")
|
||||
#end
|
||||
public CommonResult<PageResult<${respVOClass}>> get${simpleClassName}Page(@Valid ${sceneEnum.prefixClass}${table.className}PageReqVO pageReqVO) {
|
||||
PageResult<${table.className}DO> pageResult = ${classNameVar}Service.get${simpleClassName}Page(pageReqVO);
|
||||
#if ($voType == 10)
|
||||
return success(BeanUtils.toBean(pageResult, ${respVOClass}.class));
|
||||
#else
|
||||
return success(pageResult);
|
||||
#end
|
||||
}
|
||||
|
||||
## 特殊:树表专属逻辑(树不需要分页接口)
|
||||
#else
|
||||
@GetMapping("/list")
|
||||
@Operation(summary = "获得${table.classComment}列表")
|
||||
#if ($sceneEnum.scene == 1)
|
||||
@PreAuthorize("@ss.hasPermission('${permissionPrefix}:query')")
|
||||
#end
|
||||
public CommonResult<List<${respVOClass}>> get${simpleClassName}List(@Valid ${sceneEnum.prefixClass}${table.className}ListReqVO listReqVO) {
|
||||
List<${table.className}DO> list = ${classNameVar}Service.get${simpleClassName}List(listReqVO);
|
||||
#if ($voType == 10)
|
||||
return success(BeanUtils.toBean(list, ${respVOClass}.class));
|
||||
#else
|
||||
return success(list);
|
||||
#end
|
||||
}
|
||||
|
||||
#end
|
||||
@GetMapping("/export-excel")
|
||||
@Operation(summary = "导出${table.classComment} Excel")
|
||||
#if ($sceneEnum.scene == 1)
|
||||
@PreAuthorize("@ss.hasPermission('${permissionPrefix}:export')")
|
||||
#end
|
||||
@ApiAccessLog(operateType = EXPORT)
|
||||
#if ( $table.templateType != 2 )
|
||||
public void export${simpleClassName}Excel(@Valid ${sceneEnum.prefixClass}${table.className}PageReqVO pageReqVO,
|
||||
HttpServletResponse response) throws IOException {
|
||||
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
|
||||
List<${table.className}DO> list = ${classNameVar}Service.get${simpleClassName}Page(pageReqVO).getList();
|
||||
// 导出 Excel
|
||||
ExcelUtils.write(response, "${table.classComment}.xls", "数据", ${respVOClass}.class,
|
||||
BeanUtils.toBean(list, ${respVOClass}.class));
|
||||
}
|
||||
## 特殊:树表专属逻辑(树不需要分页接口)
|
||||
#else
|
||||
public void export${simpleClassName}Excel(@Valid ${sceneEnum.prefixClass}${table.className}ListReqVO listReqVO,
|
||||
HttpServletResponse response) throws IOException {
|
||||
List<${table.className}DO> list = ${classNameVar}Service.get${simpleClassName}List(listReqVO);
|
||||
// 导出 Excel
|
||||
ExcelUtils.write(response, "${table.classComment}.xls", "数据", ${table.className}RespVO.class,
|
||||
BeanUtils.toBean(list, ${table.className}RespVO.class));
|
||||
}
|
||||
#end
|
||||
|
||||
## 特殊:主子表专属逻辑
|
||||
#foreach ($subTable in $subTables)
|
||||
#set ($index = $foreach.count - 1)
|
||||
#set ($subSimpleClassName = $subSimpleClassNames.get($index))
|
||||
#set ($subPrimaryColumn = $subPrimaryColumns.get($index))##当前 primary 字段
|
||||
#set ($subJoinColumn = $subJoinColumns.get($index))##当前 join 字段
|
||||
#set ($SubJoinColumnName = $subJoinColumn.javaField.substring(0,1).toUpperCase() + ${subJoinColumn.javaField.substring(1)})##首字母大写
|
||||
#set ($subSimpleClassName_strikeCase = $subSimpleClassName_strikeCases.get($index))
|
||||
#set ($subJoinColumn_strikeCase = $subJoinColumn_strikeCases.get($index))
|
||||
#set ($subClassNameVar = $subClassNameVars.get($index))
|
||||
// ==================== 子表($subTable.classComment) ====================
|
||||
|
||||
## 情况一:MASTER_ERP 时,需要分查询页子表
|
||||
#if ( $table.templateType == 11 )
|
||||
@GetMapping("/${subSimpleClassName_strikeCase}/page")
|
||||
@Operation(summary = "获得${subTable.classComment}分页")
|
||||
@Parameter(name = "${subJoinColumn.javaField}", description = "${subJoinColumn.columnComment}")
|
||||
#if ($sceneEnum.scene == 1)
|
||||
@PreAuthorize("@ss.hasPermission('${permissionPrefix}:query')")
|
||||
#end
|
||||
public CommonResult<PageResult<${subTable.className}DO>> get${subSimpleClassName}Page(PageParam pageReqVO,
|
||||
@RequestParam("${subJoinColumn.javaField}") ${subJoinColumn.javaType} ${subJoinColumn.javaField}) {
|
||||
return success(${classNameVar}Service.get${subSimpleClassName}Page(pageReqVO, ${subJoinColumn.javaField}));
|
||||
}
|
||||
|
||||
## 情况二:非 MASTER_ERP 时,需要列表查询子表
|
||||
#else
|
||||
#if ( $subTable.subJoinMany )
|
||||
@GetMapping("/${subSimpleClassName_strikeCase}/list-by-${subJoinColumn_strikeCase}")
|
||||
@Operation(summary = "获得${subTable.classComment}列表")
|
||||
@Parameter(name = "${subJoinColumn.javaField}", description = "${subJoinColumn.columnComment}")
|
||||
#if ($sceneEnum.scene == 1)
|
||||
@PreAuthorize("@ss.hasPermission('${permissionPrefix}:query')")
|
||||
#end
|
||||
public CommonResult<List<${subTable.className}DO>> get${subSimpleClassName}ListBy${SubJoinColumnName}(@RequestParam("${subJoinColumn.javaField}") ${subJoinColumn.javaType} ${subJoinColumn.javaField}) {
|
||||
return success(${classNameVar}Service.get${subSimpleClassName}ListBy${SubJoinColumnName}(${subJoinColumn.javaField}));
|
||||
}
|
||||
|
||||
#else
|
||||
@GetMapping("/${subSimpleClassName_strikeCase}/get-by-${subJoinColumn_strikeCase}")
|
||||
@Operation(summary = "获得${subTable.classComment}")
|
||||
@Parameter(name = "${subJoinColumn.javaField}", description = "${subJoinColumn.columnComment}")
|
||||
#if ($sceneEnum.scene == 1)
|
||||
@PreAuthorize("@ss.hasPermission('${permissionPrefix}:query')")
|
||||
#end
|
||||
public CommonResult<${subTable.className}DO> get${subSimpleClassName}By${SubJoinColumnName}(@RequestParam("${subJoinColumn.javaField}") ${subJoinColumn.javaType} ${subJoinColumn.javaField}) {
|
||||
return success(${classNameVar}Service.get${subSimpleClassName}By${SubJoinColumnName}(${subJoinColumn.javaField}));
|
||||
}
|
||||
|
||||
#end
|
||||
#end
|
||||
## 特殊:MASTER_ERP 时,支持单个的新增、修改、删除操作
|
||||
#if ( $table.templateType == 11 )
|
||||
@PostMapping("/${subSimpleClassName_strikeCase}/create")
|
||||
@Operation(summary = "创建${subTable.classComment}")
|
||||
#if ($sceneEnum.scene == 1)
|
||||
@PreAuthorize("@ss.hasPermission('${permissionPrefix}:create')")
|
||||
#end
|
||||
public CommonResult<${subPrimaryColumn.javaType}> create${subSimpleClassName}(@Valid @RequestBody ${subTable.className}DO ${subClassNameVar}) {
|
||||
return success(${classNameVar}Service.create${subSimpleClassName}(${subClassNameVar}));
|
||||
}
|
||||
|
||||
@PutMapping("/${subSimpleClassName_strikeCase}/update")
|
||||
@Operation(summary = "更新${subTable.classComment}")
|
||||
#if ($sceneEnum.scene == 1)
|
||||
@PreAuthorize("@ss.hasPermission('${permissionPrefix}:update')")
|
||||
#end
|
||||
public CommonResult<Boolean> update${subSimpleClassName}(@Valid @RequestBody ${subTable.className}DO ${subClassNameVar}) {
|
||||
${classNameVar}Service.update${subSimpleClassName}(${subClassNameVar});
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/${subSimpleClassName_strikeCase}/delete")
|
||||
@Parameter(name = "id", description = "编号", required = true)
|
||||
@Operation(summary = "删除${subTable.classComment}")
|
||||
#if ($sceneEnum.scene == 1)
|
||||
@PreAuthorize("@ss.hasPermission('${permissionPrefix}:delete')")
|
||||
#end
|
||||
public CommonResult<Boolean> delete${subSimpleClassName}(@RequestParam("id") ${subPrimaryColumn.javaType} id) {
|
||||
${classNameVar}Service.delete${subSimpleClassName}(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
#if ($deleteBatchEnable)
|
||||
@DeleteMapping("/${subSimpleClassName_strikeCase}/delete-list")
|
||||
@Parameter(name = "ids", description = "编号", required = true)
|
||||
@Operation(summary = "批量删除${subTable.classComment}")
|
||||
#if ($sceneEnum.scene == 1)
|
||||
@PreAuthorize("@ss.hasPermission('${permissionPrefix}:delete')")
|
||||
#end
|
||||
public CommonResult<Boolean> delete${subSimpleClassName}List(@RequestParam("ids") List<${subPrimaryColumn.javaType}> ids) {
|
||||
${classNameVar}Service.delete${subSimpleClassName}ListByIds(ids);
|
||||
return success(true);
|
||||
}
|
||||
#end
|
||||
|
||||
@GetMapping("/${subSimpleClassName_strikeCase}/get")
|
||||
@Operation(summary = "获得${subTable.classComment}")
|
||||
@Parameter(name = "id", description = "编号", required = true)
|
||||
#if ($sceneEnum.scene == 1)
|
||||
@PreAuthorize("@ss.hasPermission('${permissionPrefix}:query')")
|
||||
#end
|
||||
public CommonResult<${subTable.className}DO> get${subSimpleClassName}(@RequestParam("id") ${subPrimaryColumn.javaType} id) {
|
||||
return success(${classNameVar}Service.get${subSimpleClassName}(id));
|
||||
}
|
||||
|
||||
#end
|
||||
#end
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
package ${basePackage}.module.${table.moduleName}.controller.${sceneEnum.basePackage}.${table.businessName}.vo;
|
||||
|
||||
import lombok.*;
|
||||
import java.util.*;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import ${PageParamClassName};
|
||||
#foreach ($column in $columns)
|
||||
#if (${column.javaType} == "BigDecimal")
|
||||
import java.math.BigDecimal;
|
||||
#break
|
||||
#end
|
||||
#end
|
||||
## 处理 LocalDateTime 字段的引入
|
||||
#foreach ($column in $columns)
|
||||
#if (${column.listOperation} && ${column.javaType} == "LocalDateTime")
|
||||
import java.time.LocalDateTime;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import static ${DateUtilsClassName}.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||
#break
|
||||
#end
|
||||
#end
|
||||
## 字段模板
|
||||
#macro(columnTpl $prefix $prefixStr)
|
||||
@Schema(description = "${prefixStr}${column.columnComment}"#if ("$!column.example" != ""), example = "${column.example}"#end)
|
||||
private ${column.javaType}#if ("$!prefix" != "") ${prefix}${JavaField}#else ${column.javaField}#end;
|
||||
#end
|
||||
|
||||
@Schema(description = "${sceneEnum.name} - ${table.classComment}列表 Request VO")
|
||||
@Data
|
||||
public class ${sceneEnum.prefixClass}${table.className}ListReqVO {
|
||||
|
||||
#foreach ($column in $columns)
|
||||
#if (${column.listOperation})##查询操作
|
||||
#if (${column.listOperationCondition} == "BETWEEN")## 情况一,Between 的时候
|
||||
@Schema(description = "${column.columnComment}"#if ("$!column.example" != ""), example = "${column.example}"#end)
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
private ${column.javaType}[] ${column.javaField};
|
||||
#else##情况二,非 Between 的时间
|
||||
#columnTpl('', '')
|
||||
#end
|
||||
|
||||
#end
|
||||
#end
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
package ${basePackage}.module.${table.moduleName}.controller.${sceneEnum.basePackage}.${table.businessName}.vo;
|
||||
|
||||
import lombok.*;
|
||||
import java.util.*;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import ${PageParamClassName};
|
||||
#foreach ($column in $columns)
|
||||
#if (${column.javaType} == "BigDecimal")
|
||||
import java.math.BigDecimal;
|
||||
#break
|
||||
#end
|
||||
#end
|
||||
## 处理 LocalDateTime 字段的引入
|
||||
#foreach ($column in $columns)
|
||||
#if (${column.listOperationCondition} && ${column.javaType} == "LocalDateTime")
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import static ${DateUtilsClassName}.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||
#break
|
||||
#end
|
||||
#end
|
||||
## 字段模板
|
||||
#macro(columnTpl $prefix $prefixStr)
|
||||
@Schema(description = "${prefixStr}${column.columnComment}"#if ("$!column.example" != ""), example = "${column.example}"#end)
|
||||
private ${column.javaType}#if ("$!prefix" != "") ${prefix}${JavaField}#else ${column.javaField}#end;
|
||||
#end
|
||||
|
||||
@Schema(description = "${sceneEnum.name} - ${table.classComment}分页 Request VO")
|
||||
@Data
|
||||
public class ${sceneEnum.prefixClass}${table.className}PageReqVO extends PageParam {
|
||||
|
||||
#foreach ($column in $columns)
|
||||
#if (${column.listOperation})##查询操作
|
||||
#if (${column.listOperationCondition} == "BETWEEN")## 情况一,Between 的时候
|
||||
@Schema(description = "${column.columnComment}"#if ("$!column.example" != ""), example = "${column.example}"#end)
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
private ${column.javaType}[] ${column.javaField};
|
||||
#else##情况二,非 Between 的时间
|
||||
#columnTpl('', '')
|
||||
#end
|
||||
|
||||
#end
|
||||
#end
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
package ${basePackage}.module.${table.moduleName}.controller.${sceneEnum.basePackage}.${table.businessName}.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.*;
|
||||
import java.util.*;
|
||||
## 处理 BigDecimal 字段的引入
|
||||
#foreach ($column in $columns)
|
||||
#if (${column.javaType} == "BigDecimal")
|
||||
import java.math.BigDecimal;
|
||||
#break
|
||||
#end
|
||||
#end
|
||||
## 处理 LocalDateTime 字段的引入
|
||||
#foreach ($column in $columns)
|
||||
#if (${column.listOperationResult} && ${column.javaType} == "LocalDateTime")
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
import java.time.LocalDateTime;
|
||||
#break
|
||||
#end
|
||||
#end
|
||||
## 处理 Excel 导出
|
||||
import cn.idev.excel.annotation.*;
|
||||
#foreach ($column in $columns)
|
||||
#if ("$!column.dictType" != "")## 有设置数据字典
|
||||
import ${DictFormatClassName};
|
||||
import ${DictConvertClassName};
|
||||
#break
|
||||
#end
|
||||
#end
|
||||
|
||||
@Schema(description = "${sceneEnum.name} - ${table.classComment} Response VO")
|
||||
@Data
|
||||
@ExcelIgnoreUnannotated
|
||||
public class ${sceneEnum.prefixClass}${table.className}RespVO {
|
||||
|
||||
## 逐个处理字段
|
||||
#foreach ($column in $columns)
|
||||
#if (${column.listOperationResult})
|
||||
## 1. 处理 Swagger 注解
|
||||
@Schema(description = "${column.columnComment}"#if (!${column.nullable}), requiredMode = Schema.RequiredMode.REQUIRED#end#if ("$!column.example" != ""), example = "${column.example}"#end)
|
||||
## 2. 处理 Excel 导出
|
||||
#if ("$!column.dictType" != "")##处理枚举值
|
||||
@ExcelProperty(value = "${column.columnComment}", converter = DictConvert.class)
|
||||
@DictFormat("${column.dictType}") // TODO 代码优化:建议设置到对应的 DictTypeConstants 枚举类中
|
||||
#else
|
||||
@ExcelProperty("${column.columnComment}")
|
||||
#end
|
||||
## 3. 处理字段定义
|
||||
private ${column.javaType} ${column.javaField};
|
||||
|
||||
#end
|
||||
#end
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
package ${basePackage}.module.${table.moduleName}.controller.${sceneEnum.basePackage}.${table.businessName}.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.*;
|
||||
import java.util.*;
|
||||
import ${jakartaPackage}.validation.constraints.*;
|
||||
## 处理 BigDecimal 字段的引入
|
||||
#foreach ($column in $columns)
|
||||
#if (${column.javaType} == "BigDecimal")
|
||||
import java.math.BigDecimal;
|
||||
#break
|
||||
#end
|
||||
#end
|
||||
## 处理 LocalDateTime 字段的引入
|
||||
#foreach ($column in $columns)
|
||||
#if ((${column.createOperation} || ${column.updateOperation}) && ${column.javaType} == "LocalDateTime")
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
import java.time.LocalDateTime;
|
||||
#break
|
||||
#end
|
||||
#end
|
||||
## 特殊:主子表专属逻辑
|
||||
#foreach ($subTable in $subTables)
|
||||
import ${basePackage}.module.${subTable.moduleName}.dal.dataobject.${subTable.businessName}.${subTable.className}DO;
|
||||
#end
|
||||
|
||||
@Schema(description = "${sceneEnum.name} - ${table.classComment}新增/修改 Request VO")
|
||||
@Data
|
||||
public class ${sceneEnum.prefixClass}${table.className}SaveReqVO {
|
||||
|
||||
## 逐个处理字段
|
||||
#foreach ($column in $columns)
|
||||
#if (${column.createOperation} || ${column.updateOperation})
|
||||
## 1. 处理 Swagger 注解
|
||||
@Schema(description = "${column.columnComment}"#if (!${column.nullable}), requiredMode = Schema.RequiredMode.REQUIRED#end#if ("$!column.example" != ""), example = "${column.example}"#end)
|
||||
## 2. 处理 Validator 参数校验
|
||||
#if (!${column.nullable} && !${column.primaryKey})
|
||||
#if (${column.javaType} == 'String')
|
||||
@NotEmpty(message = "${column.columnComment}不能为空")
|
||||
#else
|
||||
@NotNull(message = "${column.columnComment}不能为空")
|
||||
#end
|
||||
#end
|
||||
## 3. 处理字段定义
|
||||
private ${column.javaType} ${column.javaField};
|
||||
|
||||
#end
|
||||
#end
|
||||
## 特殊:主子表专属逻辑(非 ERP 模式)
|
||||
#if ( $subTables && $subTables.size() > 0 && $table.templateType != 11 )
|
||||
#foreach ($subTable in $subTables)
|
||||
#set ($index = $foreach.count - 1)
|
||||
#if ( $subTable.subJoinMany)
|
||||
@Schema(description = "${subTable.classComment}列表")
|
||||
private List<${subTable.className}DO> ${subClassNameVars.get($index)}s;
|
||||
|
||||
#else
|
||||
@Schema(description = "${subTable.classComment}")
|
||||
private ${subTable.className}DO ${subClassNameVars.get($index)};
|
||||
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
}
|
||||
@@ -1,103 +0,0 @@
|
||||
package ${basePackage}.module.${table.moduleName}.dal.dataobject.${table.businessName};
|
||||
|
||||
import lombok.*;
|
||||
import java.util.*;
|
||||
#foreach ($column in $columns)
|
||||
#if (${column.javaType} == "BigDecimal")
|
||||
import java.math.BigDecimal;
|
||||
#end
|
||||
#if (${column.javaType} == "LocalDateTime")
|
||||
import java.time.LocalDateTime;
|
||||
#end
|
||||
#end
|
||||
import com.baomidou.mybatisplus.annotation.*;
|
||||
import ${BaseDOClassName};
|
||||
## 处理 Excel 导出 + Schema 注解(仅 DO 模式)
|
||||
#if ($voType == 20)
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import cn.idev.excel.annotation.*;
|
||||
#foreach ($column in $columns)
|
||||
#if ("$!column.dictType" != "")## 有设置数据字典
|
||||
import ${DictFormatClassName};
|
||||
import ${DictConvertClassName};
|
||||
#break
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
|
||||
/**
|
||||
* ${table.classComment} DO
|
||||
*
|
||||
* @author ${table.author}
|
||||
*/
|
||||
@TableName("${table.tableName.toLowerCase()}")
|
||||
@KeySequence("${table.tableName.toLowerCase()}_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
## 处理 Excel 导出 + Schema 注解(仅 DO 模式)
|
||||
#if ($voType == 20)
|
||||
@Schema(description = "${sceneEnum.name} - ${table.classComment} Response VO")
|
||||
@ExcelIgnoreUnannotated
|
||||
#end
|
||||
public class ${table.className}DO extends BaseDO {
|
||||
|
||||
## 特殊:树表专属逻辑
|
||||
#if ( $table.templateType == 2 )
|
||||
public static final Long ${treeParentColumn_javaField_underlineCase.toUpperCase()}_ROOT = 0L;
|
||||
|
||||
#end
|
||||
#foreach ($column in $columns)
|
||||
#if (!${baseDOFields.contains(${column.javaField})})##排除 BaseDO 的字段
|
||||
/**
|
||||
* ${column.columnComment}
|
||||
#if ("$!column.dictType" != "")##处理枚举值
|
||||
*
|
||||
* 枚举 {@link TODO ${column.dictType} 对应的类}
|
||||
#end
|
||||
*/
|
||||
#if (${column.primaryKey})##处理主键
|
||||
@TableId#if (${column.javaType} == 'String')(type = IdType.INPUT)#end
|
||||
#end
|
||||
#if ($voType == 20)
|
||||
## 1. 处理 Swagger 注解
|
||||
@Schema(description = "${column.columnComment}"#if (!${column.nullable}), requiredMode = Schema.RequiredMode.REQUIRED#end#if ("$!column.example" != ""), example = "${column.example}"#end)
|
||||
## 2. 处理 Excel 导出
|
||||
#if ("$!column.dictType" != "")##处理枚举值
|
||||
@ExcelProperty(value = "${column.columnComment}", converter = DictConvert.class)
|
||||
@DictFormat("${column.dictType}") // TODO 代码优化:建议设置到对应的 DictTypeConstants 枚举类中
|
||||
#else
|
||||
@ExcelProperty("${column.columnComment}")
|
||||
#end
|
||||
#end
|
||||
## 3. 处理字段定义
|
||||
private ${column.javaType} ${column.javaField};
|
||||
#end
|
||||
#end
|
||||
|
||||
## 特殊:主子表专属逻辑(非 ERP 模式)
|
||||
#if ( $voType == 20 && $subTables && $subTables.size() > 0 && $table.templateType != 11 )
|
||||
#foreach ($subTable in $subTables)
|
||||
#set ($index = $foreach.count - 1)
|
||||
#if ( $subTable.subJoinMany)
|
||||
/**
|
||||
* ${subTable.classComment}列表
|
||||
*/
|
||||
@Schema(description = "${subTable.classComment}列表")
|
||||
@TableField(exist = false)
|
||||
private List<${subTable.className}DO> ${subClassNameVars.get($index)}s;
|
||||
#else
|
||||
/**
|
||||
* ${subTable.classComment}
|
||||
*/
|
||||
@Schema(description = "${subTable.classComment}")
|
||||
@TableField(exist = false)
|
||||
private ${subTable.className}DO ${subClassNameVars.get($index)};
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
|
||||
}
|
||||
@@ -1,69 +0,0 @@
|
||||
#set ($subTable = $subTables.get($subIndex))##当前表
|
||||
#set ($subColumns = $subColumnsList.get($subIndex))##当前字段数组
|
||||
package ${basePackage}.module.${subTable.moduleName}.dal.dataobject.${subTable.businessName};
|
||||
|
||||
import lombok.*;
|
||||
import java.util.*;
|
||||
#foreach ($column in $subColumns)
|
||||
#if (${column.javaType} == "BigDecimal")
|
||||
import java.math.BigDecimal;
|
||||
#end
|
||||
#if (${column.javaType} == "LocalDateTime")
|
||||
import java.time.LocalDateTime;
|
||||
#end
|
||||
#end
|
||||
import com.baomidou.mybatisplus.annotation.*;
|
||||
import ${BaseDOClassName};
|
||||
## 处理 Schema 注解(仅 DO 模式)
|
||||
#if ($voType == 20)
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
#foreach ($column in $columns)
|
||||
#if ("$!column.dictType" != "")## 有设置数据字典
|
||||
import ${DictFormatClassName};
|
||||
import ${DictConvertClassName};
|
||||
#break
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
|
||||
/**
|
||||
* ${subTable.classComment} DO
|
||||
*
|
||||
* @author ${subTable.author}
|
||||
*/
|
||||
@TableName("${subTable.tableName.toLowerCase()}")
|
||||
@KeySequence("${subTable.tableName.toLowerCase()}_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
## 处理 Schema 注解(仅 DO 模式)
|
||||
#if ($voType == 20)
|
||||
@Schema(description = "${sceneEnum.name} - ${table.classComment} Response VO")
|
||||
#end
|
||||
public class ${subTable.className}DO extends BaseDO {
|
||||
|
||||
#foreach ($column in $subColumns)
|
||||
#if (!${baseDOFields.contains(${column.javaField})})##排除 BaseDO 的字段
|
||||
/**
|
||||
* ${column.columnComment}
|
||||
#if ("$!column.dictType" != "")##处理枚举值
|
||||
*
|
||||
* 枚举 {@link TODO ${column.dictType} 对应的类}
|
||||
#end
|
||||
*/
|
||||
#if (${column.primaryKey})##处理主键
|
||||
@TableId#if (${column.javaType} == 'String')(type = IdType.INPUT)#end
|
||||
#end
|
||||
#if ($voType == 20)
|
||||
## 1. 处理 Swagger 注解
|
||||
@Schema(description = "${column.columnComment}"#if (!${column.nullable}), requiredMode = Schema.RequiredMode.REQUIRED#end#if ("$!column.example" != ""), example = "${column.example}"#end)
|
||||
#end
|
||||
## 2. 处理字段定义
|
||||
private ${column.javaType} ${column.javaField};
|
||||
#end
|
||||
#end
|
||||
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user