parent
ab97a08f48
commit
df0c0dd7dc
@ -20,6 +20,7 @@ import cn.hutool.core.map.MapUtil;
|
|||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
import top.charles7c.continew.starter.data.core.enums.DatabaseType;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@ -43,7 +44,7 @@ public class GeneratorProperties {
|
|||||||
/**
|
/**
|
||||||
* 类型映射
|
* 类型映射
|
||||||
*/
|
*/
|
||||||
private Map<String, Map<String, List<String>>> typeMappings = MapUtil.newHashMap();
|
private Map<DatabaseType, Map<String, List<String>>> typeMappings = MapUtil.newHashMap();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 模板配置
|
* 模板配置
|
||||||
|
@ -16,30 +16,24 @@
|
|||||||
|
|
||||||
package top.charles7c.continew.admin.generator.model.entity;
|
package top.charles7c.continew.admin.generator.model.entity;
|
||||||
|
|
||||||
import java.io.Serial;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import java.io.Serializable;
|
import com.baomidou.mybatisplus.annotation.*;
|
||||||
import java.time.LocalDateTime;
|
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import jakarta.validation.constraints.NotBlank;
|
import jakarta.validation.constraints.NotBlank;
|
||||||
import jakarta.validation.constraints.NotNull;
|
import jakarta.validation.constraints.NotNull;
|
||||||
import jakarta.validation.constraints.Pattern;
|
import jakarta.validation.constraints.Pattern;
|
||||||
|
|
||||||
import lombok.AccessLevel;
|
import lombok.AccessLevel;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
|
||||||
|
|
||||||
import org.hibernate.validator.constraints.Length;
|
import org.hibernate.validator.constraints.Length;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.annotation.*;
|
|
||||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
|
||||||
|
|
||||||
import cn.hutool.core.util.StrUtil;
|
|
||||||
|
|
||||||
import top.charles7c.continew.admin.common.constant.RegexConstants;
|
import top.charles7c.continew.admin.common.constant.RegexConstants;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 生成配置实体
|
* 生成配置实体
|
||||||
*
|
*
|
||||||
@ -80,13 +74,6 @@ public class GenConfigDO implements Serializable {
|
|||||||
@Length(max = 60, message = "包名称不能超过 {max} 个字符")
|
@Length(max = 60, message = "包名称不能超过 {max} 个字符")
|
||||||
private String packageName;
|
private String packageName;
|
||||||
|
|
||||||
/**
|
|
||||||
* 前端路径
|
|
||||||
*/
|
|
||||||
@Schema(description = "前端路径", example = "D:/continew-admin-ui/src/views/system/user")
|
|
||||||
@Length(max = 255, message = "前端路径不能超过 {max} 个字符")
|
|
||||||
private String frontendPath;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 业务名称
|
* 业务名称
|
||||||
*/
|
*/
|
||||||
|
@ -16,9 +16,8 @@
|
|||||||
|
|
||||||
package top.charles7c.continew.admin.generator.service;
|
package top.charles7c.continew.admin.generator.service;
|
||||||
|
|
||||||
import java.sql.SQLException;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import java.util.List;
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
import top.charles7c.continew.admin.generator.model.entity.FieldConfigDO;
|
import top.charles7c.continew.admin.generator.model.entity.FieldConfigDO;
|
||||||
import top.charles7c.continew.admin.generator.model.entity.GenConfigDO;
|
import top.charles7c.continew.admin.generator.model.entity.GenConfigDO;
|
||||||
import top.charles7c.continew.admin.generator.model.query.TableQuery;
|
import top.charles7c.continew.admin.generator.model.query.TableQuery;
|
||||||
@ -28,6 +27,9 @@ import top.charles7c.continew.admin.generator.model.resp.TableResp;
|
|||||||
import top.charles7c.continew.starter.extension.crud.model.query.PageQuery;
|
import top.charles7c.continew.starter.extension.crud.model.query.PageQuery;
|
||||||
import top.charles7c.continew.starter.extension.crud.model.resp.PageResp;
|
import top.charles7c.continew.starter.extension.crud.model.resp.PageResp;
|
||||||
|
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 代码生成业务接口
|
* 代码生成业务接口
|
||||||
*
|
*
|
||||||
@ -84,6 +86,8 @@ public interface GeneratorService {
|
|||||||
* 生成代码
|
* 生成代码
|
||||||
*
|
*
|
||||||
* @param tableName 表名称
|
* @param tableName 表名称
|
||||||
|
* @param request 请求对象
|
||||||
|
* @param response 响应对象
|
||||||
*/
|
*/
|
||||||
void generate(String tableName);
|
void generate(String tableName, HttpServletRequest request, HttpServletResponse response);
|
||||||
}
|
}
|
||||||
|
@ -24,9 +24,12 @@ import cn.hutool.core.io.FileUtil;
|
|||||||
import cn.hutool.core.io.file.FileNameUtil;
|
import cn.hutool.core.io.file.FileNameUtil;
|
||||||
import cn.hutool.core.util.ClassUtil;
|
import cn.hutool.core.util.ClassUtil;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import cn.hutool.core.util.ZipUtil;
|
||||||
import cn.hutool.db.meta.Column;
|
import cn.hutool.db.meta.Column;
|
||||||
import cn.hutool.system.SystemUtil;
|
import cn.hutool.system.SystemUtil;
|
||||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
@ -43,15 +46,17 @@ import top.charles7c.continew.admin.generator.model.req.GenConfigReq;
|
|||||||
import top.charles7c.continew.admin.generator.model.resp.GeneratePreviewResp;
|
import top.charles7c.continew.admin.generator.model.resp.GeneratePreviewResp;
|
||||||
import top.charles7c.continew.admin.generator.model.resp.TableResp;
|
import top.charles7c.continew.admin.generator.model.resp.TableResp;
|
||||||
import top.charles7c.continew.admin.generator.service.GeneratorService;
|
import top.charles7c.continew.admin.generator.service.GeneratorService;
|
||||||
|
import top.charles7c.continew.starter.core.autoconfigure.project.ProjectProperties;
|
||||||
import top.charles7c.continew.starter.core.constant.StringConstants;
|
import top.charles7c.continew.starter.core.constant.StringConstants;
|
||||||
import top.charles7c.continew.starter.core.exception.BusinessException;
|
import top.charles7c.continew.starter.core.exception.BusinessException;
|
||||||
import top.charles7c.continew.starter.core.util.TemplateUtils;
|
import top.charles7c.continew.starter.core.util.TemplateUtils;
|
||||||
|
import top.charles7c.continew.starter.core.util.validate.CheckUtils;
|
||||||
import top.charles7c.continew.starter.data.core.enums.DatabaseType;
|
import top.charles7c.continew.starter.data.core.enums.DatabaseType;
|
||||||
import top.charles7c.continew.starter.data.core.util.MetaUtils;
|
import top.charles7c.continew.starter.data.core.util.MetaUtils;
|
||||||
import top.charles7c.continew.starter.data.core.util.Table;
|
import top.charles7c.continew.starter.data.core.util.Table;
|
||||||
import top.charles7c.continew.starter.core.util.validate.CheckUtils;
|
|
||||||
import top.charles7c.continew.starter.extension.crud.model.query.PageQuery;
|
import top.charles7c.continew.starter.extension.crud.model.query.PageQuery;
|
||||||
import top.charles7c.continew.starter.extension.crud.model.resp.PageResp;
|
import top.charles7c.continew.starter.extension.crud.model.resp.PageResp;
|
||||||
|
import top.charles7c.continew.starter.web.util.FileUploadUtils;
|
||||||
|
|
||||||
import javax.sql.DataSource;
|
import javax.sql.DataSource;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
@ -73,6 +78,7 @@ public class GeneratorServiceImpl implements GeneratorService {
|
|||||||
|
|
||||||
private final DataSource dataSource;
|
private final DataSource dataSource;
|
||||||
private final GeneratorProperties generatorProperties;
|
private final GeneratorProperties generatorProperties;
|
||||||
|
private final ProjectProperties projectProperties;
|
||||||
private final FieldConfigMapper fieldConfigMapper;
|
private final FieldConfigMapper fieldConfigMapper;
|
||||||
private final GenConfigMapper genConfigMapper;
|
private final GenConfigMapper genConfigMapper;
|
||||||
|
|
||||||
@ -139,8 +145,7 @@ public class GeneratorServiceImpl implements GeneratorService {
|
|||||||
Collection<Column> columnList = MetaUtils.getColumns(dataSource, tableName);
|
Collection<Column> columnList = MetaUtils.getColumns(dataSource, tableName);
|
||||||
// 获取数据库对应的类型映射配置
|
// 获取数据库对应的类型映射配置
|
||||||
DatabaseType databaseType = MetaUtils.getDatabaseType(dataSource);
|
DatabaseType databaseType = MetaUtils.getDatabaseType(dataSource);
|
||||||
Map<String, List<String>> typeMappingMap = generatorProperties.getTypeMappings()
|
Map<String, List<String>> typeMappingMap = generatorProperties.getTypeMappings().get(databaseType);
|
||||||
.get(databaseType.getDatabase());
|
|
||||||
CheckUtils.throwIfEmpty(typeMappingMap, "请先配置对应数据库的类型映射");
|
CheckUtils.throwIfEmpty(typeMappingMap, "请先配置对应数据库的类型映射");
|
||||||
Set<Map.Entry<String, List<String>>> typeMappingEntrySet = typeMappingMap.entrySet();
|
Set<Map.Entry<String, List<String>>> typeMappingEntrySet = typeMappingMap.entrySet();
|
||||||
// 新增或更新字段配置
|
// 新增或更新字段配置
|
||||||
@ -198,11 +203,6 @@ public class GeneratorServiceImpl implements GeneratorService {
|
|||||||
fieldConfigMapper.insertBatch(fieldConfigList);
|
fieldConfigMapper.insertBatch(fieldConfigList);
|
||||||
// 保存或更新生成配置信息
|
// 保存或更新生成配置信息
|
||||||
GenConfigDO newGenConfig = req.getGenConfig();
|
GenConfigDO newGenConfig = req.getGenConfig();
|
||||||
String frontendPath = newGenConfig.getFrontendPath();
|
|
||||||
if (StrUtil.isNotBlank(frontendPath)) {
|
|
||||||
CheckUtils.throwIf(!FileUtil.exist(frontendPath), "前端路径不存在");
|
|
||||||
CheckUtils.throwIf(!StrUtil.containsAll(frontendPath, "src", "views"), "前端路径配置错误");
|
|
||||||
}
|
|
||||||
GenConfigDO oldGenConfig = genConfigMapper.selectById(tableName);
|
GenConfigDO oldGenConfig = genConfigMapper.selectById(tableName);
|
||||||
if (null != oldGenConfig) {
|
if (null != oldGenConfig) {
|
||||||
BeanUtil.copyProperties(newGenConfig, oldGenConfig);
|
BeanUtil.copyProperties(newGenConfig, oldGenConfig);
|
||||||
@ -236,106 +236,118 @@ public class GeneratorServiceImpl implements GeneratorService {
|
|||||||
genConfigMap.put("className", className);
|
genConfigMap.put("className", className);
|
||||||
TemplateConfig templateConfig = templateConfigEntry.getValue();
|
TemplateConfig templateConfig = templateConfigEntry.getValue();
|
||||||
String content = TemplateUtils.render(templateConfig.getTemplatePath(), genConfigMap);
|
String content = TemplateUtils.render(templateConfig.getTemplatePath(), genConfigMap);
|
||||||
GeneratePreviewResp codePreview = new GeneratePreviewResp();
|
GeneratePreviewResp generatePreview = new GeneratePreviewResp();
|
||||||
codePreview.setFileName(className + FileNameUtil.EXT_JAVA);
|
generatePreview.setFileName(className + FileNameUtil.EXT_JAVA);
|
||||||
codePreview.setContent(content);
|
generatePreview.setContent(content);
|
||||||
codePreview.setBackend(true);
|
generatePreview.setBackend(true);
|
||||||
generatePreviewList.add(codePreview);
|
generatePreviewList.add(generatePreview);
|
||||||
}
|
}
|
||||||
// 渲染前端代码
|
// 渲染前端代码
|
||||||
// api 代码
|
// api 代码
|
||||||
genConfigMap.put("fieldConfigs", fieldConfigList);
|
genConfigMap.put("fieldConfigs", fieldConfigList);
|
||||||
String apiContent = TemplateUtils.render("api.ftl", genConfigMap);
|
String apiContent = TemplateUtils.render("api.ftl", genConfigMap);
|
||||||
GeneratePreviewResp apiCodePreview = new GeneratePreviewResp();
|
GeneratePreviewResp apiGeneratePreview = new GeneratePreviewResp();
|
||||||
apiCodePreview.setFileName(classNamePrefix.toLowerCase() + ".ts");
|
apiGeneratePreview.setFileName(classNamePrefix.toLowerCase() + ".ts");
|
||||||
apiCodePreview.setContent(apiContent);
|
apiGeneratePreview.setContent(apiContent);
|
||||||
generatePreviewList.add(apiCodePreview);
|
generatePreviewList.add(apiGeneratePreview);
|
||||||
// view 代码
|
// view 代码
|
||||||
String viewContent = TemplateUtils.render("index.ftl", genConfigMap);
|
String viewContent = TemplateUtils.render("index.ftl", genConfigMap);
|
||||||
GeneratePreviewResp viewCodePreview = new GeneratePreviewResp();
|
GeneratePreviewResp viewGeneratePreview = new GeneratePreviewResp();
|
||||||
viewCodePreview.setFileName("index.vue");
|
viewGeneratePreview.setFileName("index.vue");
|
||||||
viewCodePreview.setContent(viewContent);
|
viewGeneratePreview.setContent(viewContent);
|
||||||
generatePreviewList.add(viewCodePreview);
|
generatePreviewList.add(viewGeneratePreview);
|
||||||
return generatePreviewList;
|
return generatePreviewList;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void generate(String tableName) {
|
public void generate(String tableName, HttpServletRequest request, HttpServletResponse response) {
|
||||||
// 初始化配置及数据
|
|
||||||
List<GeneratePreviewResp> generatePreviewList = this.preview(tableName);
|
|
||||||
GenConfigDO genConfig = genConfigMapper.selectById(tableName);
|
|
||||||
Boolean isOverride = genConfig.getIsOverride();
|
|
||||||
// 生成代码
|
|
||||||
String packageName = genConfig.getPackageName();
|
|
||||||
try {
|
try {
|
||||||
|
// 初始化配置及数据
|
||||||
|
List<GeneratePreviewResp> generatePreviewList = this.preview(tableName);
|
||||||
|
GenConfigDO genConfig = genConfigMapper.selectById(tableName);
|
||||||
// 生成后端代码
|
// 生成后端代码
|
||||||
String classNamePrefix = genConfig.getClassNamePrefix();
|
Map<Boolean, List<GeneratePreviewResp>> generatePreviewListMap = generatePreviewList.stream()
|
||||||
// 1.确定后端代码基础路径
|
.collect(Collectors.groupingBy(GeneratePreviewResp::isBackend));
|
||||||
// 例如:D:/continew-admin
|
this.generateBackendCode(generatePreviewListMap.get(true), genConfig);
|
||||||
String projectPath = SystemUtil.getUserInfo().getCurrentDir();
|
|
||||||
// 例如:D:/continew-admin/continew-admin-system
|
|
||||||
File backendModuleFile = new File(projectPath, genConfig.getModuleName());
|
|
||||||
// 例如:D:/continew-admin/continew-admin-system/src/main/java/top/charles7c/continew/admin/system
|
|
||||||
List<String> backendModuleChildPathList = CollUtil.newArrayList("src", "main", "java");
|
|
||||||
backendModuleChildPathList.addAll(StrUtil.split(packageName, StringConstants.DOT));
|
|
||||||
File backendParentFile = FileUtil.file(backendModuleFile, backendModuleChildPathList
|
|
||||||
.toArray(new String[0]));
|
|
||||||
// 2.生成代码
|
|
||||||
List<GeneratePreviewResp> backendCodePreviewList = generatePreviewList.stream()
|
|
||||||
.filter(GeneratePreviewResp::isBackend)
|
|
||||||
.toList();
|
|
||||||
Map<String, TemplateConfig> templateConfigMap = generatorProperties.getTemplateConfigs();
|
|
||||||
for (GeneratePreviewResp codePreview : backendCodePreviewList) {
|
|
||||||
// 例如:D:/continew-admin/continew-admin-system/src/main/java/top/charles7c/continew/admin/system/service/impl/XxxServiceImpl.java
|
|
||||||
TemplateConfig templateConfig = templateConfigMap.get(codePreview.getFileName()
|
|
||||||
.replace(classNamePrefix, StringConstants.EMPTY)
|
|
||||||
.replace(FileNameUtil.EXT_JAVA, StringConstants.EMPTY));
|
|
||||||
File classParentFile = FileUtil.file(backendParentFile, StrUtil.splitToArray(templateConfig
|
|
||||||
.getPackageName(), StringConstants.DOT));
|
|
||||||
File classFile = new File(classParentFile, codePreview.getFileName());
|
|
||||||
// 如果已经存在,且不允许覆盖,则跳过
|
|
||||||
if (classFile.exists() && Boolean.FALSE.equals(isOverride)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
FileUtil.writeUtf8String(codePreview.getContent(), classFile);
|
|
||||||
}
|
|
||||||
// 生成前端代码
|
// 生成前端代码
|
||||||
String frontendPath = genConfig.getFrontendPath();
|
List<GeneratePreviewResp> frontendGeneratePreviewList = generatePreviewListMap.get(false);
|
||||||
if (StrUtil.isBlank(frontendPath)) {
|
String packageName = genConfig.getPackageName();
|
||||||
return;
|
String moduleName = StrUtil.subSuf(packageName, StrUtil
|
||||||
}
|
|
||||||
List<GeneratePreviewResp> frontendCodePreviewList = generatePreviewList.stream()
|
|
||||||
.filter(p -> !p.isBackend())
|
|
||||||
.toList();
|
|
||||||
// 1.生成 api 代码
|
|
||||||
String apiModuleName = StrUtil.subSuf(packageName, StrUtil
|
|
||||||
.lastIndexOfIgnoreCase(packageName, StringConstants.DOT) + 1);
|
.lastIndexOfIgnoreCase(packageName, StringConstants.DOT) + 1);
|
||||||
GeneratePreviewResp apiCodePreview = frontendCodePreviewList.get(0);
|
String tempDir = SystemUtil.getUserInfo().getTempDir();
|
||||||
// 例如:D:/continew-admin-ui
|
// 例如:continew-admin-ui/src
|
||||||
List<String> frontendSubPathList = StrUtil.split(frontendPath, "src");
|
String frontendBasicPackagePath = tempDir + String.join(File.separator, projectProperties
|
||||||
String frontendModulePath = frontendSubPathList.get(0);
|
.getAppName(), projectProperties.getAppName() + "-ui", "src");
|
||||||
// 例如:D:/continew-admin-ui/src/api/tool/xxx.ts
|
// 1、生成 api 代码
|
||||||
File apiParentFile = FileUtil.file(frontendModulePath, "src", "api", apiModuleName);
|
GeneratePreviewResp apiGeneratePreview = frontendGeneratePreviewList.get(0);
|
||||||
File apiFile = new File(apiParentFile, apiCodePreview.getFileName());
|
// 例如:continew-admin-ui/src/src/api/system
|
||||||
if (apiFile.exists() && Boolean.FALSE.equals(isOverride)) {
|
String apiPath = String.join(File.separator, frontendBasicPackagePath, "api", moduleName);
|
||||||
return;
|
// 例如:continew-admin-ui/src/api/system/user.ts
|
||||||
|
File apiFile = new File(apiPath, apiGeneratePreview.getFileName());
|
||||||
|
if (!apiFile.exists() || Boolean.TRUE.equals(genConfig.getIsOverride())) {
|
||||||
|
FileUtil.writeUtf8String(apiGeneratePreview.getContent(), apiFile);
|
||||||
}
|
}
|
||||||
FileUtil.writeUtf8String(apiCodePreview.getContent(), apiFile);
|
// 2、生成 view 代码
|
||||||
// 2.生成 view 代码
|
GeneratePreviewResp viewGeneratePreview = frontendGeneratePreviewList.get(1);
|
||||||
GeneratePreviewResp viewCodePreview = frontendCodePreviewList.get(1);
|
// 例如:continew-admin-ui/src/views/system
|
||||||
// 例如:D:/continew-admin-ui/src/views/system/xxx/index.vue
|
String vuePath = String.join(File.separator, frontendBasicPackagePath, "views", moduleName, StrUtil
|
||||||
File indexFile = FileUtil.file(frontendPath, apiModuleName, StrUtil
|
.lowerFirst(genConfig.getClassNamePrefix()));
|
||||||
.lowerFirst(classNamePrefix), "index.vue");
|
// 例如:continew-admin-ui/src/views/system/user/index.vue
|
||||||
if (indexFile.exists() && Boolean.FALSE.equals(isOverride)) {
|
File vueFile = new File(vuePath, viewGeneratePreview.getFileName());
|
||||||
return;
|
if (!vueFile.exists() || Boolean.TRUE.equals(genConfig.getIsOverride())) {
|
||||||
|
FileUtil.writeUtf8String(viewGeneratePreview.getContent(), vueFile);
|
||||||
}
|
}
|
||||||
FileUtil.writeUtf8String(viewCodePreview.getContent(), indexFile);
|
// 打包下载
|
||||||
|
File tempDirFile = new File(tempDir, projectProperties.getAppName());
|
||||||
|
String zipFilePath = tempDirFile.getPath() + ".zip";
|
||||||
|
ZipUtil.zip(tempDirFile.getPath(), zipFilePath);
|
||||||
|
FileUploadUtils.download(request, response, new File(zipFilePath), true);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("Generate code occurred an error: {}. tableName: {}.", e.getMessage(), tableName, e);
|
log.error("Generate code of table '{}' occurred an error. {}", tableName, e.getMessage(), e);
|
||||||
throw new BusinessException("代码生成失败,请手动清理生成文件");
|
throw new BusinessException("代码生成失败,请手动清理生成文件");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成后端代码
|
||||||
|
*
|
||||||
|
* @param generatePreviewList 生成预览列表
|
||||||
|
* @param genConfig 生成配置
|
||||||
|
*/
|
||||||
|
private void generateBackendCode(List<GeneratePreviewResp> generatePreviewList, GenConfigDO genConfig) {
|
||||||
|
String backendBasicPackagePath = this.buildBackendBasicPackagePath(genConfig);
|
||||||
|
Map<String, TemplateConfig> templateConfigMap = generatorProperties.getTemplateConfigs();
|
||||||
|
for (GeneratePreviewResp generatePreview : generatePreviewList) {
|
||||||
|
// 获取对应模板配置
|
||||||
|
TemplateConfig templateConfig = templateConfigMap.get(generatePreview.getFileName()
|
||||||
|
.replace(genConfig.getClassNamePrefix(), StringConstants.EMPTY)
|
||||||
|
.replace(FileNameUtil.EXT_JAVA, StringConstants.EMPTY));
|
||||||
|
// 例如:continew-admin/continew-admin-system/src/main/java/top/charles7c/continew/admin/system/service/impl
|
||||||
|
String packagePath = String.join(File.separator, backendBasicPackagePath, templateConfig.getPackageName()
|
||||||
|
.replace(StringConstants.DOT, File.separator));
|
||||||
|
// 例如:continew-admin/continew-admin-system/src/main/java/top/charles7c/continew/admin/system/service/impl/XxxServiceImpl.java
|
||||||
|
File classFile = new File(packagePath, generatePreview.getFileName());
|
||||||
|
// 如果已经存在,且不允许覆盖,则跳过
|
||||||
|
if (!classFile.exists() || Boolean.TRUE.equals(genConfig.getIsOverride())) {
|
||||||
|
FileUtil.writeUtf8String(generatePreview.getContent(), classFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 构建后端包路径
|
||||||
|
*
|
||||||
|
* @param genConfig 生成配置
|
||||||
|
* @return 后端包路径
|
||||||
|
*/
|
||||||
|
private String buildBackendBasicPackagePath(GenConfigDO genConfig) {
|
||||||
|
// 例如:continew-admin/continew-admin-system/src/main/java/top/charles7c/continew/admin/system
|
||||||
|
return SystemUtil.getUserInfo().getTempDir() + String.join(File.separator, projectProperties
|
||||||
|
.getAppName(), projectProperties.getAppName(), genConfig.getModuleName(), "src", "main", "java", genConfig
|
||||||
|
.getPackageName()
|
||||||
|
.replace(StringConstants.DOT, File.separator));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 预处理生成配置
|
* 预处理生成配置
|
||||||
*
|
*
|
||||||
|
@ -13,6 +13,8 @@
|
|||||||
const { proxy } = getCurrentInstance() as any;
|
const { proxy } = getCurrentInstance() as any;
|
||||||
// const { dis_enable_status_enum } = proxy.useDict('dis_enable_status_enum');
|
// const { dis_enable_status_enum } = proxy.useDict('dis_enable_status_enum');
|
||||||
|
|
||||||
|
const queryFormRef = ref();
|
||||||
|
const formRef = ref();
|
||||||
const dataList = ref<DataRecord[]>([]);
|
const dataList = ref<DataRecord[]>([]);
|
||||||
const dataDetail = ref<DataRecord>({
|
const dataDetail = ref<DataRecord>({
|
||||||
// TODO 待补充详情字段默认值
|
// TODO 待补充详情字段默认值
|
||||||
@ -102,7 +104,7 @@
|
|||||||
form.value = {
|
form.value = {
|
||||||
// TODO 待补充需要重置的字段默认值,详情请参考其他模块 index.vue
|
// TODO 待补充需要重置的字段默认值,详情请参考其他模块 index.vue
|
||||||
};
|
};
|
||||||
proxy.$refs.formRef?.resetFields();
|
formRef.value.resetFields();
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -110,14 +112,14 @@
|
|||||||
*/
|
*/
|
||||||
const handleCancel = () => {
|
const handleCancel = () => {
|
||||||
visible.value = false;
|
visible.value = false;
|
||||||
proxy.$refs.formRef.resetFields();
|
formRef.value.resetFields();
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 确定
|
* 确定
|
||||||
*/
|
*/
|
||||||
const handleOk = () => {
|
const handleOk = () => {
|
||||||
proxy.$refs.formRef.validate((valid: any) => {
|
formRef.value.validate((valid: any) => {
|
||||||
if (!valid) {
|
if (!valid) {
|
||||||
if (form.value.id !== undefined) {
|
if (form.value.id !== undefined) {
|
||||||
update(form.value, form.value.id).then((res) => {
|
update(form.value, form.value.id).then((res) => {
|
||||||
@ -227,7 +229,7 @@
|
|||||||
* 重置
|
* 重置
|
||||||
*/
|
*/
|
||||||
const resetQuery = () => {
|
const resetQuery = () => {
|
||||||
proxy.$refs.queryRef.resetFields();
|
queryFormRef.value.resetFields();
|
||||||
handleQuery();
|
handleQuery();
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -266,7 +268,7 @@
|
|||||||
<div class="header">
|
<div class="header">
|
||||||
<!-- 搜索栏 -->
|
<!-- 搜索栏 -->
|
||||||
<div v-if="showQuery" class="header-query">
|
<div v-if="showQuery" class="header-query">
|
||||||
<a-form ref="queryRef" :model="queryParams" layout="inline">
|
<a-form ref="queryFormRef" :model="queryParams" layout="inline">
|
||||||
<#list fieldConfigs as fieldConfig>
|
<#list fieldConfigs as fieldConfig>
|
||||||
<#if fieldConfig.showInQuery>
|
<#if fieldConfig.showInQuery>
|
||||||
<a-form-item field="${fieldConfig.fieldName}" hide-label>
|
<a-form-item field="${fieldConfig.fieldName}" hide-label>
|
||||||
@ -347,7 +349,6 @@
|
|||||||
|
|
||||||
<!-- 列表区域 -->
|
<!-- 列表区域 -->
|
||||||
<a-table
|
<a-table
|
||||||
ref="tableRef"
|
|
||||||
row-key="id"
|
row-key="id"
|
||||||
:data="dataList"
|
:data="dataList"
|
||||||
:loading="loading"
|
:loading="loading"
|
||||||
|
@ -21,6 +21,8 @@ import io.swagger.v3.oas.annotations.Operation;
|
|||||||
import io.swagger.v3.oas.annotations.Parameter;
|
import io.swagger.v3.oas.annotations.Parameter;
|
||||||
import io.swagger.v3.oas.annotations.enums.ParameterIn;
|
import io.swagger.v3.oas.annotations.enums.ParameterIn;
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
@ -32,7 +34,6 @@ import top.charles7c.continew.admin.generator.model.resp.GeneratePreviewResp;
|
|||||||
import top.charles7c.continew.admin.generator.model.resp.TableResp;
|
import top.charles7c.continew.admin.generator.model.resp.TableResp;
|
||||||
import top.charles7c.continew.admin.generator.service.GeneratorService;
|
import top.charles7c.continew.admin.generator.service.GeneratorService;
|
||||||
import top.charles7c.continew.starter.core.autoconfigure.project.ProjectProperties;
|
import top.charles7c.continew.starter.core.autoconfigure.project.ProjectProperties;
|
||||||
import top.charles7c.continew.starter.core.util.validate.ValidationUtils;
|
|
||||||
import top.charles7c.continew.starter.extension.crud.model.query.PageQuery;
|
import top.charles7c.continew.starter.extension.crud.model.query.PageQuery;
|
||||||
import top.charles7c.continew.starter.extension.crud.model.resp.PageResp;
|
import top.charles7c.continew.starter.extension.crud.model.resp.PageResp;
|
||||||
import top.charles7c.continew.starter.web.model.R;
|
import top.charles7c.continew.starter.web.model.R;
|
||||||
@ -102,9 +103,7 @@ public class GeneratorController {
|
|||||||
@Parameter(name = "tableName", description = "表名称", required = true, example = "sys_user", in = ParameterIn.PATH)
|
@Parameter(name = "tableName", description = "表名称", required = true, example = "sys_user", in = ParameterIn.PATH)
|
||||||
@SaCheckPermission("tool:generator:list")
|
@SaCheckPermission("tool:generator:list")
|
||||||
@PostMapping("/{tableName}")
|
@PostMapping("/{tableName}")
|
||||||
public R<Void> generate(@PathVariable String tableName) {
|
public void generate(@PathVariable String tableName, HttpServletRequest request, HttpServletResponse response) {
|
||||||
ValidationUtils.throwIf(projectProperties.isProduction(), "仅支持在开发环境生成代码");
|
generatorService.generate(tableName, request, response);
|
||||||
generatorService.generate(tableName);
|
|
||||||
return R.ok("生成成功,请查看生成代码是否正确");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@ generator:
|
|||||||
- gen_field_config
|
- gen_field_config
|
||||||
## 类型映射
|
## 类型映射
|
||||||
typeMappings:
|
typeMappings:
|
||||||
MySQL:
|
MYSQL:
|
||||||
Integer:
|
Integer:
|
||||||
- int
|
- int
|
||||||
- tinyint
|
- tinyint
|
||||||
|
@ -277,7 +277,6 @@ CREATE TABLE IF NOT EXISTS `gen_config` (
|
|||||||
`table_name` varchar(64) NOT NULL COMMENT '表名称',
|
`table_name` varchar(64) NOT NULL COMMENT '表名称',
|
||||||
`module_name` varchar(60) NOT NULL COMMENT '模块名称',
|
`module_name` varchar(60) NOT NULL COMMENT '模块名称',
|
||||||
`package_name` varchar(60) NOT NULL COMMENT '包名称',
|
`package_name` varchar(60) NOT NULL COMMENT '包名称',
|
||||||
`frontend_path` varchar(255) DEFAULT NULL COMMENT '前端路径',
|
|
||||||
`business_name` varchar(50) NOT NULL COMMENT '业务名称',
|
`business_name` varchar(50) NOT NULL COMMENT '业务名称',
|
||||||
`author` varchar(100) NOT NULL COMMENT '作者',
|
`author` varchar(100) NOT NULL COMMENT '作者',
|
||||||
`table_prefix` varchar(20) DEFAULT NULL COMMENT '表前缀',
|
`table_prefix` varchar(20) DEFAULT NULL COMMENT '表前缀',
|
||||||
|
@ -462,7 +462,6 @@ CREATE TABLE IF NOT EXISTS "gen_config" (
|
|||||||
"table_name" varchar(64) NOT NULL,
|
"table_name" varchar(64) NOT NULL,
|
||||||
"module_name" varchar(60) NOT NULL,
|
"module_name" varchar(60) NOT NULL,
|
||||||
"package_name" varchar(60) NOT NULL,
|
"package_name" varchar(60) NOT NULL,
|
||||||
"frontend_path" varchar(255) DEFAULT NULL,
|
|
||||||
"business_name" varchar(50) NOT NULL,
|
"business_name" varchar(50) NOT NULL,
|
||||||
"author" varchar(100) NOT NULL,
|
"author" varchar(100) NOT NULL,
|
||||||
"table_prefix" varchar(20) DEFAULT NULL,
|
"table_prefix" varchar(20) DEFAULT NULL,
|
||||||
@ -474,7 +473,6 @@ CREATE TABLE IF NOT EXISTS "gen_config" (
|
|||||||
COMMENT ON COLUMN "gen_config"."table_name" IS '表名称';
|
COMMENT ON COLUMN "gen_config"."table_name" IS '表名称';
|
||||||
COMMENT ON COLUMN "gen_config"."module_name" IS '模块名称';
|
COMMENT ON COLUMN "gen_config"."module_name" IS '模块名称';
|
||||||
COMMENT ON COLUMN "gen_config"."package_name" IS '包名称';
|
COMMENT ON COLUMN "gen_config"."package_name" IS '包名称';
|
||||||
COMMENT ON COLUMN "gen_config"."frontend_path" IS '前端路径';
|
|
||||||
COMMENT ON COLUMN "gen_config"."business_name" IS '业务名称';
|
COMMENT ON COLUMN "gen_config"."business_name" IS '业务名称';
|
||||||
COMMENT ON COLUMN "gen_config"."author" IS '作者';
|
COMMENT ON COLUMN "gen_config"."author" IS '作者';
|
||||||
COMMENT ON COLUMN "gen_config"."table_prefix" IS '表前缀';
|
COMMENT ON COLUMN "gen_config"."table_prefix" IS '表前缀';
|
||||||
|
Loading…
Reference in New Issue
Block a user