objectMap, String templatePath, String outputFile) {
+ this.writer(objectMap, templatePath, Paths.get(outputFile, "pom.xml").toString());
+ }
+
+
+ private String mkModular(String servicePath, String serviceName, String modular, boolean isChildModule) {
+ //String modularName = serviceName + "-" + modular;
+ String modularName = modular;
+ if (isChildModule) {
+ String childModuleName = this.config.getProjectPrefix() + this.config.getChildModuleName();
+ modularName = childModuleName + "-" + modular;
+ }
+ log.info("已经生成模块:{}", modularName);
+ String modularPath = Paths.get(servicePath, modularName).toString();
+ File modularPathFile = new File(modularPath);
+ if (!modularPathFile.exists()) {
+ modularPathFile.mkdirs();
+ }
+ return modularPath;
+ }
+
+
+ /**
+ * 创建 maven 目录文件夹
+ *
+ * @param modularPath
+ */
+ private void mkMaven(String modularPath) {
+ for (String maven : MAVEN_PATH) {
+ String mavenPath = Paths.get(modularPath, maven).toString();
+ File mavenPathFile = new File(mavenPath);
+ if (!mavenPathFile.exists()) {
+ mavenPathFile.mkdirs();
+ }
+ }
+ }
+
+ private void mkBasePackage(String modularPath) {
+ String basePackage = Paths.get(modularPath, SRC_MAIN_JAVA, StrUtil.replace(config.getPackageBase(), ".", File.separator)).toString();
+ File mavenPathFile = new File(basePackage);
+ if (!mavenPathFile.exists()) {
+ mavenPathFile.mkdirs();
+ }
+
+
+ }
+}
diff --git a/ceres-generator-master/src/main/java/com/zkthink/ceres/generator/config/CodeGeneratorConfig.java b/ceres-generator-master/src/main/java/com/zkthink/ceres/generator/config/CodeGeneratorConfig.java
new file mode 100644
index 0000000..43d887c
--- /dev/null
+++ b/ceres-generator-master/src/main/java/com/zkthink/ceres/generator/config/CodeGeneratorConfig.java
@@ -0,0 +1,253 @@
+package com.zkthink.ceres.generator.config;
+
+
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.toolkit.StringUtils;
+import com.zkthink.ceres.generator.model.GenTableColumn;
+import com.zkthink.ceres.generator.type.EntityFiledType;
+import com.zkthink.ceres.generator.type.EntityType;
+import com.zkthink.ceres.generator.type.SuperClass;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+
+import java.io.File;
+import java.util.*;
+
+/**
+ * 代码生成配置
+ *
+ * 微服务项目默认会创建4个项目,
+ * cloud-authority-api、cloud-authority-rest、cloud-authority-entity、cloud-authority-repository
+ * 匹配符为:${projectPrefix}${serviceName}-${apiSuffix}
+ *
+ * 然后在每个项目的src/main/java下创建包:
+ * ${packageBase}.api.${childModuleName}
+ * ${packageBase}.rest.${childModuleName}
+ * ${packageBase}.entity.${childModuleName}
+ * ${packageBase}.enumeration.${childModuleName}
+ * ${packageBase}.constant.${childModuleName}
+ * ${packageBase}.dto.${childModuleName}
+ * ${packageBase}.service.${childModuleName}
+ * ${packageBase}.service.${childModuleName}.impl
+ * ${packageBase}.dao.${childModuleName}
+ * ${projectPrefix}${serviceName}-${serviceSuffix}项目的src/main/resource下创建包:
+ * mapper_${serviceName}.base.${childModuleName}
+ *
+ * @author ceres
+ * @date 2019年05月25日20:59:57
+ */
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+@Accessors(chain = true)
+public class CodeGeneratorConfig {
+
+ /**
+ * 项目跟路径
+ */
+ String projectRootPath = System.getProperty("user.dir");
+ /**
+ * 服务名
+ * 如消息服务 (用于创建cloud-%s-api、cloud-%s-entity等项目)
+ */
+ String serviceName = "";
+ /**
+ * 子模块名称
+ * 如消息服务(cloud-msgs-new)包含消息、短信、邮件3个模块
+ * 则分别填入 msgs、sms、email
+ * (用于创建cloud-%s-rest、cloud-%s-repository等项目)
+ */
+ String childModuleName = "";
+ /**
+ * 基础包 所有的代码都放置在这个包之下
+ */
+ String packageBase = "com.zkthink.authority";
+
+ /**
+ * common包 用于存放基础类
+ */
+ String packageCommon = "com.shop.cereshop.commons";
+
+ /**
+ * 子包名称
+ * 会在api、controller、service、serviceImpl、dao、entity等包下面创建子包
+ */
+ String childPackageName = "";
+ /**
+ * 作者
+ */
+ String author = "ceres";
+
+ /**
+ * 是否需要生成admin包的内容
+ */
+ boolean needAdmin = true;
+
+ /**
+ * 是否需要生成app包的内容
+ */
+ boolean needApp = true;
+
+ /**
+ * 是否需要生成business包的内容
+ */
+ boolean needBusiness = true;
+
+ /**
+ * 项目统一前缀 比如: cloud-
+ */
+ private String projectPrefix = "cereshop";
+
+ private String apiSuffix = "-api";
+ private String entitySuffix = "-commons";
+ private String adminSuffix = "-admin";
+ private String appSuffix = "-app";
+ private String businessSuffix = "-business";
+ private String serviceSuffix = "-biz";
+ private String controllerSuffix = "-controller";
+ /**
+ * 版本
+ */
+ String version = "1.0-SNAPSHOT";
+ /**
+ * 端口号
+ */
+ String serverPort = "8080";
+ String groupId = "com.zkthin";
+ String description = "服务";
+// private String serverSuffix = "-server";
+
+ public String getPackageBaseParent() {
+ return StrUtil.subPre(this.packageBase, this.packageBase.lastIndexOf("."));
+ }
+
+ /**
+ * entity的父类
+ */
+ private EntityType superEntity = EntityType.ENTITY;
+ /**
+ * controller的父类
+ */
+ private String superControllerClass = SuperClass.SUPER_CLASS.getController();
+
+ /**
+ * 自定义继承的Mapper类全称,带包名
+ */
+ private String superMapperClass = SuperClass.SUPER_CLASS.getMapper();
+ /**
+ * 自定义继承的Service类全称,带包名
+ */
+ private String superServiceClass = SuperClass.SUPER_CLASS.getService();
+ /**
+ * 自定义继承的ServiceImpl类全称,带包名
+ */
+ private String superServiceImplClass = SuperClass.SUPER_CLASS.getServiceImpl();
+ /**
+ * 表前缀
+ */
+ private String tablePrefix = "";
+ /**
+ * 字段前缀
+ */
+ private String fieldPrefix = "";
+ /**
+ * 需要包含的表名,允许正则表达式;用来自动生成代码
+ */
+ private String[] tableInclude = {"c_user"};
+ /**
+ * 基础的xml路径
+ */
+// private String xmlPath = "";
+ private String[] tableExclude = {};
+ /**
+ * 驱动连接的URL
+ */
+ private String url = "jdbc:mysql://127.0.0.1:3306/ceres_base_0000?serverTimezone=CTT&characterEncoding=utf8&useUnicode=true&useSSL=false&autoReconnect=true&zeroDateTimeBehavior=convertToNull";
+ /**
+ * 驱动名称
+ */
+ private String driverName = "com.mysql.cj.jdbc.Driver";
+ /**
+ * 数据库连接用户名
+ */
+ private String username = "root";
+ /**
+ * 数据库连接密码
+ */
+ private String password = "root";
+ /**
+ * 仅仅在微服务架构下面才进行分包
+ */
+ private boolean enableMicroService = true;
+
+ private FileCreateConfig fileCreateConfig = new FileCreateConfig();
+ /**
+ * 需要制定生成路径的枚举类列表
+ */
+ private Set filedTypes = new HashSet<>();
+
+ /**
+ * 当前处理的模块
+ */
+ private String currentModule = null;
+
+ /**
+ *
+ */
+ public final static String[] CERESHOP_MODULAR_LIST = new String[]{
+ "admin", "app", "business"
+ };
+
+ private Vue vue = new Vue();
+
+ @Data
+ public static class Vue {
+ private String viewsPath = "views" + File.separator + "ceres";
+
+ /**
+ * 表名 - <字段名 - 字段信息>
+ */
+ private Map> tableFieldMap = new HashMap<>();
+ }
+
+ /**
+ * 必填项 构造器
+ *
+ * @param serviceName 服务名
+ * eg: msgs
+ * @param childModuleName 子模块名
+ * eg: sms、emial
+ * @param author 作者
+ * @param tablePrefix 表前缀
+ * @param tableInclude 生成的表 支持通配符
+ * eg: msgs_.* 会生成msgs_开头的所有表
+ * @return
+ */
+ public static CodeGeneratorConfig build(String serviceName, String childModuleName, String author, String tablePrefix, List tableInclude) {
+ CodeGeneratorConfig config = new CodeGeneratorConfig();
+ config.setServiceName(serviceName).setAuthor(author).setTablePrefix(tablePrefix)
+ .setTableInclude(tableInclude.stream().toArray(String[]::new))
+ .setChildModuleName(childModuleName == null ? "" : childModuleName);
+ config.setPackageBase("com.zkthink." + config.getChildModuleName());
+ return config;
+ }
+
+
+ public static CodeGeneratorConfig buildVue(String serviceName, String tablePrefix, List tableInclude) {
+ CodeGeneratorConfig config = new CodeGeneratorConfig();
+ config.setServiceName(serviceName).setTablePrefix(tablePrefix)
+ .setTableInclude(tableInclude.stream().toArray(String[]::new))
+ .setChildModuleName("");
+ config.setPackageBase("com.zkthink." + config.getChildModuleName());
+ return config;
+ }
+
+ public String getChildModuleName() {
+ if (StringUtils.isBlank(this.childModuleName)) {
+ this.childModuleName = this.serviceName;
+ }
+ return this.childModuleName;
+ }
+}
diff --git a/ceres-generator-master/src/main/java/com/zkthink/ceres/generator/config/FileCreateConfig.java b/ceres-generator-master/src/main/java/com/zkthink/ceres/generator/config/FileCreateConfig.java
new file mode 100644
index 0000000..6610ba1
--- /dev/null
+++ b/ceres-generator-master/src/main/java/com/zkthink/ceres/generator/config/FileCreateConfig.java
@@ -0,0 +1,235 @@
+package com.zkthink.ceres.generator.config;
+
+import com.baomidou.mybatisplus.generator.config.IFileCreate;
+import com.baomidou.mybatisplus.generator.config.builder.ConfigBuilder;
+import com.baomidou.mybatisplus.generator.config.rules.FileType;
+import com.zkthink.ceres.generator.ext.FileOutConfigExt;
+import com.zkthink.ceres.generator.type.GenerateType;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+
+import java.io.File;
+
+/**
+ * 文件创建配置类
+ *
+ * @author ceres
+ * @date 2019-05-25
+ */
+@Data
+@Accessors(chain = true)
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class FileCreateConfig implements IFileCreate {
+
+ private GenerateType generate;
+ private GenerateType generateEnum = GenerateType.OVERRIDE;
+ private GenerateType generateEntity = GenerateType.OVERRIDE;
+ private GenerateType generateConstant = GenerateType.IGNORE;
+ private GenerateType generateDao = GenerateType.IGNORE;
+ private GenerateType generateXml = GenerateType.IGNORE;
+ private GenerateType generateService = GenerateType.IGNORE;
+ private GenerateType generateServiceImpl = GenerateType.IGNORE;
+ private GenerateType generateController = GenerateType.IGNORE;
+
+ private GenerateType generateDto = GenerateType.IGNORE;
+ private GenerateType generateQuery = GenerateType.IGNORE;
+
+ private GenerateType generateApi = GenerateType.IGNORE;
+ private GenerateType generatePageIndex = GenerateType.IGNORE;
+ private GenerateType generateTreeIndex = GenerateType.IGNORE;
+ private GenerateType generateEdit = GenerateType.IGNORE;
+ private Boolean isVue = false;
+
+ /**
+ * 指定了generate后, 会覆盖 controller、service、dao等生成策略
+ *
+ * @param generate
+ */
+ public FileCreateConfig(GenerateType generate) {
+ this.generate = generate;
+ if (generate != null) {
+ this.generateEntity = generate;
+ this.generateDao = generate;
+ this.generateXml = generate;
+ this.generateService = generate;
+ this.generateServiceImpl = generate;
+ this.generateController = generate;
+ this.generateEnum = generate;
+ this.generateDto = generate;
+ }
+ this.generateConstant = GenerateType.IGNORE;
+ this.generateQuery = GenerateType.IGNORE;
+ this.generateApi = GenerateType.IGNORE;
+ }
+
+ public FileCreateConfig(GenerateType generate, boolean isVue) {
+ this.generate = generate;
+ this.isVue = isVue;
+ if (isVue) {
+ this.generateEntity = GenerateType.IGNORE;
+ this.generateDao = GenerateType.IGNORE;
+ this.generateXml = GenerateType.IGNORE;
+ this.generateService = GenerateType.IGNORE;
+ this.generateServiceImpl = GenerateType.IGNORE;
+ this.generateController = GenerateType.IGNORE;
+ this.generateEnum = GenerateType.IGNORE;
+ this.generateDto = GenerateType.IGNORE;
+
+ //index 和 Tree 只能生成一种
+ if (GenerateType.OVERRIDE.eq(this.generatePageIndex)) {
+ this.generateTreeIndex = GenerateType.IGNORE;
+ } else if (GenerateType.OVERRIDE.eq(this.generateTreeIndex)) {
+ this.generatePageIndex = GenerateType.IGNORE;
+ this.generateEdit = GenerateType.IGNORE;
+ }
+
+ if (generate != null) {
+ this.generateApi = generate;
+ this.generatePageIndex = generate;
+ this.generateTreeIndex = GenerateType.IGNORE;
+ this.generateEdit = generate;
+ }
+ } else {
+ this.generateConstant = GenerateType.IGNORE;
+ this.generateQuery = GenerateType.IGNORE;
+ if (generate != null) {
+ this.generateEntity = generate;
+ this.generateDao = generate;
+ this.generateXml = generate;
+ this.generateService = generate;
+ this.generateServiceImpl = generate;
+ this.generateController = generate;
+ this.generateEnum = generate;
+ this.generateDto = generate;
+ }
+ }
+
+ }
+
+ /**
+ * 判断文件是否存在
+ *
+ * @param path 路径
+ */
+ public static boolean isExists(String path) {
+ File file = new File(path);
+ return file.exists();
+ }
+
+ @Override
+ public boolean isCreate(ConfigBuilder configBuilder, FileType fileType, String filePath) {
+ File file = new File(filePath);
+ if (this.generate != null) {
+ if (filePath.contains(File.separator + "constant" + File.separator)) {
+ return isCreate(generateConstant, file);
+ }
+ if (filePath.contains(File.separator + "query" + File.separator)) {
+ return isCreate(generateQuery, file);
+ }
+
+ // api.js
+ if (filePath.contains(File.separator + "api" + File.separator)) {
+ return isCreate(generateApi, file);
+ }
+ //edit.vue
+ if (filePath.endsWith("Edit" + FileOutConfigExt.DOT_VUE)) {
+ return isCreate(generateEdit, file);
+ }
+ //Index.vue
+ if (filePath.endsWith("Index" + FileOutConfigExt.DOT_VUE)) {
+ return isCreate(generatePageIndex, file);
+ }
+ //Tree.vue
+ if (filePath.endsWith("Tree" + FileOutConfigExt.DOT_VUE)) {
+ return isCreate(generateTreeIndex, file);
+ }
+
+ return isCreate(generate, file);
+ }
+ //实体
+ if (FileType.ENTITY == fileType) {
+ return isCreate(generateEntity, file);
+ //控制器
+ } else if (FileType.CONTROLLER == fileType) {
+ return isCreate(generateController, file);
+ //dao
+ } else if (FileType.XML == fileType) {
+ return isCreate(generateXml, file);
+ } else if (FileType.MAPPER == fileType) {
+ return isCreate(generateDao, file);
+ //service
+ } else if (FileType.SERVICE == fileType) {
+ return isCreate(generateService, file);
+ } else if (FileType.SERVICE_IMPL == fileType) {
+ return isCreate(generateServiceImpl, file);
+ } else if (FileType.OTHER == fileType) {
+ if (filePath.contains(File.separator + "enumeration" + File.separator)) {
+ return isCreate(generateEnum, file);
+ }
+ if (filePath.contains(File.separator + "constant" + File.separator)) {
+ return isCreate(generateConstant, file);
+ }
+ if (filePath.contains(File.separator + "query" + File.separator)) {
+ return isCreate(generateQuery, file);
+ }
+ if (filePath.contains(File.separator + "entity" + File.separator)) {
+ return isCreate(generateEntity, file);
+ }
+ if (filePath.contains(File.separator + "dto" + File.separator)) {
+ return isCreate(generateDto, file);
+ }
+ //控制器
+ if (filePath.contains(File.separator + "controller" + File.separator)) {
+ return isCreate(generateController, file);
+ }
+ //dao
+ if (filePath.contains(File.separator + "mapper_")) {
+ return isCreate(generateXml, file);
+ }
+ if (filePath.contains(File.separator + "dao" + File.separator)) {
+ return isCreate(generateDao, file);
+ }
+ if (filePath.contains(File.separator + "service" + File.separator)) {
+ return isCreate(generateService, file);
+ }
+ if (filePath.contains(File.separator + "impl" + File.separator)) {
+ return isCreate(generateServiceImpl, file);
+ }
+
+ // api.js
+ if (filePath.contains(File.separator + "api" + File.separator)) {
+ return isCreate(generateApi, file);
+ }
+ //edit.vue
+ if (filePath.endsWith("Edit" + FileOutConfigExt.DOT_VUE)) {
+ return isCreate(generateEdit, file);
+ }
+ //Index.vue
+ if (filePath.endsWith("Index" + FileOutConfigExt.DOT_VUE)) {
+ return isCreate(generatePageIndex, file);
+ }
+ //Tree.vue
+ if (filePath.endsWith("Tree" + FileOutConfigExt.DOT_VUE)) {
+ return isCreate(generateTreeIndex, file);
+ }
+
+ }
+ return true;
+ }
+
+ private boolean isCreate(GenerateType gen, File file) {
+ if (GenerateType.IGNORE.eq(gen)) {
+ return false;
+ }
+ if (!file.exists()) {
+ file.getParentFile().mkdirs();
+ }
+ return true;
+ }
+
+}
diff --git a/ceres-generator-master/src/main/java/com/zkthink/ceres/generator/ext/FileOutConfigExt.java b/ceres-generator-master/src/main/java/com/zkthink/ceres/generator/ext/FileOutConfigExt.java
new file mode 100644
index 0000000..1a4c64b
--- /dev/null
+++ b/ceres-generator-master/src/main/java/com/zkthink/ceres/generator/ext/FileOutConfigExt.java
@@ -0,0 +1,192 @@
+package com.zkthink.ceres.generator.ext;
+
+import com.baomidou.mybatisplus.core.toolkit.StringPool;
+import com.baomidou.mybatisplus.core.toolkit.StringUtils;
+import com.baomidou.mybatisplus.generator.config.ConstVal;
+import com.baomidou.mybatisplus.generator.config.FileOutConfig;
+import com.baomidou.mybatisplus.generator.config.po.TableInfo;
+import com.zkthink.ceres.generator.CodeGenerator;
+import com.zkthink.ceres.generator.config.CodeGeneratorConfig;
+import com.zkthink.ceres.generator.config.FileCreateConfig;
+import com.zkthink.ceres.generator.type.GenerateType;
+
+import java.io.File;
+import java.nio.file.Paths;
+
+/**
+ * 文件输出扩展
+ *
+ * @author ceres
+ * @date 2019/05/26
+ */
+public class FileOutConfigExt extends FileOutConfig {
+ public static final String DOT_VUE = ".vue";
+ public static final String DOT_JS = ".js";
+ String innerBasePath;
+
+ String projectSuffix;
+ String modularSuffix;
+ GenerateType generateType;
+ CodeGeneratorConfig config;
+
+ public FileOutConfigExt(String innerBasePath, String modularSuffix, CodeGeneratorConfig config) {
+ this.innerBasePath = innerBasePath;
+ this.modularSuffix = modularSuffix;
+ this.projectSuffix = "-" + config.getCurrentModule();
+ this.config = config;
+ FileCreateConfig fileCreateConfig = config.getFileCreateConfig();
+ switch (modularSuffix) {
+ case CodeGenerator.ENUM_PATH:
+ this.setTemplatePath("/templates/enum.java.ftl");
+ this.generateType = fileCreateConfig.getGenerateEnum();
+ break;
+ case CodeGenerator.SAVE_DTO_PATH:
+ this.setTemplatePath("/templates/saveDto.java.ftl");
+ this.generateType = fileCreateConfig.getGenerateDto();
+ break;
+ case CodeGenerator.PAGE_DTO_PATH:
+ this.setTemplatePath("/templates/pageDto.java.ftl");
+ this.generateType = fileCreateConfig.getGenerateDto();
+ break;
+ case CodeGenerator.UPDATE_DTO_PATH:
+ this.setTemplatePath("/templates/updateDto.java.ftl");
+ this.generateType = fileCreateConfig.getGenerateDto();
+ break;
+ case CodeGenerator.CONSTANT_PATH:
+ this.setTemplatePath("/templates/constant.java.ftl");
+ this.generateType = fileCreateConfig.getGenerateConstant();
+ break;
+ case CodeGenerator.QUERY_PATH:
+ this.setTemplatePath("/templates/query.java.ftl");
+ this.generateType = fileCreateConfig.getGenerateQuery();
+ break;
+ case ConstVal.ENTITY:
+ this.setTemplatePath(ConstVal.TEMPLATE_ENTITY_JAVA + ".ftl");
+ this.generateType = fileCreateConfig.getGenerateEntity();
+ break;
+ case ConstVal.SERVICE:
+ this.setTemplatePath(ConstVal.TEMPLATE_SERVICE + ".ftl");
+ this.generateType = fileCreateConfig.getGenerateService();
+ break;
+ case ConstVal.SERVICE_IMPL:
+ this.setTemplatePath(ConstVal.TEMPLATE_SERVICE_IMPL + ".ftl");
+ this.generateType = fileCreateConfig.getGenerateServiceImpl();
+ break;
+ case ConstVal.MAPPER:
+ this.setTemplatePath(ConstVal.TEMPLATE_MAPPER + ".ftl");
+ this.generateType = fileCreateConfig.getGenerateDao();
+ break;
+ case ConstVal.XML:
+ this.setTemplatePath(ConstVal.TEMPLATE_XML + ".ftl");
+ this.generateType = fileCreateConfig.getGenerateXml();
+ break;
+ case ConstVal.CONTROLLER:
+ this.setTemplatePath(ConstVal.TEMPLATE_CONTROLLER + ".ftl");
+ this.generateType = fileCreateConfig.getGenerateController();
+ break;
+ default:
+ break;
+ }
+ }
+
+ @Override
+ public String outputFile(TableInfo tableInfo) {
+
+ if (ConstVal.XML.equals(modularSuffix)) {
+ String projectRootPath = config.getProjectRootPath();
+ if (!projectRootPath.endsWith(File.separator)) {
+ projectRootPath += File.separator;
+ }
+
+ StringBuilder basePathSb = new StringBuilder(projectRootPath);
+ if (config.isEnableMicroService()) {
+ basePathSb.append(config.getProjectPrefix());
+ basePathSb.append(config.getChildModuleName());
+ basePathSb.append(projectSuffix)
+ .append(File.separator);
+ }
+ basePathSb.append(CodeGenerator.SRC_MAIN_RESOURCE)
+ .append(File.separator)
+ .append("mybatis")
+ .append(File.separator)
+ .append("mapper");
+ //.append(config.getChildModuleName())
+ //.append(File.separator)
+ //.append(config.getCurrentModule());
+ if (StringUtils.isNotEmpty(config.getChildPackageName())) {
+ basePathSb.append(File.separator).append(config.getChildPackageName());
+ }
+
+ //basePath = basePath + File.separator + tableInfo.getEntityName() + modularSuffix + StringPool.DOT_JAVA;
+ basePathSb.append(File.separator)
+ .append(tableInfo.getEntityName())
+ .append("DAO")
+ .append(StringPool.DOT_XML);
+
+ if (GenerateType.ADD.eq(generateType) && FileCreateConfig.isExists(basePathSb.toString())) {
+ basePathSb.append(".new");
+ }
+ return basePathSb.toString();
+ }
+
+ // 根路径 + 项目名 + SRC_MAIN_JAVA + 基础包 + service + 子模块 + EntityName+后缀
+
+ String projectName = "";
+ if (config.isEnableMicroService()) {
+ if (CodeGenerator.ENUM_PATH.equals(modularSuffix)
+ || CodeGenerator.SAVE_DTO_PATH.equals(modularSuffix)
+ || CodeGenerator.UPDATE_DTO_PATH.equals(modularSuffix)
+ || CodeGenerator.PAGE_DTO_PATH.equals(modularSuffix)
+ || CodeGenerator.CONSTANT_PATH.equals(modularSuffix)
+ || CodeGenerator.QUERY_PATH.equals(modularSuffix)
+ || ConstVal.ENTITY.equals(modularSuffix)) {
+ projectName = config.getProjectPrefix() + config.getServiceName() + projectSuffix + File.separator;
+ } else {
+ projectName = config.getProjectPrefix() + config.getChildModuleName() + projectSuffix + File.separator;
+ }
+ }
+ String basePath = String.format(innerBasePath, projectName);
+
+ String innerModularSuffix = modularSuffix;
+ if (ConstVal.SERVICE_IMPL.equals(innerModularSuffix)) {
+ innerModularSuffix = "service";
+ } else if (CodeGenerator.SAVE_DTO_PATH.equals(innerModularSuffix)) {
+ innerModularSuffix = "domain";
+ } else if (CodeGenerator.UPDATE_DTO_PATH.equals(innerModularSuffix)) {
+ innerModularSuffix = "domain";
+ } else if (CodeGenerator.PAGE_DTO_PATH.equals(innerModularSuffix)) {
+ innerModularSuffix = "domain";
+ } else if (ConstVal.MAPPER.equals(innerModularSuffix)) {
+ innerModularSuffix = "dao";
+ } else if (ConstVal.ENTITY.equals(innerModularSuffix)) {
+ innerModularSuffix = "domain";
+ } else {
+ innerModularSuffix = StringUtils.firstCharToLower(modularSuffix);
+ }
+
+ basePath = basePath + File.separator + projectSuffix.substring(1) + File.separator + innerModularSuffix;
+ if (StringUtils.isNotEmpty(config.getChildPackageName())) {
+ basePath = basePath + File.separator + config.getChildPackageName();
+ }
+ if (ConstVal.SERVICE_IMPL.equals(modularSuffix)) {
+ basePath = basePath + File.separator + "impl";
+ }
+
+ if (ConstVal.ENTITY.equals(modularSuffix)) {
+ basePath = basePath + File.separator + tableInfo.getEntityName() + StringPool.DOT_JAVA;
+ } else if (ConstVal.XML.equals(modularSuffix)) {
+ basePath = basePath + File.separator + tableInfo.getEntityName() + "DAO" + StringPool.DOT_JAVA;
+ } else if (ConstVal.MAPPER.equals(modularSuffix)) {
+ basePath = basePath + File.separator + tableInfo.getEntityName() + "DAO" + StringPool.DOT_JAVA;
+ } else if (CodeGenerator.QUERY_PATH.equals(modularSuffix)) {
+ basePath = basePath + File.separator + tableInfo.getEntityName() + "Wrapper" + StringPool.DOT_JAVA;
+ } else {
+ basePath = basePath + File.separator + tableInfo.getEntityName() + modularSuffix + StringPool.DOT_JAVA;
+ }
+
+ if (GenerateType.ADD.eq(generateType) && FileCreateConfig.isExists(basePath)) {
+ basePath += ".new";
+ }
+ return basePath;
+ }
+}
diff --git a/ceres-generator-master/src/main/java/com/zkthink/ceres/generator/ext/FreemarkerTemplateEngineExt.java b/ceres-generator-master/src/main/java/com/zkthink/ceres/generator/ext/FreemarkerTemplateEngineExt.java
new file mode 100644
index 0000000..c8dca84
--- /dev/null
+++ b/ceres-generator-master/src/main/java/com/zkthink/ceres/generator/ext/FreemarkerTemplateEngineExt.java
@@ -0,0 +1,426 @@
+package com.zkthink.ceres.generator.ext;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.toolkit.StringPool;
+import com.baomidou.mybatisplus.generator.InjectionConfig;
+import com.baomidou.mybatisplus.generator.config.ConstVal;
+import com.baomidou.mybatisplus.generator.config.FileOutConfig;
+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.FileType;
+import com.baomidou.mybatisplus.generator.engine.AbstractTemplateEngine;
+import com.baomidou.mybatisplus.generator.engine.BeetlTemplateEngine;
+import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
+import com.zkthink.ceres.generator.CodeGenerator;
+import com.zkthink.ceres.generator.config.CodeGeneratorConfig;
+import com.zkthink.ceres.generator.config.FileCreateConfig;
+import com.zkthink.ceres.generator.model.GenTableColumn;
+import com.zkthink.ceres.generator.type.EntityFiledType;
+import com.zkthink.ceres.generator.type.GenerateType;
+import org.apache.commons.lang3.StringUtils;
+
+import java.io.File;
+import java.util.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+
+
+/**
+ * 扩展 {@link BeetlTemplateEngine}
+ * 便于我们加入我们自己的模板
+ *
+ * @author ceres
+ */
+public class FreemarkerTemplateEngineExt extends FreemarkerTemplateEngine {
+
+ /**
+ * 注入字段 正则
+ * 匹配: @InjectionField(api="", method="") RemoteData
+ * 匹配: @InjectionField(api="", method="" beanClass=Xxx.class)
+ * 匹配: @InjectionField(api="orgApi", method="findXx" beanClass=Org.class) RemoteData
+ * 匹配: @InjectionField(feign=OrgApi.class, method="findXx" beanClass=Org.class) RemoteData
+ */
+ private final static Pattern INJECTION_FIELD_PATTERN = Pattern.compile("([@]InjectionField[(](api|feign)? *= *([a-zA-Z0-9\"._]+), method *= *([a-zA-Z0-9\"._]+)(, *beanClass *= *[a-zA-Z0-9._]+)?[)]){1}( *RemoteData(<[a-zA-Z0-9.]+,( *[a-zA-Z0-9.]+)>)?)*");
+
+ /**
+ * 枚举类 正则
+ * 匹配: #{xxxx} 形式的注释
+ */
+ public final static String REG_EX_VAL = "#(.*?\\{(.*?)?\\})";
+ /**
+ * 枚举类型 正则
+ * 匹配 xx:xx; 形式的注释
+ */
+ public final static String REG_EX_KEY = "([A-Za-z1-9_-]+):(.*?)?;";
+
+ private CodeGeneratorConfig config;
+
+ public FreemarkerTemplateEngineExt(CodeGeneratorConfig config) {
+ this.config = config;
+ }
+
+
+ /**
+ * 扩展父类 增加生成enum的代码。
+ */
+ @Override
+ public AbstractTemplateEngine batchOutput() {
+ ConfigBuilder cb = getConfigBuilder();
+
+ //生成枚举
+ try {
+ List tableInfoList = getConfigBuilder().getTableInfoList();
+ for (TableInfo tableInfo : tableInfoList) {
+ tableInfo.getFields().forEach(filed -> {
+ try {
+ generateEnum(tableInfo, filed);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ });
+ }
+ } catch (Exception e) {
+ logger.error("无法创建文件,请检查配置信息!", e);
+ }
+ List tableList = cb.getTableInfoList();
+
+
+ CodeGeneratorConfig.Vue vue = config.getVue();
+ Map> tableFieldMap = vue.getTableFieldMap();
+ //构造实体中的枚举类型字段
+ tableList.forEach(t -> {
+ t.getFields().forEach(field -> {
+ Map customMap = field.getCustomMap();
+ if (customMap == null) {
+ customMap = new HashMap<>();
+ }
+ Map fieldMap = tableFieldMap.get(t.getName());
+ if (CollUtil.isNotEmpty(fieldMap)) {
+ GenTableColumn genFiled = fieldMap.get(field.getName());
+ if(genFiled!= null) {
+ customMap.put("info", genFiled);
+ }
+ }
+ field.setCustomMap(customMap);
+
+ build(t, field);
+ buildInjectionField(t, field);
+ });
+ });
+
+
+ //生成实体
+ List focList = new ArrayList<>();
+ if (!config.getFileCreateConfig().getIsVue()) {
+ StringBuilder basePathSb = getBasePath();
+ String packageBase = config.getPackageBase().replace(".", File.separator);
+ basePathSb.append(File.separator).append(packageBase);
+ config.setCurrentModule("commons");
+ focList.add(new FileOutConfigExt(basePathSb.toString(), ConstVal.ENTITY, config));
+ }
+
+ InjectionConfig cfg = new InjectionConfig() {
+ @Override
+ public void initMap() {
+ Map map = CodeGenerator.initImportPackageInfo(config.getPackageBase(), config.getChildPackageName());
+
+ //这里必须 在entity生成后,赋值
+ map.put("filedTypes", config.getFiledTypes());
+ this.setMap(map);
+ }
+
+ @Override
+ public void initTableMap(TableInfo tableInfo) {
+ this.initMap();
+ }
+ };
+
+ cfg.setFileCreate(cb.getInjectionConfig().getFileCreate());
+ if (cb.getInjectionConfig().getFileOutConfigList() != null
+ && !cb.getInjectionConfig().getFileOutConfigList().isEmpty()) {
+ cb.getInjectionConfig().getFileOutConfigList().addAll(focList);
+ cfg.setFileOutConfigList(cb.getInjectionConfig().getFileOutConfigList());
+ } else {
+ cfg.setFileOutConfigList(focList);
+ }
+ cfg.setConfig(cb.getInjectionConfig().getConfig());
+
+ cb.setInjectionConfig(cfg);
+
+
+ //执行mybatis plus的代码生成器
+ super.batchOutput();
+
+ return this;
+ }
+
+
+ private static String trim(String val) {
+ return val == null ? StringPool.EMPTY : val.trim();
+ }
+
+
+ public static void main(String[] args) {
+ String comment = "@InjectionField(api=\"xxxx\", method=\"bbbbb\", beanClass=1) RemoteData";
+// String comment = "@InjectionField(feign=FreemarkerTemplateEngineExt.class, method=\"bbbbb\" beanClass= Xxx.class) RemoteData";
+ Matcher matcher = INJECTION_FIELD_PATTERN.matcher(comment);
+ if (matcher.find()) {
+ String annotation = trim(matcher.group(1)); //@InjectionField(api="xxxx", method="bbbbb")
+ String api = trim(matcher.group(3)); //xxxx
+ String method = trim(matcher.group(4)); //bbbbb
+ String type = trim(matcher.group(6)); //RemoteData
+ // 5
+ String typePackage = trim(matcher.group(8)); //Org
+ System.out.println(111);
+ }
+ }
+
+
+ /**
+ * 生成 需要注入 类型的字段
+ *
+ * @param table
+ * @param field
+ */
+ private void buildInjectionField(TableInfo table, TableField field) {
+ //注释
+ String comment = field.getComment();
+ if (comment == null) {
+ return;
+ }
+ Set importPackages = table.getImportPackages();
+ importPackages.remove("com.zkthink.base.entity.Entity");
+ Matcher matcher = INJECTION_FIELD_PATTERN.matcher(comment);
+ if (matcher.find()) {
+ String annotation = trim(matcher.group(1));
+ String api = trim(matcher.group(3));
+ String method = trim(matcher.group(4));
+ String type = trim(matcher.group(6));
+ String typePackage = trim(matcher.group(8));
+
+ if (StrUtil.isNotEmpty(type) && StrUtil.contains(typePackage, ".")) {
+ String data = StrUtil.subAfter(typePackage, ".", true);
+ if (StrUtil.isNotEmpty(data)) {
+ type = StrUtil.replace(type, typePackage, data);
+ }
+ }
+
+ field.getCustomMap().put("annotation", annotation);
+// field.getCustomMap().put("api", api);
+// field.getCustomMap().put("method", method);
+ field.getCustomMap().put("type", type);
+// field.getCustomMap().put("type", type);
+
+ if (!api.contains("\"")) {
+ if (api.contains(".")) {
+ if (api.endsWith("class")) {
+ // 导入feign class
+ importPackages.add(StrUtil.subBefore(api, ".", true));
+
+
+ } else {
+ importPackages.add("com.zkthink.common.constant.InjectionFieldConstants");
+ }
+ } else {
+ importPackages.add(String.format("static com.zkthink.common.constant.InjectionFieldConstants.%s", api));
+ }
+ }
+ if (!method.contains("\"")) {
+ if (method.contains(".")) {
+ importPackages.add("com.zkthink.common.constant.InjectionFieldConstants");
+ } else {
+ importPackages.add(String.format("static com.zkthink.common.constant.InjectionFieldConstants.%s", method));
+ }
+ }
+ if (typePackage.contains(".")) {
+ importPackages.add(typePackage);
+ }
+ importPackages.add("com.zkthink.injection.annonation.InjectionField");
+ importPackages.add("com.zkthink.model.RemoteData");
+ }
+ }
+
+ /**
+ * 生成枚举类型类
+ *
+ * @throws Exception
+ */
+ private void generateEnum(TableInfo tableInfo, TableField field) throws Exception {
+ String comment = field.getComment();
+ if (StringUtils.isBlank(comment) || !comment.contains("{") || !comment.contains("}") || !comment.contains(";")) {
+ return;
+ }
+ // 排除boolean类型值
+ if (Boolean.class.getSimpleName().equals(field.getColumnType().getType())) {
+ return;
+ }
+ String propertyName = field.getPropertyName();
+ Set filedTypes = config.getFiledTypes();
+
+ Map objectMap = getObjectMap(tableInfo);
+ Map packageInfo = (Map) objectMap.get("package");
+ String entityPackage = packageInfo.get("Entity");
+
+ String defEnumPackage = entityPackage.replaceAll("entity", "enumeration");
+
+ String enumName = comment.substring(comment.indexOf(StringPool.HASH) + 1, comment.indexOf(StringPool.LEFT_BRACE));
+ if ("".equals(enumName)) {
+ enumName = tableInfo.getEntityName() + (Character.toUpperCase(propertyName.charAt(0)) + propertyName.substring(1)) + "Enum";
+ }
+ String finalEnumName = enumName;
+ List collect = filedTypes.stream().filter((filed) -> filed.getType().equals(finalEnumName)).collect(Collectors.toList());
+ EntityFiledType entityFiledType = EntityFiledType.builder()
+ .name(field.getPropertyName()).packagePath(defEnumPackage + "." + enumName).gen(GenerateType.OVERRIDE)
+ .build();
+ if (!collect.isEmpty()) {
+ entityFiledType = collect.get(0);
+ }
+
+ String firstTypeNumber = "true";
+ Map> allFields = new LinkedHashMap<>();
+ if (comment.contains(StringPool.HASH) && comment.contains(StringPool.RIGHT_BRACE)) {
+ String enumComment = comment.substring(comment.indexOf(StringPool.HASH), comment.indexOf(StringPool.RIGHT_BRACE) + 1);
+ // 编译正则表达式
+ Pattern pattern = Pattern.compile(REG_EX_VAL);
+ Matcher matcher = pattern.matcher(enumComment);
+ while (matcher.find()) {
+ String val = matcher.group(2);
+ if (!val.endsWith(";")) {
+ val += ";";
+ }
+
+ Pattern keyPattern = Pattern.compile(REG_EX_KEY);
+ Matcher keyMatcher = keyPattern.matcher(val);
+
+ while (keyMatcher.find()) {
+ String key = keyMatcher.group(1);
+ String value = keyMatcher.group(2);
+
+ List subList = new ArrayList<>();
+ if (value.contains(",")) {
+ String[] split = value.split(StringPool.COMMA);
+ subList = Arrays.asList(split);
+ try {
+ Integer.valueOf(split[0]);
+ } catch (Exception e) {
+ //字符串
+ firstTypeNumber = "false";
+ }
+
+ } else {
+ try {
+ Integer.valueOf(value);
+ } catch (Exception e) {
+ //字符串
+ firstTypeNumber = "false";
+ }
+ subList.add(value);
+ }
+
+ allFields.put(key, subList);
+ }
+
+ }
+ }
+
+
+ Map enumCustom = new HashMap<>();
+ enumCustom.put("package", entityFiledType);
+ enumCustom.put("enumName", enumName);
+
+ enumCustom.put("comment", StringUtils.substring(comment, 0, comment.indexOf("\n")).trim());
+ enumCustom.put("firstTypeNumber", firstTypeNumber);
+ enumCustom.put("list", allFields);
+ enumCustom.put("filedTypes", filedTypes);
+
+ objectMap.put("enumCustom", enumCustom);
+
+ field.getCustomMap().put("enumCustom", enumCustom);
+
+ StringBuilder basePathSb = getBasePath();
+ System.out.println("basePathSb: " + basePathSb);
+ basePathSb.append(File.separator).append(entityFiledType.getPath())
+ .append(".java");
+
+
+ Map customMap = field.getCustomMap();
+ if (customMap == null) {
+ customMap = new HashMap<>();
+ }
+ customMap.put("isEnum", "1");
+ field.setCustomMap(customMap);
+
+ FileCreateConfig fileCreateConfig = config.getFileCreateConfig();
+ if (GenerateType.ADD.eq(fileCreateConfig.getGenerateEnum())
+ && FileCreateConfig.isExists(basePathSb.toString())) {
+ basePathSb.append(".new");
+ }
+
+ if (isCreate(FileType.OTHER, basePathSb.toString()) && GenerateType.IGNORE.neq(entityFiledType.getGen())) {
+ writer(objectMap, templateFilePath("/templates/enum.java"), basePathSb.toString());
+ }
+
+ }
+
+
+ private StringBuilder getBasePath() {
+ String projectRootPath = config.getProjectRootPath();
+ if (!projectRootPath.endsWith(File.separator)) {
+ projectRootPath += File.separator;
+ }
+
+ StringBuilder basePathSb = new StringBuilder(projectRootPath);
+ basePathSb.append(config.getProjectPrefix()).append(config.getServiceName())
+ .append(config.getEntitySuffix()).append(File.separator)
+ .append(CodeGenerator.SRC_MAIN_JAVA);
+
+
+ return basePathSb;
+ }
+
+
+ /**
+ * 生成实体类中字段的 枚举类型
+ *
+ * @param tableInfo
+ * @param field
+ */
+ private void build(TableInfo tableInfo, TableField field) {
+ String comment = field.getComment();
+ String entityName = tableInfo.getEntityName();
+ String propertyName = field.getPropertyName();
+ if (StringUtils.isBlank(comment) || !comment.contains(StringPool.LEFT_BRACE)
+ || !comment.contains(StringPool.RIGHT_BRACE) || !comment.contains(StringPool.SEMICOLON)) {
+ return;
+ }
+ // 排除boolean类型值
+ if (Boolean.class.getSimpleName().equals(field.getColumnType().getType())) {
+ return;
+ }
+
+ String enumName = comment.substring(comment.indexOf(StringPool.HASH) + 1, comment.indexOf(StringPool.LEFT_BRACE));
+ if (StringPool.EMPTY.equals(enumName)) {
+ enumName = entityName + (Character.toUpperCase(propertyName.charAt(0)) + propertyName.substring(1)) + "Enum";
+ }
+
+ Set filedTypes = config.getFiledTypes();
+
+ EntityFiledType cur = EntityFiledType.builder().name(propertyName).table(tableInfo.getName()).build();
+ if (!filedTypes.contains(cur)) {
+ ConfigBuilder configBuilder = getConfigBuilder();
+ Map packageInfo = configBuilder.getPackageInfo();
+ String entityPackage = packageInfo.get("Entity");
+ String defEnumPackage = entityPackage.replaceAll("entity", "enumeration");
+
+ filedTypes.add(EntityFiledType.builder()
+ .name(propertyName)
+ .packagePath(defEnumPackage + "." + enumName)
+ .table(tableInfo.getName())
+ .gen(config.getFileCreateConfig().getGenerateEnum())
+ .build());
+ }
+ }
+}
diff --git a/ceres-generator-master/src/main/java/com/zkthink/ceres/generator/ext/MySqlQueryExt.java b/ceres-generator-master/src/main/java/com/zkthink/ceres/generator/ext/MySqlQueryExt.java
new file mode 100644
index 0000000..fe3b388
--- /dev/null
+++ b/ceres-generator-master/src/main/java/com/zkthink/ceres/generator/ext/MySqlQueryExt.java
@@ -0,0 +1,16 @@
+package com.zkthink.ceres.generator.ext;
+
+import com.baomidou.mybatisplus.generator.config.querys.MySqlQuery;
+
+/**
+ * 扩展 {@link MySqlQuery} 方便加入sql查询表元数据信息 增加自定义列,辅助我们的检验器的自动生成
+ *
+ * @author ceres
+ */
+public class MySqlQueryExt extends MySqlQuery {
+
+ @Override
+ public String[] fieldCustom() {
+ return new String[]{"Null", "Default", "Collation"};
+ }
+}
diff --git a/ceres-generator-master/src/main/java/com/zkthink/ceres/generator/ext/OracleQueryExt.java b/ceres-generator-master/src/main/java/com/zkthink/ceres/generator/ext/OracleQueryExt.java
new file mode 100644
index 0000000..f9ba78b
--- /dev/null
+++ b/ceres-generator-master/src/main/java/com/zkthink/ceres/generator/ext/OracleQueryExt.java
@@ -0,0 +1,32 @@
+package com.zkthink.ceres.generator.ext;
+
+import com.baomidou.mybatisplus.generator.config.querys.OracleQuery;
+
+/**
+ * 扩展 {@link OracleQuery} 方便加入sql查询表元数据信息 增加自定义列,辅助我们的检验器的自动生成
+ *
+ * @author ceres
+ * @date 2020年01月19日10:23:23
+ */
+public class OracleQueryExt extends OracleQuery {
+
+ @Override
+ public String[] fieldCustom() {
+ return new String[]{"NULLABLE", "DATA_SCALE"};
+ }
+
+ @Override
+ public String tableFieldsSql() {
+ return "SELECT A.COLUMN_NAME, CASE WHEN A.DATA_TYPE='NUMBER' THEN "
+ + "(CASE WHEN A.DATA_PRECISION IS NULL THEN A.DATA_TYPE "
+ + "WHEN NVL(A.DATA_SCALE, 0) > 0 THEN A.DATA_TYPE||'('||A.DATA_PRECISION||','||A.DATA_SCALE||')' "
+ + "ELSE A.DATA_TYPE||'('||A.DATA_PRECISION||')' END) "
+ + "ELSE A.DATA_TYPE END DATA_TYPE, B.COMMENTS,DECODE(C.POSITION, '1', 'PRI') KEY "
+ + ", A.NULLABLE, A.DATA_SCALE "
+ + "FROM ALL_TAB_COLUMNS A "
+ + " INNER JOIN ALL_COL_COMMENTS B ON A.TABLE_NAME = B.TABLE_NAME AND A.COLUMN_NAME = B.COLUMN_NAME AND B.OWNER = '#schema'"
+ + " LEFT JOIN ALL_CONSTRAINTS D ON D.TABLE_NAME = A.TABLE_NAME AND D.CONSTRAINT_TYPE = 'P' AND D.OWNER = '#schema'"
+ + " LEFT JOIN ALL_CONS_COLUMNS C ON C.CONSTRAINT_NAME = D.CONSTRAINT_NAME AND C.COLUMN_NAME=A.COLUMN_NAME AND C.OWNER = '#schema'"
+ + "WHERE A.OWNER = '#schema' AND A.TABLE_NAME = '%s' ORDER BY A.COLUMN_ID ";
+ }
+}
diff --git a/ceres-generator-master/src/main/java/com/zkthink/ceres/generator/model/GenTableColumn.java b/ceres-generator-master/src/main/java/com/zkthink/ceres/generator/model/GenTableColumn.java
new file mode 100644
index 0000000..6f26c5b
--- /dev/null
+++ b/ceres-generator-master/src/main/java/com/zkthink/ceres/generator/model/GenTableColumn.java
@@ -0,0 +1,140 @@
+package com.zkthink.ceres.generator.model;
+
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.ToString;
+import lombok.experimental.Accessors;
+
+/**
+ * 代码生成业务字段表
+ *
+ * @author ceres
+ */
+@Data
+@Builder
+@AllArgsConstructor
+@ToString
+@Accessors(chain = true)
+public class GenTableColumn {
+ public static final String YES = "1";
+ public static final String NO = "0";
+ private static final long serialVersionUID = 1L;
+ /**
+ * 归属表 自动计算
+ */
+ private String tableName;
+
+ /**
+ * 列名称 自动计算
+ */
+ private String name;
+
+ /**
+ * 列描述 自动计算
+ */
+ private String columnComment;
+
+ /**
+ * 列类型 自动计算
+ */
+ private String type;
+
+ /**
+ * JAVA类型 自动计算
+ */
+ private String propertyType;
+
+ /**
+ * JAVA字段名 自动计算
+ */
+ private String javaField;
+ /**
+ * Index页面 Table 的列宽度
+ *
+ * @since 2.0 支持
+ */
+ private String width;
+
+ /**
+ * 是否必填(1是) 为空时自动计算 暂时不支持
+ */
+ private String isRequired;
+
+ /**
+ * 是否为插入字段(1是) 为空时自动计算
+ *
+ * @since 2.0 支持
+ */
+ private String isInsert;
+
+ /**
+ * 是否编辑字段(1是) 为空时自动计算
+ *
+ * @since 2.0 支持
+ */
+ private String isEdit;
+
+ /**
+ * 是否列表字段(1是)为空时自动计算
+ *
+ * @since 2.0 支持
+ */
+ private String isList;
+
+ /**
+ * 是否查询字段(1是) 为空时自动计算
+ *
+ * @since 2.0 支持
+ */
+ private String isQuery;
+
+ /**
+ * 查询方式(EQ等于、NE不等于、GT大于、LT小于、LIKE模糊、BETWEEN范围) 暂时不支持
+ */
+ private String queryType;
+
+ /**
+ * 显示类型(input文本框、textarea文本域、select下拉框、checkbox复选框、radio单选框、datetime日期控件) 为空时自动计算
+ *
+ * @since 2.0 支持
+ */
+ private String htmlType;
+
+ /**
+ * 字典类型
+ *
+ * @since 2.0 支持
+ */
+ private String dictType;
+ /**
+ * 枚举类型
+ *
+ * @since 2.0 支持
+ */
+ private String enumType;
+
+ public GenTableColumn() {
+ }
+
+ /**
+ * 因为前段新增和报错共用一个页面,所以目前 isInsert 和 isEdit 必须都为0才不会显示在编辑页面
+ *
+ * @param name 字段名
+ * @param isInsert 是否显示在新增页面 1/0 空字符串就自动计算
+ * @param isEdit 是否显示在修改页面 1/0 空字符串就自动计算
+ * @param isList 是否显示在分页列表 1/0 空字符串就自动计算
+ * @param isQuery 是否显示在分页查询条件 1/0 空字符串就自动计算
+ * @param htmlType 输入框的类型 见: HtmlType
+ */
+ public GenTableColumn(String name, String isInsert, String isEdit, String isList, String isQuery, String htmlType) {
+ this.name = name;
+ this.isInsert = isInsert;
+ this.isEdit = isEdit;
+ this.isList = isList;
+ this.isQuery = isQuery;
+ this.htmlType = htmlType;
+ }
+
+}
diff --git a/ceres-generator-master/src/main/java/com/zkthink/ceres/generator/type/EntityFiledType.java b/ceres-generator-master/src/main/java/com/zkthink/ceres/generator/type/EntityFiledType.java
new file mode 100644
index 0000000..9d768fc
--- /dev/null
+++ b/ceres-generator-master/src/main/java/com/zkthink/ceres/generator/type/EntityFiledType.java
@@ -0,0 +1,76 @@
+package com.zkthink.ceres.generator.type;
+
+
+import java.io.File;
+
+import lombok.Builder;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.ToString;
+import org.apache.commons.lang3.StringUtils;
+
+/**
+ * 实体字段类型
+ *
+ * @author ceres
+ * @date 2019/05/14
+ */
+@Data
+@Builder
+@ToString
+@EqualsAndHashCode(of = {"name", "table"})
+public class EntityFiledType {
+ /**
+ * 枚举类型的字段名(不是数据库字段哦!!!)
+ */
+ private String name;
+ /**
+ * 枚举类型的完整包路径 eg: com.xx.xx.Type
+ */
+ private String packagePath = "";
+ /**
+ * 表名
+ */
+ private String table = "";
+
+ /**
+ * 是否生成
+ */
+ private GenerateType gen = GenerateType.OVERRIDE;
+
+ /**
+ * 枚举类型的完整路径,会根据 packagePath 自动解析
+ */
+ private String path;
+ /**
+ * 导包
+ */
+ private String importPackage;
+ /**
+ * 枚举类型: 会根据 packagePath 自动解析
+ */
+ private String type;
+
+ public String getPath() {
+ if (packagePath != null && !"".equals(packagePath)) {
+ this.path = packagePath.replace(".", File.separator);
+ }
+ return path;
+ }
+
+ public String getType() {
+ if (packagePath != null && !"".equals(packagePath)) {
+ this.type = packagePath.substring(packagePath.lastIndexOf(".") + 1);
+ }
+ return type;
+ }
+
+ public String getImportPackage() {
+ if (this.importPackage == null || "".equals(this.importPackage)) {
+ this.importPackage = StringUtils.substring(packagePath, 0, packagePath.lastIndexOf("."));
+ }
+ return this.importPackage;
+ }
+
+}
+
diff --git a/ceres-generator-master/src/main/java/com/zkthink/ceres/generator/type/EntityType.java b/ceres-generator-master/src/main/java/com/zkthink/ceres/generator/type/EntityType.java
new file mode 100644
index 0000000..e927d26
--- /dev/null
+++ b/ceres-generator-master/src/main/java/com/zkthink/ceres/generator/type/EntityType.java
@@ -0,0 +1,53 @@
+package com.zkthink.ceres.generator.type;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * 父类实体类型
+ *
+ * @author ceres
+ * @date 2019/05/14
+ */
+@Getter
+@AllArgsConstructor
+public enum EntityType {
+ /**
+ * 只有id
+ */
+ SUPER_ENTITY("com.zkthink.base.entity.SuperEntity", new String[]{"id", "tenant_code", "create_time", "create_user"}),
+ /**
+ * 有创建人创建时间等
+ */
+ ENTITY("com.zkthink.base.entity.Entity", new String[]{}),
+
+ /**
+ * 树形实体
+ */
+ TREE_ENTITY("com.zkthink.base.entity.TreeEntity", new String[]{"id", "tenant_code", "create_time", "create_user", "update_time", "update_user", "label", "parent_id", "sort_value"}),
+
+ /**
+ * 不继承任何实体
+ */
+ NONE("", new String[]{""}),
+ ;
+
+ private String val;
+ private String[] columns;
+
+
+ public boolean eq(String val) {
+ if (this.name().equals(val)) {
+ return true;
+ }
+ return false;
+ }
+
+ public boolean eq(EntityType val) {
+ if (val == null) {
+ return false;
+ }
+ return eq(val.name());
+ }
+
+}
diff --git a/ceres-generator-master/src/main/java/com/zkthink/ceres/generator/type/GenerateType.java b/ceres-generator-master/src/main/java/com/zkthink/ceres/generator/type/GenerateType.java
new file mode 100644
index 0000000..55508ba
--- /dev/null
+++ b/ceres-generator-master/src/main/java/com/zkthink/ceres/generator/type/GenerateType.java
@@ -0,0 +1,43 @@
+package com.zkthink.ceres.generator.type;
+
+/**
+ * 生成策略
+ *
+ * @author ceres
+ * @date 2019/05/14
+ */
+public enum GenerateType {
+ /**
+ * 覆盖
+ */
+ OVERRIDE,
+ /**
+ * 新增
+ */
+ ADD,
+ /**
+ * 存在则忽略
+ */
+ IGNORE,
+ ;
+
+
+ public boolean eq(String val) {
+ if (this.name().equals(val)) {
+ return true;
+ }
+ return false;
+ }
+
+ public boolean eq(GenerateType val) {
+ if (val == null) {
+ return false;
+ }
+ return eq(val.name());
+ }
+
+ public boolean neq(GenerateType val) {
+ return !eq(val);
+ }
+
+}
diff --git a/ceres-generator-master/src/main/java/com/zkthink/ceres/generator/type/HtmlType.java b/ceres-generator-master/src/main/java/com/zkthink/ceres/generator/type/HtmlType.java
new file mode 100644
index 0000000..7d7df91
--- /dev/null
+++ b/ceres-generator-master/src/main/java/com/zkthink/ceres/generator/type/HtmlType.java
@@ -0,0 +1,26 @@
+package com.zkthink.ceres.generator.type;
+
+public class HtmlType {
+ public static final String INPUT = "input";
+ public static final String TEXTAREA = "textarea";
+ public static final String SELECT = "select";
+ /**
+ * 不支持
+ *
+ * @since 2.0 不支持
+ */
+ public static final String SELECT_USER = "select_user";
+ /**
+ * 不支持
+ *
+ * @since 2.0 不支持
+ */
+ public static final String SELECT_ORG = "select_org";
+ public static final String RADIO = "radio";
+ public static final String RADIO_BUTTON = "radio-button";
+ public static final String SWITCH = "switch";
+ public static final String CHECKBOX = "checkbox";
+ public static final String CHECKBOX_BUTTON = "checkbox-button";
+ public static final String DATE_PICKER = "date-picker";
+ public static final String DATE_TIME_PICKER = "datetime-picker";
+}
diff --git a/ceres-generator-master/src/main/java/com/zkthink/ceres/generator/type/SuperClass.java b/ceres-generator-master/src/main/java/com/zkthink/ceres/generator/type/SuperClass.java
new file mode 100644
index 0000000..1bb8625
--- /dev/null
+++ b/ceres-generator-master/src/main/java/com/zkthink/ceres/generator/type/SuperClass.java
@@ -0,0 +1,42 @@
+package com.zkthink.ceres.generator.type;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+
+@Getter
+@NoArgsConstructor
+@AllArgsConstructor
+public enum SuperClass {
+
+ SUPER_CLASS("com.zkthink.base.controller.SuperController", "com.zkthink.base.service.SuperService",
+ "com.zkthink.base.service.SuperServiceImpl", "com.baomidou.mybatisplus.core.mapper.BaseMapper"),
+ SUPER_CACHE_CLASS("com.zkthink.base.controller.SuperCacheController", "com.zkthink.base.service.SuperCacheService",
+ "com.zkthink.base.service.SuperCacheServiceImpl", "com.baomidou.mybatisplus.core.mapper.BaseMapper"),
+ NONE("", "", "", "");
+
+ private String controller;
+ private String service;
+ private String serviceImpl;
+ private String mapper;
+
+ public SuperClass setController(String controller) {
+ this.controller = controller;
+ return this;
+ }
+
+ public SuperClass setService(String service) {
+ this.service = service;
+ return this;
+ }
+
+ public SuperClass setMapper(String mapper) {
+ this.mapper = mapper;
+ return this;
+ }
+
+ public SuperClass setServiceImpl(String serviceImpl) {
+ this.serviceImpl = serviceImpl;
+ return this;
+ }
+}
diff --git a/ceres-generator-master/src/main/resources/init/java/Application.java.ftl b/ceres-generator-master/src/main/resources/init/java/Application.java.ftl
new file mode 100644
index 0000000..c323c57
--- /dev/null
+++ b/ceres-generator-master/src/main/resources/init/java/Application.java.ftl
@@ -0,0 +1,55 @@
+package ${packageBaseParent};
+
+import com.zkthink.security.annotation.EnableLoginArgResolver;
+import com.zkthink.validator.config.EnableFormValidator;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
+import org.springframework.cloud.openfeign.EnableFeignClients;
+import org.springframework.context.ConfigurableApplicationContext;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.EnableAspectJAutoProxy;
+<#if packageBaseParent != "com.zkthink">
+import org.springframework.context.annotation.ComponentScan;
+#if>
+import org.springframework.core.env.Environment;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+
+/**
+ * ${description}启动类
+ *
+ * @author ${author}
+ * @date ${date}
+ */
+@SpringBootApplication
+@EnableDiscoveryClient
+@Configuration
+<#if packageBaseParent != "com.zkthink">
+@EnableFeignClients(value = { "${packageBaseParent}", "com.zkthink" })
+@ComponentScan(basePackages = {"${packageBaseParent}", "com.zkthink"})
+<#else>
+@EnableFeignClients(value = { "${packageBaseParent}" })
+#if>
+@EnableAspectJAutoProxy(proxyTargetClass = true, exposeProxy = true)
+@Slf4j
+@EnableLoginArgResolver
+@EnableFormValidator
+public class ${service}ServerApplication {
+ public static void main(String[] args) throws UnknownHostException {
+ ConfigurableApplicationContext application = SpringApplication.run(${service}ServerApplication.class, args);
+ Environment env = application.getEnvironment();
+ log.info("\n----------------------------------------------------------\n\t" +
+ "应用 '{}' 启动成功! 访问连接:\n\t" +
+ "Swagger文档: \t\thttp://{}:{}/doc.html\n\t" +
+ "数据库监控: \t\thttp://{}:{}/druid\n" +
+ "----------------------------------------------------------",
+ env.getProperty("spring.application.name"),
+ InetAddress.getLocalHost().getHostAddress(),
+ env.getProperty("server.port"),
+ "127.0.0.1",
+ env.getProperty("server.port"));
+ }
+}
diff --git a/ceres-generator-master/src/main/resources/init/java/DatabaseAutoConfiguration.java.ftl b/ceres-generator-master/src/main/resources/init/java/DatabaseAutoConfiguration.java.ftl
new file mode 100644
index 0000000..3673b26
--- /dev/null
+++ b/ceres-generator-master/src/main/resources/init/java/DatabaseAutoConfiguration.java.ftl
@@ -0,0 +1,123 @@
+package ${packageBase}.config.datasource;
+
+import cn.hutool.core.util.ArrayUtil;
+import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
+import com.baomidou.mybatisplus.autoconfigure.ConfigurationCustomizer;
+import com.baomidou.mybatisplus.autoconfigure.MybatisPlusProperties;
+import com.baomidou.mybatisplus.autoconfigure.MybatisPlusPropertiesCustomizer;
+import com.zkthink.database.datasource.BaseDatabaseConfiguration;
+import com.zkthink.database.properties.DatabaseProperties;
+import com.p6spy.engine.spy.P6DataSource;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.ibatis.mapping.DatabaseIdProvider;
+import org.apache.ibatis.plugin.Interceptor;
+import org.apache.ibatis.scripting.LanguageDriver;
+import org.apache.ibatis.session.ExecutorType;
+import org.apache.ibatis.session.SqlSessionFactory;
+import org.apache.ibatis.type.TypeHandler;
+import org.mybatis.spring.SqlSessionTemplate;
+import org.mybatis.spring.annotation.MapperScan;
+import org.springframework.beans.factory.ObjectProvider;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Primary;
+import org.springframework.core.io.ResourceLoader;
+import org.springframework.stereotype.Repository;
+
+import javax.sql.DataSource;
+import java.util.List;
+
+/**
+ * ceres.database.multiTenantType != DATASOURCE 时,该类启用.
+ * 此时,项目的多租户模式切换成:${r"${ceres.database.multiTenantType}"}。
+ *
+ * NONE("非租户模式"): 不存在租户的概念
+ * COLUMN("字段模式"): 在sql中拼接 tenant_code 字段
+ * SCHEMA("独立schema模式"): 在sql中拼接 数据库 schema
+ *
+ * COLUMN和SCHEMA模式的实现 参考下面的 @see 中的3个类
+ *
+ * @author ${author}
+ * @date ${date}
+ * 断点查看原理:👇👇👇
+ * @see com.zkthink.database.datasource.BaseMybatisConfiguration#paginationInterceptor()
+ * @see com.zkthink.database.servlet.TenantContextHandlerInterceptor
+ * @see com.zkthink.database.parsers.DynamicTableNameParser
+*/
+@Configuration
+@Slf4j
+@MapperScan(
+ basePackages = { "${packageBaseParent}", <#if packageBaseParent != "com.zkthink">"com.zkthink"#if>}, annotationClass = Repository.class,
+ sqlSessionFactoryRef = ${service}DatabaseAutoConfiguration.DATABASE_PREFIX + "SqlSessionFactory")
+@EnableConfigurationProperties({MybatisPlusProperties.class})
+@ConditionalOnExpression("!'DATASOURCE'.equals('${r"${ceres.database.multiTenantType}"}')")
+public class ${service}DatabaseAutoConfiguration extends BaseDatabaseConfiguration {
+ /**
+ * 每个数据源配置不同即可
+ */
+ final static String DATABASE_PREFIX = "master";
+
+ public ${service}DatabaseAutoConfiguration(MybatisPlusProperties properties,
+ DatabaseProperties databaseProperties,
+ ObjectProvider${r""} interceptorsProvider,
+ ObjectProvider${r""} typeHandlersProvider,
+ ObjectProvider${r""} languageDriversProvider,
+ ResourceLoader resourceLoader,
+ ObjectProvider${r""} databaseIdProvider,
+ ObjectProvider${r">"} configurationCustomizersProvider,
+ ObjectProvider${r">"} mybatisPlusPropertiesCustomizerProvider,
+ ApplicationContext applicationContext) {
+ super(properties, databaseProperties, interceptorsProvider, typeHandlersProvider,
+ languageDriversProvider, resourceLoader, databaseIdProvider,
+ configurationCustomizersProvider, mybatisPlusPropertiesCustomizerProvider, applicationContext);
+ log.debug("检测到 ceres.database.multiTenantType!=DATASOURCE,加载了 ${service}DatabaseAutoConfiguration");
+ }
+
+ @Bean(DATABASE_PREFIX + "SqlSessionTemplate")
+ public SqlSessionTemplate getSqlSessionTemplate(@Qualifier(DATABASE_PREFIX + "SqlSessionFactory") SqlSessionFactory sqlSessionFactory) {
+ ExecutorType executorType = this.properties.getExecutorType();
+ if (executorType != null) {
+ return new SqlSessionTemplate(sqlSessionFactory, executorType);
+ } else {
+ return new SqlSessionTemplate(sqlSessionFactory);
+ }
+ }
+
+ /**
+ * 数据源信息
+ *
+ * @return
+ */
+ @Primary
+ @Bean(name = DATABASE_PREFIX + "DruidDataSource")
+ @ConfigurationProperties(prefix = "spring.datasource.druid")
+ public DataSource druidDataSource() {
+ return DruidDataSourceBuilder.create().build();
+ }
+
+ @Bean(name = DATABASE_PREFIX + "DataSource")
+ public DataSource dataSource(@Qualifier(DATABASE_PREFIX + "DruidDataSource") DataSource dataSource) {
+ if (ArrayUtil.contains(DEV_PROFILES, this.profiles)) {
+ return new P6DataSource(dataSource);
+ } else {
+ return dataSource;
+ }
+ }
+
+ /**
+ * mybatis Sql Session 工厂
+ *
+ * @return
+ * @throws Exception
+ */
+ @Bean(DATABASE_PREFIX + "SqlSessionFactory")
+ public SqlSessionFactory getSqlSessionFactory(@Qualifier(DATABASE_PREFIX + "DataSource") DataSource dataSource) throws Exception {
+ return super.sqlSessionFactory(dataSource);
+ }
+
+}
diff --git a/ceres-generator-master/src/main/resources/init/java/ExceptionConfiguration.java.ftl b/ceres-generator-master/src/main/resources/init/java/ExceptionConfiguration.java.ftl
new file mode 100644
index 0000000..d8f6517
--- /dev/null
+++ b/ceres-generator-master/src/main/resources/init/java/ExceptionConfiguration.java.ftl
@@ -0,0 +1,20 @@
+package ${packageBase}.config;
+
+import com.zkthink.boot.handler.DefaultGlobalExceptionHandler;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.ControllerAdvice;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * ${description}-全局异常处理
+ *
+ * @author ${author}
+ * @date ${date}
+ */
+@Configuration
+@ControllerAdvice(annotations = {RestController.class, Controller.class})
+@ResponseBody
+public class ${service}ExceptionConfiguration extends DefaultGlobalExceptionHandler {
+}
diff --git a/ceres-generator-master/src/main/resources/init/java/MybatisAutoConfiguration.java.ftl b/ceres-generator-master/src/main/resources/init/java/MybatisAutoConfiguration.java.ftl
new file mode 100644
index 0000000..a99794f
--- /dev/null
+++ b/ceres-generator-master/src/main/resources/init/java/MybatisAutoConfiguration.java.ftl
@@ -0,0 +1,43 @@
+package ${packageBase}.config.datasource;
+
+
+import com.zkthink.oauth.api.UserApi;
+import com.zkthink.database.datasource.BaseMybatisConfiguration;
+import com.zkthink.database.mybatis.auth.DataScopeInterceptor;
+import com.zkthink.database.properties.DatabaseProperties;
+import com.zkthink.utils.SpringUtils;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.annotation.Order;
+
+/**
+ * ${description}-Mybatis 常用重用拦截器
+ *
+ * @author ${author}
+ * @date ${date}
+ */
+@Configuration
+@Slf4j
+@EnableConfigurationProperties({DatabaseProperties.class})
+public class ${service}MybatisAutoConfiguration extends BaseMybatisConfiguration {
+
+ public ${service}MybatisAutoConfiguration(DatabaseProperties databaseProperties) {
+ super(databaseProperties);
+ }
+
+ /**
+ * 数据权限插件
+ *
+ * @return DataScopeInterceptor
+ */
+ @Order(10)
+ @Bean
+ @ConditionalOnProperty(prefix = DatabaseProperties.PREFIX, name = "isDataScope", havingValue = "true", matchIfMissing = true)
+ public DataScopeInterceptor dataScopeInterceptor() {
+ return new DataScopeInterceptor((userId) -> SpringUtils.getBean(UserApi.class).getDataScopeById(userId));
+ }
+
+}
diff --git a/ceres-generator-master/src/main/resources/init/java/WebConfiguration.java.ftl b/ceres-generator-master/src/main/resources/init/java/WebConfiguration.java.ftl
new file mode 100644
index 0000000..637ce67
--- /dev/null
+++ b/ceres-generator-master/src/main/resources/init/java/WebConfiguration.java.ftl
@@ -0,0 +1,30 @@
+package ${packageBase}.config;
+
+import com.zkthink.boot.config.BaseConfig;
+import org.springframework.context.annotation.Configuration;
+import com.zkthink.oauth.api.LogApi;
+import com.zkthink.log.event.SysLogListener;
+import org.springframework.context.annotation.Bean;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
+
+/**
+ * ${description}-Web配置
+ *
+ * @author ${author}
+ * @date ${date}
+ */
+@Configuration
+public class ${service}WebConfiguration extends BaseConfig {
+
+ /**
+ * ceres.log.enabled = true 并且 ceres.log.type=DB时实例该类
+ *
+ * @param optLogService
+ * @return
+ */
+ @Bean
+ @ConditionalOnExpression("${r'${'}ceres.log.enabled:true${r'}'} && 'DB'.equals('${r'${'}ceres.log.type:LOGGER${r'}'}')")
+ public SysLogListener sysLogListener(LogApi logApi) {
+ return new SysLogListener((log) -> logApi.save(log));
+ }
+}
diff --git a/ceres-generator-master/src/main/resources/init/pom/api.java.ftl b/ceres-generator-master/src/main/resources/init/pom/api.java.ftl
new file mode 100644
index 0000000..116b051
--- /dev/null
+++ b/ceres-generator-master/src/main/resources/init/pom/api.java.ftl
@@ -0,0 +1,46 @@
+
+
+
+ ${projectPrefix}${serviceName}
+ ${groupId}
+ ${version}
+ ../
+
+
+ 4.0.0
+ ${projectPrefix}${serviceName}-api
+ ${r"${"}project.artifactId${r"}"}
+ ${description}-FeignApi模块
+
+
+
+ ${groupId}
+ ${projectPrefix}${serviceName}-entity
+ ${r"${"}ceres-project.version${r"}"}
+
+
+
+ org.springframework.cloud
+ spring-cloud-starter-openfeign
+
+
+ com.google.guava
+ guava
+
+
+
+
+ org.springframework.cloud
+ spring-cloud-starter-netflix-hystrix
+
+
+ com.google.guava
+ guava
+
+
+
+
+
+
diff --git a/ceres-generator-master/src/main/resources/init/pom/biz.java.ftl b/ceres-generator-master/src/main/resources/init/pom/biz.java.ftl
new file mode 100644
index 0000000..524e048
--- /dev/null
+++ b/ceres-generator-master/src/main/resources/init/pom/biz.java.ftl
@@ -0,0 +1,61 @@
+
+
+
+ ${projectPrefix}${serviceName}
+ ${groupId}
+ ${version}
+ ../
+
+
+ 4.0.0
+ <#if isChildModule>
+ ${projectPrefix}${childModuleName}-biz
+ <#else>
+ ${projectPrefix}${serviceName}-biz
+ #if>
+ ${r"${"}project.artifactId${r"}"}
+ ${description}-业务模块
+
+
+
+ ${groupId}
+ ${projectPrefix}${serviceName}-entity
+
+
+
+ ${groupId}
+ ${projectPrefix}oauth-api
+ ${r"${"}ceres-project.version${r"}"}
+
+
+ com.zkthink
+ ceres-databases
+
+
+ com.zkthink
+ ceres-dozer-starter
+
+
+ com.zkthink
+ ceres-j2cache-starter
+
+
+ com.zkthink
+ ceres-boot
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+
+ com.baomidou
+ mybatis-plus
+
+
+
+
+
diff --git a/ceres-generator-master/src/main/resources/init/pom/controller.java.ftl b/ceres-generator-master/src/main/resources/init/pom/controller.java.ftl
new file mode 100644
index 0000000..95932bf
--- /dev/null
+++ b/ceres-generator-master/src/main/resources/init/pom/controller.java.ftl
@@ -0,0 +1,42 @@
+
+
+
+ ${projectPrefix}${serviceName}
+ ${groupId}
+ ${version}
+ ../
+
+
+ 4.0.0
+ <#if isChildModule>
+ ${projectPrefix}${childModuleName}-controller
+ <#else>
+ ${projectPrefix}${serviceName}-controller
+ #if>
+ ${r"${"}project.artifactId${r"}"}
+ ${description}-控制器模块
+
+
+
+ ${groupId}
+ <#if isChildModule>
+ ${projectPrefix}${childModuleName}-biz
+ <#else>
+ ${projectPrefix}${serviceName}-biz
+ #if>
+
+
+
+ com.zkthink
+ ceres-security-starter
+
+
+ com.zkthink
+ ceres-log-starter
+
+
+
+
+
diff --git a/ceres-generator-master/src/main/resources/init/pom/entity.java.ftl b/ceres-generator-master/src/main/resources/init/pom/entity.java.ftl
new file mode 100644
index 0000000..845eace
--- /dev/null
+++ b/ceres-generator-master/src/main/resources/init/pom/entity.java.ftl
@@ -0,0 +1,41 @@
+
+
+
+ ${projectPrefix}${serviceName}
+ ${groupId}
+ ${version}
+ ../
+
+
+ 4.0.0
+ ${projectPrefix}${serviceName}-entity
+ ${r"${"}project.artifactId${r"}"}
+ ${description}-实体模块
+
+
+
+ com.zkthink
+ ceres-common
+ ${r"${"}ceres-project.version${r"}"}
+
+
+ com.zkthink
+ ceres-injection-starter
+
+
+ com.baomidou
+ mybatis-plus-annotation
+
+
+ cn.afterturn
+ easypoi-annotation
+
+
+ cn.afterturn
+ easypoi-base
+
+
+
+
diff --git a/ceres-generator-master/src/main/resources/init/pom/pom.java.ftl b/ceres-generator-master/src/main/resources/init/pom/pom.java.ftl
new file mode 100644
index 0000000..0fee326
--- /dev/null
+++ b/ceres-generator-master/src/main/resources/init/pom/pom.java.ftl
@@ -0,0 +1,46 @@
+
+
+
+ ${groupId}
+ ${projectPrefix}admin-cloud
+ ${version}
+ ../
+
+
+ 4.0.0
+ ${projectPrefix}${serviceName}
+ ${r"${"}project.artifactId${r"}"}
+ ${description}服务
+ pom
+
+
+ ${projectPrefix}${serviceName}-api
+ ${projectPrefix}${serviceName}-entity
+ ${projectPrefix}${serviceName}-biz
+ ${projectPrefix}${serviceName}-controller
+ ${projectPrefix}${serviceName}-server
+
+
+
+
+
+ ${groupId}
+ ${projectPrefix}${serviceName}-entity
+ ${r"${"}ceres-project.version${r"}"}
+
+
+ ${groupId}
+ ${projectPrefix}${serviceName}-biz
+ ${r"${"}ceres-project.version${r"}"}
+
+
+ ${groupId}
+ ${projectPrefix}${serviceName}-controller
+ ${r"${"}ceres-project.version${r"}"}
+
+
+
+
+
diff --git a/ceres-generator-master/src/main/resources/init/pom/server.java.ftl b/ceres-generator-master/src/main/resources/init/pom/server.java.ftl
new file mode 100644
index 0000000..4a463c1
--- /dev/null
+++ b/ceres-generator-master/src/main/resources/init/pom/server.java.ftl
@@ -0,0 +1,127 @@
+
+
+
+ ${projectPrefix}${serviceName}
+ ${groupId}
+ ${version}
+ ../
+
+
+ 4.0.0
+ ${projectPrefix}${serviceName}-server
+ ${r"${"}project.artifactId${r"}"}
+ ${description}-启动模块
+
+
+
+ ${groupId}
+ ${projectPrefix}${serviceName}-controller
+
+
+
+ com.zkthink
+ ceres-scan-starter
+
+
+ com.zkthink
+ ceres-swagger2-starter
+
+
+ com.zkthink
+ ceres-validator-starter
+
+
+ com.zkthink
+ ceres-xss-starter
+
+
+ com.zkthink
+ ceres-j2cache-starter
+
+
+ com.zkthink
+ ceres-cloud-starter
+
+
+ com.zkthink
+ ceres-zipkin-client-starter
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.apache.tomcat.embed
+ tomcat-embed-websocket
+
+
+ org.springframework.boot
+ spring-boot-starter-tomcat
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-undertow
+
+
+ org.springframework.boot
+ spring-boot-starter-aop
+
+
+ org.springframework.boot
+ spring-boot-starter-actuator
+
+
+ com.baomidou
+ mybatis-plus-boot-starter
+
+
+ cn.afterturn
+ easypoi-spring-boot-starter
+
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+
+
+
+ ../../src/main/filters/config-${r"${"}profile.active${r"}"}.properties
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+ repackage
+
+
+
+
+
+
+
+ com.spotify
+ dockerfile-maven-plugin
+ ${r"${"}dockerfile-maven-plugin.version${r"}"}
+
+ ${r"${"}docker.image.prefix${r"}"}/${r"${"}project.artifactId${r"}"}
+ ${r"${"}ceres-project.version${r"}"}
+
+ target/${r"${"}project.build.finalName${r"}"}.jar
+
+
+
+
+
+
+
diff --git a/ceres-generator-master/src/main/resources/init/resources/application.java.ftl b/ceres-generator-master/src/main/resources/init/resources/application.java.ftl
new file mode 100644
index 0000000..827aab3
--- /dev/null
+++ b/ceres-generator-master/src/main/resources/init/resources/application.java.ftl
@@ -0,0 +1,12 @@
+ceres:
+ swagger:
+ docket:
+ ${serviceName}:
+ title: ${description}服务
+ base-package: ${packageBase}.controller
+server:
+ port: ${serverPort}
+
+
+## 请在nacos中新建一个名为: ${projectPrefix}${serviceName}-server.yml 的配置文件,并将: ${projectPrefix}${serviceName}-server/src/main/resources/${projectPrefix}${serviceName}-server.yml 配置文件的内容移动过去
+## 然后删除此文件!!!
diff --git a/ceres-generator-master/src/main/resources/init/resources/banner.java.ftl b/ceres-generator-master/src/main/resources/init/resources/banner.java.ftl
new file mode 100644
index 0000000..548cc39
--- /dev/null
+++ b/ceres-generator-master/src/main/resources/init/resources/banner.java.ftl
@@ -0,0 +1,10 @@
+${r"${"}AnsiColor.BRIGHT_YELLOW${r"}"}
+ .__.__ .___ .__ .__ .___
+__________ __|__| |__ ____ __ __ _____ __| _/_____ |__| ____ ____ | | ____ __ __ __| _/
+\___ / | \ | | \ / _ \| | \ ______ \__ \ / __ |/ \| |/ \ ______ _/ ___\| | / _ \| | \/ __ |
+ / /| | / | Y ( ${r"<_>"} ) | / /_____/ / __ \_/ /_/ | Y Y \ | | \ /_____/ \ \___| |_( ${r"<_>"} ) | / /_/ |
+/_____ \____/|__|___| /\____/|____/ (____ /\____ |__|_| /__|___| / \___ >____/\____/|____/\____ |
+ \/ \/ \/ \/ \/ \/ \/ \/
+Application Version: @project.description@ - @project.version@
+Spring Boot Version: ${r"${"}spring-boot.version${r"}"}${r"${"}spring-boot.formatted-version${r"}"}
+${r"${"}AnsiColor.DEFAULT${r"}"}
diff --git a/ceres-generator-master/src/main/resources/init/resources/bootstrap.java.ftl b/ceres-generator-master/src/main/resources/init/resources/bootstrap.java.ftl
new file mode 100644
index 0000000..2835d7d
--- /dev/null
+++ b/ceres-generator-master/src/main/resources/init/resources/bootstrap.java.ftl
@@ -0,0 +1,50 @@
+# @xxx@ 从pom.xml中取值, 所以 @xx@ 标注的值,都不能从nacos中获取
+ceres:
+ nacos:
+ ip: ${r"${"}NACOS_IP:@nacos.ip@${r"}"}
+ port: ${r"${"}NACOS_PORT:@nacos.port@${r"}"}
+ namespace: ${r"${"}NACOS_ID:@nacos.namespace@${r"}"}
+
+spring:
+ main:
+ allow-bean-definition-overriding: true
+ application:
+ name: @project.artifactId@
+ profiles:
+ active: @profile.active@
+ cloud:
+ nacos:
+ config:
+ server-addr: ${r"${"}ceres.nacos.ip${r"}"}:${r"${"}ceres.nacos.port${r"}"}
+ file-extension: yml
+ namespace: ${r"${"}ceres.nacos.namespace${r"}"}
+ shared-configs:
+ - dataId: common.yml
+ refresh: true
+ - dataId: redis.yml
+ refresh: false
+ - dataId: mysql.yml
+ refresh: true
+ - dataId: rabbitmq.yml
+ refresh: false
+ enabled: true
+ discovery:
+ server-addr: ${r"${"}ceres.nacos.ip}:${r"${"}ceres.nacos.port${r"}"}
+ namespace: ${r"${"}ceres.nacos.namespace${r"}"}
+ metadata: # 元数据,用于权限服务实时获取各个服务的所有接口
+ management.context-path: ${r"${"}server.servlet.context-path:${r"}"}${r"${"}spring.mvc.servlet.path:${r"}"}${r"${"}management.endpoints.web.base-path:${r"}"}
+
+# 只能配置在bootstrap.yml ,否则会生成 log.path_IS_UNDEFINED 文件夹
+# window会自动在 代码所在盘 根目录下自动创建文件夹, 如: D:/data/projects/logs
+logging:
+ file:
+ path: @logging.file.path@
+ name: ${r"${"}logging.file.path${r"}"}/${r"${"}spring.application.name}/root.log
+
+# 用于/actuator/info
+info:
+ name: '@project.name@'
+ description: '@project.description@'
+ version: '@project.version@'
+ spring-boot-version: '${r"${spring.boot.version}"}'
+ spring-cloud-version: '@spring.cloud.version@'
diff --git a/ceres-generator-master/src/main/resources/init/resources/logback-spring.java.ftl b/ceres-generator-master/src/main/resources/init/resources/logback-spring.java.ftl
new file mode 100644
index 0000000..88b0083
--- /dev/null
+++ b/ceres-generator-master/src/main/resources/init/resources/logback-spring.java.ftl
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ceres-generator-master/src/main/resources/init/resources/spy.java.ftl b/ceres-generator-master/src/main/resources/init/resources/spy.java.ftl
new file mode 100644
index 0000000..04c82c1
--- /dev/null
+++ b/ceres-generator-master/src/main/resources/init/resources/spy.java.ftl
@@ -0,0 +1,21 @@
+module.log=com.p6spy.engine.logging.P6LogFactory,com.p6spy.engine.outage.P6OutageFactory
+# \u81EA\u5B9A\u4E49\u65E5\u5FD7\u6253\u5370
+logMessageFormat=com.baomidou.mybatisplus.extension.p6spy.P6SpyLogger
+#\u65E5\u5FD7\u8F93\u51FA\u5230\u63A7\u5236\u53F0
+appender=com.baomidou.mybatisplus.extension.p6spy.StdoutLogger
+# \u4F7F\u7528\u65E5\u5FD7\u7CFB\u7EDF\u8BB0\u5F55 sql
+#appender=com.p6spy.engine.spy.appender.Slf4JLogger
+# \u8BBE\u7F6E p6spy driver \u4EE3\u7406
+deregisterdrivers=true
+# \u53D6\u6D88JDBC URL\u524D\u7F00
+useprefix=true
+# \u914D\u7F6E\u8BB0\u5F55 Log \u4F8B\u5916,\u53EF\u53BB\u6389\u7684\u7ED3\u679C\u96C6\u6709error,info,batch,debug,statement,commit,rollback,result,resultset.
+excludecategories=info,debug,result,commit,resultset
+# \u65E5\u671F\u683C\u5F0F
+dateformat=yyyy-MM-dd HH:mm:ss
+# \u5B9E\u9645\u9A71\u52A8\u53EF\u591A\u4E2A
+driverlist=com.mysql.cj.jdbc.Driver
+# \u662F\u5426\u5F00\u542F\u6162SQL\u8BB0\u5F55
+outagedetection=true
+# \u6162SQL\u8BB0\u5F55\u6807\u51C6 2 \u79D2
+outagedetectioninterval=2
diff --git a/ceres-generator-master/src/main/resources/logback.xml b/ceres-generator-master/src/main/resources/logback.xml
new file mode 100644
index 0000000..a5cd9e1
--- /dev/null
+++ b/ceres-generator-master/src/main/resources/logback.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+ %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %class{36}:%L - %msg%n
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/ceres-generator-master/src/main/resources/templates/constant.java.ftl b/ceres-generator-master/src/main/resources/templates/constant.java.ftl
new file mode 100644
index 0000000..9c0c649
--- /dev/null
+++ b/ceres-generator-master/src/main/resources/templates/constant.java.ftl
@@ -0,0 +1,32 @@
+package ${cfg.Constant};
+
+import java.io.Serializable;
+
+/**
+ *
+ * 数据库常量
+ * ${table.comment!?replace("\n","\n * ")}
+ *
+ *
+ * @author ${author}
+ * @date ${date}
+ */
+public class ${entity}${cfg.constantSuffix} implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ private ${entity}${cfg.constantSuffix}(){
+ super();
+ }
+
+<#-- 字段常量 -->
+<#if entityColumnConstant>
+ /**
+ * 字段常量
+ */
+ <#list table.fields as field>
+ public static final String ${field.name?upper_case} = "${field.name}";
+ #list>
+#if>
+
+}
diff --git a/ceres-generator-master/src/main/resources/templates/controller.java.ftl b/ceres-generator-master/src/main/resources/templates/controller.java.ftl
new file mode 100644
index 0000000..734e8f6
--- /dev/null
+++ b/ceres-generator-master/src/main/resources/templates/controller.java.ftl
@@ -0,0 +1,81 @@
+/*
+* Copyright (C) 2017-2021
+* All rights reserved, Designed By 深圳中科鑫智科技有限公司
+* Copyright authorization contact 18814114118
+*/
+package ${package.Controller};
+
+<#if superControllerClass??>
+import ${package.Entity}.${entity};
+import ${cfg.SaveDTO}.${entity}SaveDTO;
+import ${cfg.SaveDTO}.${entity}UpdateDTO;
+import ${cfg.SaveDTO}.${entity}PageDTO;
+import ${package.Service}.${table.serviceName};
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+#if>
+<#if superControllerClassPackage??>
+import ${superControllerClassPackage};
+#if>
+import io.swagger.annotations.Api;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.bind.annotation.RequestMapping;
+<#if restControllerStyle>
+import org.springframework.web.bind.annotation.RestController;
+<#else>
+import org.springframework.stereotype.Controller;
+#if>
+
+
+<#assign tableComment = "${table.comment!''}"/>
+<#if table.comment?? && table.comment!?contains('\n')>
+ <#assign tableComment = "${table.comment!?substring(0,table.comment?index_of('\n'))?trim}"/>
+#if>
+/**
+ *
+ * 前端控制器
+ * ${table.comment!?replace("\n","\n * ")}
+ *
+ *
+ * @author ${author}
+ * @date ${date}
+ */
+@Slf4j
+<#if restControllerStyle>
+@RestController
+<#else>
+@Controller
+#if>
+@RequestMapping("<#if package.ModuleName??>/${package.ModuleName}#if>/<#if controllerMappingHyphenStyle??>${controllerMappingHyphen}<#else>${table.entityPath}#if>")
+<#if swagger2>
+@Api(value = "${entity}", tags = "${tableComment}")
+#if>
+<#if kotlin>
+ class ${table.controllerName}<#if superControllerClass??> : ${superControllerClass}()#if>
+<#else>
+ <#if superControllerClass??>
+public class ${table.controllerName} extends ${superControllerClass}<${table.serviceName}, <#list table.commonFields as field><#if field.keyFlag>${field.propertyType}#if>#list><#list table.fields as field><#if field.keyFlag>${field.propertyType}#if>#list>, ${entity}, ${entity}PageDTO, ${entity}SaveDTO, ${entity}UpdateDTO> {
+ <#else>
+public class ${table.controllerName} {
+ #if>
+
+<#if superControllerClass??>
+ /**
+ * Excel导入后的操作
+ *
+ * @param list
+ */
+ @Override
+ public R handlerImport(List