ProjectFieldTreeService.java 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319
  1. package cn.cslg.pas.service;
  2. import cn.cslg.pas.domain.ProjectField;
  3. import cn.cslg.pas.domain.ProjectFieldOption;
  4. import cn.cslg.pas.domain.ProjectFieldTree;
  5. import cn.cslg.pas.common.utils.Response;
  6. import cn.cslg.pas.mapper.ProjectFieldTreeMapper;
  7. import cn.hutool.core.collection.CollUtil;
  8. import cn.hutool.core.lang.tree.Tree;
  9. import cn.hutool.core.lang.tree.TreeNode;
  10. import cn.hutool.core.lang.tree.TreeNodeConfig;
  11. import cn.hutool.core.lang.tree.TreeUtil;
  12. import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
  13. import com.baomidou.mybatisplus.core.toolkit.Wrappers;
  14. import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
  15. import lombok.RequiredArgsConstructor;
  16. import org.apache.commons.lang3.StringUtils;
  17. import org.springframework.context.annotation.Lazy;
  18. import org.springframework.stereotype.Service;
  19. import org.springframework.transaction.annotation.Transactional;
  20. import java.util.ArrayList;
  21. import java.util.Collections;
  22. import java.util.List;
  23. import java.util.stream.Collectors;
  24. /**
  25. * <p>
  26. * 自定义字段树类型关联表 服务实现类
  27. * </p>
  28. *
  29. * @author 王岩
  30. * @since 2021-12-17
  31. */
  32. @Service
  33. @RequiredArgsConstructor(onConstructor_ = {@Lazy})
  34. public class ProjectFieldTreeService extends ServiceImpl<ProjectFieldTreeMapper, ProjectFieldTree> {
  35. private final ProjectFieldPatentLinkService projectFieldPatentLinkService;
  36. private final ProjectFieldService projectFieldService;
  37. public Integer getTreeNodeIdByPathNameAndUpdateTreeData(List<String> pathName, ProjectField projectField) {
  38. List<Integer> treeNode = new ArrayList<>();
  39. for (int i = 0; i < pathName.size(); i++) {
  40. ProjectFieldTree projectFieldTree = this.getProjectFieldTreeOptionByFieldIdAndNameAndLevel(projectField.getId(), (i == 0 ? 0 : treeNode.get(i - 1)), pathName.get(i), i + 1);
  41. if (projectFieldTree == null) {
  42. projectFieldTree = new ProjectFieldTree();
  43. projectFieldTree.setFieldId(projectField.getId());
  44. projectFieldTree.setName(pathName.get(i));
  45. projectFieldTree.setLevel(i + 1);
  46. projectFieldTree.insert();
  47. }
  48. treeNode.add(projectFieldTree.getId());
  49. projectFieldTree.setTreeId(projectFieldTree.getId());
  50. projectFieldTree.setOrder(projectFieldTree.getId());
  51. projectFieldTree.setPath(StringUtils.join(treeNode, "/"));
  52. if (treeNode.size() == 1) {
  53. projectFieldTree.setParentId(0);
  54. } else {
  55. projectFieldTree.setParentId(treeNode.get(i - 1));
  56. }
  57. projectFieldTree.updateById();
  58. }
  59. if (treeNode.size() == 0) {
  60. return 0;
  61. }
  62. return treeNode.get(treeNode.size() - 1);
  63. }
  64. public List<ProjectFieldTree> getProjectFieldTreeOptionByFieldId(Integer fieldId) {
  65. LambdaQueryWrapper<ProjectFieldTree> queryWrapper = new LambdaQueryWrapper<>();
  66. queryWrapper.eq(ProjectFieldTree::getFieldId, fieldId);
  67. queryWrapper.orderByAsc(ProjectFieldTree::getOrder);
  68. return this.list(queryWrapper);
  69. }
  70. public ProjectFieldTree getProjectFieldTreeNodeByFieldIdAndParentIdAndName(Integer fieldId, Integer parentId, String name) {
  71. LambdaQueryWrapper<ProjectFieldTree> queryWrapper = new LambdaQueryWrapper<>();
  72. queryWrapper.eq(ProjectFieldTree::getFieldId, fieldId);
  73. queryWrapper.eq(ProjectFieldTree::getParentId, parentId);
  74. queryWrapper.eq(ProjectFieldTree::getName, name);
  75. return this.getOne(queryWrapper);
  76. }
  77. public ProjectFieldTree getProjectFieldTreeOptionByFieldIdAndNameAndLevel(Integer fieldId, Integer parentId, String name, Integer level) {
  78. LambdaQueryWrapper<ProjectFieldTree> queryWrapper = new LambdaQueryWrapper<>();
  79. queryWrapper.eq(ProjectFieldTree::getFieldId, fieldId);
  80. queryWrapper.eq(ProjectFieldTree::getName, name);
  81. queryWrapper.eq(ProjectFieldTree::getLevel, level);
  82. queryWrapper.eq(ProjectFieldTree::getParentId, parentId);
  83. return this.getOne(queryWrapper);
  84. }
  85. public ProjectFieldTree getProjectFieldTreeOptionByFieldIdAndNameAndLevel(Integer fieldId, String name, Integer level) {
  86. LambdaQueryWrapper<ProjectFieldTree> queryWrapper = new LambdaQueryWrapper<>();
  87. queryWrapper.eq(ProjectFieldTree::getFieldId, fieldId);
  88. queryWrapper.eq(ProjectFieldTree::getName, name);
  89. queryWrapper.eq(ProjectFieldTree::getLevel, level);
  90. return this.getOne(queryWrapper);
  91. }
  92. public List<ProjectFieldTree> getProjectFieldTreeOptionByFieldIds(List<Integer> fieldIds) {
  93. if (fieldIds == null || fieldIds.size() == 0) {
  94. return new ArrayList<>();
  95. }
  96. LambdaQueryWrapper<ProjectFieldTree> queryWrapper = new LambdaQueryWrapper<>();
  97. queryWrapper.in(ProjectFieldTree::getFieldId, fieldIds);
  98. queryWrapper.orderByAsc(ProjectFieldTree::getOrder);
  99. return this.list(queryWrapper);
  100. }
  101. public List<ProjectFieldTree> getProjectFieldTreeOptionByIds(List<Integer> ids) {
  102. if (ids == null || ids.size() == 0) {
  103. return new ArrayList<>();
  104. }
  105. LambdaQueryWrapper<ProjectFieldTree> queryWrapper = new LambdaQueryWrapper<>();
  106. queryWrapper.in(ProjectFieldTree::getId, ids);
  107. queryWrapper.orderByAsc(ProjectFieldTree::getOrder);
  108. return this.list(queryWrapper);
  109. }
  110. public List<Tree<Integer>> getProjectFieldTreeNodeByFieldId(Integer fieldId) {
  111. List<ProjectFieldTree> dataList = this.getProjectFieldTreeOptionByFieldId(fieldId);
  112. for (ProjectFieldTree tree : dataList) {
  113. List<ProjectFieldTree> tempList = dataList.stream().filter(item -> item.getParentId().equals(tree.getTreeId())).collect(Collectors.toList());
  114. tempList.forEach(item -> item.setParentId(tree.getId()));
  115. }
  116. TreeNodeConfig treeNodeConfig = new TreeNodeConfig();
  117. treeNodeConfig.setWeightKey("order");
  118. List<TreeNode<Integer>> nodeList = CollUtil.newArrayList();
  119. for (ProjectFieldTree data : dataList) {
  120. nodeList.add(new TreeNode<>(data.getId(), data.getParentId(), data.getName(), data.getOrder()));
  121. }
  122. List<Tree<Integer>> treeNodes = TreeUtil.build(nodeList, 0, treeNodeConfig, (treeNode, tree) -> {
  123. ProjectFieldTree temp = dataList.stream().filter(item -> item.getId().equals(treeNode.getId())).findFirst().orElse(new ProjectFieldTree());
  124. tree.setId(treeNode.getId());
  125. tree.setParentId(treeNode.getParentId());
  126. tree.setWeight(treeNode.getWeight());
  127. tree.setName(treeNode.getName());
  128. tree.putExtra("level", temp.getLevel());
  129. tree.putExtra("path", temp.getPath());
  130. tree.putExtra("fieldId", temp.getFieldId());
  131. });
  132. return treeNodes;
  133. }
  134. public Integer getFieldTreeNodeTotal(Integer fieldId) {
  135. return (int) this.count(Wrappers.<ProjectFieldTree>lambdaQuery().eq(ProjectFieldTree::getFieldId, fieldId));
  136. }
  137. public Integer getFieldTreeParentId(Integer id) {
  138. ProjectFieldTree tree = this.getById(id);
  139. if (tree != null) {
  140. return tree.getTreeId();
  141. }
  142. return 0;
  143. }
  144. public Integer[] getFieldTreeNodePath(Integer id, Integer parentId) {
  145. ProjectFieldTree parentNode = this.getById(parentId);
  146. String[] nodePath = parentNode.getPath().split("/");
  147. Integer[] nodeIds = new Integer[nodePath.length + 1];
  148. for (int i = 0; i < nodeIds.length - 1; i++) {
  149. nodeIds[i] = Integer.parseInt(nodePath[i]);
  150. }
  151. nodeIds[nodePath.length] = id;
  152. return nodeIds;
  153. }
  154. @Transactional
  155. public Integer add(ProjectFieldTree tree) {
  156. // Integer total = this.getFieldTreeNodeTotal(tree.getFieldId());
  157. tree.setOrder(-1);
  158. tree.insert();
  159. this.edit(tree);
  160. return tree.getId();
  161. }
  162. @Transactional
  163. public void edit(ProjectFieldTree tree) {
  164. Integer[] path = tree.getParentId() == 0 ? new Integer[]{tree.getId()} : this.getFieldTreeNodePath(tree.getId(), tree.getParentId());
  165. tree.setPath(StringUtils.join(path, "/"));
  166. tree.setLevel(path.length);
  167. tree.setParentId(this.getFieldTreeParentId(tree.getParentId()));
  168. tree.setTreeId(tree.getId());
  169. if (tree.getOrder() == -1) {
  170. tree.setOrder(tree.getId());
  171. }
  172. tree.updateById();
  173. }
  174. @Transactional
  175. public void addBatch(List<ProjectFieldOption> optionList, Integer fieldId) {
  176. this.saveOrUpdateOption(optionList, fieldId, 0);
  177. this.updateNodePath(fieldId);
  178. }
  179. @Transactional
  180. public void editBatch(List<ProjectFieldOption> optionList, Integer fieldId) {
  181. List<ProjectFieldTree> tempList = this.getProjectFieldTreeOptionByFieldId(fieldId);
  182. List<Integer> nodeIds = this.getTreeNodeIds(optionList, new ArrayList<>());
  183. List<Integer> deleteIds = tempList.stream().map(ProjectFieldTree::getId).filter(id -> !nodeIds.contains(id)).collect(Collectors.toList());
  184. this.deleteByIds(deleteIds);
  185. this.saveOrUpdateOption(optionList, fieldId, 0);
  186. this.updateNodePath(fieldId);
  187. }
  188. private List<Integer> getTreeNodeIds(List<ProjectFieldOption> optionList, List<Integer> ids) {
  189. for (ProjectFieldOption option : optionList) {
  190. if (option.getId() != null) {
  191. ids.add(option.getId());
  192. }
  193. if (option.getChildren() != null && option.getChildren().size() != 0) {
  194. this.getTreeNodeIds(option.getChildren(), ids);
  195. }
  196. }
  197. return ids;
  198. }
  199. private void saveOrUpdateOption(List<ProjectFieldOption> optionList, Integer fieldId, Integer parentId) {
  200. for (ProjectFieldOption option : optionList) {
  201. option.setParentId(parentId);
  202. option.setFieldId(fieldId);
  203. Integer id = this.saveOption(option);
  204. if (option.getChildren() != null && option.getChildren().size() != 0) {
  205. this.saveOrUpdateOption(option.getChildren(), fieldId, id);
  206. }
  207. }
  208. }
  209. private Integer saveOption(ProjectFieldOption option) {
  210. ProjectFieldTree tree = new ProjectFieldTree();
  211. tree.setId(option.getId());
  212. tree.setName(option.getName());
  213. tree.setFieldId(option.getFieldId());
  214. tree.setOrder(option.getOrder());
  215. tree.setParentId(option.getParentId());
  216. if (tree.getId() == null) {
  217. tree.insert();
  218. }
  219. tree.setTreeId(tree.getId());
  220. tree.updateById();
  221. return tree.getId();
  222. }
  223. private void updateNodePath(Integer fieldId) {
  224. List<ProjectFieldTree> treeList = this.getProjectFieldTreeOptionByFieldId(fieldId);
  225. treeList.forEach(tree -> {
  226. Integer[] paths = this.findTreeNodePath(tree.getId());
  227. tree.setLevel(paths.length);
  228. tree.setPath(StringUtils.join(paths, "/"));
  229. });
  230. this.saveOrUpdateBatch(treeList);
  231. }
  232. public Integer[] findTreeNodePath(Integer id) {
  233. List<Integer> paths = new ArrayList<>();
  234. List<Integer> parentPath = this.findParentPath(id, paths);
  235. Collections.reverse(parentPath);
  236. return parentPath.toArray(new Integer[parentPath.size()]);
  237. }
  238. private List<Integer> findParentPath(Integer id, List<Integer> paths) {
  239. paths.add(id);
  240. ProjectFieldTree tree = this.getById(id);
  241. if (tree.getParentId() != 0) {
  242. findParentPath(tree.getParentId(), paths);
  243. }
  244. return paths;
  245. }
  246. public void deleteByFieldId(Integer fieldId) {
  247. this.remove(Wrappers.<ProjectFieldTree>lambdaQuery().eq(ProjectFieldTree::getFieldId, fieldId));
  248. }
  249. private List<Integer> findTreeNodes(Integer id, List<Integer> nodes) {
  250. nodes.add(id);
  251. List<ProjectFieldTree> treeList = this.list(Wrappers.<ProjectFieldTree>lambdaQuery().eq(ProjectFieldTree::getParentId, id));
  252. if (treeList != null && treeList.size() != 0) {
  253. treeList.forEach(item -> {
  254. nodes.add(item.getId());
  255. this.findTreeNodes(item.getId(), nodes);
  256. });
  257. }
  258. return nodes;
  259. }
  260. @Transactional
  261. public void delete(Integer id) {
  262. List<Integer> nodes = this.findTreeNodes(id, new ArrayList<>());
  263. projectFieldPatentLinkService.deleteByOptionIds(nodes);
  264. this.removeByIds(nodes);
  265. }
  266. @Transactional
  267. public void deleteByIds(List<Integer> ids) {
  268. if (ids != null && ids.size() != 0) {
  269. projectFieldPatentLinkService.deleteByOptionIds(ids);
  270. this.removeByIds(ids);
  271. }
  272. }
  273. @Transactional
  274. public String updateByProjectFieldTreeNode(ProjectFieldOption projectFieldOption) {
  275. ProjectFieldTree temp = this.getProjectFieldTreeNodeByFieldIdAndParentIdAndName(projectFieldOption.getFieldId(), projectFieldOption.getParentId(), projectFieldOption.getName());
  276. if (temp != null && !temp.getId().equals(projectFieldOption.getId())) {
  277. return Response.error("选项名称已存在");
  278. }
  279. ProjectFieldTree projectFieldTree = new ProjectFieldTree();
  280. projectFieldTree.setId(projectFieldOption.getId());
  281. projectFieldTree.setFieldId(projectFieldOption.getFieldId());
  282. projectFieldTree.setOrder(projectFieldOption.getOrder());
  283. projectFieldTree.setParentId(projectFieldOption.getParentId());
  284. projectFieldTree.setName(projectFieldOption.getName());
  285. projectFieldTree.insertOrUpdate();
  286. this.edit(projectFieldTree);
  287. return Response.success(projectFieldTree.getId());
  288. }
  289. }