Commit 8cfb82659bad1fd23ee19b047ebe1821789962e7

Authored by YunaiV
1 parent ea631ee4

代码预览的功能,完成

ruoyi-generator/src/main/java/com/ruoyi/generator/controller/GenController.java
... ... @@ -39,17 +39,6 @@ import com.ruoyi.generator.service.IGenTableService;
39 39 public class GenController extends BaseController {
40 40  
41 41 /**
42   - * 查询数据库列表
43   - */
44   - @PreAuthorize("@ss.hasPermi('tool:gen:list')")
45   - @GetMapping("/db/list")
46   - public TableDataInfo dataList(GenTable genTable) {
47   - startPage();
48   - List<GenTable> list = genTableService.selectDbTableList(genTable);
49   - return getDataTable(list);
50   - }
51   -
52   - /**
53 42 * 查询数据表字段列表
54 43 */
55 44 @PreAuthorize("@ss.hasPermi('tool:gen:list')")
... ... @@ -88,16 +77,6 @@ public class GenController extends BaseController {
88 77 }
89 78  
90 79 /**
91   - * 预览代码
92   - */
93   - @PreAuthorize("@ss.hasPermi('tool:gen:preview')")
94   - @GetMapping("/preview/{tableId}")
95   - public AjaxResult preview(@PathVariable("tableId") Long tableId) throws IOException {
96   - Map<String, String> dataMap = genTableService.previewCode(tableId);
97   - return AjaxResult.success(dataMap);
98   - }
99   -
100   - /**
101 80 * 生成代码(下载方式)
102 81 */
103 82 @PreAuthorize("@ss.hasPermi('tool:gen:code')")
... ... @@ -131,18 +110,6 @@ public class GenController extends BaseController {
131 110 }
132 111  
133 112 /**
134   - * 批量生成代码
135   - */
136   - @PreAuthorize("@ss.hasPermi('tool:gen:code')")
137   - @Log(title = "代码生成", businessType = BusinessType.GENCODE)
138   - @GetMapping("/batchGenCode")
139   - public void batchGenCode(HttpServletResponse response, String tables) throws IOException {
140   - String[] tableNames = Convert.toStrArray(tables);
141   - byte[] data = genTableService.downloadCode(tableNames);
142   - genCode(response, data);
143   - }
144   -
145   - /**
146 113 * 生成zip文件
147 114 */
148 115 private void genCode(HttpServletResponse response, byte[] data) throws IOException {
... ... @@ -154,4 +121,5 @@ public class GenController extends BaseController {
154 121 response.setContentType("application/octet-stream; charset=UTF-8");
155 122 IOUtils.write(data, response.getOutputStream());
156 123 }
  124 +
157 125 }
... ...
ruoyi-generator/src/main/java/com/ruoyi/generator/service/GenTableServiceImpl.java
... ... @@ -44,7 +44,6 @@ import com.ruoyi.generator.util.VelocityUtils;
44 44 */
45 45 @Service
46 46 public class GenTableServiceImpl implements IGenTableService {
47   - private static final Logger log = LoggerFactory.getLogger(GenTableServiceImpl.class);
48 47  
49 48 @Autowired
50 49 private GenTableMapper genTableMapper;
... ... @@ -66,17 +65,6 @@ public class GenTableServiceImpl implements IGenTableService {
66 65 }
67 66  
68 67 /**
69   - * 查询业务列表
70   - *
71   - * @param genTable 业务信息
72   - * @return 业务集合
73   - */
74   - @Override
75   - public List<GenTable> selectGenTableList(GenTable genTable) {
76   - return genTableMapper.selectGenTableList(genTable);
77   - }
78   -
79   - /**
80 68 * 查询据库列表
81 69 *
82 70 * @param genTable 业务信息
... ... @@ -99,25 +87,6 @@ public class GenTableServiceImpl implements IGenTableService {
99 87 }
100 88  
101 89 /**
102   - * 修改业务
103   - *
104   - * @param genTable 业务信息
105   - * @return 结果
106   - */
107   - @Override
108   - @Transactional
109   - public void updateGenTable(GenTable genTable) {
110   - String options = JSON.toJSONString(genTable.getParams());
111   - genTable.setOptions(options);
112   - int row = genTableMapper.updateGenTable(genTable);
113   - if (row > 0) {
114   - for (GenTableColumn cenTableColumn : genTable.getColumns()) {
115   - genTableColumnMapper.updateGenTableColumn(cenTableColumn);
116   - }
117   - }
118   - }
119   -
120   - /**
121 90 * 删除业务对象
122 91 *
123 92 * @param tableIds 需要删除的数据ID
... ... @@ -159,36 +128,6 @@ public class GenTableServiceImpl implements IGenTableService {
159 128 }
160 129  
161 130 /**
162   - * 预览代码
163   - *
164   - * @param tableId 表编号
165   - * @return 预览数据列表
166   - */
167   - @Override
168   - public Map<String, String> previewCode(Long tableId) {
169   - Map<String, String> dataMap = new LinkedHashMap<>();
170   - // 查询表信息
171   - GenTable table = genTableMapper.selectGenTableById(tableId);
172   - // 查询列信息
173   - List<GenTableColumn> columns = table.getColumns();
174   - setPkColumn(table, columns);
175   - VelocityInitializer.initVelocity();
176   -
177   - VelocityContext context = VelocityUtils.prepareContext(table);
178   -
179   - // 获取模板列表
180   - List<String> templates = VelocityUtils.getTemplateList(table.getTplCategory());
181   - for (String template : templates) {
182   - // 渲染模板
183   - StringWriter sw = new StringWriter();
184   - Template tpl = Velocity.getTemplate(template, Constants.UTF8);
185   - tpl.merge(context, sw);
186   - dataMap.put(template, sw.toString());
187   - }
188   - return dataMap;
189   - }
190   -
191   - /**
192 131 * 生成代码(下载方式)
193 132 *
194 133 * @param tableName 表名称
... ... @@ -203,40 +142,6 @@ public class GenTableServiceImpl implements IGenTableService {
203 142 return outputStream.toByteArray();
204 143 }
205 144  
206   - /**
207   - * 生成代码(自定义路径)
208   - *
209   - * @param tableName 表名称
210   - */
211   - @Override
212   - public void generatorCode(String tableName) {
213   - // 查询表信息
214   - GenTable table = genTableMapper.selectGenTableByName(tableName);
215   - // 查询列信息
216   - List<GenTableColumn> columns = table.getColumns();
217   - setPkColumn(table, columns);
218   -
219   - VelocityInitializer.initVelocity();
220   -
221   - VelocityContext context = VelocityUtils.prepareContext(table);
222   -
223   - // 获取模板列表
224   - List<String> templates = VelocityUtils.getTemplateList(table.getTplCategory());
225   - for (String template : templates) {
226   - if (!StringUtils.containsAny(template, "sql.vm", "api.js.vm", "index.vue.vm", "index-tree.vue.vm")) {
227   - // 渲染模板
228   - StringWriter sw = new StringWriter();
229   - Template tpl = Velocity.getTemplate(template, Constants.UTF8);
230   - tpl.merge(context, sw);
231   - try {
232   - String path = getGenPath(table, template);
233   - FileUtils.writeStringToFile(new File(path), sw.toString(), CharsetKit.UTF_8);
234   - } catch (IOException e) {
235   - throw new CustomException("渲染模板失败,表名:" + table.getTableName());
236   - }
237   - }
238   - }
239   - }
240 145  
241 146 /**
242 147 * 同步数据库
... ... @@ -267,57 +172,6 @@ public class GenTableServiceImpl implements IGenTableService {
267 172 }
268 173  
269 174 /**
270   - * 批量生成代码(下载方式)
271   - *
272   - * @param tableNames 表数组
273   - * @return 数据
274   - */
275   - @Override
276   - public byte[] downloadCode(String[] tableNames) {
277   - ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
278   - ZipOutputStream zip = new ZipOutputStream(outputStream);
279   - for (String tableName : tableNames) {
280   - generatorCode(tableName, zip);
281   - }
282   - IOUtils.closeQuietly(zip);
283   - return outputStream.toByteArray();
284   - }
285   -
286   - /**
287   - * 查询表信息并生成代码
288   - */
289   - private void generatorCode(String tableName, ZipOutputStream zip) {
290   - // 查询表信息
291   - GenTable table = genTableMapper.selectGenTableByName(tableName);
292   - // 查询列信息
293   - List<GenTableColumn> columns = table.getColumns();
294   - setPkColumn(table, columns);
295   -
296   - VelocityInitializer.initVelocity();
297   -
298   - VelocityContext context = VelocityUtils.prepareContext(table);
299   -
300   - // 获取模板列表
301   - List<String> templates = VelocityUtils.getTemplateList(table.getTplCategory());
302   - for (String template : templates) {
303   - // 渲染模板
304   - StringWriter sw = new StringWriter();
305   - Template tpl = Velocity.getTemplate(template, Constants.UTF8);
306   - tpl.merge(context, sw);
307   - try {
308   - // 添加到zip
309   - zip.putNextEntry(new ZipEntry(VelocityUtils.getFileName(template, table)));
310   - IOUtils.write(sw.toString(), zip, Constants.UTF8);
311   - IOUtils.closeQuietly(sw);
312   - zip.flush();
313   - zip.closeEntry();
314   - } catch (IOException e) {
315   - log.error("渲染模板失败,表名:" + table.getTableName(), e);
316   - }
317   - }
318   - }
319   -
320   - /**
321 175 * 修改保存参数校验
322 176 *
323 177 * @param genTable 业务信息
... ... @@ -337,58 +191,4 @@ public class GenTableServiceImpl implements IGenTableService {
337 191 }
338 192 }
339 193  
340   - /**
341   - * 设置主键列信息
342   - *
343   - * @param table 业务表信息
344   - * @param columns 业务字段列表
345   - */
346   - public void setPkColumn(GenTable table, List<GenTableColumn> columns) {
347   - for (GenTableColumn column : columns) {
348   - if (column.isPk()) {
349   - table.setPkColumn(column);
350   - break;
351   - }
352   - }
353   - if (StringUtils.isNull(table.getPkColumn())) {
354   - table.setPkColumn(columns.get(0));
355   - }
356   - }
357   -
358   - /**
359   - * 设置代码生成其他选项值
360   - *
361   - * @param genTable 设置后的生成对象
362   - */
363   - public void setTableFromOptions(GenTable genTable) {
364   - JSONObject paramsObj = JSONObject.parseObject(genTable.getOptions());
365   - if (StringUtils.isNotNull(paramsObj)) {
366   - String treeCode = paramsObj.getString(GenConstants.TREE_CODE);
367   - String treeParentCode = paramsObj.getString(GenConstants.TREE_PARENT_CODE);
368   - String treeName = paramsObj.getString(GenConstants.TREE_NAME);
369   - String parentMenuId = paramsObj.getString(GenConstants.PARENT_MENU_ID);
370   - String parentMenuName = paramsObj.getString(GenConstants.PARENT_MENU_NAME);
371   -
372   - genTable.setTreeCode(treeCode);
373   - genTable.setTreeParentCode(treeParentCode);
374   - genTable.setTreeName(treeName);
375   - genTable.setParentMenuId(parentMenuId);
376   - genTable.setParentMenuName(parentMenuName);
377   - }
378   - }
379   -
380   - /**
381   - * 获取代码生成地址
382   - *
383   - * @param table 业务表信息
384   - * @param template 模板文件路径
385   - * @return 生成地址
386   - */
387   - public static String getGenPath(GenTable table, String template) {
388   - String genPath = table.getGenPath();
389   - if (StringUtils.equals(genPath, "/")) {
390   - return System.getProperty("user.dir") + File.separator + "src" + File.separator + VelocityUtils.getFileName(template, table);
391   - }
392   - return genPath + File.separator + VelocityUtils.getFileName(template, table);
393   - }
394 194 }
... ...
ruoyi-generator/src/main/java/com/ruoyi/generator/util/VelocityUtils.java
... ... @@ -18,15 +18,6 @@ import com.ruoyi.generator.domain.GenTableColumn;
18 18 * @author ruoyi
19 19 */
20 20 public class VelocityUtils {
21   - /**
22   - * 项目空间路径
23   - */
24   - private static final String PROJECT_PATH = "main/java";
25   -
26   - /**
27   - * mybatis空间路径
28   - */
29   - private static final String MYBATIS_PATH = "main/resources/mapper";
30 21  
31 22 /**
32 23 * 默认上级菜单,系统工具
... ...
ruoyi-ui/src/api/tool/codegen.js
... ... @@ -25,3 +25,20 @@ export function updateCodegen(data) {
25 25 data: data
26 26 })
27 27 }
  28 +
  29 +// 预览生成代码
  30 +export function previewCodegen(tableId) {
  31 + return request({
  32 + url: '/tool/codegen/preview?tableId=' + tableId,
  33 + method: 'get'
  34 + })
  35 +}
  36 +
  37 +// 下载生成代码
  38 +export function downloadCodegen(tableId) {
  39 + return request({
  40 + url: '/tool/codegen/download?tableId=' + tableId,
  41 + method: 'get',
  42 + responseType: 'blob'
  43 + })
  44 +}
... ...
ruoyi-ui/src/api/tool/gen.js
... ... @@ -18,14 +18,6 @@ export function importTable(data) {
18 18 })
19 19 }
20 20  
21   -// 预览生成代码
22   -export function previewTable(tableId) {
23   - return request({
24   - url: '/tool/gen/preview/' + tableId,
25   - method: 'get'
26   - })
27   -}
28   -
29 21 // 删除表数据
30 22 export function delTable(tableId) {
31 23 return request({
... ...
ruoyi-ui/src/main.js
... ... @@ -16,7 +16,17 @@ import &#39;./assets/icons&#39; // icon
16 16 import './permission' // permission control
17 17 import { getDicts } from "@/api/system/dict/data";
18 18 import { getConfigKey } from "@/api/infra/config";
19   -import { parseTime, resetForm, addDateRange, selectDictLabel, selectDictLabels, download, handleTree, downloadExcel } from "@/utils/ruoyi";
  19 +import {
  20 + parseTime,
  21 + resetForm,
  22 + addDateRange,
  23 + selectDictLabel,
  24 + selectDictLabels,
  25 + download,
  26 + handleTree,
  27 + downloadExcel,
  28 + downloadZip
  29 +} from "@/utils/ruoyi";
20 30 import Pagination from "@/components/Pagination";
21 31 // 自定义表格工具扩展
22 32 import RightToolbar from "@/components/RightToolbar"
... ... @@ -38,6 +48,7 @@ Vue.prototype.getDictDataLabel = getDictDataLabel
38 48 Vue.prototype.DICT_TYPE = DICT_TYPE
39 49 Vue.prototype.download = download
40 50 Vue.prototype.downloadExcel = downloadExcel
  51 +Vue.prototype.downloadZip = downloadZip
41 52 Vue.prototype.handleTree = handleTree
42 53  
43 54 Vue.prototype.msgSuccess = function (msg) {
... ...
ruoyi-ui/src/utils/ruoyi.js
... ... @@ -116,6 +116,21 @@ export function downloadExcel(data, fileName) {
116 116 window.URL.revokeObjectURL(href);
117 117 }
118 118  
  119 +// 下载 Zip 方法
  120 +export function downloadZip(data, fileName) {
  121 + // 创建 blob
  122 + let blob = new Blob([data], {type: 'application/zip'});
  123 + // 创建 href 超链接,点击进行下载
  124 + window.URL = window.URL || window.webkitURL;
  125 + let href = URL.createObjectURL(blob);
  126 + let downA = document.createElement("a");
  127 + downA.href = href;
  128 + downA.download = fileName;
  129 + downA.click();
  130 + // 销毁超连接
  131 + window.URL.revokeObjectURL(href);
  132 +}
  133 +
119 134 // 字符串格式化(%s )
120 135 export function sprintf(str) {
121 136 var args = arguments, flag = true, i = 1;
... ...
ruoyi-ui/src/views/tool/gen/index.vue
... ... @@ -39,70 +39,18 @@
39 39  
40 40 <el-row :gutter="10" class="mb8">
41 41 <el-col :span="1.5">
42   - <el-button
43   - type="primary"
44   - plain
45   - icon="el-icon-download"
46   - size="mini"
47   - @click="handleGenTable"
48   - v-hasPermi="['tool:gen:code']"
49   - >生成</el-button>
  42 + <el-button type="primary" plain icon="el-icon-download" size="mini" @click="handleGenTable" v-hasPermi="['tool:gen:code']">生成</el-button>
50 43 </el-col>
51 44 <el-col :span="1.5">
52   - <el-button
53   - type="info"
54   - plain
55   - icon="el-icon-upload"
56   - size="mini"
57   - @click="openImportTable"
58   - v-hasPermi="['tool:gen:import']"
59   - >导入</el-button>
60   - </el-col>
61   - <el-col :span="1.5">
62   - <el-button
63   - type="success"
64   - plain
65   - icon="el-icon-edit"
66   - size="mini"
67   - @click="handleEditTable"
68   - v-hasPermi="['tool:gen:edit']"
69   - >修改</el-button>
70   - </el-col>
71   - <el-col :span="1.5">
72   - <el-button
73   - type="danger"
74   - plain
75   - icon="el-icon-delete"
76   - size="mini"
77   - @click="handleDelete"
78   - v-hasPermi="['tool:gen:remove']"
79   - >删除</el-button>
  45 + <el-button type="info" plain icon="el-icon-upload" size="mini" @click="openImportTable" v-hasPermi="['tool:gen:import']">导入</el-button>
80 46 </el-col>
81 47 <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
82 48 </el-row>
83 49  
84 50 <el-table v-loading="loading" :data="tableList">
85   - <el-table-column
86   - label="表名称"
87   - align="center"
88   - prop="tableName"
89   - :show-overflow-tooltip="true"
90   - width="120"
91   - />
92   - <el-table-column
93   - label="表描述"
94   - align="center"
95   - prop="tableComment"
96   - :show-overflow-tooltip="true"
97   - width="120"
98   - />
99   - <el-table-column
100   - label="实体"
101   - align="center"
102   - prop="className"
103   - :show-overflow-tooltip="true"
104   - width="120"
105   - />
  51 + <el-table-column label="表名称" align="center" prop="tableName" :show-overflow-tooltip="true" width="200"/>
  52 + <el-table-column label="表描述" align="center" prop="tableComment" :show-overflow-tooltip="true" width="120"/>
  53 + <el-table-column label="实体" align="center" prop="className" :show-overflow-tooltip="true" width="200"/>
106 54 <el-table-column label="创建时间" align="center" prop="createTime" width="160">
107 55 <template slot-scope="scope">
108 56 <span>{{ parseTime(scope.row.createTime) }}</span>
... ... @@ -115,61 +63,20 @@
115 63 </el-table-column>
116 64 <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
117 65 <template slot-scope="scope">
118   - <el-button
119   - type="text"
120   - size="small"
121   - icon="el-icon-view"
122   - @click="handlePreview(scope.row)"
123   - v-hasPermi="['tool:gen:preview']"
124   - >预览</el-button>
125   - <el-button
126   - type="text"
127   - size="small"
128   - icon="el-icon-edit"
129   - @click="handleEditTable(scope.row)"
130   - v-hasPermi="['tool:gen:edit']"
131   - >编辑</el-button>
132   - <el-button
133   - type="text"
134   - size="small"
135   - icon="el-icon-delete"
136   - @click="handleDelete(scope.row)"
137   - v-hasPermi="['tool:gen:remove']"
138   - >删除</el-button>
139   - <el-button
140   - type="text"
141   - size="small"
142   - icon="el-icon-refresh"
143   - @click="handleSynchDb(scope.row)"
144   - v-hasPermi="['tool:gen:edit']"
145   - >同步</el-button>
146   - <el-button
147   - type="text"
148   - size="small"
149   - icon="el-icon-download"
150   - @click="handleGenTable(scope.row)"
151   - v-hasPermi="['tool:gen:code']"
152   - >生成代码</el-button>
  66 + <el-button type="text" size="small" icon="el-icon-view" @click="handlePreview(scope.row)" v-hasPermi="['tool:gen:preview']">预览</el-button>
  67 + <el-button type="text" size="small" icon="el-icon-edit" @click="handleEditTable(scope.row)" v-hasPermi="['tool:gen:edit']">编辑</el-button>
  68 + <el-button type="text" size="small" icon="el-icon-delete" @click="handleDelete(scope.row)" v-hasPermi="['tool:gen:remove']">删除</el-button>
  69 + <el-button type="text" size="small" icon="el-icon-refresh" @click="handleSynchDb(scope.row)" v-hasPermi="['tool:gen:edit']">同步</el-button>
  70 + <el-button type="text" size="small" icon="el-icon-download" @click="handleGenTable(scope.row)" v-hasPermi="['tool:gen:code']">生成代码</el-button>
153 71 </template>
154 72 </el-table-column>
155 73 </el-table>
156   - <pagination
157   - v-show="total>0"
158   - :total="total"
159   - :page.sync="queryParams.pageNo"
160   - :limit.sync="queryParams.pageSize"
161   - @pagination="getList"
162   - />
  74 + <pagination v-show="total>0" :total="total" :page.sync="queryParams.pageNo" :limit.sync="queryParams.pageSize" @pagination="getList"/>
163 75 <!-- 预览界面 -->
164 76 <el-dialog :title="preview.title" :visible.sync="preview.open" width="80%" top="5vh" append-to-body>
165   - <el-tabs v-model="preview.activeName">
166   - <el-tab-pane
167   - v-for="(value, key) in preview.data"
168   - :label="key.substring(key.lastIndexOf('/')+1,key.indexOf('.vm'))"
169   - :name="key.substring(key.lastIndexOf('/')+1,key.indexOf('.vm'))"
170   - :key="key"
171   - >
172   - <pre><code class="hljs" v-html="highlightedCode(value, key)"></code></pre>
  77 + <el-tabs tab-position="left" v-model="preview.activeName">
  78 + <el-tab-pane v-for="item in preview.data" :label="item.filePath.substring(item.filePath.lastIndexOf('/') + 1)" :name="item.filePath" :key="item.filePath">
  79 + <pre><code class="hljs" v-html="highlightedCode(item)"></code></pre>
173 80 </el-tab-pane>
174 81 </el-tabs>
175 82 </el-dialog>
... ... @@ -179,7 +86,7 @@
179 86  
180 87 <script>
181 88 import { previewTable, delTable, genCode, synchDb } from "@/api/tool/gen";
182   -import { getCodeGenTablePage } from "@/api/tool/codegen";
  89 +import { getCodeGenTablePage, previewCodegen, } from "@/api/tool/codegen";
183 90  
184 91 import importTable from "./importTable";
185 92 import { downLoadZip } from "@/utils/zipdownload";
... ... @@ -260,18 +167,20 @@ export default {
260 167 },
261 168 /** 生成代码操作 */
262 169 handleGenTable(row) {
263   - const tableNames = row.tableName || this.tableNames;
264   - if (tableNames === "") {
265   - this.msgError("请选择要生成的数据");
266   - return;
267   - }
268   - if(row.genType === "1") {
269   - genCode(row.tableName).then(response => {
270   - this.msgSuccess("成功生成到自定义路径:" + row.genPath);
271   - });
272   - } else {
273   - downLoadZip("/tool/gen/batchGenCode?tables=" + tableNames, "ruoyi");
274   - }
  170 + // const tableNames = row.tableName || this.tableNames;
  171 + // if (tableNames === "") {
  172 + // this.msgError("请选择要生成的数据");
  173 + // return;
  174 + // }
  175 + // if(row.genType === "1") {
  176 + // genCode(row.tableName).then(response => {
  177 + // this.msgSuccess("成功生成到自定义路径:" + row.genPath);
  178 + // });
  179 + // } else {
  180 + // downLoadZip("/tool/gen/batchGenCode?tables=" + tableNames, "ruoyi");
  181 + // }
  182 +
  183 +
275 184 },
276 185 /** 同步数据库操作 */
277 186 handleSynchDb(row) {
... ... @@ -298,16 +207,18 @@ export default {
298 207 },
299 208 /** 预览按钮 */
300 209 handlePreview(row) {
301   - previewTable(row.tableId).then(response => {
  210 + previewCodegen(row.id).then(response => {
302 211 this.preview.data = response.data;
  212 + this.preview.activeName = response.data[0].filePath;
303 213 this.preview.open = true;
304 214 });
305 215 },
306 216 /** 高亮显示 */
307   - highlightedCode(code, key) {
308   - const vmName = key.substring(key.lastIndexOf("/") + 1, key.indexOf(".vm"));
309   - var language = vmName.substring(vmName.indexOf(".") + 1, vmName.length);
310   - const result = hljs.highlight(language, code || "", true);
  217 + highlightedCode(item) {
  218 + // const vmName = key.substring(key.lastIndexOf("/") + 1, key.indexOf(".vm"));
  219 + // var language = vmName.substring(vmName.indexOf(".") + 1, vmName.length);
  220 + var language = item.filePath.substring(item.filePath.lastIndexOf(".") + 1);
  221 + const result = hljs.highlight(language, item.code || "", true);
311 222 return result.value || '&nbsp;';
312 223 },
313 224 /** 修改按钮操作 */
... ...
src/main/java/cn/iocoder/dashboard/modules/tool/controller/codegen/ToolCodegenController.java
1 1 package cn.iocoder.dashboard.modules.tool.controller.codegen;
2 2  
  3 +import cn.hutool.core.io.IoUtil;
3 4 import cn.iocoder.dashboard.common.pojo.CommonResult;
4 5 import cn.iocoder.dashboard.common.pojo.PageResult;
5 6 import cn.iocoder.dashboard.modules.tool.controller.codegen.vo.ToolCodegenDetailRespVO;
  7 +import cn.iocoder.dashboard.modules.tool.controller.codegen.vo.ToolCodegenPreviewRespVO;
6 8 import cn.iocoder.dashboard.modules.tool.controller.codegen.vo.ToolCodegenUpdateReqVO;
7 9 import cn.iocoder.dashboard.modules.tool.controller.codegen.vo.table.ToolCodegenTablePageReqVO;
8 10 import cn.iocoder.dashboard.modules.tool.controller.codegen.vo.table.ToolCodegenTableRespVO;
... ... @@ -11,13 +13,20 @@ import cn.iocoder.dashboard.modules.tool.dal.dataobject.codegen.ToolCodegenColum
11 13 import cn.iocoder.dashboard.modules.tool.dal.dataobject.codegen.ToolCodegenTableDO;
12 14 import cn.iocoder.dashboard.modules.tool.service.codegen.ToolCodegenService;
13 15 import io.swagger.annotations.Api;
  16 +import io.swagger.annotations.ApiImplicitParam;
14 17 import io.swagger.annotations.ApiOperation;
15 18 import org.springframework.validation.annotation.Validated;
16 19 import org.springframework.web.bind.annotation.*;
17 20  
18 21 import javax.annotation.Resource;
  22 +import javax.servlet.http.HttpServletResponse;
19 23 import javax.validation.Valid;
  24 +import java.io.ByteArrayOutputStream;
  25 +import java.io.IOException;
20 26 import java.util.List;
  27 +import java.util.Map;
  28 +import java.util.zip.ZipEntry;
  29 +import java.util.zip.ZipOutputStream;
21 30  
22 31 import static cn.iocoder.dashboard.common.pojo.CommonResult.success;
23 32  
... ... @@ -55,9 +64,6 @@ public class ToolCodegenController {
55 64 return success(codegenService.createCodegen(tableName));
56 65 }
57 66  
58   - /**
59   - * 修改保存代码生成业务
60   - */
61 67 @ApiOperation("更新数据库的表和字段定义")
62 68 @PutMapping("/update")
63 69 // @PreAuthorize("@ss.hasPermi('tool:gen:edit')") TODO 权限
... ... @@ -66,4 +72,70 @@ public class ToolCodegenController {
66 72 return success(true);
67 73 }
68 74  
  75 + @ApiOperation("预览生成代码")
  76 + @GetMapping("/preview")
  77 + @ApiImplicitParam(name = "tableId", required = true, example = "表编号", dataTypeClass = Long.class)
  78 +// @PreAuthorize("@ss.hasPermi('tool:gen:preview')") TODO 权限
  79 + public CommonResult<List<ToolCodegenPreviewRespVO>> previewCodegen(@RequestParam("tableId") Long tableId) {
  80 + Map<String, String> codes = codegenService.generationCodes(tableId);
  81 + return success(ToolCodegenConvert.INSTANCE.convert(codes));
  82 + }
  83 +
  84 + @ApiOperation("下载生成代码")
  85 + @GetMapping("/download")
  86 + @ApiImplicitParam(name = "tableId", required = true, example = "表编号", dataTypeClass = Long.class)
  87 + public void downloadCodegen(@RequestParam("tableId") Long tableId,
  88 + HttpServletResponse response) throws IOException {
  89 + // 生成代码
  90 + Map<String, String> codes = codegenService.generationCodes(tableId);
  91 + // 构建压缩包
  92 + byte[] data;
  93 + ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
  94 + ZipOutputStream zip = new ZipOutputStream(outputStream);
  95 + for (Map.Entry<String, String> entry : codes.entrySet()) {
  96 +// zip.putNextEntry(new ZipEntry(entry.getKey()));
  97 + zip.putNextEntry(new ZipEntry("123"));
  98 +// IoUtil.write(zip, Charset.defaultCharset(), false, entry.getValue());
  99 + zip.write(entry.getValue().getBytes());
  100 + zip.flush();
  101 + zip.closeEntry();
  102 + if (true) {
  103 + break;
  104 + }
  105 + }
  106 + data = outputStream.toByteArray();
  107 + IoUtil.close(zip);
  108 +// try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
  109 +// ZipOutputStream zip = new ZipOutputStream(outputStream)) {
  110 +// for (Map.Entry<String, String> entry : codes.entrySet()) {
  111 +//// zip.putNextEntry(new ZipEntry(entry.getKey()));
  112 +// zip.putNextEntry(new ZipEntry("123"));
  113 +//// IoUtil.write(zip, Charset.defaultCharset(), false, entry.getValue());
  114 +// zip.write(entry.getValue().getBytes());
  115 +// zip.flush();
  116 +// zip.closeEntry();
  117 +// if (true) {
  118 +// break;
  119 +// }
  120 +// }
  121 +// data = outputStream.toByteArray();
  122 +// }
  123 + // 返回
  124 +// ServletUtils.writeAttachment(response, "yudao.zip", data);
  125 + genCode(response, data);
  126 + }
  127 +
  128 + /**
  129 + * 生成zip文件
  130 + */
  131 + private void genCode(HttpServletResponse response, byte[] data) throws IOException
  132 + {
  133 + response.reset();
  134 + response.addHeader("Access-Control-Allow-Origin", "*");
  135 + response.addHeader("Access-Control-Expose-Headers", "Content-Disposition");
  136 + response.setHeader("Content-Disposition", "attachment; filename=\"ruoyi.zip\"");
  137 + response.addHeader("Content-Length", "" + data.length);
  138 + response.setContentType("application/octet-stream; charset=UTF-8");
  139 + IoUtil.write(response.getOutputStream(), false, data);
  140 + }
69 141 }
... ...
src/main/java/cn/iocoder/dashboard/modules/tool/controller/codegen/vo/ToolCodegenPreviewRespVO.java 0 → 100644
  1 +package cn.iocoder.dashboard.modules.tool.controller.codegen.vo;
  2 +
  3 +import io.swagger.annotations.ApiModel;
  4 +import io.swagger.annotations.ApiModelProperty;
  5 +import lombok.Data;
  6 +
  7 +@ApiModel(value = "代码生成预览 Response VO", description ="注意,每个文件都是一个该对象")
  8 +@Data
  9 +public class ToolCodegenPreviewRespVO {
  10 +
  11 + @ApiModelProperty(value = "文件路径", required = true, example = "java/cn/iocoder/dashboard/modules/system/controller/test/SysTestDemoController.java")
  12 + private String filePath;
  13 +
  14 + @ApiModelProperty(value = "代码", required = true, example = "Hello World")
  15 + private String code;
  16 +
  17 +}
... ...
src/main/java/cn/iocoder/dashboard/modules/tool/convert/codegen/ToolCodegenConvert.java
1 1 package cn.iocoder.dashboard.modules.tool.convert.codegen;
2 2  
3 3 import cn.iocoder.dashboard.common.pojo.PageResult;
  4 +import cn.iocoder.dashboard.modules.tool.controller.codegen.vo.ToolCodegenDetailRespVO;
  5 +import cn.iocoder.dashboard.modules.tool.controller.codegen.vo.ToolCodegenPreviewRespVO;
4 6 import cn.iocoder.dashboard.modules.tool.controller.codegen.vo.ToolCodegenUpdateReqVO;
5 7 import cn.iocoder.dashboard.modules.tool.controller.codegen.vo.column.ToolCodegenColumnRespVO;
6   -import cn.iocoder.dashboard.modules.tool.controller.codegen.vo.ToolCodegenDetailRespVO;
7 8 import cn.iocoder.dashboard.modules.tool.controller.codegen.vo.table.ToolCodegenTableRespVO;
8 9 import cn.iocoder.dashboard.modules.tool.dal.dataobject.codegen.ToolCodegenColumnDO;
9 10 import cn.iocoder.dashboard.modules.tool.dal.dataobject.codegen.ToolCodegenTableDO;
... ... @@ -13,6 +14,8 @@ import org.mapstruct.Mapper;
13 14 import org.mapstruct.factory.Mappers;
14 15  
15 16 import java.util.List;
  17 +import java.util.Map;
  18 +import java.util.stream.Collectors;
16 19  
17 20 @Mapper
18 21 public interface ToolCodegenConvert {
... ... @@ -52,4 +55,13 @@ public interface ToolCodegenConvert {
52 55 return respVO;
53 56 }
54 57  
  58 + default List<ToolCodegenPreviewRespVO> convert(Map<String, String> codes) {
  59 + return codes.entrySet().stream().map(entry -> {
  60 + ToolCodegenPreviewRespVO respVO = new ToolCodegenPreviewRespVO();
  61 + respVO.setFilePath(entry.getKey());
  62 + respVO.setCode(entry.getValue());
  63 + return respVO;
  64 + }).collect(Collectors.toList());
  65 + }
  66 +
55 67 }
... ...
src/main/java/cn/iocoder/dashboard/modules/tool/service/codegen/ToolCodegenService.java
... ... @@ -7,6 +7,7 @@ import cn.iocoder.dashboard.modules.tool.dal.dataobject.codegen.ToolCodegenColum
7 7 import cn.iocoder.dashboard.modules.tool.dal.dataobject.codegen.ToolCodegenTableDO;
8 8  
9 9 import java.util.List;
  10 +import java.util.Map;
10 11  
11 12 /**
12 13 * 代码生成 Service 接口
... ... @@ -54,4 +55,12 @@ public interface ToolCodegenService {
54 55 */
55 56 List<ToolCodegenColumnDO> getCodegenColumnListByTableId(Long tableId);
56 57  
  58 + /**
  59 + * 执行指定表的代码生成
  60 + *
  61 + * @param tableId 表编号
  62 + * @return 生成结果。key 为文件路径,value 为对应的代码内容
  63 + */
  64 + Map<String, String> generationCodes(Long tableId);
  65 +
57 66 }
... ...
src/main/java/cn/iocoder/dashboard/modules/tool/service/codegen/impl/ToolCodegenEngine.java
... ... @@ -21,6 +21,7 @@ import org.springframework.stereotype.Component;
21 21  
22 22 import javax.annotation.Resource;
23 23 import java.util.HashMap;
  24 +import java.util.LinkedHashMap;
24 25 import java.util.List;
25 26 import java.util.Map;
26 27  
... ... @@ -42,7 +43,7 @@ public class ToolCodegenEngine {
42 43 * key:模板在 resources 的地址
43 44 * value:生成的路径
44 45 */
45   - private static final Map<String, String> TEMPLATES = MapUtil.<String, String>builder()
  46 + private static final Map<String, String> TEMPLATES = MapUtil.<String, String>builder(new LinkedHashMap<>()) // 有序
46 47 // Java
47 48 .put("codegen/java/controller/controller.vm", "java/${basePackage}/${table.moduleName}/controller/${table.businessName}/${table.className}Controller.java")
48 49 .put("codegen/java/controller/vo/baseVO.vm", "java/${basePackage}/${table.moduleName}/controller/${table.businessName}/vo/${table.className}BaseVO.java")
... ... @@ -53,7 +54,7 @@ public class ToolCodegenEngine {
53 54 .put("codegen/java/convert/convert.vm", "java/${basePackage}/${table.moduleName}/convert/${table.businessName}/${table.className}Convert.java")
54 55 .put("codegen/java/dal/do.vm", "java/${basePackage}/${table.moduleName}/dal/dataobject/${table.businessName}/${table.className}DO.java")
55 56 .put("codegen/java/dal/mapper.vm", "java/${basePackage}/${table.moduleName}/dal/mysql/${table.businessName}/${table.className}Mapper.java")
56   - .put("codegen/java/enums/errorcode.vm", "java/${basePackage}.${table.moduleName}.enums.${simpleModuleName_upperFirst}ErrorCodeConstants.java")
  57 + .put("codegen/java/enums/errorcode.vm", "java/${basePackage}/${table.moduleName}/enums/${simpleModuleName_upperFirst}ErrorCodeConstants.java")
57 58 .put("codegen/java/service/service.vm", "java/${basePackage}/${table.moduleName}/service/${table.businessName}/${table.className}Service.java")
58 59 .put("codegen/java/service/serviceImpl.vm", "java/${basePackage}/${table.moduleName}/service/${table.businessName}/impl/${table.className}ServiceImpl.java")
59 60 // Vue
... ... @@ -117,7 +118,7 @@ public class ToolCodegenEngine {
117 118 bindingMap.put("simpleClassName_strikeCase", toSymbolCase(simpleClassName, '-')); // 将 DictType 转换成 dict-type
118 119  
119 120 // 执行生成
120   - final Map<String, String> result = Maps.newHashMapWithExpectedSize(TEMPLATES.size());
  121 + final Map<String, String> result = Maps.newLinkedHashMapWithExpectedSize(TEMPLATES.size()); // 有序
121 122 TEMPLATES.forEach((vmPath, filePath) -> {
122 123 filePath = formatFilePath(filePath, bindingMap);
123 124 String content = templateEngine.getTemplate(vmPath).render(bindingMap);
... ...
src/main/java/cn/iocoder/dashboard/modules/tool/service/codegen/impl/ToolCodegenServiceImpl.java
... ... @@ -19,6 +19,7 @@ import org.springframework.transaction.annotation.Transactional;
19 19  
20 20 import javax.annotation.Resource;
21 21 import java.util.List;
  22 +import java.util.Map;
22 23  
23 24 /**
24 25 * 代码生成 Service 实现类
... ... @@ -102,4 +103,20 @@ public class ToolCodegenServiceImpl implements ToolCodegenService {
102 103 return codegenColumnMapper.selectListByTableId(tableId);
103 104 }
104 105  
  106 + @Override
  107 + public Map<String, String> generationCodes(Long tableId) {
  108 + // 校验是否已经存在
  109 + ToolCodegenTableDO table = codegenTableMapper.selectById(tableId);
  110 + if (codegenTableMapper.selectById(tableId) == null) {
  111 + throw new RuntimeException(""); // TODO
  112 + }
  113 + List<ToolCodegenColumnDO> columns = codegenColumnMapper.selectListByTableId(tableId);
  114 + if (CollUtil.isEmpty(columns)) {
  115 + throw new RuntimeException(""); // TODO
  116 + }
  117 +
  118 + // 执行生成
  119 + return codegenEngine.execute(table, columns);
  120 + }
  121 +
105 122 }
... ...
src/main/resources/codegen/java/controller/controller.vm
... ... @@ -42,8 +42,8 @@ public class ${table.className}Controller {
42 42 return success(true);
43 43 }
44 44  
45   - @ApiOperation("删除${table.classComment}")
46   - @DeleteMapping("/delete")
  45 + @ApiOperation("删除${table.classComment}")
  46 + @DeleteMapping("/delete")
47 47 @ApiImplicitParam(name = "id", value = "编号", required = true)
48 48 public CommonResult<Boolean> delete${simpleClassName}(@RequestParam("id") ${primaryColumn.javaType} id) {
49 49 ${classNameVar}Service.delete${simpleClassName}(id);
... ... @@ -52,7 +52,7 @@ public class ${table.className}Controller {
52 52  
53 53 @GetMapping("/get")
54 54 @ApiOperation("获得${table.classComment}")
55   - @ApiImplicitParam(name = "id", value = "编号", required = true)
  55 + @ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = ${primaryColumn.javaType}.class)
56 56 public CommonResult<${table.className}RespVO> get${simpleClassName}(@RequestParam("id") ${primaryColumn.javaType} id) {
57 57 ${table.className}DO ${classNameVar} = ${classNameVar}Service.get${simpleClassName}(id);
58 58 return success(${table.className}Convert.INSTANCE.convert(${classNameVar}));
... ... @@ -60,7 +60,7 @@ public class ${table.className}Controller {
60 60  
61 61 @GetMapping("/list")
62 62 @ApiOperation("获得${table.classComment}列表")
63   - @ApiImplicitParam(name = "ids", value = "编号列表", required = true)
  63 + @ApiImplicitParam(name = "ids", value = "编号列表", required = true, dataTypeClass = List.class)
64 64 public CommonResult<List<${table.className}RespVO>> get${simpleClassName}List(@RequestParam("ids") Collection<${primaryColumn.javaType}> ids) {
65 65 List<${table.className}DO> list = ${classNameVar}Service.get${simpleClassName}List(ids);
66 66 return success(${table.className}Convert.INSTANCE.convertList(list));
... ...
src/main/resources/codegen/java/convert/convert.vm
... ... @@ -27,6 +27,6 @@ public interface ${table.className}Convert {
27 27  
28 28 List<${table.className}RespVO> convertList(List<${table.className}DO> list);
29 29  
30   - PageResult<${table.className}RespVO> convertPage(PageResult<${table.className}DO> page);
  30 + PageResult<${table.className}RespVO> convertPage(PageResult<${table.className}DO> page);
31 31  
32 32 }
... ...
src/main/resources/codegen/java/service/service.vm
... ... @@ -57,6 +57,6 @@ public interface ${table.className}Service {
57 57 * @param pageReqVO 分页查询
58 58 * @return ${table.classComment}分页
59 59 */
60   - PageResult<${table.className}DO> get${simpleClassName}Page(${table.className}PageReqVO pageReqVO);
  60 + PageResult<${table.className}DO> get${simpleClassName}Page(${table.className}PageReqVO pageReqVO);
61 61  
62 62 }
... ...
src/main/resources/codegen/java/service/serviceImpl.vm
... ... @@ -72,7 +72,7 @@ public class ${table.className}ServiceImpl implements ${table.className}Service
72 72 return ${classNameVar}Mapper.selectBatchIds(ids);
73 73 }
74 74  
75   - @Override
  75 + @Override
76 76 public PageResult<${table.className}DO> get${simpleClassName}Page(${table.className}PageReqVO pageReqVO) {
77 77 return ${classNameVar}Mapper.selectPage(pageReqVO);
78 78 }
... ...