package me.zhengjie.utils; import cn.hutool.core.util.StrUtil; import cn.hutool.extra.template.*; import lombok.extern.slf4j.Slf4j; import me.zhengjie.domain.GenConfig; import me.zhengjie.domain.ColumnInfo; import org.springframework.util.ObjectUtils; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.io.Writer; import java.time.LocalDate; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; /** * 代码生成 * @author Zheng Jie * @date 2019-01-02 */ @Slf4j public class GenUtil { private static final String TIMESTAMP = "Timestamp"; private static final String BIGDECIMAL = "BigDecimal"; public static final String PK = "PRI"; public static final String EXTRA = "auto_increment"; /** * 获取后端代码模板名称 * @return List */ private static List getAdminTemplateNames() { List templateNames = new ArrayList<>(); templateNames.add("Entity"); templateNames.add("Dto"); templateNames.add("Mapper"); templateNames.add("Repository"); templateNames.add("Service"); templateNames.add("ServiceImpl"); templateNames.add("QueryCriteria"); templateNames.add("Controller"); return templateNames; } /** * 获取前端代码模板名称 * @return List */ private static List getFrontTemplateNames() { List templateNames = new ArrayList<>(); templateNames.add("api"); templateNames.add("index"); templateNames.add("eForm"); return templateNames; } public static void generatorCode(List columnInfos, GenConfig genConfig) throws IOException { // 存储模版字段数据 Map genMap = new HashMap<>(); // 包名称 genMap.put("package",genConfig.getPack()); // 模块名称 genMap.put("moduleName",genConfig.getModuleName()); // 作者 genMap.put("author",genConfig.getAuthor()); // 创建日期 genMap.put("date", LocalDate.now().toString()); // 表名 genMap.put("tableName",genConfig.getTableName()); // 大写开头的类名 String className = StringUtils.toCapitalizeCamelCase(genConfig.getTableName()); // 小写开头的类名 String changeClassName = StringUtils.toCamelCase(genConfig.getTableName()); // 判断是否去除表前缀 if (StringUtils.isNotEmpty(genConfig.getPrefix())) { className = StringUtils.toCapitalizeCamelCase(StrUtil.removePrefix(genConfig.getTableName(),genConfig.getPrefix())); changeClassName = StringUtils.toCamelCase(StrUtil.removePrefix(genConfig.getTableName(),genConfig.getPrefix())); } // 保存类名 genMap.put("className", className); // 保存小写开头的类名 genMap.put("changeClassName", changeClassName); // 存在 Timestamp 字段 genMap.put("hasTimestamp",false); // 查询类中存在 Timestamp 字段 genMap.put("queryHasTimestamp",false); // 存在 BigDecimal 字段 genMap.put("hasBigDecimal",false); // 查询类中存在 BigDecimal 字段 genMap.put("queryHasBigDecimal",false); // 是否需要创建查询 genMap.put("hasQuery",false); // 自增主键 genMap.put("auto",false); // 存在字典 genMap.put("hasDict",false); // 存在日期注解 genMap.put("hasDateAnnotation",false); // 保存字段信息 List> columns = new ArrayList<>(); // 保存查询字段的信息 List> queryColumns = new ArrayList<>(); // 存储字典信息 List dicts = new ArrayList<>(); // 存储 DateRange 信息 List> dateRanges = new ArrayList<>(); // 存储不为空的字段信息 List> isNotNullColumns = new ArrayList<>(); for (ColumnInfo column : columnInfos) { Map listMap = new HashMap<>(); // 字段描述 listMap.put("remark",column.getRemark()); // 字段类型 listMap.put("columnKey",column.getKeyType()); // 主键类型 String colType = ColUtil.cloToJava(column.getColumnType()); // 小写开头的字段名 String changeColumnName = StringUtils.toCamelCase(column.getColumnName().toString()); // 大写开头的字段名 String capitalColumnName = StringUtils.toCapitalizeCamelCase(column.getColumnName().toString()); if(PK.equals(column.getKeyType())){ // 存储主键类型 genMap.put("pkColumnType",colType); // 存储小写开头的字段名 genMap.put("pkChangeColName",changeColumnName); // 存储大写开头的字段名 genMap.put("pkCapitalColName",capitalColumnName); } // 是否存在 Timestamp 类型的字段 if(TIMESTAMP.equals(colType)){ genMap.put("hasTimestamp",true); } // 是否存在 BigDecimal 类型的字段 if(BIGDECIMAL.equals(colType)){ genMap.put("hasBigDecimal",true); } // 主键是否自增 if(EXTRA.equals(column.getExtra())){ genMap.put("auto",true); } // 主键存在字典 if(StringUtils.isNotBlank(column.getDictName())){ genMap.put("hasDict",true); dicts.add(column.getDictName()); } // 存储字段类型 listMap.put("columnType",colType); // 存储字原始段名称 listMap.put("columnName",column.getColumnName()); // 不为空 listMap.put("istNotNull",column.getNotNull()); // 字段列表显示 listMap.put("columnShow",column.getListShow()); // 表单显示 listMap.put("formShow",column.getFormShow()); // 表单组件类型 listMap.put("formType",column.getFormType()); // 小写开头的字段名称 listMap.put("changeColumnName",changeColumnName); //大写开头的字段名称 listMap.put("capitalColumnName",capitalColumnName); // 字典名称 listMap.put("dictName",column.getDictName()); // 关联字段 listMap.put("joinName",column.getJoinName()); // 日期注解 listMap.put("dateAnnotation",column.getDateAnnotation()); if(StringUtils.isNotBlank(column.getDateAnnotation())){ genMap.put("hasDateAnnotation",true); } // 添加非空字段信息 if(column.getNotNull()){ isNotNullColumns.add(listMap); } // 判断是否有查询,如有则把查询的字段set进columnQuery if(!StringUtils.isBlank(column.getQueryType())){ // 查询类型 listMap.put("queryType",column.getQueryType()); // 是否存在查询 genMap.put("hasQuery",true); if(TIMESTAMP.equals(colType)){ // 查询中存储 Timestamp 类型 genMap.put("queryHasTimestamp",true); } if(BIGDECIMAL.equals(colType)){ // 查询中存储 BigDecimal 类型 genMap.put("queryHasBigDecimal",true); } if("DateRange".equalsIgnoreCase(column.getQueryType())){ dateRanges.add(listMap); } else { // 添加到查询列表中 queryColumns.add(listMap); } } // 添加到字段列表中 columns.add(listMap); } // 保存字段列表 genMap.put("columns",columns); // 保存查询列表 genMap.put("queryColumns",queryColumns); // 保存字段列表 genMap.put("dicts",dicts); // 保存查询列表 genMap.put("dateRanges",dateRanges); // 保存非空字段信息 genMap.put("isNotNullColumns",isNotNullColumns); TemplateEngine engine = TemplateUtil.createEngine(new TemplateConfig("template", TemplateConfig.ResourceMode.CLASSPATH)); // 生成后端代码 List templates = getAdminTemplateNames(); for (String templateName : templates) { Template template = engine.getTemplate("generator/admin/"+templateName+".ftl"); String filePath = getAdminFilePath(templateName,genConfig,className); assert filePath != null; File file = new File(filePath); // 如果非覆盖生成 if(!genConfig.getCover() && FileUtil.exist(file)){ continue; } // 生成代码 genFile(file, template, genMap); } // 生成前端代码 templates = getFrontTemplateNames(); for (String templateName : templates) { Template template = engine.getTemplate("generator/front/"+templateName+".ftl"); String filePath = getFrontFilePath(templateName,genConfig,genMap.get("changeClassName").toString()); assert filePath != null; File file = new File(filePath); // 如果非覆盖生成 if(!genConfig.getCover() && FileUtil.exist(file)){ continue; } // 生成代码 genFile(file, template, genMap); } } /** * 定义后端文件路径以及名称 */ private static String getAdminFilePath(String templateName, GenConfig genConfig, String className) { String projectPath = System.getProperty("user.dir") + File.separator + genConfig.getModuleName(); String packagePath = projectPath + File.separator + "src" +File.separator+ "main" + File.separator + "java" + File.separator; if (!ObjectUtils.isEmpty(genConfig.getPack())) { packagePath += genConfig.getPack().replace(".", File.separator) + File.separator; } if ("Entity".equals(templateName)) { return packagePath + "domain" + File.separator + className + ".java"; } if ("Controller".equals(templateName)) { return packagePath + "rest" + File.separator + className + "Controller.java"; } if ("Service".equals(templateName)) { return packagePath + "service" + File.separator + className + "Service.java"; } if ("ServiceImpl".equals(templateName)) { return packagePath + "service" + File.separator + "impl" + File.separator + className + "ServiceImpl.java"; } if ("Dto".equals(templateName)) { return packagePath + "service" + File.separator + "dto" + File.separator + className + "DTO.java"; } if ("QueryCriteria".equals(templateName)) { return packagePath + "service" + File.separator + "dto" + File.separator + className + "QueryCriteria.java"; } if ("Mapper".equals(templateName)) { return packagePath + "service" + File.separator + "mapper" + File.separator + className + "Mapper.java"; } if ("Repository".equals(templateName)) { return packagePath + "repository" + File.separator + className + "Repository.java"; } return null; } /** * 定义前端文件路径以及名称 */ private static String getFrontFilePath(String templateName, GenConfig genConfig, String apiName) { String path = genConfig.getPath(); if ("api".equals(templateName)) { return genConfig.getApiPath() + File.separator + apiName + ".js"; } if ("index".equals(templateName)) { return path + File.separator + "index.vue"; } if ("eForm".equals(templateName)) { return path + File.separator + File.separator + "form.vue"; } return null; } private static void genFile(File file, Template template, Map map) throws IOException { // 生成目标文件 Writer writer = null; try { FileUtil.touch(file); writer = new FileWriter(file); template.render(map, writer); } catch (TemplateException | IOException e) { throw new RuntimeException(e); } finally { assert writer != null; writer.close(); } } }