AppFuncDesignServiceImpl.java 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340
  1. package com.xjrsoft.module.app.service.impl;
  2. import cn.hutool.core.bean.BeanUtil;
  3. import cn.hutool.core.io.FileUtil;
  4. import cn.hutool.core.util.IdUtil;
  5. import cn.hutool.core.util.StrUtil;
  6. import cn.hutool.db.Db;
  7. import cn.hutool.db.meta.MetaUtil;
  8. import cn.hutool.db.meta.Table;
  9. import cn.hutool.json.JSON;
  10. import cn.hutool.json.JSONArray;
  11. import cn.hutool.json.JSONUtil;
  12. import com.baomidou.mybatisplus.annotation.DbType;
  13. import com.baomidou.mybatisplus.core.toolkit.StringPool;
  14. import com.github.yulichang.base.MPJBaseServiceImpl;
  15. import com.xjrsoft.common.constant.GlobalConstant;
  16. import com.xjrsoft.common.enums.FormTemplateType;
  17. import com.xjrsoft.common.enums.YesOrNoEnum;
  18. import com.xjrsoft.common.exception.MyException;
  19. import com.xjrsoft.common.utils.DatasourceUtil;
  20. import com.xjrsoft.config.GeneratePathConfig;
  21. import com.xjrsoft.module.app.dto.AddAppMenuDto;
  22. import com.xjrsoft.module.app.dto.AddFuncDesignDto;
  23. import com.xjrsoft.module.app.dto.UpdateAppFuncDesignDto;
  24. import com.xjrsoft.module.app.entity.AppFuncDesign;
  25. import com.xjrsoft.module.app.entity.AppMenu;
  26. import com.xjrsoft.module.app.mapper.AppFuncDesignMapper;
  27. import com.xjrsoft.module.app.mapper.AppMenuMapper;
  28. import com.xjrsoft.module.app.service.IAppFuncDesignService;
  29. import com.xjrsoft.module.generator.dto.GeneratorAppDto;
  30. import com.xjrsoft.module.generator.entity.GeneratorConfig;
  31. import com.xjrsoft.module.generator.entity.OutputConfig;
  32. import com.xjrsoft.module.generator.entity.TableConfig;
  33. import com.xjrsoft.module.generator.service.IGeneratorService;
  34. import com.xjrsoft.module.generator.utils.GeneratorUtil;
  35. import com.xjrsoft.module.generator.utils.SqlUtil;
  36. import com.xjrsoft.module.system.service.IDatabaselinkService;
  37. import lombok.AllArgsConstructor;
  38. import lombok.SneakyThrows;
  39. import org.apache.commons.lang3.ArrayUtils;
  40. import org.apache.commons.lang3.BooleanUtils;
  41. import org.springframework.stereotype.Service;
  42. import org.springframework.transaction.annotation.Transactional;
  43. import javax.sql.DataSource;
  44. import java.io.File;
  45. import java.io.FileNotFoundException;
  46. import java.nio.charset.StandardCharsets;
  47. import java.util.ArrayList;
  48. import java.util.HashMap;
  49. import java.util.List;
  50. import java.util.Map;
  51. import java.util.Optional;
  52. /**
  53. * <p>
  54. * 服务实现类
  55. * </p>
  56. *
  57. * @author tzx
  58. * @since 2023-07-26
  59. */
  60. @Service
  61. @AllArgsConstructor
  62. public class AppFuncDesignServiceImpl extends MPJBaseServiceImpl<AppFuncDesignMapper, AppFuncDesign> implements IAppFuncDesignService {
  63. private final AppMenuMapper appMenuMapper;
  64. private final IGeneratorService generatorService;
  65. private final GeneratePathConfig generatePathConfig;
  66. private final IDatabaselinkService databaselinkService;
  67. @Override
  68. @SneakyThrows
  69. @Transactional(rollbackFor = Exception.class)
  70. public Boolean add(AddFuncDesignDto dto) {
  71. AppFuncDesign appFuncDesign = BeanUtil.toBean(dto, AppFuncDesign.class);
  72. //如果是自定义表单 不需要生成代码 以及 page.json
  73. if (dto.getFormType() == FormTemplateType.CUSTOM.getCode() && dto.getIsGeneratorCode() != YesOrNoEnum.YES.getCode()) {
  74. AppMenu appMenu = BeanUtil.toBean(dto.getMenuConfigs(), AppMenu.class);
  75. long snowflakeNextId = IdUtil.getSnowflakeNextId();
  76. appMenu.setUrl(appMenu.getUrl() + StringPool.QUESTION_MARK + "id=" + snowflakeNextId);
  77. appMenuMapper.insert(appMenu);
  78. appFuncDesign.setId(snowflakeNextId);
  79. appFuncDesign.setAppMenuId(appMenu.getId());
  80. save(appFuncDesign);
  81. } else {
  82. if(dto.getFormType() == FormTemplateType.CUSTOM.getCode()){
  83. GeneratorConfig generatorConfig = JSONUtil.toBean(dto.getJsonContent(), GeneratorConfig.class);
  84. generatorEndCode(generatorConfig);
  85. }
  86. AppMenu appMenu = BeanUtil.toBean(dto.getMenuConfigs(), AppMenu.class);
  87. appMenu.setUrl("/pages/" + dto.getCodes().getOutputValue() + StringPool.SLASH + dto.getCodes().getClassName().toLowerCase() + StringPool.SLASH + "list");
  88. appMenuMapper.insert(appMenu);
  89. appFuncDesign.setAppMenuId(appMenu.getId());
  90. save(appFuncDesign);
  91. //保存成功之后 生成代码
  92. modifyPageJsonFile(dto.getCodes(), dto.getMenuConfigs());
  93. generatorService.generateAppCodes(dto.getCodes());
  94. }
  95. return Boolean.TRUE;
  96. }
  97. @Override
  98. @SneakyThrows
  99. @Transactional(rollbackFor = Exception.class)
  100. public Boolean modify(UpdateAppFuncDesignDto dto) {
  101. AppFuncDesign appFuncDesign = BeanUtil.toBean(dto, AppFuncDesign.class);
  102. //如果是自定义表单 不需要生成代码 以及 page.json
  103. if (dto.getFormType() == FormTemplateType.CUSTOM.getCode() && dto.getIsGeneratorCode() != YesOrNoEnum.YES.getCode()) {
  104. AppMenu appMenu = BeanUtil.toBean(dto.getMenuConfigs(), AppMenu.class);
  105. appMenu.setId(dto.getAppMenuId());
  106. appMenu.setUrl(appMenu.getUrl() + StringPool.QUESTION_MARK + "id=" + appFuncDesign.getId());
  107. appMenuMapper.updateById(appMenu);
  108. appFuncDesign.setAppMenuId(appMenu.getId());
  109. updateById(appFuncDesign);
  110. } else {
  111. if(dto.getFormType() == FormTemplateType.CUSTOM.getCode()){
  112. GeneratorConfig generatorConfig = JSONUtil.toBean(dto.getJsonContent(), GeneratorConfig.class);
  113. generatorEndCode(generatorConfig);
  114. }
  115. AppMenu appMenu = BeanUtil.toBean(dto.getMenuConfigs(), AppMenu.class);
  116. appMenu.setId(dto.getAppMenuId());
  117. appMenu.setUrl("/pages/" + dto.getCodes().getOutputValue() + StringPool.SLASH + dto.getCodes().getClassName().toLowerCase() + StringPool.SLASH + "list");
  118. appMenuMapper.updateById(appMenu);
  119. updateById(appFuncDesign);
  120. //保存成功之后 生成代码
  121. modifyPageJsonFile(dto.getCodes(), dto.getMenuConfigs());
  122. generatorService.generateAppCodes(dto.getCodes());
  123. }
  124. return Boolean.TRUE;
  125. }
  126. private void modifyPageJsonFile(GeneratorAppDto dto, AddAppMenuDto menuDto) {
  127. File tempFile = FileUtil.file(generatePathConfig.getAppPath() + StringPool.SLASH + "pages.json");
  128. JSON jsonContent = JSONUtil.readJSON(tempFile, StandardCharsets.UTF_8);
  129. //如果已经包含了此地址 就不再生成
  130. if (jsonContent.getByPath("pages").toString().contains( "pages/" + dto.getOutputValue() + StringPool.SLASH + dto.getClassName().toLowerCase() + StringPool.SLASH + "list")) {
  131. return;
  132. }
  133. Map<String, Object> listJsonMap = new HashMap<>();
  134. listJsonMap.put("path", "pages/" + dto.getOutputValue() + StringPool.SLASH + dto.getClassName().toLowerCase() + StringPool.SLASH + "list");
  135. Map<String, Object> listStyleMap = new HashMap<>();
  136. listStyleMap.put("navigationBarTitleText", menuDto.getName());
  137. listJsonMap.put("style", listStyleMap);
  138. Map<String, Object> formJsonMap = new HashMap<>();
  139. formJsonMap.put("path", "pages/" + dto.getOutputValue() + StringPool.SLASH + dto.getClassName().toLowerCase() + StringPool.SLASH + "form");
  140. Map<String, Object> formStyleMap = new HashMap<>();
  141. formStyleMap.put("navigationBarTitleText", "新增");
  142. formJsonMap.put("style", formStyleMap);
  143. JSONArray pages = JSONUtil.parseArray(jsonContent.getByPath("pages").toString());
  144. pages.add(listJsonMap);
  145. pages.add(formJsonMap);
  146. jsonContent.putByPath("pages", pages);
  147. FileUtil.writeString(jsonContent.toJSONString(4), tempFile, StandardCharsets.UTF_8);
  148. }
  149. /**
  150. * 根据json 生成后端代码
  151. * @param generatorConfig
  152. */
  153. @SneakyThrows
  154. private void generatorEndCode(GeneratorConfig generatorConfig){
  155. Optional<TableConfig> tableConfigOptional = generatorConfig.getTableConfigs().stream().filter(TableConfig::getIsMain).findFirst();
  156. //主表
  157. TableConfig mainTable;
  158. if (tableConfigOptional.isPresent()) {
  159. mainTable = tableConfigOptional.get();
  160. } else {
  161. throw new MyException("请选择主表");
  162. }
  163. OutputConfig outputConfig = generatorConfig.getOutputConfig();
  164. String databaseId = generatorConfig.getDatabaseId();
  165. if (BooleanUtils.isTrue(outputConfig.getIsDataAuth())) {
  166. // 添加权限字段 rule_user_id
  167. DataSource dataSource = DatasourceUtil.getDataSource(databaseId);
  168. String[] columnNames = MetaUtil.getColumnNames(dataSource, mainTable.getTableName());
  169. if (!ArrayUtils.contains(columnNames, GlobalConstant.AUTH_USER_ID)) {
  170. DbType dbType = databaselinkService.getDbType(databaseId);
  171. Db.use(dataSource).executeBatch(SqlUtil.buildAddDataAuthFieldSqls(dbType, mainTable.getTableName()));
  172. }
  173. }
  174. //修改 getTableInfos 也记得修改 FromTemplateServiceImpl 的同名方法
  175. List<Table> tableInfos = getTableInfos(generatorConfig);
  176. createCodeFile(generatorConfig, mainTable, tableInfos);
  177. }
  178. /**
  179. * 获取表结构信息
  180. *
  181. * @param generatorConfig
  182. * @return
  183. */
  184. private List<Table> getTableInfos(GeneratorConfig generatorConfig) {
  185. List<Table> tableInfos = new ArrayList<>();
  186. for (TableConfig tableConfig : generatorConfig.getTableConfigs()) {
  187. //判断是否为默认数据源
  188. if (StrUtil.equalsIgnoreCase(generatorConfig.getDatabaseId(), GlobalConstant.DEFAULT_DATASOURCE_KEY)) {
  189. tableInfos.add(MetaUtil.getTableMeta(DatasourceUtil.getDatasourceMaster(), tableConfig.getTableName()));
  190. } else {
  191. tableInfos.add(MetaUtil.getTableMeta(DatasourceUtil.getDataSource(generatorConfig.getDatabaseId()), tableConfig.getTableName()));
  192. }
  193. }
  194. return tableInfos;
  195. }
  196. /**
  197. * 根据配置生成文件
  198. *
  199. * @param generatorConfig
  200. * @param mainTable
  201. * @param tableInfos
  202. * @throws FileNotFoundException
  203. */
  204. private void createCodeFile(GeneratorConfig generatorConfig, TableConfig mainTable, List<Table> tableInfos) throws FileNotFoundException {
  205. String className = generatorConfig.getOutputConfig().getClassName();
  206. String dirValue = generatorConfig.getOutputConfig().getOutputValue();
  207. //---------------------------------------生成entity开始----------------------------------------------------
  208. {
  209. Map<String, String> entityCodeMap = GeneratorUtil.getEntityCode(generatorConfig, tableInfos);
  210. for (Map.Entry<String, String> entry : entityCodeMap.entrySet()) {
  211. GeneratorUtil.writeFile(GeneratorUtil.getEntityOutputDir(dirValue), entry.getKey() + StringPool.DOT_JAVA, entry.getValue());
  212. }
  213. }
  214. //---------------------------------------生成entity结束----------------------------------------------------
  215. //********************************************生成dto开始************************************************
  216. {
  217. Map<String, String> dtoMap = new HashMap<>(3);
  218. dtoMap.putAll(GeneratorUtil.getAddDtoCode(generatorConfig, tableInfos));
  219. dtoMap.putAll(GeneratorUtil.getUpdateDtoCode(generatorConfig, tableInfos));
  220. dtoMap.putAll(GeneratorUtil.getPageDtoCode(generatorConfig, tableInfos, mainTable));
  221. for (Map.Entry<String, String> entry : dtoMap.entrySet()) {
  222. GeneratorUtil.writeFile(GeneratorUtil.getDtoOutputDir(dirValue), entry.getKey() + StringPool.DOT_JAVA, entry.getValue());
  223. }
  224. }
  225. //********************************************生成dto结束************************************************
  226. //###############################################生成Vo开始###############################################
  227. {
  228. Map<String, String> voMap = new HashMap<>(2);
  229. voMap.putAll(GeneratorUtil.getPageVoCode(generatorConfig, tableInfos, mainTable));
  230. voMap.putAll(GeneratorUtil.getInfoVoCode(generatorConfig, tableInfos, mainTable));
  231. for (Map.Entry<String, String> entry : voMap.entrySet()) {
  232. GeneratorUtil.writeFile(GeneratorUtil.getVoOutputDir(dirValue), entry.getKey() + StringPool.DOT_JAVA, entry.getValue());
  233. }
  234. }
  235. //###############################################生成Vo结束###############################################
  236. //---------------------------------------生成三层代码开始----------------------------------------------------
  237. {
  238. Map<String, String> mapperCode = GeneratorUtil.getMapperCode(generatorConfig, tableInfos);
  239. for (Map.Entry<String, String> entry : mapperCode.entrySet()) {
  240. GeneratorUtil.writeFile(GeneratorUtil.getMapperOutputDir(dirValue), entry.getKey() + StringPool.DOT_JAVA, entry.getValue());
  241. }
  242. }
  243. {
  244. Map<String, String> serviceCode = GeneratorUtil.getServiceCode(generatorConfig, mainTable, tableInfos.size() > 1);
  245. for (Map.Entry<String, String> entry : serviceCode.entrySet()) {
  246. GeneratorUtil.writeFile(GeneratorUtil.getServiceOutputDir(dirValue), entry.getKey() + StringPool.DOT_JAVA, entry.getValue());
  247. }
  248. }
  249. {
  250. Map<String, String> serviceImplCode = GeneratorUtil.getServiceImplCode(generatorConfig, mainTable, tableInfos.size() > 1);
  251. for (Map.Entry<String, String> entry : serviceImplCode.entrySet()) {
  252. GeneratorUtil.writeFile(GeneratorUtil.getServiceImplOutputDir(dirValue), entry.getKey() + StringPool.DOT_JAVA, entry.getValue());
  253. }
  254. }
  255. {
  256. Map<String, String> controllerCode = GeneratorUtil.getControllerCode(generatorConfig, tableInfos, mainTable);
  257. for (Map.Entry<String, String> entry : controllerCode.entrySet()) {
  258. GeneratorUtil.writeFile(GeneratorUtil.getControllerOutputDir(dirValue), entry.getKey() + StringPool.DOT_JAVA, entry.getValue());
  259. }
  260. }
  261. //---------------------------------------生成三层代码结束----------------------------------------------------
  262. }
  263. }