¶Ô±ÈÐÂÎļþ |
| | |
| | | /* |
| | | * Copyright (c) 2018-2028, Chill Zhuang All rights reserved. |
| | | * |
| | | * Redistribution and use in source and binary forms, with or without |
| | | * modification, are permitted provided that the following conditions are met: |
| | | * |
| | | * Redistributions of source code must retain the above copyright notice, |
| | | * this list of conditions and the following disclaimer. |
| | | * Redistributions in binary form must reproduce the above copyright |
| | | * notice, this list of conditions and the following disclaimer in the |
| | | * documentation and/or other materials provided with the distribution. |
| | | * Neither the name of the dreamlu.net developer nor the names of its |
| | | * contributors may be used to endorse or promote products derived from |
| | | * this software without specific prior written permission. |
| | | * Author: Chill åºéª (smallchill@163.com) |
| | | */ |
| | | package org.springblade.develop.support; |
| | | |
| | | import com.baomidou.mybatisplus.generator.FastAutoGenerator; |
| | | import com.baomidou.mybatisplus.generator.config.TemplateType; |
| | | import com.baomidou.mybatisplus.generator.config.rules.DateType; |
| | | import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy; |
| | | import lombok.Data; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.apache.ibatis.annotations.Mapper; |
| | | import org.springblade.core.tool.utils.Func; |
| | | import org.springblade.core.tool.utils.StringUtil; |
| | | import org.springframework.core.io.ClassPathResource; |
| | | import org.springframework.core.io.Resource; |
| | | import org.springframework.core.io.support.PropertiesLoaderUtils; |
| | | |
| | | import java.io.IOException; |
| | | import java.util.*; |
| | | import java.util.stream.Collectors; |
| | | |
| | | import static org.springblade.develop.constant.DevelopConstant.*; |
| | | |
| | | /** |
| | | * 代ç çæå¨é
置类 |
| | | * |
| | | * @author Chill |
| | | */ |
| | | @Data |
| | | @Slf4j |
| | | public class BladeCodeGenerator { |
| | | /** |
| | | * 代ç 飿 ¼ |
| | | */ |
| | | private String codeStyle = SABER_NAME; |
| | | /** |
| | | * ä»£ç æ¨¡ååç§° |
| | | */ |
| | | private String codeName; |
| | | /** |
| | | * 模åç¼å· |
| | | */ |
| | | private String modelCode; |
| | | /** |
| | | * 模åå®ä½ç±» |
| | | */ |
| | | private String modelClass; |
| | | /** |
| | | * ä»£ç æå¨æå¡å |
| | | */ |
| | | private String serviceName = "blade-service"; |
| | | /** |
| | | * 代ç çæçå
å |
| | | */ |
| | | private String packageName = "org.springblade.test"; |
| | | /** |
| | | * 模çç±»å |
| | | */ |
| | | private String templateType; |
| | | /** |
| | | * ä½è
ä¿¡æ¯ |
| | | */ |
| | | private String author; |
| | | /** |
| | | * å表模åä¸»é® |
| | | */ |
| | | private String subModelId; |
| | | /** |
| | | * å表ç»å®å¤é® |
| | | */ |
| | | private String subFkId; |
| | | /** |
| | | * æ 主é®å段 |
| | | */ |
| | | private String treeId; |
| | | /** |
| | | * æ ç¶ä¸»é®å段 |
| | | */ |
| | | private String treePid; |
| | | /** |
| | | * æ åç§°åæ®µ |
| | | */ |
| | | private String treeName; |
| | | /** |
| | | * 代ç å端çæçå°å |
| | | */ |
| | | private String packageDir; |
| | | /** |
| | | * 代ç å端çæçå°å |
| | | */ |
| | | private String packageWebDir; |
| | | /** |
| | | * éè¦å»æç表åç¼ |
| | | */ |
| | | private String[] tablePrefix = {"blade_"}; |
| | | /** |
| | | * éè¦çæç表å(两è
åªè½åå
¶ä¸) |
| | | */ |
| | | private String[] includeTables = {"blade_test"}; |
| | | /** |
| | | * éè¦æé¤ç表å(两è
åªè½åå
¶ä¸) |
| | | */ |
| | | private String[] excludeTables = {}; |
| | | /** |
| | | * æ¯å¦å
å«åºç¡ä¸å¡å段 |
| | | */ |
| | | private Boolean hasSuperEntity = Boolean.TRUE; |
| | | /** |
| | | * æ¯å¦å
å«å
è£
å¨ |
| | | */ |
| | | private Boolean hasWrapper = Boolean.TRUE; |
| | | /** |
| | | * æ¯å¦å
å«è¿ç¨è°ç¨ |
| | | */ |
| | | private Boolean hasFeign = Boolean.FALSE; |
| | | /** |
| | | * æ¯å¦å
嫿å¡å |
| | | */ |
| | | private Boolean hasServiceName = Boolean.FALSE; |
| | | /** |
| | | * åºç¡ä¸å¡å段 |
| | | */ |
| | | private String[] superEntityColumns = {"create_time", "create_user", "create_dept", "update_time", "update_user", "status", "is_deleted"}; |
| | | /** |
| | | * ç§æ·å段 |
| | | */ |
| | | private String tenantColumn = "tenant_id"; |
| | | /** |
| | | * æ°æ®åºé©±å¨å |
| | | */ |
| | | private String driverName; |
| | | /** |
| | | * æ°æ®åºé¾æ¥å°å |
| | | */ |
| | | private String url; |
| | | /** |
| | | * æ°æ®åºç¨æ·å |
| | | */ |
| | | private String username; |
| | | /** |
| | | * æ°æ®åºå¯ç |
| | | */ |
| | | private String password; |
| | | /** |
| | | * æ°æ®æ¨¡å |
| | | */ |
| | | private Map<String, Object> model; |
| | | /** |
| | | * æ°æ®åå |
| | | */ |
| | | private List<Map<String, Object>> prototypes; |
| | | /** |
| | | * åæ°æ®æ¨¡å |
| | | */ |
| | | private Map<String, Object> subModel; |
| | | /** |
| | | * åæ°æ®åå |
| | | */ |
| | | private List<Map<String, Object>> subPrototypes; |
| | | |
| | | /** |
| | | * 代ç çææ§è¡ |
| | | */ |
| | | public void run() { |
| | | // 主模å代ç çæ |
| | | getAutoGenerator(getCustomMap(TEMPLATE_MAIN), getCustomFile(TEMPLATE_MAIN)).templateEngine(new BladeTemplateEngine(getOutputDir(), getOutputWebDir())).execute(); |
| | | // 忍¡å代ç çæ |
| | | if (Func.equals(templateType, TEMPLATE_SUB) && StringUtil.isNotBlank(subModelId)) { |
| | | getAutoGenerator(getCustomMap(TEMPLATE_SUB), getCustomFile(TEMPLATE_SUB)).templateEngine(new BladeTemplateEngine(getOutputDir(), getOutputWebDir())).execute(); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 设置 customMap |
| | | */ |
| | | private Map<String, Object> getCustomMap(String generateType) { |
| | | List<Map<String, Object>> prototypeList; |
| | | String[] split = packageName.split("\\."); |
| | | String serviceCode = split[split.length - 1]; |
| | | Map<String, Object> customMap = new HashMap<>(11); |
| | | customMap.put("generateType", generateType); |
| | | customMap.put("codeName", codeName); |
| | | customMap.put("serviceName", serviceName); |
| | | customMap.put("serviceCode", serviceCode); |
| | | customMap.put("packageName", packageName); |
| | | customMap.put("tenantColumn", tenantColumn); |
| | | customMap.put("hasWrapper", hasWrapper); |
| | | customMap.put("hasServiceName", hasServiceName); |
| | | customMap.put("templateType", templateType); |
| | | customMap.put("author", author); |
| | | customMap.put("subModelId", subModelId); |
| | | customMap.put("subFkId", subFkId); |
| | | customMap.put("treeId", treeId); |
| | | customMap.put("treePid", treePid); |
| | | customMap.put("treeName", treeName); |
| | | customMap.put("subFkIdHump", StringUtil.underlineToHump(subFkId)); |
| | | customMap.put("treeIdHump", StringUtil.underlineToHump(treeId)); |
| | | customMap.put("treePidHump", StringUtil.underlineToHump(treePid)); |
| | | if (Func.equals(generateType, TEMPLATE_SUB)) { |
| | | prototypeList = subPrototypes; |
| | | customMap.put("model", subModel); |
| | | customMap.put("prototypes", subPrototypes); |
| | | customMap.put("modelCode", subModel.get("modelCode")); |
| | | customMap.put("modelClass", subModel.get("modelClass")); |
| | | customMap.put("modelTable", subModel.get("modelTable")); |
| | | } else { |
| | | prototypeList = prototypes; |
| | | customMap.put("model", model); |
| | | customMap.put("prototypes", prototypes); |
| | | customMap.put("subModel", subModel); |
| | | customMap.put("subPrototypes", subPrototypes); |
| | | customMap.put("modelCode", model.get("modelCode")); |
| | | customMap.put("modelClass", model.get("modelClass")); |
| | | customMap.put("modelTable", model.get("modelTable")); |
| | | } |
| | | List<String> propertyImport = prototypeList.stream().filter(prototype -> { |
| | | String propertyType = String.valueOf(prototype.get("propertyType")); |
| | | return !"String".equals(propertyType) && !"Integer".equals(propertyType) && !"Long".equals(propertyType); |
| | | }).map(prototype -> String.valueOf(prototype.get("propertyEntity"))).distinct().collect(Collectors.toList()); |
| | | customMap.put("propertyImport", propertyImport); |
| | | return customMap; |
| | | } |
| | | |
| | | /** |
| | | * 设置 customFile |
| | | */ |
| | | private Map<String, String> getCustomFile(String type) { |
| | | Map<String, String> customFile = new HashMap<>(15); |
| | | if (!Func.equals(type, TEMPLATE_SUB)) { |
| | | customFile.put("menu.sql", "/templates/sql/menu.sql.btl"); |
| | | } |
| | | customFile.put("entityVO.java", "/templates/api/entityVO.java.btl"); |
| | | customFile.put("entityDTO.java", "/templates/api/entityDTO.java.btl"); |
| | | if (hasWrapper) { |
| | | customFile.put("wrapper.java", "/templates/api/wrapper.java.btl"); |
| | | } |
| | | if (hasFeign) { |
| | | customFile.put("feign.java", "/templates/api/feign.java.btl"); |
| | | customFile.put("feignclient.java", "/templates/api/feignclient.java.btl"); |
| | | } |
| | | if (Func.isNotBlank(packageWebDir)) { |
| | | if (Func.equals(codeStyle, SWORD_NAME)) { |
| | | customFile.put("action.js", "/templates/sword/action.js.btl"); |
| | | customFile.put("model.js", "/templates/sword/model.js.btl"); |
| | | customFile.put("service.js", "/templates/sword/service.js.btl"); |
| | | customFile.put("list.js", "/templates/sword/list.js.btl"); |
| | | customFile.put("add.js", "/templates/sword/add.js.btl"); |
| | | customFile.put("edit.js", "/templates/sword/edit.js.btl"); |
| | | customFile.put("view.js", "/templates/sword/view.js.btl"); |
| | | } else if (Func.equals(codeStyle, SABER_NAME)) { |
| | | customFile.put("api.js", "/templates/saber/" + templateType + "/api.js.btl"); |
| | | customFile.put("const.js", "/templates/saber/" + templateType + "/const.js.btl"); |
| | | if (!Func.equals(type, TEMPLATE_SUB)) { |
| | | customFile.put("crud.vue", "/templates/saber/" + templateType + "/crud.vue.btl"); |
| | | } |
| | | } else if (Func.equals(codeStyle, ELEMENT_NAME)) { |
| | | customFile.put("api.js", "/templates/element/" + templateType + "/api.js.btl"); |
| | | customFile.put("const.js", "/templates/element/" + templateType + "/const.js.btl"); |
| | | if (!Func.equals(type, TEMPLATE_SUB)) { |
| | | customFile.put("crud.vue", "/templates/element/" + templateType + "/crud.vue.btl"); |
| | | } else { |
| | | customFile.put("sub.vue", "/templates/element/" + templateType + "/sub.vue.btl"); |
| | | } |
| | | } else if (Func.equals(codeStyle, LEMON_NAME)) { |
| | | customFile.put("data.ts", "/templates/lemon/" + templateType + "/data.ts.btl"); |
| | | customFile.put("Modal.vue", "/templates/lemon/" + templateType + "/Modal.vue.btl"); |
| | | customFile.put("data.data.ts", "/templates/lemon/" + templateType + "/data.data.ts.btl"); |
| | | if (!Func.equals(type, TEMPLATE_SUB)) { |
| | | customFile.put("index.vue", "/templates/lemon/" + templateType + "/index.vue.btl"); |
| | | } else { |
| | | customFile.put("lemonSub.vue", "/templates/lemon/" + templateType + "/sub.vue.btl"); |
| | | } |
| | | |
| | | } |
| | | } |
| | | return customFile; |
| | | } |
| | | |
| | | private FastAutoGenerator getAutoGenerator(Map<String, Object> customMap, Map<String, String> customFile) { |
| | | Properties props = getProperties(); |
| | | String url = Func.toStr(this.url, props.getProperty("spring.datasource.url")); |
| | | String username = Func.toStr(this.username, props.getProperty("spring.datasource.username")); |
| | | String password = Func.toStr(this.password, props.getProperty("spring.datasource.password")); |
| | | return FastAutoGenerator.create(url, username, password) |
| | | .globalConfig(builder -> builder.author(StringUtil.isBlank(author) ? props.getProperty("author") : author).dateType(DateType.TIME_PACK).enableSwagger().outputDir(getOutputDir()).disableOpenDir()) |
| | | .packageConfig(builder -> builder.parent(packageName).controller("controller").entity("entity").service("service").serviceImpl("service.impl").mapper("mapper").xml("mapper")) |
| | | .strategyConfig(builder -> builder.addTablePrefix(tablePrefix).addInclude(Func.toStrArray(String.valueOf(customMap.get("modelTable")))).addExclude(excludeTables) |
| | | .entityBuilder().naming(NamingStrategy.underline_to_camel).columnNaming(NamingStrategy.underline_to_camel).enableLombok().superClass("org.springblade.core.mp.base.BaseEntity").formatFileName("%sEntity").addSuperEntityColumns(superEntityColumns).enableFileOverride() |
| | | .serviceBuilder().superServiceClass("org.springblade.core.mp.base.BaseService").superServiceImplClass("org.springblade.core.mp.base.BaseServiceImpl").formatServiceFileName("I%sService").formatServiceImplFileName("%sServiceImpl").enableFileOverride() |
| | | .mapperBuilder().mapperAnnotation(Mapper.class).enableBaseResultMap().enableBaseColumnList().formatMapperFileName("%sMapper").formatXmlFileName("%sMapper").enableFileOverride() |
| | | .controllerBuilder().superClass("org.springblade.core.boot.ctrl.BladeController").formatFileName("%sController").enableRestStyle().enableHyphenStyle().enableFileOverride() |
| | | ) |
| | | .templateConfig(builder -> builder.disable(TemplateType.ENTITY) |
| | | .entity("/templates/api/entity.java") |
| | | .service("/templates/api/service.java") |
| | | .serviceImpl("/templates/api/serviceImpl.java") |
| | | .mapper("/templates/api/mapper.java") |
| | | .xml("/templates/api/mapper.xml") |
| | | .controller("/templates/api/controller.java")) |
| | | .injectionConfig(builder -> builder.beforeOutputFile( |
| | | (tableInfo, objectMap) -> System.out.println("tableInfo: " + tableInfo.getEntityName() + " objectMap: " + objectMap.size()) |
| | | ).customMap(customMap).customFile(customFile) |
| | | ); |
| | | } |
| | | |
| | | /** |
| | | * è·åé
ç½®æä»¶ |
| | | * |
| | | * @return é
ç½®Props |
| | | */ |
| | | private Properties getProperties() { |
| | | // 读åé
ç½®æä»¶ |
| | | Resource resource = new ClassPathResource("/templates/code.properties"); |
| | | Properties props = new Properties(); |
| | | try { |
| | | props = PropertiesLoaderUtils.loadProperties(resource); |
| | | } catch (IOException e) { |
| | | e.printStackTrace(); |
| | | } |
| | | return props; |
| | | } |
| | | |
| | | /** |
| | | * çæå°é¡¹ç®ä¸ |
| | | * |
| | | * @return outputDir |
| | | */ |
| | | public String getOutputDir() { |
| | | return (Func.isBlank(packageDir) ? System.getProperty("user.dir") + "/blade-ops/blade-develop" : packageDir) + "/src/main/java"; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * çæå°Web项ç®ä¸ |
| | | * |
| | | * @return outputDir |
| | | */ |
| | | public String getOutputWebDir() { |
| | | return (Func.isBlank(packageWebDir) ? System.getProperty("user.dir") : packageWebDir) + "/src"; |
| | | } |
| | | |
| | | } |