diff --git a/pom.xml b/pom.xml index e68c5bfe5..e1f890dc1 100644 --- a/pom.xml +++ b/pom.xml @@ -55,6 +55,7 @@ 5.5.6 2.2.7 2.2 + 1.0.5 @@ -234,6 +235,12 @@ ${velocity.version} + + cn.smallbun.screw + screw-core + ${screw.version} + + diff --git a/src/main/java/cn/iocoder/dashboard/modules/infra/controller/dbdoc/InfDbDocController.java b/src/main/java/cn/iocoder/dashboard/modules/infra/controller/dbdoc/InfDbDocController.java new file mode 100644 index 000000000..114efa266 --- /dev/null +++ b/src/main/java/cn/iocoder/dashboard/modules/infra/controller/dbdoc/InfDbDocController.java @@ -0,0 +1,103 @@ +package cn.iocoder.dashboard.modules.infra.controller.dbdoc; + +import cn.hutool.extra.servlet.ServletUtil; +import cn.smallbun.screw.core.Configuration; +import cn.smallbun.screw.core.engine.EngineConfig; +import cn.smallbun.screw.core.engine.EngineFileType; +import cn.smallbun.screw.core.engine.EngineTemplateType; +import cn.smallbun.screw.core.execute.DocumentationExecute; +import cn.smallbun.screw.core.process.ProcessConfig; +import com.zaxxer.hikari.HikariConfig; +import com.zaxxer.hikari.HikariDataSource; +import io.swagger.annotations.Api; +import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties; +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; +import javax.sql.DataSource; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.util.Collections; + +@Api(tags = "数据库文档") +@RestController +@RequestMapping("/infra/db-doc") +public class InfDbDocController { + + @Resource + private DataSourceProperties dataSourceProperties; + + private static final String FILE_OUTPUT_DIR = System.getProperty("java.io.tmpdir") + File.separator + + "db-doc"; + private static final EngineFileType FILE_OUTPUT_TYPE = EngineFileType.HTML; // 可以设置 Word 或者 Markdown 格式 + private static final String DOC_FILE_NAME = "数据库文档"; + private static final String DOC_VERSION = "1.0.0"; + private static final String DOC_DESCRIPTION = "文档描述"; + + @Resource + private DataSource dataSource; + + @GetMapping("/export-html") + public synchronized void exportHtml(HttpServletResponse response) throws FileNotFoundException { + // 创建 screw 的配置 + Configuration config = Configuration.builder() + .version(DOC_VERSION) // 版本 + .description(DOC_DESCRIPTION) // 描述 + .dataSource(buildDataSource()) // 数据源 + .engineConfig(buildEngineConfig()) // 引擎配置 + .produceConfig(buildProcessConfig()) // 处理配置 + .build(); + + // 执行 screw,生成数据库文档 + new DocumentationExecute(config).execute(); + + // 读取,返回 + ServletUtil.write(response, + new FileInputStream(FILE_OUTPUT_DIR + File.separator + DOC_FILE_NAME + FILE_OUTPUT_TYPE.getFileSuffix()), + MediaType.TEXT_HTML_VALUE); + } + + /** + * 创建数据源 + */ + private DataSource buildDataSource() { + // 创建 HikariConfig 配置类 + HikariConfig hikariConfig = new HikariConfig(); +// hikariConfig.setDriverClassName("com.mysql.cj.jdbc.Driver"); + hikariConfig.setJdbcUrl(dataSourceProperties.getUrl()); + hikariConfig.setUsername(dataSourceProperties.getUsername()); + hikariConfig.setPassword(dataSourceProperties.getPassword()); + hikariConfig.addDataSourceProperty("useInformationSchema", "true"); // 设置可以获取 tables remarks 信息 + // 创建数据源 + return new HikariDataSource(hikariConfig); + } + + /** + * 创建 screw 的引擎配置 + */ + private static EngineConfig buildEngineConfig() { + return EngineConfig.builder() + .fileOutputDir(FILE_OUTPUT_DIR) // 生成文件路径 + .openOutputDir(false) // 打开目录 + .fileType(FILE_OUTPUT_TYPE) // 文件类型 + .produceType(EngineTemplateType.freemarker) // 文件类型 + .fileName(DOC_FILE_NAME) // 自定义文件名称 + .build(); + } + + /** + * 创建 screw 的处理配置,一般可忽略 + * 指定生成逻辑、当存在指定表、指定表前缀、指定表后缀时,将生成指定表,其余表不生成、并跳过忽略表配置 + */ + private static ProcessConfig buildProcessConfig() { + return ProcessConfig.builder() + .ignoreTablePrefix(Collections.singletonList("QRTZ_")) // 忽略表前缀 + .build(); + } + +} diff --git a/src/main/java/cn/iocoder/dashboard/modules/tool/service/codegen/impl/ToolCodegenEngine.java b/src/main/java/cn/iocoder/dashboard/modules/tool/service/codegen/impl/ToolCodegenEngine.java index 6ed88ad8d..927c9775a 100644 --- a/src/main/java/cn/iocoder/dashboard/modules/tool/service/codegen/impl/ToolCodegenEngine.java +++ b/src/main/java/cn/iocoder/dashboard/modules/tool/service/codegen/impl/ToolCodegenEngine.java @@ -4,7 +4,7 @@ import cn.hutool.core.map.MapUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.extra.template.TemplateConfig; import cn.hutool.extra.template.TemplateEngine; -import cn.hutool.extra.template.TemplateUtil; +import cn.hutool.extra.template.engine.velocity.VelocityEngine; import cn.iocoder.dashboard.common.exception.util.ServiceExceptionUtil; import cn.iocoder.dashboard.common.pojo.CommonResult; import cn.iocoder.dashboard.common.pojo.PageParam; @@ -28,7 +28,10 @@ import org.springframework.stereotype.Component; import javax.annotation.PostConstruct; import javax.annotation.Resource; -import java.util.*; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; import static cn.hutool.core.map.MapUtil.getStr; import static cn.hutool.core.text.CharSequenceUtil.*; @@ -107,7 +110,7 @@ public class ToolCodegenEngine { // 初始化 TemplateEngine 属性 TemplateConfig config = new TemplateConfig(); config.setResourceMode(TemplateConfig.ResourceMode.CLASSPATH); - this.templateEngine = TemplateUtil.createEngine(config); + this.templateEngine = new VelocityEngine(config); } @PostConstruct