package cn.cslg.pas.service; import cn.cslg.pas.domain.ProjectField; import cn.cslg.pas.domain.ProjectFieldOption; import cn.cslg.pas.domain.ProjectFieldTree; import cn.cslg.pas.common.utils.Response; import cn.cslg.pas.mapper.ProjectFieldTreeMapper; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.lang.tree.Tree; import cn.hutool.core.lang.tree.TreeNode; import cn.hutool.core.lang.tree.TreeNodeConfig; import cn.hutool.core.lang.tree.TreeUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import lombok.RequiredArgsConstructor; import org.apache.commons.lang3.StringUtils; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.stream.Collectors; /** *

* 自定义字段树类型关联表 服务实现类 *

* * @author 王岩 * @since 2021-12-17 */ @Service @RequiredArgsConstructor(onConstructor_ = {@Lazy}) public class ProjectFieldTreeService extends ServiceImpl { private final ProjectFieldPatentLinkService projectFieldPatentLinkService; private final ProjectFieldService projectFieldService; public Integer getTreeNodeIdByPathNameAndUpdateTreeData(List pathName, ProjectField projectField) { List treeNode = new ArrayList<>(); for (int i = 0; i < pathName.size(); i++) { ProjectFieldTree projectFieldTree = this.getProjectFieldTreeOptionByFieldIdAndNameAndLevel(projectField.getId(), (i == 0 ? 0 : treeNode.get(i - 1)), pathName.get(i), i + 1); if (projectFieldTree == null) { projectFieldTree = new ProjectFieldTree(); projectFieldTree.setFieldId(projectField.getId()); projectFieldTree.setName(pathName.get(i)); projectFieldTree.setLevel(i + 1); projectFieldTree.insert(); } treeNode.add(projectFieldTree.getId()); projectFieldTree.setTreeId(projectFieldTree.getId()); projectFieldTree.setOrder(projectFieldTree.getId()); projectFieldTree.setPath(StringUtils.join(treeNode, "/")); if (treeNode.size() == 1) { projectFieldTree.setParentId(0); } else { projectFieldTree.setParentId(treeNode.get(i - 1)); } projectFieldTree.updateById(); } if (treeNode.size() == 0) { return 0; } return treeNode.get(treeNode.size() - 1); } public List getProjectFieldTreeOptionByFieldId(Integer fieldId) { LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.eq(ProjectFieldTree::getFieldId, fieldId); queryWrapper.orderByAsc(ProjectFieldTree::getOrder); return this.list(queryWrapper); } public ProjectFieldTree getProjectFieldTreeNodeByFieldIdAndParentIdAndName(Integer fieldId, Integer parentId, String name) { LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.eq(ProjectFieldTree::getFieldId, fieldId); queryWrapper.eq(ProjectFieldTree::getParentId, parentId); queryWrapper.eq(ProjectFieldTree::getName, name); return this.getOne(queryWrapper); } public ProjectFieldTree getProjectFieldTreeOptionByFieldIdAndNameAndLevel(Integer fieldId, Integer parentId, String name, Integer level) { LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.eq(ProjectFieldTree::getFieldId, fieldId); queryWrapper.eq(ProjectFieldTree::getName, name); queryWrapper.eq(ProjectFieldTree::getLevel, level); queryWrapper.eq(ProjectFieldTree::getParentId, parentId); return this.getOne(queryWrapper); } public ProjectFieldTree getProjectFieldTreeOptionByFieldIdAndNameAndLevel(Integer fieldId, String name, Integer level) { LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.eq(ProjectFieldTree::getFieldId, fieldId); queryWrapper.eq(ProjectFieldTree::getName, name); queryWrapper.eq(ProjectFieldTree::getLevel, level); return this.getOne(queryWrapper); } public List getProjectFieldTreeOptionByFieldIds(List fieldIds) { if (fieldIds == null || fieldIds.size() == 0) { return new ArrayList<>(); } LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.in(ProjectFieldTree::getFieldId, fieldIds); queryWrapper.orderByAsc(ProjectFieldTree::getOrder); return this.list(queryWrapper); } public List getProjectFieldTreeOptionByIds(List ids) { if (ids == null || ids.size() == 0) { return new ArrayList<>(); } LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.in(ProjectFieldTree::getId, ids); queryWrapper.orderByAsc(ProjectFieldTree::getOrder); return this.list(queryWrapper); } public List> getProjectFieldTreeNodeByFieldId(Integer fieldId) { List dataList = this.getProjectFieldTreeOptionByFieldId(fieldId); for (ProjectFieldTree tree : dataList) { List tempList = dataList.stream().filter(item -> item.getParentId().equals(tree.getTreeId())).collect(Collectors.toList()); tempList.forEach(item -> item.setParentId(tree.getId())); } TreeNodeConfig treeNodeConfig = new TreeNodeConfig(); treeNodeConfig.setWeightKey("order"); List> nodeList = CollUtil.newArrayList(); for (ProjectFieldTree data : dataList) { nodeList.add(new TreeNode<>(data.getId(), data.getParentId(), data.getName(), data.getOrder())); } List> treeNodes = TreeUtil.build(nodeList, 0, treeNodeConfig, (treeNode, tree) -> { ProjectFieldTree temp = dataList.stream().filter(item -> item.getId().equals(treeNode.getId())).findFirst().orElse(new ProjectFieldTree()); tree.setId(treeNode.getId()); tree.setParentId(treeNode.getParentId()); tree.setWeight(treeNode.getWeight()); tree.setName(treeNode.getName()); tree.putExtra("level", temp.getLevel()); tree.putExtra("path", temp.getPath()); tree.putExtra("fieldId", temp.getFieldId()); }); return treeNodes; } public Integer getFieldTreeNodeTotal(Integer fieldId) { return (int) this.count(Wrappers.lambdaQuery().eq(ProjectFieldTree::getFieldId, fieldId)); } public Integer getFieldTreeParentId(Integer id) { ProjectFieldTree tree = this.getById(id); if (tree != null) { return tree.getTreeId(); } return 0; } public Integer[] getFieldTreeNodePath(Integer id, Integer parentId) { ProjectFieldTree parentNode = this.getById(parentId); String[] nodePath = parentNode.getPath().split("/"); Integer[] nodeIds = new Integer[nodePath.length + 1]; for (int i = 0; i < nodeIds.length - 1; i++) { nodeIds[i] = Integer.parseInt(nodePath[i]); } nodeIds[nodePath.length] = id; return nodeIds; } @Transactional public Integer add(ProjectFieldTree tree) { // Integer total = this.getFieldTreeNodeTotal(tree.getFieldId()); tree.setOrder(-1); tree.insert(); this.edit(tree); return tree.getId(); } @Transactional public void edit(ProjectFieldTree tree) { Integer[] path = tree.getParentId() == 0 ? new Integer[]{tree.getId()} : this.getFieldTreeNodePath(tree.getId(), tree.getParentId()); tree.setPath(StringUtils.join(path, "/")); tree.setLevel(path.length); tree.setParentId(this.getFieldTreeParentId(tree.getParentId())); tree.setTreeId(tree.getId()); if (tree.getOrder() == -1) { tree.setOrder(tree.getId()); } tree.updateById(); } @Transactional public void addBatch(List optionList, Integer fieldId) { this.saveOrUpdateOption(optionList, fieldId, 0); this.updateNodePath(fieldId); } @Transactional public void editBatch(List optionList, Integer fieldId) { List tempList = this.getProjectFieldTreeOptionByFieldId(fieldId); List nodeIds = this.getTreeNodeIds(optionList, new ArrayList<>()); List deleteIds = tempList.stream().map(ProjectFieldTree::getId).filter(id -> !nodeIds.contains(id)).collect(Collectors.toList()); this.deleteByIds(deleteIds); this.saveOrUpdateOption(optionList, fieldId, 0); this.updateNodePath(fieldId); } private List getTreeNodeIds(List optionList, List ids) { for (ProjectFieldOption option : optionList) { if (option.getId() != null) { ids.add(option.getId()); } if (option.getChildren() != null && option.getChildren().size() != 0) { this.getTreeNodeIds(option.getChildren(), ids); } } return ids; } private void saveOrUpdateOption(List optionList, Integer fieldId, Integer parentId) { for (ProjectFieldOption option : optionList) { option.setParentId(parentId); option.setFieldId(fieldId); Integer id = this.saveOption(option); if (option.getChildren() != null && option.getChildren().size() != 0) { this.saveOrUpdateOption(option.getChildren(), fieldId, id); } } } private Integer saveOption(ProjectFieldOption option) { ProjectFieldTree tree = new ProjectFieldTree(); tree.setId(option.getId()); tree.setName(option.getName()); tree.setFieldId(option.getFieldId()); tree.setOrder(option.getOrder()); tree.setParentId(option.getParentId()); if (tree.getId() == null) { tree.insert(); } tree.setTreeId(tree.getId()); tree.updateById(); return tree.getId(); } private void updateNodePath(Integer fieldId) { List treeList = this.getProjectFieldTreeOptionByFieldId(fieldId); treeList.forEach(tree -> { Integer[] paths = this.findTreeNodePath(tree.getId()); tree.setLevel(paths.length); tree.setPath(StringUtils.join(paths, "/")); }); this.saveOrUpdateBatch(treeList); } public Integer[] findTreeNodePath(Integer id) { List paths = new ArrayList<>(); List parentPath = this.findParentPath(id, paths); Collections.reverse(parentPath); return parentPath.toArray(new Integer[parentPath.size()]); } private List findParentPath(Integer id, List paths) { paths.add(id); ProjectFieldTree tree = this.getById(id); if (tree.getParentId() != 0) { findParentPath(tree.getParentId(), paths); } return paths; } public void deleteByFieldId(Integer fieldId) { this.remove(Wrappers.lambdaQuery().eq(ProjectFieldTree::getFieldId, fieldId)); } private List findTreeNodes(Integer id, List nodes) { nodes.add(id); List treeList = this.list(Wrappers.lambdaQuery().eq(ProjectFieldTree::getParentId, id)); if (treeList != null && treeList.size() != 0) { treeList.forEach(item -> { nodes.add(item.getId()); this.findTreeNodes(item.getId(), nodes); }); } return nodes; } @Transactional public void delete(Integer id) { List nodes = this.findTreeNodes(id, new ArrayList<>()); projectFieldPatentLinkService.deleteByOptionIds(nodes); this.removeByIds(nodes); } @Transactional public void deleteByIds(List ids) { if (ids != null && ids.size() != 0) { projectFieldPatentLinkService.deleteByOptionIds(ids); this.removeByIds(ids); } } @Transactional public String updateByProjectFieldTreeNode(ProjectFieldOption projectFieldOption) { ProjectFieldTree temp = this.getProjectFieldTreeNodeByFieldIdAndParentIdAndName(projectFieldOption.getFieldId(), projectFieldOption.getParentId(), projectFieldOption.getName()); if (temp != null && !temp.getId().equals(projectFieldOption.getId())) { return Response.error("选项名称已存在"); } ProjectFieldTree projectFieldTree = new ProjectFieldTree(); projectFieldTree.setId(projectFieldOption.getId()); projectFieldTree.setFieldId(projectFieldOption.getFieldId()); projectFieldTree.setOrder(projectFieldOption.getOrder()); projectFieldTree.setParentId(projectFieldOption.getParentId()); projectFieldTree.setName(projectFieldOption.getName()); projectFieldTree.insertOrUpdate(); this.edit(projectFieldTree); return Response.success(projectFieldTree.getId()); } }