中国算力平台算力登记系统2.0
yanzhaofeige
3 days ago 5cc82f45d73865489cc39e5ffbf521bf4279ec53
commit | author | age
43dc29 1 package com.odcc.cpzidc.generator.service;
Y 2
3 import java.io.ByteArrayOutputStream;
4 import java.io.File;
5 import java.io.IOException;
6 import java.io.StringWriter;
7 import java.util.LinkedHashMap;
8 import java.util.List;
9 import java.util.Map;
10 import java.util.function.Function;
11 import java.util.stream.Collectors;
12 import java.util.zip.ZipEntry;
13 import java.util.zip.ZipOutputStream;
14 import org.apache.commons.io.FileUtils;
15 import org.apache.commons.io.IOUtils;
16 import org.apache.velocity.Template;
17 import org.apache.velocity.VelocityContext;
18 import org.apache.velocity.app.Velocity;
19 import org.slf4j.Logger;
20 import org.slf4j.LoggerFactory;
21 import org.springframework.beans.factory.annotation.Autowired;
22 import org.springframework.stereotype.Service;
23 import org.springframework.transaction.annotation.Transactional;
24 import com.alibaba.fastjson2.JSON;
25 import com.alibaba.fastjson2.JSONObject;
26 import com.odcc.cpzidc.common.constant.Constants;
27 import com.odcc.cpzidc.common.constant.GenConstants;
28 import com.odcc.cpzidc.common.core.text.CharsetKit;
29 import com.odcc.cpzidc.common.exception.ServiceException;
30 import com.odcc.cpzidc.common.utils.StringUtils;
31 import com.odcc.cpzidc.generator.domain.GenTable;
32 import com.odcc.cpzidc.generator.domain.GenTableColumn;
33 import com.odcc.cpzidc.generator.mapper.GenTableColumnMapper;
34 import com.odcc.cpzidc.generator.mapper.GenTableMapper;
35 import com.odcc.cpzidc.generator.util.GenUtils;
36 import com.odcc.cpzidc.generator.util.VelocityInitializer;
37 import com.odcc.cpzidc.generator.util.VelocityUtils;
38
39 /**
40  * 业务 服务层实现
41  * 
42  * @author ruoyi
43  */
44 @Service
45 public class GenTableServiceImpl implements IGenTableService
46 {
47     private static final Logger log = LoggerFactory.getLogger(GenTableServiceImpl.class);
48
49     @Autowired
50     private GenTableMapper genTableMapper;
51
52     @Autowired
53     private GenTableColumnMapper genTableColumnMapper;
54
55     /**
56      * 查询业务信息
57      * 
58      * @param id 业务ID
59      * @return 业务信息
60      */
61     @Override
62     public GenTable selectGenTableById(Long id)
63     {
64         GenTable genTable = genTableMapper.selectGenTableById(id);
65         setTableFromOptions(genTable);
66         return genTable;
67     }
68
69     /**
70      * 查询业务列表
71      * 
72      * @param genTable 业务信息
73      * @return 业务集合
74      */
75     @Override
76     public List<GenTable> selectGenTableList(GenTable genTable)
77     {
78         return genTableMapper.selectGenTableList(genTable);
79     }
80
81     /**
82      * 查询据库列表
83      * 
84      * @param genTable 业务信息
85      * @return 数据库表集合
86      */
87     @Override
88     public List<GenTable> selectDbTableList(GenTable genTable)
89     {
90         return genTableMapper.selectDbTableList(genTable);
91     }
92
93     /**
94      * 查询据库列表
95      * 
96      * @param tableNames 表名称组
97      * @return 数据库表集合
98      */
99     @Override
100     public List<GenTable> selectDbTableListByNames(String[] tableNames)
101     {
102         return genTableMapper.selectDbTableListByNames(tableNames);
103     }
104
105     /**
106      * 查询所有表信息
107      * 
108      * @return 表信息集合
109      */
110     @Override
111     public List<GenTable> selectGenTableAll()
112     {
113         return genTableMapper.selectGenTableAll();
114     }
115
116     /**
117      * 修改业务
118      * 
119      * @param genTable 业务信息
120      * @return 结果
121      */
122     @Override
123     @Transactional
124     public void updateGenTable(GenTable genTable)
125     {
126         String options = JSON.toJSONString(genTable.getParams());
127         genTable.setOptions(options);
128         int row = genTableMapper.updateGenTable(genTable);
129         if (row > 0)
130         {
131             for (GenTableColumn cenTableColumn : genTable.getColumns())
132             {
133                 genTableColumnMapper.updateGenTableColumn(cenTableColumn);
134             }
135         }
136     }
137
138     /**
139      * 删除业务对象
140      * 
141      * @param tableIds 需要删除的数据ID
142      * @return 结果
143      */
144     @Override
145     @Transactional
146     public void deleteGenTableByIds(Long[] tableIds)
147     {
148         genTableMapper.deleteGenTableByIds(tableIds);
149         genTableColumnMapper.deleteGenTableColumnByIds(tableIds);
150     }
151
152     /**
153      * 创建表
154      *
155      * @param sql 创建表语句
156      * @return 结果
157      */
158     @Override
159     public boolean createTable(String sql)
160     {
161         return genTableMapper.createTable(sql) == 0;
162     }
163
164     /**
165      * 导入表结构
166      * 
167      * @param tableList 导入表列表
168      */
169     @Override
170     @Transactional
171     public void importGenTable(List<GenTable> tableList, String operName)
172     {
173         try
174         {
175             for (GenTable table : tableList)
176             {
177                 String tableName = table.getTableName();
178                 GenUtils.initTable(table, operName);
179                 int row = genTableMapper.insertGenTable(table);
180                 if (row > 0)
181                 {
182                     // 保存列信息
183                     List<GenTableColumn> genTableColumns = genTableColumnMapper.selectDbTableColumnsByName(tableName);
184                     for (GenTableColumn column : genTableColumns)
185                     {
186                         GenUtils.initColumnField(column, table);
187                         genTableColumnMapper.insertGenTableColumn(column);
188                     }
189                 }
190             }
191         }
192         catch (Exception e)
193         {
194             throw new ServiceException("导入失败:" + e.getMessage());
195         }
196     }
197
198     /**
199      * 预览代码
200      * 
201      * @param tableId 表编号
202      * @return 预览数据列表
203      */
204     @Override
205     public Map<String, String> previewCode(Long tableId)
206     {
207         Map<String, String> dataMap = new LinkedHashMap<>();
208         // 查询表信息
209         GenTable table = genTableMapper.selectGenTableById(tableId);
210         // 设置主子表信息
211         setSubTable(table);
212         // 设置主键列信息
213         setPkColumn(table);
214         VelocityInitializer.initVelocity();
215
216         VelocityContext context = VelocityUtils.prepareContext(table);
217
218         // 获取模板列表
219         List<String> templates = VelocityUtils.getTemplateList(table.getTplCategory(), table.getTplWebType());
220         for (String template : templates)
221         {
222             // 渲染模板
223             StringWriter sw = new StringWriter();
224             Template tpl = Velocity.getTemplate(template, Constants.UTF8);
225             tpl.merge(context, sw);
226             dataMap.put(template, sw.toString());
227         }
228         return dataMap;
229     }
230
231     /**
232      * 生成代码(下载方式)
233      * 
234      * @param tableName 表名称
235      * @return 数据
236      */
237     @Override
238     public byte[] downloadCode(String tableName)
239     {
240         ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
241         ZipOutputStream zip = new ZipOutputStream(outputStream);
242         generatorCode(tableName, zip);
243         IOUtils.closeQuietly(zip);
244         return outputStream.toByteArray();
245     }
246
247     /**
248      * 生成代码(自定义路径)
249      * 
250      * @param tableName 表名称
251      */
252     @Override
253     public void generatorCode(String tableName)
254     {
255         // 查询表信息
256         GenTable table = genTableMapper.selectGenTableByName(tableName);
257         // 设置主子表信息
258         setSubTable(table);
259         // 设置主键列信息
260         setPkColumn(table);
261
262         VelocityInitializer.initVelocity();
263
264         VelocityContext context = VelocityUtils.prepareContext(table);
265
266         // 获取模板列表
267         List<String> templates = VelocityUtils.getTemplateList(table.getTplCategory(), table.getTplWebType());
268         for (String template : templates)
269         {
270             if (!StringUtils.containsAny(template, "sql.vm", "api.js.vm", "index.vue.vm", "index-tree.vue.vm"))
271             {
272                 // 渲染模板
273                 StringWriter sw = new StringWriter();
274                 Template tpl = Velocity.getTemplate(template, Constants.UTF8);
275                 tpl.merge(context, sw);
276                 try
277                 {
278                     String path = getGenPath(table, template);
279                     FileUtils.writeStringToFile(new File(path), sw.toString(), CharsetKit.UTF_8);
280                 }
281                 catch (IOException e)
282                 {
283                     throw new ServiceException("渲染模板失败,表名:" + table.getTableName());
284                 }
285             }
286         }
287     }
288
289     /**
290      * 同步数据库
291      * 
292      * @param tableName 表名称
293      */
294     @Override
295     @Transactional
296     public void synchDb(String tableName)
297     {
298         GenTable table = genTableMapper.selectGenTableByName(tableName);
299         List<GenTableColumn> tableColumns = table.getColumns();
300         Map<String, GenTableColumn> tableColumnMap = tableColumns.stream().collect(Collectors.toMap(GenTableColumn::getColumnName, Function.identity()));
301
302         List<GenTableColumn> dbTableColumns = genTableColumnMapper.selectDbTableColumnsByName(tableName);
303         if (StringUtils.isEmpty(dbTableColumns))
304         {
305             throw new ServiceException("同步数据失败,原表结构不存在");
306         }
307         List<String> dbTableColumnNames = dbTableColumns.stream().map(GenTableColumn::getColumnName).collect(Collectors.toList());
308
309         dbTableColumns.forEach(column -> {
310             GenUtils.initColumnField(column, table);
311             if (tableColumnMap.containsKey(column.getColumnName()))
312             {
313                 GenTableColumn prevColumn = tableColumnMap.get(column.getColumnName());
314                 column.setColumnId(prevColumn.getColumnId());
315                 if (column.isList())
316                 {
317                     // 如果是列表,继续保留查询方式/字典类型选项
318                     column.setDictType(prevColumn.getDictType());
319                     column.setQueryType(prevColumn.getQueryType());
320                 }
321                 if (StringUtils.isNotEmpty(prevColumn.getIsRequired()) && !column.isPk()
322                         && (column.isInsert() || column.isEdit())
323                         && ((column.isUsableColumn()) || (!column.isSuperColumn())))
324                 {
325                     // 如果是(新增/修改&非主键/非忽略及父属性),继续保留必填/显示类型选项
326                     column.setIsRequired(prevColumn.getIsRequired());
327                     column.setHtmlType(prevColumn.getHtmlType());
328                 }
329                 genTableColumnMapper.updateGenTableColumn(column);
330             }
331             else
332             {
333                 genTableColumnMapper.insertGenTableColumn(column);
334             }
335         });
336
337         List<GenTableColumn> delColumns = tableColumns.stream().filter(column -> !dbTableColumnNames.contains(column.getColumnName())).collect(Collectors.toList());
338         if (StringUtils.isNotEmpty(delColumns))
339         {
340             genTableColumnMapper.deleteGenTableColumns(delColumns);
341         }
342     }
343
344     /**
345      * 批量生成代码(下载方式)
346      * 
347      * @param tableNames 表数组
348      * @return 数据
349      */
350     @Override
351     public byte[] downloadCode(String[] tableNames)
352     {
353         ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
354         ZipOutputStream zip = new ZipOutputStream(outputStream);
355         for (String tableName : tableNames)
356         {
357             generatorCode(tableName, zip);
358         }
359         IOUtils.closeQuietly(zip);
360         return outputStream.toByteArray();
361     }
362
363     /**
364      * 查询表信息并生成代码
365      */
366     private void generatorCode(String tableName, ZipOutputStream zip)
367     {
368         // 查询表信息
369         GenTable table = genTableMapper.selectGenTableByName(tableName);
370         // 设置主子表信息
371         setSubTable(table);
372         // 设置主键列信息
373         setPkColumn(table);
374
375         VelocityInitializer.initVelocity();
376
377         VelocityContext context = VelocityUtils.prepareContext(table);
378
379         // 获取模板列表
380         List<String> templates = VelocityUtils.getTemplateList(table.getTplCategory(), table.getTplWebType());
381         for (String template : templates)
382         {
383             // 渲染模板
384             StringWriter sw = new StringWriter();
385             Template tpl = Velocity.getTemplate(template, Constants.UTF8);
386             tpl.merge(context, sw);
387             try
388             {
389                 // 添加到zip
390                 zip.putNextEntry(new ZipEntry(VelocityUtils.getFileName(template, table)));
391                 IOUtils.write(sw.toString(), zip, Constants.UTF8);
392                 IOUtils.closeQuietly(sw);
393                 zip.flush();
394                 zip.closeEntry();
395             }
396             catch (IOException e)
397             {
398                 log.error("渲染模板失败,表名:" + table.getTableName(), e);
399             }
400         }
401     }
402
403     /**
404      * 修改保存参数校验
405      * 
406      * @param genTable 业务信息
407      */
408     @Override
409     public void validateEdit(GenTable genTable)
410     {
411         if (GenConstants.TPL_TREE.equals(genTable.getTplCategory()))
412         {
413             String options = JSON.toJSONString(genTable.getParams());
414             JSONObject paramsObj = JSON.parseObject(options);
415             if (StringUtils.isEmpty(paramsObj.getString(GenConstants.TREE_CODE)))
416             {
417                 throw new ServiceException("树编码字段不能为空");
418             }
419             else if (StringUtils.isEmpty(paramsObj.getString(GenConstants.TREE_PARENT_CODE)))
420             {
421                 throw new ServiceException("树父编码字段不能为空");
422             }
423             else if (StringUtils.isEmpty(paramsObj.getString(GenConstants.TREE_NAME)))
424             {
425                 throw new ServiceException("树名称字段不能为空");
426             }
427             else if (GenConstants.TPL_SUB.equals(genTable.getTplCategory()))
428             {
429                 if (StringUtils.isEmpty(genTable.getSubTableName()))
430                 {
431                     throw new ServiceException("关联子表的表名不能为空");
432                 }
433                 else if (StringUtils.isEmpty(genTable.getSubTableFkName()))
434                 {
435                     throw new ServiceException("子表关联的外键名不能为空");
436                 }
437             }
438         }
439     }
440
441     /**
442      * 设置主键列信息
443      * 
444      * @param table 业务表信息
445      */
446     public void setPkColumn(GenTable table)
447     {
448         for (GenTableColumn column : table.getColumns())
449         {
450             if (column.isPk())
451             {
452                 table.setPkColumn(column);
453                 break;
454             }
455         }
456         if (StringUtils.isNull(table.getPkColumn()))
457         {
458             table.setPkColumn(table.getColumns().get(0));
459         }
460         if (GenConstants.TPL_SUB.equals(table.getTplCategory()))
461         {
462             for (GenTableColumn column : table.getSubTable().getColumns())
463             {
464                 if (column.isPk())
465                 {
466                     table.getSubTable().setPkColumn(column);
467                     break;
468                 }
469             }
470             if (StringUtils.isNull(table.getSubTable().getPkColumn()))
471             {
472                 table.getSubTable().setPkColumn(table.getSubTable().getColumns().get(0));
473             }
474         }
475     }
476
477     /**
478      * 设置主子表信息
479      * 
480      * @param table 业务表信息
481      */
482     public void setSubTable(GenTable table)
483     {
484         String subTableName = table.getSubTableName();
485         if (StringUtils.isNotEmpty(subTableName))
486         {
487             table.setSubTable(genTableMapper.selectGenTableByName(subTableName));
488         }
489     }
490
491     /**
492      * 设置代码生成其他选项值
493      * 
494      * @param genTable 设置后的生成对象
495      */
496     public void setTableFromOptions(GenTable genTable)
497     {
498         JSONObject paramsObj = JSON.parseObject(genTable.getOptions());
499         if (StringUtils.isNotNull(paramsObj))
500         {
501             String treeCode = paramsObj.getString(GenConstants.TREE_CODE);
502             String treeParentCode = paramsObj.getString(GenConstants.TREE_PARENT_CODE);
503             String treeName = paramsObj.getString(GenConstants.TREE_NAME);
504             Long parentMenuId = paramsObj.getLongValue(GenConstants.PARENT_MENU_ID);
505             String parentMenuName = paramsObj.getString(GenConstants.PARENT_MENU_NAME);
506
507             genTable.setTreeCode(treeCode);
508             genTable.setTreeParentCode(treeParentCode);
509             genTable.setTreeName(treeName);
510             genTable.setParentMenuId(parentMenuId);
511             genTable.setParentMenuName(parentMenuName);
512         }
513     }
514
515     /**
516      * 获取代码生成地址
517      * 
518      * @param table 业务表信息
519      * @param template 模板文件路径
520      * @return 生成地址
521      */
522     public static String getGenPath(GenTable table, String template)
523     {
524         String genPath = table.getGenPath();
525         if (StringUtils.equals(genPath, "/"))
526         {
527             return System.getProperty("user.dir") + File.separator + "src" + File.separator + VelocityUtils.getFileName(template, table);
528         }
529         return genPath + File.separator + VelocityUtils.getFileName(template, table);
530     }
531 }