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
package com.ruoyi.production.service.impl;
 
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.production.mapper.ProductionLineMapper;
import com.ruoyi.production.pojo.ProductionLine;
import com.ruoyi.production.service.ProductionLineService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
 
import java.util.ArrayList;
import java.util.List;
 
/**
 * @author :yys
 * @date : 2025/12/4 11:19
 */
@Service
@Slf4j
public class ProductionLineServiceImpl extends ServiceImpl<ProductionLineMapper, ProductionLine> implements ProductionLineService {
 
    @Autowired
    private ProductionLineMapper productionLineMapper;
 
    /**
     * 递归查询产线树
     * @return
     */
    @Override
    public List<ProductionLine> listTree() {
        List<ProductionLine> productionLines = productionLineMapper.selectList(Wrappers.lambdaQuery(ProductionLine.class)
                .eq(ProductionLine::getParentId, 0)
                .eq(ProductionLine::getType, 1));
        // 2. 递归为每个根节点加载子节点(工序/子产线)
        for (ProductionLine rootLine : productionLines) {
            loadChildren(rootLine,1);
        }
        return productionLines;
    }
 
    /**
     * 递归加载子节点(核心方法)
     * @param parentNode 父节点对象
     */
    private void loadChildren(ProductionLine parentNode,Integer type) {
        // 1. 查询当前父节点的所有子节点
        List<ProductionLine> children = productionLineMapper.selectList(Wrappers.lambdaQuery(ProductionLine.class)
                .eq(ProductionLine::getParentId, parentNode.getId())
                .eq(ProductionLine::getType, type));
 
        // 2. 若有子节点,继续递归加载子节点的子节点
        if (!children.isEmpty()) {
            parentNode.setChildren(children); // 设置子节点
            for (ProductionLine child : children) {
                loadChildren(child,type); // 递归调用,加载孙子节点
            }
        }
    }
 
    /**
     * 按需提供:根据父节点ID查询单个子树(如查询某个产线下的所有工序)
     */
    @Override
    public IPage<ProductionLine> getSubTreeByParentId(Page page, ProductionLine productionLine) {
        // 1. 查询父节点本身
        ProductionLine parentNode = productionLineMapper.selectById(productionLine.getId());
        if (parentNode == null) {
            return null;
        }
        // 2. 递归加载子节点
        loadChildren(productionLine,1);
        List<Long> ids = new ArrayList<>();
        ids.add(productionLine.getId());
        if(CollectionUtils.isNotEmpty(productionLine.getChildren())){
            // 递归获取所有子节点的id
            getAllChildIds(productionLine,ids);
        }
        return productionLineMapper.selectPage(page, Wrappers.lambdaQuery(ProductionLine.class)
                .in(ProductionLine::getParentId, ids)
                .eq(ProductionLine::getType, 2));
    }
 
    /**
     * 递归获取所有子节点的id
     */
    public List<Long> getAllChildIds(ProductionLine node,List<Long> ids) {
        if (node.getChildren() != null) {
            for (ProductionLine child : node.getChildren()) {
                ids.add(child.getId());
                ids.addAll(getAllChildIds(child,ids));
            }
        }
        return ids;
    }
}