|
@@ -1,22 +1,39 @@
|
|
|
package com.aizuda.boot.modules.gen.service.impl;
|
|
|
|
|
|
+import com.aizuda.boot.modules.gen.entity.GenDatabase;
|
|
|
+import com.aizuda.boot.modules.gen.entity.GenTemplate;
|
|
|
+import com.aizuda.boot.modules.gen.entity.dto.GenDTO;
|
|
|
+import com.aizuda.boot.modules.gen.entity.vo.GenVO;
|
|
|
+import com.aizuda.boot.modules.gen.service.IGenDatabaseService;
|
|
|
import com.aizuda.boot.modules.gen.service.IGenTableService;
|
|
|
+import com.aizuda.boot.modules.gen.service.IGenTemplateService;
|
|
|
+import com.aizuda.common.toolkit.CollectionUtils;
|
|
|
+import com.aizuda.core.api.ApiAssert;
|
|
|
import com.aizuda.core.bean.BaseEntity;
|
|
|
+import com.aizuda.service.web.UserSession;
|
|
|
import com.baomidou.mybatisplus.annotation.FieldFill;
|
|
|
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
|
|
|
import com.baomidou.mybatisplus.generator.config.*;
|
|
|
import com.baomidou.mybatisplus.generator.config.builder.ConfigBuilder;
|
|
|
+import com.baomidou.mybatisplus.generator.config.po.TableField;
|
|
|
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
|
|
|
import com.baomidou.mybatisplus.generator.config.rules.DateType;
|
|
|
import com.baomidou.mybatisplus.generator.engine.VelocityTemplateEngine;
|
|
|
import com.baomidou.mybatisplus.generator.fill.Column;
|
|
|
+import jakarta.servlet.http.HttpServletResponse;
|
|
|
import lombok.AllArgsConstructor;
|
|
|
+import org.apache.commons.collections.MapUtils;
|
|
|
+import org.apache.ibatis.type.JdbcType;
|
|
|
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
|
|
|
+import java.io.ByteArrayOutputStream;
|
|
|
+import java.util.Arrays;
|
|
|
import java.util.HashMap;
|
|
|
import java.util.List;
|
|
|
import java.util.Map;
|
|
|
+import java.util.zip.ZipEntry;
|
|
|
+import java.util.zip.ZipOutputStream;
|
|
|
|
|
|
/**
|
|
|
* 代码生成业务表 服务实现类
|
|
@@ -27,21 +44,95 @@ import java.util.Map;
|
|
|
@Service
|
|
|
@AllArgsConstructor
|
|
|
public class GenTableServiceImpl implements IGenTableService {
|
|
|
+ private IGenDatabaseService genDatabaseService;
|
|
|
+ private IGenTemplateService genTemplateService;
|
|
|
private DataSourceProperties dsp;
|
|
|
|
|
|
@Override
|
|
|
- public boolean gen() {
|
|
|
- DataSourceConfig.Builder dataSource = new DataSourceConfig.Builder(dsp.getUrl(), dsp.getUsername(), dsp.getPassword());
|
|
|
+ public List<GenVO> preview(GenDTO dto) {
|
|
|
+ List<GenTemplate> genTemplates = genTemplateService.listByIds(dto.getTemplateIds());
|
|
|
+ ApiAssert.fail(CollectionUtils.isEmpty(genTemplates), "请选择生成模板");
|
|
|
+
|
|
|
+ // 生成预览内容
|
|
|
+ ConfigBuilder configBuilder = this.buildConfigBuilder(dto);
|
|
|
+ TableInfo tableInfo = this.buildConfigBuilder(dto).getTableInfoList().get(0);
|
|
|
+ VelocityTemplateEngine templateEngine = new VelocityTemplateEngine();
|
|
|
+ templateEngine.init(configBuilder);
|
|
|
+ return genTemplates.stream().map(t -> {
|
|
|
+ GenVO vo = new GenVO();
|
|
|
+ try {
|
|
|
+ Map<String, Object> objectMap = this.getObjectMap(configBuilder, tableInfo);
|
|
|
+ vo.setTplName(t.getTplName());
|
|
|
+ vo.setTplContent(templateEngine.writer(objectMap, tableInfo.getEntityName(), t.getTplContent()));
|
|
|
+ vo.setOutFile(t.getOutFile());
|
|
|
+ vo.setRemark(t.getRemark());
|
|
|
+ } catch (Exception e) {
|
|
|
+ ApiAssert.fail("模板【" + t.getTplName() + "】内容异常");
|
|
|
+ }
|
|
|
+ return vo;
|
|
|
+ }).toList();
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void download(HttpServletResponse response, GenDTO dto) {
|
|
|
+ List<GenTemplate> genTemplates = genTemplateService.listByIds(dto.getTemplateIds());
|
|
|
+ ApiAssert.fail(CollectionUtils.isEmpty(genTemplates), "请选择生成模板");
|
|
|
+
|
|
|
+ // 生成预览内容
|
|
|
+ ConfigBuilder configBuilder = this.buildConfigBuilder(dto);
|
|
|
+ TableInfo tableInfo = this.buildConfigBuilder(dto).getTableInfoList().get(0);
|
|
|
+ VelocityTemplateEngine templateEngine = new VelocityTemplateEngine();
|
|
|
+ templateEngine.init(configBuilder);
|
|
|
+
|
|
|
+ // 设置响应内容类型
|
|
|
+ response.setContentType("application/zip");
|
|
|
+ response.setHeader("Content-Disposition", "attachment; filename=\"generatedCode.zip\"");
|
|
|
+ // 创建ZIP输出流
|
|
|
+ try (ZipOutputStream zos = new ZipOutputStream(response.getOutputStream())) {
|
|
|
+ // 渲染模板
|
|
|
+ for (GenTemplate gt : genTemplates) {
|
|
|
+ // 创建输出流
|
|
|
+ ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
|
|
|
+ Map<String, Object> objectMap = this.getObjectMap(configBuilder, tableInfo);
|
|
|
+ String context = templateEngine.writer(objectMap, tableInfo.getEntityName(), gt.getTplContent());
|
|
|
+ byteArrayOutputStream.write(context.getBytes());
|
|
|
+
|
|
|
+ // 创建文件内容
|
|
|
+ String packageName = configBuilder.getPackageConfig().getParent();
|
|
|
+ ZipEntry zipEntry = new ZipEntry(packageName.replace('.', '/') + "/" +
|
|
|
+ String.format(gt.getOutFile(), tableInfo.getEntityName()));
|
|
|
+ zos.putNextEntry(zipEntry);
|
|
|
+ zos.write(byteArrayOutputStream.toByteArray());
|
|
|
+ zos.closeEntry();
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ ApiAssert.fail("生成文件异常");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private ConfigBuilder buildConfigBuilder(GenDTO dto) {
|
|
|
+ DataSourceConfig.Builder dataSource;
|
|
|
+ if (null != dto.getDatabaseId()) {
|
|
|
+ GenDatabase gb = genDatabaseService.getById(dto.getDatabaseId());
|
|
|
+ ApiAssert.fail(null == gb, "指定数据源不存在");
|
|
|
+ dataSource = new DataSourceConfig.Builder(gb.url(), gb.getUsername(), gb.getPassword());
|
|
|
+ } else {
|
|
|
+ dataSource = new DataSourceConfig.Builder(dsp.getUrl(), dsp.getUsername(), dsp.getPassword());
|
|
|
+ }
|
|
|
+
|
|
|
// 全局配置
|
|
|
- GlobalConfig.Builder globalConfig = new GlobalConfig.Builder().author("青苗")
|
|
|
- .outputDir("C://aizuda-code")
|
|
|
+ String author = dto.getAuthor();
|
|
|
+ if (StringUtils.isBlank(author)) {
|
|
|
+ author = UserSession.getLoginInfo().getUsername();
|
|
|
+ }
|
|
|
+ GlobalConfig.Builder globalConfig = new GlobalConfig.Builder().author(author)
|
|
|
.dateType(DateType.ONLY_DATE)
|
|
|
.enableSwagger();
|
|
|
// 包配置
|
|
|
- PackageConfig.Builder packageInfo = new PackageConfig.Builder().parent("com.aizuda.boot.modules.gen");
|
|
|
+ PackageConfig.Builder packageInfo = new PackageConfig.Builder().parent("com.aizuda.boot.modules." + dto.getModule());
|
|
|
// 策略配置
|
|
|
StrategyConfig.Builder strategy = new StrategyConfig.Builder();
|
|
|
- strategy.addInclude(List.of("sys_user", "sys_role"))
|
|
|
+ strategy.addInclude(Arrays.stream(dto.getTableName().split(",")).toList())
|
|
|
.controllerBuilder().enableRestStyle().enableHyphenStyle()
|
|
|
.serviceBuilder().superServiceClass("com.aizuda.service.service.IBaseService")
|
|
|
.mapperBuilder().superClass("com.aizuda.service.mapper.CrudMapper")
|
|
@@ -57,30 +148,20 @@ public class GenTableServiceImpl implements IGenTableService {
|
|
|
.superClass(BaseEntity.class);
|
|
|
// 注入配置
|
|
|
InjectionConfig.Builder injection = new InjectionConfig.Builder();
|
|
|
- // 模板配置
|
|
|
- TemplateConfig.Builder template = new TemplateConfig.Builder().disable(TemplateType.XML);
|
|
|
// 模板渲染引擎 new CodeTemplateEngine()
|
|
|
- ConfigBuilder config = new ConfigBuilder(packageInfo.build(), dataSource.build(), strategy.build(), template.build(),
|
|
|
+ return new ConfigBuilder(packageInfo.build(), dataSource.build(), strategy.build(), null,
|
|
|
globalConfig.build(), injection.build());
|
|
|
- List<TableInfo> tableInfos = config.getTableInfoList();
|
|
|
- VelocityTemplateEngine templateEngine = new VelocityTemplateEngine();
|
|
|
- templateEngine.init(config);
|
|
|
- tableInfos.forEach((tableInfo) -> {
|
|
|
- Map<String, Object> objectMap = this.getObjectMap(config, tableInfo);
|
|
|
- try {
|
|
|
- String tmp = templateEngine.writer(objectMap, tableInfo.getEntityName(), "hi ${author}");
|
|
|
- System.err.println("----dsa----" + tmp);
|
|
|
- } catch (Exception e) {
|
|
|
- throw new RuntimeException(e);
|
|
|
- }
|
|
|
- });
|
|
|
- return true;
|
|
|
}
|
|
|
|
|
|
- public Map<String, Object> getObjectMap(ConfigBuilder config, TableInfo tableInfo) {
|
|
|
+ private Map<String, Object> getObjectMap(ConfigBuilder config, TableInfo tableInfo) {
|
|
|
+
|
|
|
+ // 验证注解
|
|
|
+ this.validationAnnotations(tableInfo);
|
|
|
+
|
|
|
+ // 策略配置
|
|
|
StrategyConfig strategyConfig = config.getStrategyConfig();
|
|
|
Map<String, Object> controllerData = strategyConfig.controller().renderData(tableInfo);
|
|
|
- Map<String, Object> objectMap = new HashMap(controllerData);
|
|
|
+ Map<String, Object> objectMap = new HashMap<>(controllerData);
|
|
|
Map<String, Object> mapperData = strategyConfig.mapper().renderData(tableInfo);
|
|
|
objectMap.putAll(mapperData);
|
|
|
Map<String, Object> serviceData = strategyConfig.service().renderData(tableInfo);
|
|
@@ -109,4 +190,59 @@ public class GenTableServiceImpl implements IGenTableService {
|
|
|
objectMap.put("entity", tableInfo.getEntityName());
|
|
|
return objectMap;
|
|
|
}
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 追加校验注解
|
|
|
+ */
|
|
|
+ protected void validationAnnotations(TableInfo tableInfo) {
|
|
|
+ List<TableField> fields = tableInfo.getFields();
|
|
|
+ fields.forEach(tableField -> {
|
|
|
+ TableField.MetaInfo metaInfo = tableField.getMetaInfo();
|
|
|
+ final String lt = "\t";
|
|
|
+ final String lnt = "\n\t";
|
|
|
+ final JdbcType jdbcType = metaInfo.getJdbcType();
|
|
|
+ StringBuilder annotations = new StringBuilder();
|
|
|
+ boolean tabLine = false;
|
|
|
+ if (!metaInfo.isNullable()) {
|
|
|
+ annotations.append(lt);
|
|
|
+ if (JdbcType.VARCHAR == jdbcType) {
|
|
|
+ annotations.append("@NotBlank(groups = Create.class)");
|
|
|
+ tableInfo.addImportPackages("jakarta.validation.constraints.NotBlank");
|
|
|
+ } else {
|
|
|
+ annotations.append("@NotNull(groups = Create.class)");
|
|
|
+ tableInfo.addImportPackages("jakarta.validation.constraints.NotNull");
|
|
|
+ }
|
|
|
+ tabLine = true;
|
|
|
+ }
|
|
|
+ if (JdbcType.VARCHAR == jdbcType) {
|
|
|
+ annotations.append(tabLine ? lnt : lt);
|
|
|
+ annotations.append("@Size(max = ").append(metaInfo.getLength()).append(")");
|
|
|
+ tableInfo.addImportPackages("jakarta.validation.constraints.Size");
|
|
|
+ } else if (JdbcType.BIGINT == jdbcType
|
|
|
+ || JdbcType.INTEGER == jdbcType
|
|
|
+ || JdbcType.TINYINT == jdbcType
|
|
|
+ || JdbcType.SMALLINT == jdbcType
|
|
|
+ || JdbcType.BIT == jdbcType
|
|
|
+ || JdbcType.FLOAT == jdbcType
|
|
|
+ || JdbcType.DOUBLE == jdbcType
|
|
|
+ || JdbcType.DECIMAL == jdbcType) {
|
|
|
+ annotations.append(tabLine ? lnt : lt);
|
|
|
+ annotations.append("@PositiveOrZero");
|
|
|
+ tableInfo.addImportPackages("jakarta.validation.constraints.PositiveOrZero");
|
|
|
+ }
|
|
|
+ Map<String, Object> customMap = tableField.getCustomMap();
|
|
|
+ if (MapUtils.isEmpty(customMap)) {
|
|
|
+ customMap = new HashMap<>();
|
|
|
+ }
|
|
|
+ String va = annotations.toString();
|
|
|
+ if (org.apache.commons.lang3.StringUtils.isNotBlank(va)) {
|
|
|
+ va += lnt;
|
|
|
+ tableInfo.addImportPackages("com.aizuda.core.validation.Create");
|
|
|
+ } else {
|
|
|
+ va = lt;
|
|
|
+ }
|
|
|
+ customMap.put("validationAnnotations", va);
|
|
|
+ tableField.setCustomMap(customMap);
|
|
|
+ });
|
|
|
+ }
|
|
|
}
|