maven
2025-11-20 5c0bc75816a7b5fa348d658897a304f588d9d0ed
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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
package com.ruoyi.lavorissue.service.impl;
 
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.common.utils.SecurityUtils;
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.lavorissue.mapper.DeptPositionMapper;
import com.ruoyi.lavorissue.mapper.LaborConfMapper;
import com.ruoyi.lavorissue.pojo.DeptPosition;
import com.ruoyi.lavorissue.pojo.LaborConf;
import com.ruoyi.lavorissue.service.DeptPositionService;
import com.ruoyi.staff.mapper.StaffOnJobMapper;
import com.ruoyi.staff.pojo.StaffJoinLeaveRecord;
import com.ruoyi.staff.pojo.StaffOnJob;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
 
import java.util.*;
import java.util.stream.Collectors;
 
/**
 * @author :yys
 * @date : 2025/11/19 13:21
 */
@Service
@Slf4j
public class DeptPositionServiceImpl extends ServiceImpl<DeptPositionMapper, DeptPosition> implements DeptPositionService {
 
    @Autowired
    private DeptPositionMapper deptPositionMapper;
 
 
    /**
     * 递归获取部门岗位树形结构
     * @return
     */
    @Override
    public AjaxResult getDeptPositionTree() {
        List<DeptPosition> deptPositions = deptPositionMapper.selectList(null);
        // 2. 筛选根部门(parentId为0或null,且类型为部门type=1)
        List<DeptPosition> rootDepts = deptPositions.stream()
                .filter(item -> (item.getParentId() == null || item.getParentId() == 0)
                        && item.getType() == 1) // 根节点必须是部门
                .sorted(Comparator.comparingInt(DeptPosition::getSort)) // 按排序字段升序
                .collect(Collectors.toList());
 
        // 3. 为每个根部门递归查找下属岗位(子集)
        for (DeptPosition rootDept : rootDepts) {
            buildDeptChildren(rootDept, deptPositions);
        }
        return AjaxResult.success(rootDepts);
    }
 
    @Autowired
    private StaffOnJobMapper staffOnJobMapper;
 
    /**
     * 通过id递归查询所有的岗位
     * @param deptPosition
     * @return
     */
    @Override
    public List<StaffOnJob> getDeptPositionByDeptId(DeptPosition deptPosition) {
        Long deptId = deptPosition.getId();
        // 1. 校验部门是否存在
        DeptPosition dept = deptPositionMapper.selectById(deptId);
        if (dept == null) {
            throw new IllegalArgumentException("无效的部门或岗位ID");
        }
        if(dept.getType() == 2){
            return staffOnJobMapper.selectList(Wrappers.lambdaQuery(StaffOnJob.class)
                    .eq(StaffOnJob::getStaffState, 1)
                    .eq(StaffOnJob::getDeptPositionId, deptId));
        }
 
        // 2. 递归获取当前部门及所有子部门的ID集合
        Set<Long> deptIdSet = new HashSet<>();
        // 先添加当前部门ID
        deptIdSet.add(deptId);
        // 递归获取所有子部门ID
        findAllChildDeptIds(deptId, deptIdSet);
 
        // 3. 查询这些部门下的所有岗位(type=2)
        if (deptIdSet.isEmpty()) {
            return Collections.emptyList();
        }
        List<DeptPosition> deptPositions = deptPositionMapper.selectList(
                Wrappers.<DeptPosition>lambdaQuery()
                        .in(DeptPosition::getParentId, deptIdSet) // 父ID在部门ID集合中
                        .eq(DeptPosition::getType, 2) // 类型为岗位
                        .orderByAsc(DeptPosition::getSort) // 按排序字段升序
        );
        if(CollectionUtils.isEmpty(deptPositions)){
            return Collections.emptyList();
        }
        return staffOnJobMapper.selectList(Wrappers.lambdaQuery(StaffOnJob.class)
                .eq(StaffOnJob::getStaffState, 1)
                .in(StaffOnJob::getDeptPositionId, deptPositions
                        .stream()
                        .map(DeptPosition::getId)
                        .collect(Collectors.toSet())));
    }
 
    @Autowired
    private LaborConfMapper laborConfMapper;
 
    @Override
    public List<LaborConf> getDeptPositionByDeptIdLabor(DeptPosition deptPosition) {
        Long deptId = deptPosition.getId();
        // 1. 校验部门是否存在
        DeptPosition dept = deptPositionMapper.selectById(deptId);
        if (dept == null) {
            throw new IllegalArgumentException("无效的部门或岗位ID");
        }
        if(dept.getType() == 2){
            List<Long> ids = new ArrayList<>();
            ids.add(deptId);
            return laborConfMapper.list(ids);
        }
 
        // 2. 递归获取当前部门及所有子部门的ID集合
        Set<Long> deptIdSet = new HashSet<>();
        // 先添加当前部门ID
        deptIdSet.add(deptId);
        // 递归获取所有子部门ID
        findAllChildDeptIds(deptId, deptIdSet);
 
        // 3. 查询这些部门下的所有岗位(type=2)
        if (deptIdSet.isEmpty()) {
            return Collections.emptyList();
        }
        List<DeptPosition> deptPositions = deptPositionMapper.selectList(
                Wrappers.<DeptPosition>lambdaQuery()
                        .in(DeptPosition::getParentId, deptIdSet) // 父ID在部门ID集合中
                        .eq(DeptPosition::getType, 2) // 类型为岗位
                        .orderByAsc(DeptPosition::getSort) // 按排序字段升序
        );
        if(CollectionUtils.isEmpty(deptPositions)){
            return Collections.emptyList();
        }
        return laborConfMapper.list(deptPositions.stream()
                .map(DeptPosition::getId)
                .collect(Collectors.toList()));
    }
 
    /**
     * 递归获取所有子部门ID(仅包括type=1的部门)
     * @param parentDeptId 父部门ID
     * @param deptIdSet 存储部门ID的集合(引用传递,持续添加子部门ID)
     */
    private void findAllChildDeptIds(Long parentDeptId, Set<Long> deptIdSet) {
        // 查询当前父部门下的所有子部门(type=1)
        List<DeptPosition> childDepts = deptPositionMapper.selectList(
                Wrappers.<DeptPosition>lambdaQuery()
                        .eq(DeptPosition::getParentId, parentDeptId)
                        .eq(DeptPosition::getType, 1) // 只查子部门,不查岗位
        );
 
        // 若有子部门,添加ID到集合,并继续递归查询其子部门
        if (!childDepts.isEmpty()) {
            for (DeptPosition childDept : childDepts) {
                Long childDeptId = childDept.getId();
                deptIdSet.add(childDeptId); // 添加子部门ID
                findAllChildDeptIds(childDeptId, deptIdSet); // 递归查询该子部门的子部门
            }
        }
    }
 
 
    /**
     * 递归构建部门的子节点(可能是子部门或岗位)
     * @param parent 父节点(部门)
     * @param allList 所有数据
     */
    private void buildDeptChildren(DeptPosition parent, List<DeptPosition> allList) {
        // 第一步:查找当前部门的子部门(type=1),构建部门层级
        List<DeptPosition> childDepts = allList.stream()
                .filter(item -> parent.getId().equals(item.getParentId())
                        && item.getType() == 1) // 子节点是部门
                .sorted(Comparator.comparingInt(DeptPosition::getSort))
                .collect(Collectors.toList());
 
        // 第二步:查找当前部门的岗位(type=2),作为子节点
        List<DeptPosition> childPositions = allList.stream()
                .filter(item -> parent.getId().equals(item.getParentId())
                        && item.getType() == 2) // 子节点是岗位
                .sorted(Comparator.comparingInt(DeptPosition::getSort))
                .collect(Collectors.toList());
 
        // 合并子部门和岗位(子部门在前,岗位在后,或按sort排序)
        List<DeptPosition> allChildren = new ArrayList<>();
        allChildren.addAll(childDepts);
        allChildren.addAll(childPositions);
 
        // 设置子节点
        if (!allChildren.isEmpty()) {
            parent.setChildren(allChildren);
 
            // 递归处理子部门(岗位无需递归,因为岗位是叶子节点)
            for (DeptPosition child : childDepts) {
                buildDeptChildren(child, allList); // 子部门继续找它的子节点
            }
        }
    }
}