mirror of
https://github.com/continew-org/continew-admin.git
synced 2025-10-21 14:57:09 +08:00
feat: 新增生成代码接口(后端代码)
This commit is contained in:
@@ -79,4 +79,12 @@ public interface GeneratorService {
|
||||
* 表名称
|
||||
*/
|
||||
void saveConfig(GenConfigRequest request, String tableName);
|
||||
|
||||
/**
|
||||
* 生成代码
|
||||
*
|
||||
* @param tableName
|
||||
* 表名称
|
||||
*/
|
||||
void generate(String tableName);
|
||||
}
|
||||
|
@@ -16,6 +16,8 @@
|
||||
|
||||
package top.charles7c.cnadmin.tool.service.impl;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
@@ -35,15 +37,24 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import cn.hutool.core.io.file.FileNameUtil;
|
||||
import cn.hutool.core.map.MapUtil;
|
||||
import cn.hutool.core.util.ClassUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.db.meta.Column;
|
||||
import cn.hutool.system.SystemUtil;
|
||||
|
||||
import top.charles7c.cnadmin.common.constant.StringConsts;
|
||||
import top.charles7c.cnadmin.common.enums.QueryTypeEnum;
|
||||
import top.charles7c.cnadmin.common.exception.ServiceException;
|
||||
import top.charles7c.cnadmin.common.model.query.PageQuery;
|
||||
import top.charles7c.cnadmin.common.model.vo.PageDataVO;
|
||||
import top.charles7c.cnadmin.common.util.TemplateUtils;
|
||||
import top.charles7c.cnadmin.common.util.validate.CheckUtils;
|
||||
import top.charles7c.cnadmin.tool.config.properties.GeneratorProperties;
|
||||
import top.charles7c.cnadmin.tool.config.properties.GeneratorProperties.TemplateConfig;
|
||||
import top.charles7c.cnadmin.tool.mapper.FieldConfigMapper;
|
||||
import top.charles7c.cnadmin.tool.mapper.GenConfigMapper;
|
||||
import top.charles7c.cnadmin.tool.model.entity.FieldConfigDO;
|
||||
@@ -182,6 +193,10 @@ public class GeneratorServiceImpl implements GeneratorService {
|
||||
|
||||
// 保存或更新生成配置信息
|
||||
GenConfigDO newGenConfig = request.getGenConfig();
|
||||
String frontendPath = newGenConfig.getFrontendPath();
|
||||
if (StrUtil.isNotBlank(frontendPath)) {
|
||||
CheckUtils.throwIf(!StrUtil.containsAll(frontendPath, "src", "views"), "前端路径配置错误");
|
||||
}
|
||||
GenConfigDO oldGenConfig = genConfigMapper.selectById(tableName);
|
||||
if (null != oldGenConfig) {
|
||||
BeanUtil.copyProperties(newGenConfig, oldGenConfig);
|
||||
@@ -190,4 +205,122 @@ public class GeneratorServiceImpl implements GeneratorService {
|
||||
genConfigMapper.insert(newGenConfig);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generate(String tableName) {
|
||||
GenConfigDO genConfig = genConfigMapper.selectById(tableName);
|
||||
CheckUtils.throwIfNull(genConfig, "请先进行数据表 [{}] 生成配置", tableName);
|
||||
List<FieldConfigDO> fieldConfigList = fieldConfigMapper.selectListByTableName(tableName);
|
||||
CheckUtils.throwIfEmpty(fieldConfigList, "请先进行数据表 [{}] 字段配置", tableName);
|
||||
Map<String, Object> genConfigMap = this.pretreatment(genConfig, fieldConfigList);
|
||||
|
||||
try {
|
||||
String classNamePrefix = genConfig.getClassNamePrefix();
|
||||
Boolean isOverride = genConfig.getIsOverride();
|
||||
// 生成后端代码
|
||||
// 1、确定后端代码基础路径
|
||||
// 例如:D:/continew-admin
|
||||
String projectPath = SystemUtil.getUserInfo().getCurrentDir();
|
||||
// 例如:D:/continew-admin/continew-admin-tool
|
||||
File backendModuleFile = new File(projectPath, genConfig.getModuleName());
|
||||
// 例如:D:/continew-admin/continew-admin-tool/src/main/java/top/charles7c/cnadmin/tool
|
||||
List<String> backendModuleChildPathList = CollUtil.newArrayList("src", "main", "java");
|
||||
backendModuleChildPathList.addAll(StrUtil.split(genConfig.getPackageName(), StringConsts.DOT));
|
||||
File backendParentFile =
|
||||
FileUtil.file(backendModuleFile, backendModuleChildPathList.toArray(new String[0]));
|
||||
// 2、生成代码
|
||||
Map<String, TemplateConfig> templateConfigMap = generatorProperties.getTemplateConfigs();
|
||||
for (Map.Entry<String, TemplateConfig> templateConfigEntry : templateConfigMap.entrySet()) {
|
||||
// 例如:D:/continew-admin/continew-admin-tool/src/main/java/top/charles7c/cnadmin/tool/service/impl/XxxServiceImpl.java
|
||||
TemplateConfig templateConfig = templateConfigEntry.getValue();
|
||||
String subPackageName = templateConfig.getPackageName();
|
||||
genConfigMap.put("subPackageName", subPackageName);
|
||||
File classParentFile =
|
||||
FileUtil.file(backendParentFile, StrUtil.splitToArray(subPackageName, StringConsts.DOT));
|
||||
String className = classNamePrefix + StrUtil.nullToEmpty(templateConfigEntry.getKey());
|
||||
genConfigMap.put("className", className);
|
||||
File classFile = new File(classParentFile, className + FileNameUtil.EXT_JAVA);
|
||||
// 如果已经存在,且不允许覆盖,则跳过
|
||||
if (classFile.exists() && !isOverride) {
|
||||
continue;
|
||||
}
|
||||
String content = TemplateUtils.render(templateConfig.getTemplatePath(), genConfigMap);
|
||||
FileUtil.writeString(content, classFile, StandardCharsets.UTF_8);
|
||||
}
|
||||
|
||||
// 生成前端代码
|
||||
String frontendPath = genConfig.getFrontendPath();
|
||||
if (StrUtil.isBlank(frontendPath)) {
|
||||
return;
|
||||
}
|
||||
// 1、生成 api 代码
|
||||
// 例如:D:/continew-admin/continew-admin-ui
|
||||
List<String> frontendSubPathList = StrUtil.split(frontendPath, "src");
|
||||
String frontendModulePath = frontendSubPathList.get(0);
|
||||
// 例如:D:/continew-admin/continew-admin-ui/src/api/tool/xxx.ts
|
||||
String moduleSimpleName = new File(frontendPath).getName();
|
||||
File apiParentFile = FileUtil.file(frontendModulePath, "src", "api", moduleSimpleName);
|
||||
String apiFileName = classNamePrefix.toLowerCase() + ".ts";
|
||||
File apiFile = new File(apiParentFile, apiFileName);
|
||||
if (apiFile.exists() && !isOverride) {
|
||||
return;
|
||||
}
|
||||
String apiContent = TemplateUtils.render("generator/api.ftl", genConfigMap);
|
||||
FileUtil.writeString(apiContent, apiFile, StandardCharsets.UTF_8);
|
||||
// 2、生成 view 代码
|
||||
// 例如:D:/continew-admin/continew-admin-ui/src/views/tool/xxx/index.vue
|
||||
File indexFile = FileUtil.file(frontendPath, classNamePrefix, "index.vue");
|
||||
if (indexFile.exists() && !isOverride) {
|
||||
return;
|
||||
}
|
||||
String indexContent = TemplateUtils.render("generator/index.ftl", genConfigMap);
|
||||
FileUtil.writeString(indexContent, indexFile, StandardCharsets.UTF_8);
|
||||
} catch (Exception e) {
|
||||
log.error("Generate code occurred an error: {}. tableName: {}.", e.getMessage(), tableName, e);
|
||||
throw new ServiceException("代码生成失败,请手动清理生成文件");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 预处理生成配置
|
||||
*
|
||||
* @param genConfig
|
||||
* 生成配置
|
||||
* @param fieldConfigList
|
||||
* 字段配置列表
|
||||
* @return 处理后的生成配置
|
||||
*/
|
||||
private Map<String, Object> pretreatment(GenConfigDO genConfig, List<FieldConfigDO> fieldConfigList) {
|
||||
Map<String, Object> genConfigMap = MapUtil.newHashMap();
|
||||
genConfigMap.put("date", DateUtil.date().toString("yyyy/MM/dd HH:mm"));
|
||||
genConfigMap.put("hasLocalDateTime", false);
|
||||
genConfigMap.put("hasBigDecimal", false);
|
||||
genConfigMap.put("hasRequiredField", false);
|
||||
genConfigMap.put("hasListQueryField", false);
|
||||
for (FieldConfigDO fieldConfig : fieldConfigList) {
|
||||
String fieldType = fieldConfig.getFieldType();
|
||||
if ("LocalDateTime".equals(fieldType)) {
|
||||
genConfigMap.put("hasLocalDateTime", true);
|
||||
}
|
||||
if ("BigDecimal".equals(fieldType)) {
|
||||
genConfigMap.put("hasLocalDateTime", true);
|
||||
}
|
||||
if (Boolean.TRUE.equals(fieldConfig.getIsRequired())) {
|
||||
genConfigMap.put("hasRequiredField", true);
|
||||
}
|
||||
QueryTypeEnum queryType = fieldConfig.getQueryType();
|
||||
if (null != queryType && StrUtil.equalsAny(queryType.name(), QueryTypeEnum.IN.name(),
|
||||
QueryTypeEnum.NOT_IN.name(), QueryTypeEnum.BETWEEN.name())) {
|
||||
genConfigMap.put("hasListQueryField", true);
|
||||
}
|
||||
}
|
||||
genConfig.setFieldConfigs(fieldConfigList);
|
||||
genConfigMap.putAll(BeanUtil.beanToMap(genConfig));
|
||||
String packageName = genConfig.getPackageName();
|
||||
String moduleName =
|
||||
StrUtil.subSuf(packageName, StrUtil.lastIndexOfIgnoreCase(packageName, StringConsts.DOT) + 1);
|
||||
genConfigMap.put("moduleName", moduleName);
|
||||
genConfigMap.put("apiName", StrUtil.lowerFirst(genConfig.getClassNamePrefix()));
|
||||
return genConfigMap;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user