Commit 7089ef7651edb115bedbc504c584a7aedcac98a5

Authored by timfruit
1 parent 98917630

根据艿艿的说明修改

src/main/java/cn/iocoder/dashboard/modules/infra/controller/doc/InfDbDocController.java
1 package cn.iocoder.dashboard.modules.infra.controller.doc; 1 package cn.iocoder.dashboard.modules.infra.controller.doc;
2 2
  3 +import cn.hutool.core.io.FileUtil;
  4 +import cn.hutool.core.io.IoUtil;
3 import cn.hutool.core.lang.UUID; 5 import cn.hutool.core.lang.UUID;
  6 +import cn.hutool.core.util.IdUtil;
  7 +import cn.hutool.extra.servlet.ServletUtil;
4 import cn.iocoder.dashboard.util.servlet.ServletUtils; 8 import cn.iocoder.dashboard.util.servlet.ServletUtils;
5 import cn.smallbun.screw.core.Configuration; 9 import cn.smallbun.screw.core.Configuration;
6 import cn.smallbun.screw.core.engine.EngineConfig; 10 import cn.smallbun.screw.core.engine.EngineConfig;
@@ -11,7 +15,11 @@ import cn.smallbun.screw.core.process.ProcessConfig; @@ -11,7 +15,11 @@ import cn.smallbun.screw.core.process.ProcessConfig;
11 import com.zaxxer.hikari.HikariConfig; 15 import com.zaxxer.hikari.HikariConfig;
12 import com.zaxxer.hikari.HikariDataSource; 16 import com.zaxxer.hikari.HikariDataSource;
13 import io.swagger.annotations.Api; 17 import io.swagger.annotations.Api;
  18 +import io.swagger.annotations.ApiImplicitParam;
  19 +import io.swagger.annotations.ApiImplicitParams;
  20 +import io.swagger.annotations.ApiOperation;
14 import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties; 21 import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
  22 +import org.springframework.http.MediaType;
15 import org.springframework.util.StreamUtils; 23 import org.springframework.util.StreamUtils;
16 import org.springframework.web.bind.annotation.GetMapping; 24 import org.springframework.web.bind.annotation.GetMapping;
17 import org.springframework.web.bind.annotation.RequestMapping; 25 import org.springframework.web.bind.annotation.RequestMapping;
@@ -39,74 +47,78 @@ public class InfDbDocController { @@ -39,74 +47,78 @@ public class InfDbDocController {
39 47
40 48
41 @GetMapping("/export-html") 49 @GetMapping("/export-html")
  50 + @ApiOperation("导出html格式的数据文档")
  51 + @ApiImplicitParams({
  52 + @ApiImplicitParam(name = "deleteFile", value = "是否删除在服务器本地生成的数据库文档", example = "true", dataTypeClass = Boolean.class),
  53 + })
42 public void exportHtml(@RequestParam(defaultValue = "true") Boolean deleteFile, 54 public void exportHtml(@RequestParam(defaultValue = "true") Boolean deleteFile,
43 - HttpServletResponse response) throws IOException {  
44 - EngineFileType fileOutputType=EngineFileType.HTML;  
45 - doExportFile(fileOutputType,deleteFile,response); 55 + HttpServletResponse response) throws IOException {
  56 + doExportFile(EngineFileType.HTML, deleteFile, response);
46 } 57 }
47 58
48 -  
49 -  
50 @GetMapping("/export-word") 59 @GetMapping("/export-word")
  60 + @ApiOperation("导出word格式的数据文档")
  61 + @ApiImplicitParams({
  62 + @ApiImplicitParam(name = "deleteFile", value = "是否删除在服务器本地生成的数据库文档", example = "true", dataTypeClass = Boolean.class),
  63 + })
51 public void exportWord(@RequestParam(defaultValue = "true") Boolean deleteFile, 64 public void exportWord(@RequestParam(defaultValue = "true") Boolean deleteFile,
52 - HttpServletResponse response) throws IOException {  
53 - EngineFileType fileOutputType=EngineFileType.WORD;  
54 - doExportFile(fileOutputType,deleteFile,response); 65 + HttpServletResponse response) throws IOException {
  66 + doExportFile(EngineFileType.WORD, deleteFile, response);
55 } 67 }
56 68
57 -  
58 @GetMapping("/export-markdown") 69 @GetMapping("/export-markdown")
  70 + @ApiOperation("导出markdown格式的数据文档")
  71 + @ApiImplicitParams({
  72 + @ApiImplicitParam(name = "deleteFile", value = "是否删除在服务器本地生成的数据库文档", example = "true", dataTypeClass = Boolean.class),
  73 + })
59 public void exportMarkdown(@RequestParam(defaultValue = "true") Boolean deleteFile, 74 public void exportMarkdown(@RequestParam(defaultValue = "true") Boolean deleteFile,
60 - HttpServletResponse response) throws IOException {  
61 - EngineFileType fileOutputType=EngineFileType.MD;  
62 - doExportFile(fileOutputType,deleteFile,response); 75 + HttpServletResponse response) throws IOException {
  76 + doExportFile(EngineFileType.MD, deleteFile, response);
63 } 77 }
64 78
65 private void doExportFile(EngineFileType fileOutputType, Boolean deleteFile, 79 private void doExportFile(EngineFileType fileOutputType, Boolean deleteFile,
66 HttpServletResponse response) throws IOException { 80 HttpServletResponse response) throws IOException {
67 - String docFileName=DOC_FILE_NAME+"_"+ UUID.fastUUID().toString(true);  
68 - String filePath= doExportFile(fileOutputType,docFileName);  
69 - String downloadFileName=DOC_FILE_NAME+fileOutputType.getFileSuffix(); //下载后的文件名 81 + String docFileName = DOC_FILE_NAME + "_" + IdUtil.fastSimpleUUID();
  82 + String filePath = doExportFile(fileOutputType, docFileName);
  83 + String downloadFileName = DOC_FILE_NAME + fileOutputType.getFileSuffix(); //下载后的文件名
70 // 读取,返回 84 // 读取,返回
71 - try (InputStream is=new FileInputStream(filePath)){//处理后关闭文件流才能删除  
72 - ServletUtils.writeAttachment(response,downloadFileName, StreamUtils.copyToByteArray(is));  
73 - }  
74 - handleDeleteFile(deleteFile,filePath); 85 + //IoUtil.readBytes 直接读取FileInputStream 不会关闭流,有bug,所以用BufferedInputStream包装一下, 关闭流后才能删除文件
  86 + byte[] content = IoUtil.readBytes(new BufferedInputStream(new FileInputStream(filePath)));
  87 + //这里不用hutool工具类,它的中文文件名编码有问题,导致在浏览器下载时有问题
  88 + ServletUtils.writeAttachment(response, downloadFileName, content);
  89 + handleDeleteFile(deleteFile, filePath);
75 } 90 }
76 91
77 -  
78 /** 92 /**
79 * 输出文件,返回文件路径 93 * 输出文件,返回文件路径
80 - * @param fileOutputType  
81 - * @param fileName  
82 - * @return 94 + *
  95 + * @param fileOutputType 文件类型
  96 + * @param fileName 文件名, 无需 ".docx" 等文件后缀
  97 + * @return 生成的文件所在路径
83 */ 98 */
84 - private String doExportFile(EngineFileType fileOutputType, String fileName){ 99 + private String doExportFile(EngineFileType fileOutputType, String fileName) {
85 try (HikariDataSource dataSource = buildDataSource()) { 100 try (HikariDataSource dataSource = buildDataSource()) {
86 // 创建 screw 的配置 101 // 创建 screw 的配置
87 Configuration config = Configuration.builder() 102 Configuration config = Configuration.builder()
88 .version(DOC_VERSION) // 版本 103 .version(DOC_VERSION) // 版本
89 .description(DOC_DESCRIPTION) // 描述 104 .description(DOC_DESCRIPTION) // 描述
90 .dataSource(dataSource) // 数据源 105 .dataSource(dataSource) // 数据源
91 - .engineConfig(buildEngineConfig(fileOutputType,fileName)) // 引擎配置 106 + .engineConfig(buildEngineConfig(fileOutputType, fileName)) // 引擎配置
92 .produceConfig(buildProcessConfig()) // 处理配置 107 .produceConfig(buildProcessConfig()) // 处理配置
93 .build(); 108 .build();
94 109
95 // 执行 screw,生成数据库文档 110 // 执行 screw,生成数据库文档
96 new DocumentationExecute(config).execute(); 111 new DocumentationExecute(config).execute();
97 112
98 -  
99 - String filePath=FILE_OUTPUT_DIR + File.separator + fileName + fileOutputType.getFileSuffix();  
100 - return filePath; 113 + return FILE_OUTPUT_DIR + File.separator + fileName + fileOutputType.getFileSuffix();
101 } 114 }
102 } 115 }
103 116
104 - private void handleDeleteFile(Boolean deleteFile,String filePath){  
105 - if(!deleteFile){ 117 + private void handleDeleteFile(Boolean deleteFile, String filePath) {
  118 + if (!deleteFile) {
106 return; 119 return;
107 } 120 }
108 - File file=new File(filePath);  
109 - file.delete(); 121 + FileUtil.del(filePath);
110 } 122 }
111 123
112 /** 124 /**
@@ -128,7 +140,7 @@ public class InfDbDocController { @@ -128,7 +140,7 @@ public class InfDbDocController {
128 /** 140 /**
129 * 创建 screw 的引擎配置 141 * 创建 screw 的引擎配置
130 */ 142 */
131 - private static EngineConfig buildEngineConfig(EngineFileType fileOutputType,String docFileName) { 143 + private static EngineConfig buildEngineConfig(EngineFileType fileOutputType, String docFileName) {
132 return EngineConfig.builder() 144 return EngineConfig.builder()
133 .fileOutputDir(FILE_OUTPUT_DIR) // 生成文件路径 145 .fileOutputDir(FILE_OUTPUT_DIR) // 生成文件路径
134 .openOutputDir(false) // 打开目录 146 .openOutputDir(false) // 打开目录