zhangherong
2025-06-25 2fb6c67b2c0c72195eef6fe5f7904d739b46e2c0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
package org.jeecg.modules.dnc.service.impl;
 
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.shiro.SecurityUtils;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.modules.dnc.entity.ProductMix;
import org.jeecg.modules.dnc.mapper.ProductMixMapper;
import org.jeecg.modules.dnc.service.IPermissionStreamNewService;
import org.jeecg.modules.dnc.service.IProductMixService;
import org.jeecg.modules.dnc.utils.TreeBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
 
import java.util.*;
 
@Service
public class ProductMixServiceImpl extends ServiceImpl<ProductMixMapper, ProductMix> implements IProductMixService {
 
    @Autowired
    private IPermissionStreamNewService permissionStreamNewService;
 
    /**
     * 默认结构树查询
     * @return
     */
    @Override
    public List<ProductMix> getTree() {
        LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        List<ProductMix> rawData = new ArrayList<>();
        if (loginUser.getUsername().equals("admin")) {
            //不需要权限过滤
            rawData=permissionStreamNewService.loadProductMixAll(loginUser.getId());
        }else{
            //需要权限过滤
            String productIds = loginUser.getProductionIds();
            if (productIds != null && !productIds.isEmpty()) {
                List<String> productIdList = Arrays.asList(productIds.split(","));
                rawData = permissionStreamNewService.loadProductMix(loginUser.getId(),productIdList);
            }
        }
        TreeBuilder builder = new TreeBuilder();
        TreeBuilder.CleanResult cleanResult = builder.preprocessData(rawData);
        List<ProductMix> sorted = builder.topologicalSort(
                cleanResult.getValidNodes(),
                cleanResult.getNodeMap()
        );
        List<ProductMix> result =builder.assembleTree(sorted, cleanResult.getNodeMap());
        result.sort(Comparator.comparing(ProductMix::getCreateTime, Comparator.nullsLast(Date::compareTo)));
        return result;
    }
 
    @Override
    public List<ProductMix> getParentList(String id) {
        List<ProductMix> parentList = new ArrayList<>();
        // 1. 根据ID查询当前节点
        ProductMix current = this.getById(id);
        if (current == null) {
            return parentList; // 节点不存在时返回空列表
        }
        // 2. 从当前节点开始向上查找父节点
        Long parentId = current.getParentId();
        while ( parentId != 0L) {
            ProductMix parent = this.getById(parentId.toString());
            if (parent == null) {
                break;
            }
            parentList.add(parent);
            parentId = parent.getParentId();
        }
 
        return parentList;
    }
 
    @Override
    public List<ProductMix> getChildrenList(String id) {
        List<ProductMix> childrenList = new ArrayList<>();
        ProductMix current = this.getById(id);
        if (current == null) {
            return childrenList;
        }
 
        // 使用队列进行BFS
        Queue<ProductMix> queue = new LinkedList<>();
        queue.add(current); // 加入当前节点作为起点
 
        // 记录已访问节点的ID,避免循环引用
        Set<String> visited = new HashSet<>();
        visited.add(id); // 起始节点已访问
 
        while (!queue.isEmpty()) {
            ProductMix node = queue.poll();
            // 跳过起始节点(即传入的节点),不加入结果列表
            if (!node.getId().toString().equals(id)) {
                childrenList.add(node);
            }
 
            // 查询当前节点的直接子节点
            List<ProductMix> directChildren = this.lambdaQuery().eq(ProductMix::getParentId, node.getId()).list();
            if (directChildren != null && !directChildren.isEmpty()) {
                for (ProductMix child : directChildren) {
                    String childId = child.getId().toString();
                    // 如果该子节点还未访问过
                    if (!visited.contains(childId)) {
                        visited.add(childId);
                        queue.add(child);
                    }
                    // 否则忽略,避免循环引用导致的死循环
                }
            }
        }
        return childrenList;
    }
 
}