diff --git a/cloud-common-plugin-dynamic/src/main/java/com/cm/common/plugin/controller/apis/dynamic/config/DynamicConfigTableController.java b/cloud-common-plugin-dynamic/src/main/java/com/cm/common/plugin/controller/apis/dynamic/config/DynamicConfigTableController.java index babcef4..f4adeef 100644 --- a/cloud-common-plugin-dynamic/src/main/java/com/cm/common/plugin/controller/apis/dynamic/config/DynamicConfigTableController.java +++ b/cloud-common-plugin-dynamic/src/main/java/com/cm/common/plugin/controller/apis/dynamic/config/DynamicConfigTableController.java @@ -3,15 +3,19 @@ package com.cm.common.plugin.controller.apis.dynamic.config; import com.cm.common.annotation.CheckRequestBodyAnnotation; import com.cm.common.base.AbstractController; import com.cm.common.constants.ISystemConstant; +import com.cm.common.exception.ParamsException; import com.cm.common.exception.SearchException; import com.cm.common.plugin.pojo.dtos.dynamic.config.DynamicConfigTableDTO; import com.cm.common.plugin.pojo.vos.dynamic.config.DynamicConfigTableVO; +import com.cm.common.plugin.pojo.vos.dynamic.config.EmptyProjectVO; import com.cm.common.plugin.service.dynamic.config.IDynamicConfigTableService; import com.cm.common.pojo.ListPage; import com.cm.common.result.ErrorResult; import com.cm.common.result.SuccessResult; import com.cm.common.result.SuccessResultList; +import com.cm.common.utils.RegexUtil; import io.swagger.annotations.*; +import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; @@ -131,10 +135,57 @@ public class DynamicConfigTableController extends AbstractController { @ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)}) @GetMapping("getgeneratorcode/{id}") public void getGeneratorCode(@PathVariable("id") String id, - @RequestParam(name = "basePackage") String basePackage, - @RequestParam(name = "context") String context, - HttpServletResponse response) throws Exception { + @RequestParam(name = "basePackage") String basePackage, + @RequestParam(name = "context") String context, + HttpServletResponse response) throws Exception { dynamicConfigTableService.getStaticCode(id, basePackage, context, response); } + @ApiOperation(value = "下载空项目", notes = "下载空项目接口") + @ApiImplicitParams({ + @ApiImplicitParam(name = "systemUrl", value = "系统地址", paramType = "form"), + @ApiImplicitParam(name = "systemPort", value = "系统端口", paramType = "form", dataType = "Integer"), + @ApiImplicitParam(name = "systemName", value = "系统名", paramType = "form", dataType = "String"), + @ApiImplicitParam(name = "systemSummary", value = "系统说明", paramType = "form", dataType = "String"), + @ApiImplicitParam(name = "oauthServerUrl", value = "认证地址", paramType = "form", dataType = "String") + }) + @ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)}) + @GetMapping("getemptyproject") + public void saveEmptyProject(@RequestParam("systemUrl") String systemUrl, + @RequestParam("systemPort") Integer systemPort, + @RequestParam("systemName") String systemName, + @RequestParam("systemSummary") String systemSummary, + @RequestParam("oauthServerUrl") String oauthServerUrl, + HttpServletResponse response) throws Exception { + if (StringUtils.isBlank(systemUrl) || !RegexUtil.isUrl(systemUrl)) { + throw new ParamsException("系统地址格式不正确"); + } + if (systemPort == null || systemPort <= 0 || systemPort > 65535) { + throw new ParamsException("系统端口不在范围"); + } + if (StringUtils.isBlank(systemName) || !RegexUtil.isLetter(systemName)) { + throw new ParamsException("系统名必须全部为字母"); + } + if (StringUtils.isBlank(systemSummary)) { + throw new ParamsException("系统说明必须全部为字母"); + } + if (StringUtils.isBlank(oauthServerUrl) || !RegexUtil.isUrl(oauthServerUrl)) { + throw new ParamsException("认证地址格式不正确"); + } + EmptyProjectVO emptyProjectVO = new EmptyProjectVO(); + emptyProjectVO.setSystemUrl(systemUrl); + emptyProjectVO.setSystemPort(systemPort.toString()); + emptyProjectVO.setSystemName(systemName); + emptyProjectVO.setSystemSummary(systemSummary); + emptyProjectVO.setOauthServerUrl(oauthServerUrl); + dynamicConfigTableService.getEmptyProject(emptyProjectVO, response); + } + + @ApiOperation(value = "下载空项目", notes = "下载空项目接口") + @ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)}) + @GetMapping("getassetszip") + public void getAssetsZip(HttpServletResponse response) { + dynamicConfigTableService.getAssetsZip(response); + } + } diff --git a/cloud-common-plugin-dynamic/src/main/java/com/cm/common/plugin/controller/routes/dynamic/config/DynamicConfigTableRouteController.java b/cloud-common-plugin-dynamic/src/main/java/com/cm/common/plugin/controller/routes/dynamic/config/DynamicConfigTableRouteController.java index 805fdbf..b8e6db8 100644 --- a/cloud-common-plugin-dynamic/src/main/java/com/cm/common/plugin/controller/routes/dynamic/config/DynamicConfigTableRouteController.java +++ b/cloud-common-plugin-dynamic/src/main/java/com/cm/common/plugin/controller/routes/dynamic/config/DynamicConfigTableRouteController.java @@ -59,4 +59,11 @@ public class DynamicConfigTableRouteController { return mv; } + @ApiOperation(value = "生成空项目页面", notes = "生成空项目页面接口") + @GetMapping("getgeneratoremptyproject") + public ModelAndView getGeneratorEmptyProject() { + ModelAndView mv = new ModelAndView("dynamic/config/get-generator-empty-project"); + return mv; + } + } diff --git a/cloud-common-plugin-dynamic/src/main/java/com/cm/common/plugin/pojo/vos/dynamic/config/EmptyProjectVO.java b/cloud-common-plugin-dynamic/src/main/java/com/cm/common/plugin/pojo/vos/dynamic/config/EmptyProjectVO.java new file mode 100644 index 0000000..81cae4f --- /dev/null +++ b/cloud-common-plugin-dynamic/src/main/java/com/cm/common/plugin/pojo/vos/dynamic/config/EmptyProjectVO.java @@ -0,0 +1,117 @@ +package com.cm.common.plugin.pojo.vos.dynamic.config; + +import com.cm.common.annotation.CheckEmptyAnnotation; +import com.cm.common.annotation.CheckNumberAnnotation; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +/** + * When you feel like quitting. Think about why you started + * 当你想要放弃的时候,想想当初你为何开始 + * + * @ClassName: EmptyProjectVO + * @Description: 空项目 + * @Author: WangGeng + * @Date: 2020/3/16 10:45 下午 + * @Version: 1.0 + **/ +@ApiModel +public class EmptyProjectVO { + + @ApiModelProperty(name = "systemUrl", value = "系统地址") + @CheckEmptyAnnotation(name = "系统地址", verifyType = "url") + private String systemUrl; + @ApiModelProperty(name = "systemPort", value = "系统端口") + @CheckEmptyAnnotation(name = "系统端口", verifyType = "number") + private String systemPort; + @ApiModelProperty(name = "systemName", value = "系统名") + @CheckEmptyAnnotation(name = "系统名", verifyType = "letter") + private String systemName; + @ApiModelProperty(name = "systemSummary", value = "系统说明") + @CheckEmptyAnnotation(name = "系统说明") + private String systemSummary; + @ApiModelProperty(name = "oauthServerUrl", value = "认证地址") + @CheckEmptyAnnotation(name = "认证地址", verifyType = "url") + private String oauthServerUrl; + @ApiModelProperty(name = "clientId", value = "认证用户名") + private String clientId; + @ApiModelProperty(name = "clientSecret", value = "认证密码") + private String clientSecret; + + public String getSystemUrl() { + return systemUrl == null ? "" : systemUrl.trim(); + } + + public void setSystemUrl(String systemUrl) { + this.systemUrl = systemUrl; + } + + public String getSystemPort() { + return systemPort; + } + + public void setSystemPort(String systemPort) { + this.systemPort = systemPort; + } + + public String getSystemName() { + return systemName == null ? "" : systemName.trim(); + } + + public void setSystemName(String systemName) { + this.systemName = systemName; + } + + public String getSystemSummary() { + return systemSummary == null ? "" : systemSummary.trim(); + } + + public void setSystemSummary(String systemSummary) { + this.systemSummary = systemSummary; + } + + public String getOauthServerUrl() { + return oauthServerUrl == null ? "" : oauthServerUrl.trim(); + } + + public void setOauthServerUrl(String oauthServerUrl) { + this.oauthServerUrl = oauthServerUrl; + } + + public String getClientId() { + return clientId == null ? "客户端认证用户名" : clientId.trim(); + } + + public void setClientId(String clientId) { + this.clientId = clientId; + } + + public String getClientSecret() { + return clientSecret == null ? "客户端认证密码" : clientSecret.trim(); + } + + public void setClientSecret(String clientSecret) { + this.clientSecret = clientSecret; + } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder("{"); + sb.append("\"systemUrl\":") + .append("\"").append(systemUrl).append("\""); + sb.append(",\"systemPort\":") + .append(systemPort); + sb.append(",\"systemName\":") + .append("\"").append(systemName).append("\""); + sb.append(",\"systemSummary\":") + .append("\"").append(systemSummary).append("\""); + sb.append(",\"oauthServerUrl\":") + .append("\"").append(oauthServerUrl).append("\""); + sb.append(",\"clientId\":") + .append("\"").append(clientId).append("\""); + sb.append(",\"clientSecret\":") + .append("\"").append(clientSecret).append("\""); + sb.append('}'); + return sb.toString(); + } +} diff --git a/cloud-common-plugin-dynamic/src/main/java/com/cm/common/plugin/service/dynamic/config/IDynamicConfigTableService.java b/cloud-common-plugin-dynamic/src/main/java/com/cm/common/plugin/service/dynamic/config/IDynamicConfigTableService.java index e7cd5a6..a3c9bdb 100644 --- a/cloud-common-plugin-dynamic/src/main/java/com/cm/common/plugin/service/dynamic/config/IDynamicConfigTableService.java +++ b/cloud-common-plugin-dynamic/src/main/java/com/cm/common/plugin/service/dynamic/config/IDynamicConfigTableService.java @@ -5,6 +5,7 @@ import com.cm.common.exception.SearchException; import com.cm.common.exception.UpdateException; import com.cm.common.plugin.pojo.dtos.dynamic.config.DynamicConfigTableDTO; import com.cm.common.plugin.pojo.vos.dynamic.config.DynamicConfigTableVO; +import com.cm.common.plugin.pojo.vos.dynamic.config.EmptyProjectVO; import com.cm.common.pojo.ListPage; import com.cm.common.result.SuccessResult; import com.cm.common.result.SuccessResultList; @@ -110,4 +111,20 @@ public interface IDynamicConfigTableService { * @throws SearchException */ void getStaticCode(String id, String basePackage, String context, HttpServletResponse response) throws Exception; + + /** + * 下载空项目 + * + * @param emptyProjectVO + * @param response + * @throws Exception + */ + void getEmptyProject(EmptyProjectVO emptyProjectVO, HttpServletResponse response) throws Exception; + + /** + * 下载静态资源包 + * + * @param response + */ + void getAssetsZip(HttpServletResponse response); } diff --git a/cloud-common-plugin-dynamic/src/main/java/com/cm/common/plugin/service/dynamic/config/impl/DynamicConfigTableServiceImpl.java b/cloud-common-plugin-dynamic/src/main/java/com/cm/common/plugin/service/dynamic/config/impl/DynamicConfigTableServiceImpl.java index bf27ba7..ed076b4 100644 --- a/cloud-common-plugin-dynamic/src/main/java/com/cm/common/plugin/service/dynamic/config/impl/DynamicConfigTableServiceImpl.java +++ b/cloud-common-plugin-dynamic/src/main/java/com/cm/common/plugin/service/dynamic/config/impl/DynamicConfigTableServiceImpl.java @@ -15,6 +15,7 @@ import com.cm.common.plugin.pojo.dtos.dynamic.config.form.DynamicConfigFormDTO; import com.cm.common.plugin.pojo.vos.dynamic.DynamicFormFieldVO; import com.cm.common.plugin.pojo.vos.dynamic.DynamicFormVO; import com.cm.common.plugin.pojo.vos.dynamic.config.DynamicConfigTableVO; +import com.cm.common.plugin.pojo.vos.dynamic.config.EmptyProjectVO; import com.cm.common.plugin.service.dynamic.IDynamicFormService; import com.cm.common.plugin.service.dynamic.IDynamicTableService; import com.cm.common.plugin.service.dynamic.config.IDynamicConfigTableService; @@ -27,9 +28,11 @@ import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageInfo; import freemarker.template.Template; import freemarker.template.TemplateException; +import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; import org.joda.time.DateTime; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.io.ClassPathResource; import org.springframework.stereotype.Service; import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer; @@ -219,7 +222,7 @@ public class DynamicConfigTableServiceImpl extends AbstractService implements ID fieldList.add(field); } String baseCodeFolder = String.format("%s/gencodes/%s/%s", fileProperties.getUploadPath(), dynamicConfigTableDTO.getTableName().toLowerCase(), String.valueOf(System.currentTimeMillis())); - String templatePath = String.format("codetemplate/%s", "default"); + String templatePath = "codetemplate/default"; try { generatorDefaultCode(templateMap, baseCodeFolder, templatePath); @@ -232,6 +235,254 @@ public class DynamicConfigTableServiceImpl extends AbstractService implements ID } } + @Override + public void getEmptyProject(EmptyProjectVO emptyProjectVO, HttpServletResponse response) throws Exception { + Map params = HashMapUtil.beanToMap(emptyProjectVO); + params.put("lowerSystemName", emptyProjectVO.getSystemName().toLowerCase()); + params.put("firstUpperSystemName", WStringUtil.firstToUpper(emptyProjectVO.getSystemName())); + params.put("gmtCreate", DateUtil.getDay()); + + String baseCodeFolder = String.format("%s/emptyproject/%s/system-%s", fileProperties.getUploadPath(), String.valueOf(System.currentTimeMillis()), params.get("lowerSystemName").toString()); + String templatePath = String.format("codetemplate/base"); + + try { + dynamicEmptyProject(params, baseCodeFolder, templatePath, response); + + String zipCodeFile = baseCodeFolder + ".zip"; + ZipUtil.zip(baseCodeFolder, zipCodeFile); + RequestUtil.downLoad(response, zipCodeFile); + } catch (Exception e) { + LOG.error(e.getMessage(), e); + throw new SearchException("生成代码失败"); + } + } + + @Override + public void getAssetsZip(HttpServletResponse response) { + response.setCharacterEncoding(ISystemConstant.CHARSET_UTF8); + response.setHeader("Content-Disposition", "attachment;filename=assets.zip"); + response.setContentType("application/octet-stream"); + ClassPathResource classPathResource = new ClassPathResource("assets.zip"); + InputStream inputStream = null; + try { + inputStream = classPathResource.getInputStream(); + IOUtils.copy(inputStream, response.getOutputStream()); + response.flushBuffer(); + } catch (IOException e) { + LOG.error(e.getMessage(), e); + } finally { + IOUtils.closeQuietly(inputStream); + } + } + + /** + * 生成空项目 + * + * @param params + * @param response + */ + private void dynamicEmptyProject(Map params, String baseCodeFolder, String templatePath, HttpServletResponse response) throws IOException { + freeMarkerConfigurer.getConfiguration().setClassForTemplateLoading(DynamicConfigTableServiceImpl.class, "/templates"); + LOG.debug("生成pom.xml"); + generatorEmptyProjectPomXML(params, baseCodeFolder, templatePath); + LOG.debug("生成banner.txt"); + generatorEmptyProjectBannerTxt(params, baseCodeFolder, templatePath); + LOG.debug("生成application.yml"); + generatorEmptyProjectApplicationYml(params, baseCodeFolder, templatePath); + LOG.debug("生成Application.java"); + generatorEmptyProjectApplicationJava(params, baseCodeFolder, templatePath); + LOG.debug("生成AuthClientSecurityConfig.java"); + generatorEmptyProjectAuthClientSecurityConfigJava(params, baseCodeFolder, templatePath); + LOG.debug("生成index.html"); + generatorEmptyProjectIndexHtml(params, baseCodeFolder, templatePath); + LOG.debug("生成index.html"); + generatorEmptyProjectDefaultHtml(params, baseCodeFolder, templatePath); + LOG.debug("生成403.html"); + generatorEmptyProject403Html(params, baseCodeFolder, templatePath); + LOG.debug("生成404.html"); + generatorEmptyProject404Html(params, baseCodeFolder, templatePath); + LOG.debug("生成500.html"); + generatorEmptyProject500Html(params, baseCodeFolder, templatePath); + LOG.debug("生成mybatis-config.xml"); + generatorEmptyProjectMybatisConfigXml(params, baseCodeFolder, templatePath); + } + + /** + * 生成空项目pom.xml + * + * @param params + * @param baseCodeFolder + * @param templatePath + * @throws IOException + */ + private void generatorEmptyProjectPomXML(Map params, String baseCodeFolder, String templatePath) throws IOException { + String codePath = baseCodeFolder; + FolderUtil.createFolder(codePath); + Template template = freeMarkerConfigurer.getConfiguration().getTemplate(String.format("%s/pom.ftl", templatePath)); + Writer writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(String.format("%s/pom.xml", codePath)), ISystemConstant.CHARSET_UTF8)); + generatorCode(params, writer, template); + } + + /** + * 生成空项目banner.txt + * + * @param params + * @param baseCodeFolder + * @param templatePath + * @throws IOException + */ + private void generatorEmptyProjectBannerTxt(Map params, String baseCodeFolder, String templatePath) throws IOException { + String codePath = String.format("%s/src/main/resources", baseCodeFolder); + FolderUtil.createFolder(codePath); + Template template = freeMarkerConfigurer.getConfiguration().getTemplate(String.format("%s/banner.ftl", templatePath)); + Writer writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(String.format("%s/banner.txt", codePath)), ISystemConstant.CHARSET_UTF8)); + generatorCode(params, writer, template); + } + + /** + * 生成空项目application.yml + * + * @param params + * @param baseCodeFolder + * @param templatePath + * @throws IOException + */ + private void generatorEmptyProjectApplicationYml(Map params, String baseCodeFolder, String templatePath) throws IOException { + String codePath = String.format("%s/src/main/resources", baseCodeFolder); + FolderUtil.createFolder(codePath); + Template template = freeMarkerConfigurer.getConfiguration().getTemplate(String.format("%s/application.ftl", templatePath)); + Writer writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(String.format("%s/application.yml", codePath)), ISystemConstant.CHARSET_UTF8)); + generatorCode(params, writer, template); + } + + /** + * 生成空项目Application.java + * + * @param params + * @param baseCodeFolder + * @param templatePath + * @throws IOException + */ + private void generatorEmptyProjectApplicationJava(Map params, String baseCodeFolder, String templatePath) throws IOException { + String codePath = String.format("%s/src/main/java/com/cm/%s", baseCodeFolder, params.get("lowerSystemName").toString()); + FolderUtil.createFolder(codePath); + Template template = freeMarkerConfigurer.getConfiguration().getTemplate(String.format("%s/src/Application.ftl", templatePath)); + Writer writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(String.format("%s/%sApplication.java", codePath, params.get("firstUpperSystemName").toString())), ISystemConstant.CHARSET_UTF8)); + generatorCode(params, writer, template); + } + + /** + * 生成空项目AuthClientSecurityConfig.java + * + * @param params + * @param baseCodeFolder + * @param templatePath + * @throws IOException + */ + private void generatorEmptyProjectAuthClientSecurityConfigJava(Map params, String baseCodeFolder, String templatePath) throws IOException { + String codePath = String.format("%s/src/main/java/com/cm/%s/config", baseCodeFolder, params.get("lowerSystemName").toString()); + FolderUtil.createFolder(codePath); + Template template = freeMarkerConfigurer.getConfiguration().getTemplate(String.format("%s/src/AuthClientSecurityConfig.ftl", templatePath)); + Writer writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(String.format("%s/AuthClientSecurityConfig.java", codePath)), ISystemConstant.CHARSET_UTF8)); + generatorCode(params, writer, template); + } + + /** + * 生成空项目index.html + * + * @param params + * @param baseCodeFolder + * @param templatePath + * @throws IOException + */ + private void generatorEmptyProjectIndexHtml(Map params, String baseCodeFolder, String templatePath) throws IOException { + String codePath = String.format("%s/src/main/resources/templates", baseCodeFolder); + FolderUtil.createFolder(codePath); + Template template = freeMarkerConfigurer.getConfiguration().getTemplate(String.format("%s/route/index.ftl", templatePath)); + Writer writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(String.format("%s/index.html", codePath)), ISystemConstant.CHARSET_UTF8)); + generatorCode(params, writer, template); + } + + /** + * 生成空项目default.html + * + * @param params + * @param baseCodeFolder + * @param templatePath + * @throws IOException + */ + private void generatorEmptyProjectDefaultHtml(Map params, String baseCodeFolder, String templatePath) throws IOException { + String codePath = String.format("%s/src/main/resources/static", baseCodeFolder); + FolderUtil.createFolder(codePath); + Template template = freeMarkerConfigurer.getConfiguration().getTemplate(String.format("%s/route/default.ftl", templatePath)); + Writer writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(String.format("%s/default.html", codePath)), ISystemConstant.CHARSET_UTF8)); + generatorCode(params, writer, template); + } + + /** + * 生成空项目403.html + * + * @param params + * @param baseCodeFolder + * @param templatePath + * @throws IOException + */ + private void generatorEmptyProject403Html(Map params, String baseCodeFolder, String templatePath) throws IOException { + String codePath = String.format("%s/src/main/resources/static/error", baseCodeFolder); + FolderUtil.createFolder(codePath); + Template template = freeMarkerConfigurer.getConfiguration().getTemplate(String.format("%s/error/403.ftl", templatePath)); + Writer writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(String.format("%s/403.html", codePath)), ISystemConstant.CHARSET_UTF8)); + generatorCode(params, writer, template); + } + + /** + * 生成空项目404.html + * + * @param params + * @param baseCodeFolder + * @param templatePath + * @throws IOException + */ + private void generatorEmptyProject404Html(Map params, String baseCodeFolder, String templatePath) throws IOException { + String codePath = String.format("%s/src/main/resources/static/error", baseCodeFolder); + FolderUtil.createFolder(codePath); + Template template = freeMarkerConfigurer.getConfiguration().getTemplate(String.format("%s/error/404.ftl", templatePath)); + Writer writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(String.format("%s/404.html", codePath)), ISystemConstant.CHARSET_UTF8)); + generatorCode(params, writer, template); + } + + /** + * 生成空项目500.html + * + * @param params + * @param baseCodeFolder + * @param templatePath + * @throws IOException + */ + private void generatorEmptyProject500Html(Map params, String baseCodeFolder, String templatePath) throws IOException { + String codePath = String.format("%s/src/main/resources/static/error", baseCodeFolder); + FolderUtil.createFolder(codePath); + Template template = freeMarkerConfigurer.getConfiguration().getTemplate(String.format("%s/error/500.ftl", templatePath)); + Writer writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(String.format("%s/500.html", codePath)), ISystemConstant.CHARSET_UTF8)); + generatorCode(params, writer, template); + } + + /** + * 生成空项目mybatis-config.xml + * + * @param params + * @param baseCodeFolder + * @param templatePath + * @throws IOException + */ + private void generatorEmptyProjectMybatisConfigXml(Map params, String baseCodeFolder, String templatePath) throws IOException { + String codePath = String.format("%s/src/main/resources/mybatis", baseCodeFolder); + FolderUtil.createFolder(codePath); + Template template = freeMarkerConfigurer.getConfiguration().getTemplate(String.format("%s/mapper/mybatis-config.ftl", templatePath)); + Writer writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(String.format("%s/mybatis-config.xml", codePath)), ISystemConstant.CHARSET_UTF8)); + generatorCode(params, writer, template); + } + /** * 动态表单转hashMap * diff --git a/cloud-common-plugin-dynamic/src/main/resources/assets.zip b/cloud-common-plugin-dynamic/src/main/resources/assets.zip new file mode 100644 index 0000000..54b5cff Binary files /dev/null and b/cloud-common-plugin-dynamic/src/main/resources/assets.zip differ diff --git a/cloud-common-plugin-dynamic/src/main/resources/templates/codetemplate/base/application.ftl b/cloud-common-plugin-dynamic/src/main/resources/templates/codetemplate/base/application.ftl new file mode 100755 index 0000000..c3c76de --- /dev/null +++ b/cloud-common-plugin-dynamic/src/main/resources/templates/codetemplate/base/application.ftl @@ -0,0 +1,121 @@ +server: + port: ${systemPort} + url: ${systemUrl}:${systemPort}/${lowerSystemName} + title: ${lowerSystemName} + servlet: + context-path: /${lowerSystemName} + +spring: + thymeleaf: + prefix: classpath:/templates/ + suffix: .html + mode: HTML5 + encoding: UTF-8 + cache: false + main: + allow-bean-definition-overriding: true + servlet: + multipart: + max-file-size: 1GB + max-request-size: 1GB + datasource: + druid: + url: jdbc:mysql://127.0.0.1:3306/db_cloud_${lowerSystemName}?useUnicode=true&characterEncoding=utf8&characterSetResults=utf8&autoReconnect=true&failOverReadOnly=false&useSSL=false + db-type: mysql + driver-class-name: com.mysql.jdbc.Driver + username: root + password: root + initial-size: 2 + min-idle: 2 + max-active: 5 + max-wait: 60000 + time-between-eviction-runs-millis: 60000 + min-evictable-idle-time-millis: 300000 + validation-query: SELECT 1 FROM DUAL + test-while-idle: true + test-on-borrow: false + test-on-return: false + pool-prepared-statements: true + max-pool-prepared-statement-per-connection-size: 10 + filter: + commons-log: + connection-logger-name: stat,wall,log4j + stat: + log-slow-sql: true + slow-sql-millis: 2000 + connection-properties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000 + use-global-data-source-stat: true + +# 数据库 +mybatis: + config-location: classpath:mybatis/mybatis-config.xml + mapper-locations: classpath*:mybatis/mapper/**/*.xml + +# 文档 +swagger: + title: 接口文档 + description: ${systemSummary}接口文档 + service-url: https://baidu.com/ + version: 1.0 + swagger-base-package: com.cm + +# 文件 +file: + uploadPath: /Users/wenc/Desktop/filetest + imageTypes: png,jpg,jpeg,gif,blob + videoTypes: mp4,rmvb + audioTypes: mp3,wmv + fileTypes: doc,docx,xls,xlsx,ppt,pptx,txt,zip,rar,apk,pdf + maxFileCount: 6 + +# 安全 +security: + oauth2: + oauth-server: ${oauthServerUrl} + oauth-logout: ${r"${security.oauth2.oauth-server}/logout?redirect_uri=${server.url}"} + client: + client-id: ${clientId} + client-secret: ${clientSecret} + user-authorization-uri: ${r"${security.oauth2.oauth-server}/oauth/authorize"} + access-token-uri: ${r"${security.oauth2.oauth-server}/oauth/token"} + grant-type: authorization_code + resource: + jwt: + key-uri: ${r"${security.oauth2.oauth-server}/oauth/token_key"} + token-info-uri: ${r"${security.oauth2.oauth-server}/oauth/check_token"} + user-info-uri: ${r"${security.oauth2.oauth-server}/user"} + authorization: + check-token-access: ${r"${security.oauth2.oauth-server}/oauth/token_key"} + +api-path: + user-center: ${r"${security.oauth2.oauth-server}"} + +# 访问控制 +access-control: + pass-paths: + - /index.html + - /logout.html + - /default.html + - /assets/** + - /route/file/downloadfile/** + save-paths: + - /**/save*/** + - /**/add*/** + delete-paths: + - /**/delete*/** + - /**/remove*/** + update-paths: + - /**/update*/** + - /**/edit*/** + query-paths: + - /**/get*/** + - /**/query*/** + - /**/find*/** + - /**/list*/** + - /**/count*/** + +# 日志 +logging: + level: + root: error + com.cm: debug diff --git a/cloud-common-plugin-dynamic/src/main/resources/templates/codetemplate/base/banner.ftl b/cloud-common-plugin-dynamic/src/main/resources/templates/codetemplate/base/banner.ftl new file mode 100644 index 0000000..1257727 --- /dev/null +++ b/cloud-common-plugin-dynamic/src/main/resources/templates/codetemplate/base/banner.ftl @@ -0,0 +1 @@ +banner \ No newline at end of file diff --git a/cloud-common-plugin-dynamic/src/main/resources/templates/codetemplate/base/error/403.ftl b/cloud-common-plugin-dynamic/src/main/resources/templates/codetemplate/base/error/403.ftl new file mode 100755 index 0000000..7e286f2 --- /dev/null +++ b/cloud-common-plugin-dynamic/src/main/resources/templates/codetemplate/base/error/403.ftl @@ -0,0 +1,28 @@ + + + + + + + + + + + + +
+
+ +
+ 权限不足 +

+ 4 + 0 + 3 +

+
+
+
+ + + diff --git a/cloud-common-plugin-dynamic/src/main/resources/templates/codetemplate/base/error/404.ftl b/cloud-common-plugin-dynamic/src/main/resources/templates/codetemplate/base/error/404.ftl new file mode 100755 index 0000000..afaaf36 --- /dev/null +++ b/cloud-common-plugin-dynamic/src/main/resources/templates/codetemplate/base/error/404.ftl @@ -0,0 +1,28 @@ + + + + + + + + + + + + +
+
+ +
+ 无法访问 +

+ 4 + 0 + 4 +

+
+
+
+ + + diff --git a/cloud-common-plugin-dynamic/src/main/resources/templates/codetemplate/base/error/500.ftl b/cloud-common-plugin-dynamic/src/main/resources/templates/codetemplate/base/error/500.ftl new file mode 100755 index 0000000..a2b8478 --- /dev/null +++ b/cloud-common-plugin-dynamic/src/main/resources/templates/codetemplate/base/error/500.ftl @@ -0,0 +1,28 @@ + + + + + + + + + + + + +
+
+ +
+ 系统错误 +

+ 4 + 0 + 5 +

+
+
+
+ + + diff --git a/cloud-common-plugin-dynamic/src/main/resources/templates/codetemplate/base/mapper/mybatis-config.ftl b/cloud-common-plugin-dynamic/src/main/resources/templates/codetemplate/base/mapper/mybatis-config.ftl new file mode 100755 index 0000000..5e7e86d --- /dev/null +++ b/cloud-common-plugin-dynamic/src/main/resources/templates/codetemplate/base/mapper/mybatis-config.ftl @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/cloud-common-plugin-dynamic/src/main/resources/templates/codetemplate/base/pom.ftl b/cloud-common-plugin-dynamic/src/main/resources/templates/codetemplate/base/pom.ftl new file mode 100755 index 0000000..0f17b51 --- /dev/null +++ b/cloud-common-plugin-dynamic/src/main/resources/templates/codetemplate/base/pom.ftl @@ -0,0 +1,109 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 2.1.2.RELEASE + + + + com.cm + system-${systemName} + 1.0.0-SNAPSHOT + system-${systemName} + ${systemSummary} + + + 1.8 + 1.0.31 + 2.1.2.RELEASE + 1.3.2 + 5.1.4.RELEASE + 5.1.47 + 2.3.28 + 1.1.9 + 1.0.1-SNAPSHOT + + + + + org.springframework.boot + spring-boot-starter-web + ${r"${spring-boot.version}"} + + + org.springframework.boot + spring-boot-starter-thymeleaf + ${r"${spring-boot.version}"} + + + org.springframework.boot + spring-boot-starter-jdbc + ${r"${spring-boot.version}"} + + + org.springframework.boot + spring-boot-starter-freemarker + ${r"${spring-boot.version}"} + + + mysql + mysql-connector-java + ${r"${mysql.version}"} + + + + org.springframework.boot + spring-boot-starter-test + test + + + + org.springframework + spring-jdbc + ${r"${spring-jdbc.version}"} + + + org.mybatis.spring.boot + mybatis-spring-boot-starter + ${r"${spring-mybatis.version}"} + + + + com.alibaba + druid-spring-boot-starter + ${r"${druid.version}"} + + + + com.cm + cloud-common-plugin-oauth + ${r"${cm-cloud.version}"} + + + + com.cm + cloud-common-plugin-dynamic + ${r"${cm-cloud.version}"} + + + + log4j + log4j + 1.2.14 + + + + + + + org.springframework.boot + spring-boot-maven-plugin + ${r"${spring-boot.version}"} + + + + + diff --git a/cloud-common-plugin-dynamic/src/main/resources/templates/codetemplate/base/route/default.ftl b/cloud-common-plugin-dynamic/src/main/resources/templates/codetemplate/base/route/default.ftl new file mode 100755 index 0000000..fc5af7c --- /dev/null +++ b/cloud-common-plugin-dynamic/src/main/resources/templates/codetemplate/base/route/default.ftl @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + +
+
+
+ + + + + + \ No newline at end of file diff --git a/cloud-common-plugin-dynamic/src/main/resources/templates/codetemplate/base/route/index.ftl b/cloud-common-plugin-dynamic/src/main/resources/templates/codetemplate/base/route/index.ftl new file mode 100755 index 0000000..6c667ec --- /dev/null +++ b/cloud-common-plugin-dynamic/src/main/resources/templates/codetemplate/base/route/index.ftl @@ -0,0 +1,236 @@ + + + + + + + + + + + + + + + +
+
+
+ + + +
+ + +
+ +
+ + +
+
+
+ +
+
    +
  • +
+
+
+ + +
+
+ +
+
+ + +
+
+
+ + + + + diff --git a/cloud-common-plugin-dynamic/src/main/resources/templates/codetemplate/base/src/Application.ftl b/cloud-common-plugin-dynamic/src/main/resources/templates/codetemplate/base/src/Application.ftl new file mode 100755 index 0000000..4330151 --- /dev/null +++ b/cloud-common-plugin-dynamic/src/main/resources/templates/codetemplate/base/src/Application.ftl @@ -0,0 +1,24 @@ +package com.cm.${lowerSystemName}; + +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.ComponentScan; +import springfox.documentation.swagger2.annotations.EnableSwagger2; + +/** + * ${systemSummary} + * + * @author WenG + */ +@EnableSwagger2 +@SpringBootApplication +@ComponentScan("com.cm") +@MapperScan({"com.cm.**.dao"}) +public class ${firstUpperSystemName}Application { + + public static void main(String[] args) { + SpringApplication.run(${firstUpperSystemName}Application.class, args); + } + +} diff --git a/cloud-common-plugin-dynamic/src/main/resources/templates/codetemplate/base/src/AuthClientSecurityConfig.ftl b/cloud-common-plugin-dynamic/src/main/resources/templates/codetemplate/base/src/AuthClientSecurityConfig.ftl new file mode 100755 index 0000000..42c462e --- /dev/null +++ b/cloud-common-plugin-dynamic/src/main/resources/templates/codetemplate/base/src/AuthClientSecurityConfig.ftl @@ -0,0 +1,83 @@ +package com.cm.${lowerSystemName}.config; + +import com.cm.common.config.properties.OauthProperties; +import com.cm.common.plugin.converter.ClientUserAccessTokenConverter; +import com.cm.common.plugin.utils.RestTemplateUtil; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.security.oauth2.client.EnableOAuth2Sso; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Primary; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.security.oauth2.provider.token.DefaultTokenServices; +import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter; +import org.springframework.security.oauth2.provider.token.store.JwtTokenStore; + +/** + * @ClassName: AuthClientSecurityConfig + * @Description: ${systemSummary}认证配置 + * @Author: WenG + * @Date: ${gmtCreate} + **/ +@EnableWebSecurity +@EnableOAuth2Sso +public class AuthClientSecurityConfig extends WebSecurityConfigurerAdapter { + + @Autowired + private OauthProperties authServer; + @Autowired + private RestTemplateUtil restTemplateUtil; + @Autowired + private OauthProperties oauthProperties; + + @Override + protected void configure(HttpSecurity http) throws Exception { + http + .formLogin() + .defaultSuccessUrl("/authorize", true) + .and() + .logout().logoutSuccessUrl(authServer.getOauthLogout()) + .and() + .authorizeRequests().antMatchers("/app/**", "/route/file/**", "/assets/**").permitAll() + .and() + .authorizeRequests() + .anyRequest() + .access("@clientRbacService.hasPermission(request, authentication)") + .and() + .headers().frameOptions().sameOrigin() + .and() + .cors() + .and() + .csrf().disable(); + } + + @Bean + @Primary + public DefaultTokenServices defaultTokenServices() { + DefaultTokenServices defaultTokenServices = new DefaultTokenServices(); + defaultTokenServices.setTokenStore(jwtTokenStore()); + return defaultTokenServices; + } + + @Bean + public JwtTokenStore jwtTokenStore() { + return new JwtTokenStore(jwtAccessTokenConverter()); + } + + @Bean + public JwtAccessTokenConverter jwtAccessTokenConverter() { + JwtAccessTokenConverter jwtAccessTokenConverter = new JwtAccessTokenConverter(); + jwtAccessTokenConverter.setAccessTokenConverter(new ClientUserAccessTokenConverter(this.oauthProperties, this.restTemplateUtil)); + jwtAccessTokenConverter.setSigningKey("cmxx"); + return jwtAccessTokenConverter; + } + + @Bean + public PasswordEncoder passwordEncoder() { + return new BCryptPasswordEncoder(); + } + +} diff --git a/cloud-common-plugin-dynamic/src/main/resources/templates/dynamic/config/get-generator-empty-project.html b/cloud-common-plugin-dynamic/src/main/resources/templates/dynamic/config/get-generator-empty-project.html new file mode 100644 index 0000000..2f0e8ff --- /dev/null +++ b/cloud-common-plugin-dynamic/src/main/resources/templates/dynamic/config/get-generator-empty-project.html @@ -0,0 +1,111 @@ + + + + + + + + + + + + + +
+
+
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+
+ +
+
+
+
+
+
+ + + + + \ No newline at end of file diff --git a/cloud-common-plugin-dynamic/src/main/resources/templates/dynamic/config/list.html b/cloud-common-plugin-dynamic/src/main/resources/templates/dynamic/config/list.html index 51cf37e..cd1d171 100644 --- a/cloud-common-plugin-dynamic/src/main/resources/templates/dynamic/config/list.html +++ b/cloud-common-plugin-dynamic/src/main/resources/templates/dynamic/config/list.html @@ -21,15 +21,15 @@
-
- -
-
- -
+ +
@@ -67,13 +67,14 @@ var windowWidth = $(window).width(); var windowHeight = $(window).height(); var resizeTimeout = null; + var tableUrl = top.restAjax.path('api/dynamicconfigtable/listpagetable', []); // 初始化表格 function initTable() { table.render({ elem: '#dataTable', id: 'dataTable', - url: top.restAjax.path('api/dynamicconfigtable/listpagetable', []), + url: tableUrl, width: admin.screen() > 1 ? '100%' : '', height: $win.height() - 90, limit: 20, @@ -125,27 +126,13 @@ // 重载表格 function reloadTable() { table.reload('dataTable', { - url: top.restAjax.path('api/dynamicconfigtable/listpagetable', []), + url: tableUrl, where: { - keywords: $('#keywords').val(), - startTime: $('#startTime').val(), - endTime: $('#endTime').val() + keywords: $('#keywords').val() }, height: $win.height() - 90, }); } - // 初始化日期 - function initDate() { - // 日期选择 - laydate.render({ - elem: '#startTime', - format: 'yyyy-MM-dd' - }); - laydate.render({ - elem: '#endTime', - format: 'yyyy-MM-dd' - }); - } // 删除 function removeData(ids) { top.dialog.msg(top.dataMessage.delete, { @@ -170,7 +157,6 @@ }); } initTable(); - initDate(); // 事件 - 页面变化 $win.on('resize', function() { clearTimeout(resizeTimeout); @@ -182,6 +168,17 @@ $(document).on('click', '#search', function() { reloadTable(); }); + $(document).on('click', '#emptyProject', function() { + top.dialog.open({ + url: top.restAjax.path('route/dynamicconfigtable/getgeneratoremptyproject', []), + title: '生成空项目', + width: '400px', + height: '400px' + }); + }); + $(document).on('click', '#staticAssets', function() { + top.window.open(top.restAjax.path('api/dynamicconfigtable/getassetszip', [])) + }); // 事件 - 增删改 table.on('toolbar(dataTable)', function(obj) { var layEvent = obj.event;