| | |
| | | import com.sinata.appointment.entity.MpPassLocalUnitMember; |
| | | import com.sinata.appointment.entity.MpStaffGroupMember; |
| | | import com.sinata.appointment.entity.MpUser; |
| | | import com.sinata.appointment.entity.SysDept; |
| | | import com.sinata.appointment.exception.BizException; |
| | | import com.sinata.appointment.mapper.ApprovalInstanceMapper; |
| | | import com.sinata.appointment.mapper.ApprovalTaskMapper; |
| | |
| | | import com.sinata.appointment.mapper.MpPassLocalUnitMemberMapper; |
| | | import com.sinata.appointment.mapper.MpStaffGroupMemberMapper; |
| | | import com.sinata.appointment.mapper.MpUserMapper; |
| | | import com.sinata.appointment.mapper.SysDeptMapper; |
| | | import com.sinata.appointment.constants.BizErrorCode; |
| | | import java.time.LocalDateTime; |
| | | import java.util.ArrayList; |
| | |
| | | |
| | | private static final TypeReference<List<Long>> LONG_LIST_TYPE = new TypeReference<>() {}; |
| | | private static final String AUTO_APPROVE_COMMENT = "前序节点已审批,系统自动同意"; |
| | | private static final String LOCAL_UNIT_GROUP_TOKEN = ":UNIT:"; |
| | | |
| | | private final BizApprovalNodeConfigMapper bizApprovalNodeConfigMapper; |
| | | private final ApprovalInstanceMapper approvalInstanceMapper; |
| | | private final ApprovalTaskMapper approvalTaskMapper; |
| | | private final MpUserMapper mpUserMapper; |
| | | private final SysDeptMapper sysDeptMapper; |
| | | private final MpPassLocalUnitMapper mpPassLocalUnitMapper; |
| | | private final MpPassLocalUnitMemberMapper mpPassLocalUnitMemberMapper; |
| | | private final MpStaffGroupMemberMapper mpStaffGroupMemberMapper; |
| | |
| | | } |
| | | if (ApprovalNodeCode.LEVEL2_DEPT_LEADER.equals(nodeCode)) { |
| | | Long deptId = resolveVisitedDeptId(order); |
| | | return listEmployeeIdsByDeptAndLeaderFlag(deptId, true); |
| | | return getDeptLeaderIds(deptId); |
| | | } |
| | | if (ApprovalNodeCode.LEVEL4_VISIT_DEPT.equals(nodeCode)) { |
| | | Long competentDeptId = getVisitCompetentDeptId(); |
| | | return listEmployeeIdsByDeptAndLeaderFlag(competentDeptId, false); |
| | | return listEmployeeIdsByDeptWithLeaderFallback(competentDeptId); |
| | | } |
| | | if (ApprovalNodeCode.LEVEL5_VISIT_DEPT_LEADER.equals(nodeCode)) { |
| | | Long competentDeptId = getVisitCompetentDeptId(); |
| | | return listEmployeeIdsByDeptAndLeaderFlag(competentDeptId, true); |
| | | return getDeptLeaderIds(competentDeptId); |
| | | } |
| | | if (ApprovalNodeCode.LEVEL3_LOCAL_DEPT_LEADER.equals(nodeCode)) { |
| | | return List.of(); |
| | |
| | | } |
| | | } |
| | | |
| | | private List<Long> listEmployeeIdsByDeptAndLeaderFlag(Long deptId, boolean leaderFlag) { |
| | | private List<Long> getDeptLeaderIds(Long deptId) { |
| | | if (deptId == null || deptId <= 0) { |
| | | return List.of(); |
| | | } |
| | | SysDept dept = sysDeptMapper.selectById(deptId); |
| | | if (dept == null || dept.getDelFlag() != null && dept.getDelFlag() == 1) { |
| | | return List.of(); |
| | | } |
| | | List<Long> leaderIds = parseDeptLeaderIds(dept); |
| | | if (leaderIds.isEmpty()) { |
| | | return List.of(); |
| | | } |
| | | List<MpUser> leaders = |
| | | mpUserMapper.selectList( |
| | | new LambdaQueryWrapper<MpUser>() |
| | | .eq(MpUser::getDelFlag, 0) |
| | | .eq(MpUser::getStatus, 1) |
| | | .eq(MpUser::getUserType, MiniUserType.EMPLOYEE) |
| | | .in(MpUser::getId, leaderIds)); |
| | | Map<Long, MpUser> leaderMap = new LinkedHashMap<>(); |
| | | for (MpUser leader : leaders) { |
| | | leaderMap.put(leader.getId(), leader); |
| | | } |
| | | List<Long> result = new ArrayList<>(); |
| | | for (Long id : leaderIds) { |
| | | if (leaderMap.containsKey(id)) { |
| | | result.add(id); |
| | | } |
| | | } |
| | | return result; |
| | | } |
| | | |
| | | private List<Long> parseDeptLeaderIds(SysDept dept) { |
| | | List<Long> ids = new ArrayList<>(); |
| | | Set<Long> seen = new LinkedHashSet<>(); |
| | | if (StringUtils.hasText(dept.getLeaderIds())) { |
| | | for (String part : dept.getLeaderIds().split(",")) { |
| | | if (!StringUtils.hasText(part)) { |
| | | continue; |
| | | } |
| | | try { |
| | | Long id = Long.parseLong(part.trim()); |
| | | if (id > 0 && seen.add(id)) { |
| | | ids.add(id); |
| | | } |
| | | } catch (NumberFormatException ignored) { |
| | | } |
| | | } |
| | | } |
| | | return ids; |
| | | } |
| | | |
| | | private List<Long> listAllActiveEmployeeIdsByDept(Long deptId) { |
| | | if (deptId == null || deptId <= 0) { |
| | | return List.of(); |
| | | } |
| | |
| | | .eq(MpUser::getDelFlag, 0) |
| | | .eq(MpUser::getStatus, 1) |
| | | .eq(MpUser::getUserType, MiniUserType.EMPLOYEE) |
| | | .eq(MpUser::getDeptId, deptId) |
| | | .eq(MpUser::getDeptLeaderFlag, leaderFlag)); |
| | | return users.stream().map(MpUser::getId).filter(Objects::nonNull).toList(); |
| | | .eq(MpUser::getDeptId, deptId)); |
| | | return users.stream().map(MpUser::getId).filter(Objects::nonNull).distinct().toList(); |
| | | } |
| | | |
| | | private List<Long> listEmployeeIdsByDeptWithLeaderFallback(Long deptId) { |
| | | return listAllActiveEmployeeIdsByDept(deptId); |
| | | } |
| | | |
| | | @Transactional(rollbackFor = Exception.class) |
| | |
| | | inst.setStatus(ApprovalInstanceStatus.REJECTED); |
| | | inst.setFinishedAt(LocalDateTime.now()); |
| | | approvalInstanceMapper.updateById(inst); |
| | | List<ApprovalTask> remainingTasks = |
| | | approvalTaskMapper.selectList( |
| | | new LambdaQueryWrapper<ApprovalTask>() |
| | | .eq(ApprovalTask::getInstanceId, inst.getId()) |
| | | .in( |
| | | ApprovalTask::getTaskStatus, |
| | | ApprovalTaskStatus.PENDING, |
| | | ApprovalTaskStatus.WAITING)); |
| | | for (ApprovalTask t : remainingTasks) { |
| | | t.setTaskStatus(ApprovalTaskStatus.REJECTED); |
| | | t.setComment(null); |
| | | approvalTaskMapper.updateById(t); |
| | | } |
| | | } |
| | | |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void cancelInstance(ApprovalInstance inst, String reason) { |
| | | inst.setStatus(ApprovalInstanceStatus.CANCELLED); |
| | | inst.setFinishedAt(LocalDateTime.now()); |
| | | approvalInstanceMapper.updateById(inst); |
| | | List<ApprovalTask> pending = |
| | | approvalTaskMapper.selectList( |
| | | new LambdaQueryWrapper<ApprovalTask>() |
| | |
| | | ApprovalTaskStatus.PENDING, |
| | | ApprovalTaskStatus.WAITING)); |
| | | for (ApprovalTask t : pending) { |
| | | t.setTaskStatus(ApprovalTaskStatus.REJECTED); |
| | | t.setTaskStatus(ApprovalTaskStatus.CANCELLED); |
| | | t.setComment(reason); |
| | | approvalTaskMapper.updateById(t); |
| | | } |
| | |
| | | } |
| | | |
| | | private int createTasksForLocalUnitNode(Long instanceId, AppointmentOrder order, String initialStatus) { |
| | | List<Long> localUnitIds = parseLongJsonArray(order.getPassLocalUnitIds()); |
| | | if (localUnitIds.isEmpty()) { |
| | | return 0; |
| | | } |
| | | List<MpPassLocalUnit> units = |
| | | mpPassLocalUnitMapper.selectList( |
| | | new LambdaQueryWrapper<MpPassLocalUnit>() |
| | | .eq(MpPassLocalUnit::getDelFlag, 0) |
| | | .in(MpPassLocalUnit::getId, localUnitIds)); |
| | | if (units.isEmpty()) { |
| | | return 0; |
| | | } |
| | | Map<Long, MpPassLocalUnit> unitMap = |
| | | units.stream().collect(java.util.stream.Collectors.toMap(MpPassLocalUnit::getId, x -> x, (a, b) -> a)); |
| | | |
| | | LinkedHashSet<Long> deptIds = new LinkedHashSet<>(); |
| | | LinkedHashSet<Long> groupIds = new LinkedHashSet<>(); |
| | | LinkedHashMap<String, List<Long>> tempGroups = new LinkedHashMap<>(); |
| | | |
| | | for (Long unitId : localUnitIds) { |
| | | MpPassLocalUnit unit = unitMap.get(unitId); |
| | | if (unit == null || unit.getApproverType() == null) { |
| | | continue; |
| | | } |
| | | if (unit.getApproverType() == LocalUnitApproverType.DEPT) { |
| | | for (Long deptId : parseLongJsonArray(unit.getApproverDeptIds())) { |
| | | if (deptId != null && deptId > 0) { |
| | | deptIds.add(deptId); |
| | | } |
| | | } |
| | | continue; |
| | | } |
| | | if (unit.getApproverType() == LocalUnitApproverType.STAFF_GROUP) { |
| | | Long gid = unit.getApproverGroupId(); |
| | | if (gid != null && gid > 0) { |
| | | groupIds.add(gid); |
| | | } |
| | | continue; |
| | | } |
| | | if (unit.getApproverType() == LocalUnitApproverType.STAFF) { |
| | | List<MpPassLocalUnitMember> members = |
| | | mpPassLocalUnitMemberMapper.selectList( |
| | | new LambdaQueryWrapper<MpPassLocalUnitMember>() |
| | | .eq(MpPassLocalUnitMember::getDelFlag, 0) |
| | | .eq(MpPassLocalUnitMember::getUnitId, unitId) |
| | | .orderByAsc(MpPassLocalUnitMember::getId)); |
| | | LinkedHashSet<Long> mids = new LinkedHashSet<>(); |
| | | for (MpPassLocalUnitMember m : members) { |
| | | if (m.getMpUserId() != null && m.getMpUserId() > 0) { |
| | | mids.add(m.getMpUserId()); |
| | | } |
| | | } |
| | | if (mids.isEmpty()) { |
| | | continue; |
| | | } |
| | | List<Long> ordered = mids.stream().toList(); |
| | | String sign = buildTempGroupSign(ordered); |
| | | tempGroups.putIfAbsent(sign, ordered); |
| | | } |
| | | } |
| | | |
| | | List<LocalUnitApprovalGroup> groups = resolveLocalUnitApprovalGroups(order, false); |
| | | int total = 0; |
| | | for (Long deptId : deptIds) { |
| | | List<Long> assignees = listEmployeeIdsByDeptAndLeaderFlag(deptId, true); |
| | | String key = ApprovalNodeCode.LEVEL3_LOCAL_DEPT_LEADER + ":DEPT:" + deptId; |
| | | total += createTasksWithGroupKey(instanceId, ApprovalNodeCode.LEVEL3_LOCAL_DEPT_LEADER, key, assignees, initialStatus); |
| | | } |
| | | for (Long groupId : groupIds) { |
| | | List<MpStaffGroupMember> members = |
| | | mpStaffGroupMemberMapper.selectList( |
| | | new LambdaQueryWrapper<MpStaffGroupMember>() |
| | | .eq(MpStaffGroupMember::getDelFlag, 0) |
| | | .eq(MpStaffGroupMember::getGroupId, groupId) |
| | | .orderByAsc(MpStaffGroupMember::getId)); |
| | | LinkedHashSet<Long> mids = new LinkedHashSet<>(); |
| | | for (MpStaffGroupMember m : members) { |
| | | if (m.getMpUserId() != null && m.getMpUserId() > 0) { |
| | | mids.add(m.getMpUserId()); |
| | | } |
| | | } |
| | | List<Long> assignees = filterActiveEmployeeIds(mids.stream().toList()); |
| | | String key = ApprovalNodeCode.LEVEL3_LOCAL_DEPT_LEADER + ":GROUP:" + groupId; |
| | | total += createTasksWithGroupKey(instanceId, ApprovalNodeCode.LEVEL3_LOCAL_DEPT_LEADER, key, assignees, initialStatus); |
| | | } |
| | | for (Map.Entry<String, List<Long>> e : tempGroups.entrySet()) { |
| | | List<Long> assignees = filterActiveEmployeeIds(e.getValue()); |
| | | String key = ApprovalNodeCode.LEVEL3_LOCAL_DEPT_LEADER + ":TMP:" + e.getKey(); |
| | | total += createTasksWithGroupKey(instanceId, ApprovalNodeCode.LEVEL3_LOCAL_DEPT_LEADER, key, assignees, initialStatus); |
| | | for (LocalUnitApprovalGroup group : groups) { |
| | | total += |
| | | createTasksWithGroupKey( |
| | | instanceId, |
| | | ApprovalNodeCode.LEVEL3_LOCAL_DEPT_LEADER, |
| | | buildLocalUnitGroupKey(group.unitId()), |
| | | group.assigneeIds(), |
| | | initialStatus); |
| | | } |
| | | return total; |
| | | } |
| | |
| | | List<Long> assignees = resolveAssignees(nodeCode, order); |
| | | int created = createTasksWithGroupKey(inst.getId(), nodeCode, nodeCode, assignees, initialStatus); |
| | | if (created <= 0) { |
| | | throw new BizException(BizErrorCode.CONFIG_NOT_FOUND, "节点无审批人: " + nodeCode); |
| | | throw new BizException( |
| | | BizErrorCode.CONFIG_NOT_FOUND, |
| | | "节点无审批人: " + resolveNodeName(nodeCode)); |
| | | } |
| | | return created; |
| | | } |
| | |
| | | if (!Boolean.TRUE.equals(order.getInvolveOtherLocalUnit()) || localUnitIds.isEmpty()) { |
| | | throw new BizException( |
| | | BizErrorCode.CONFIG_NOT_FOUND, |
| | | "节点无审批人: " + ApprovalNodeCode.LEVEL3_LOCAL_DEPT_LEADER); |
| | | "节点无审批人: " + resolveNodeName(ApprovalNodeCode.LEVEL3_LOCAL_DEPT_LEADER)); |
| | | } |
| | | |
| | | List<LocalUnitApprovalGroup> groups = resolveLocalUnitApprovalGroups(order, true); |
| | | int total = 0; |
| | | for (LocalUnitApprovalGroup group : groups) { |
| | | total += |
| | | createTasksWithGroupKey( |
| | | instanceId, |
| | | ApprovalNodeCode.LEVEL3_LOCAL_DEPT_LEADER, |
| | | buildLocalUnitGroupKey(group.unitId()), |
| | | group.assigneeIds(), |
| | | initialStatus); |
| | | } |
| | | if (total <= 0) { |
| | | throw new BizException( |
| | | BizErrorCode.CONFIG_NOT_FOUND, |
| | | "节点无审批人: " + resolveNodeName(ApprovalNodeCode.LEVEL3_LOCAL_DEPT_LEADER)); |
| | | } |
| | | return total; |
| | | } |
| | | |
| | | private List<LocalUnitApprovalGroup> resolveLocalUnitApprovalGroups( |
| | | AppointmentOrder order, boolean strict) { |
| | | List<Long> localUnitIds = parseLongJsonArray(order.getPassLocalUnitIds()); |
| | | if (localUnitIds.isEmpty()) { |
| | | return List.of(); |
| | | } |
| | | List<MpPassLocalUnit> units = |
| | | mpPassLocalUnitMapper.selectList( |
| | | new LambdaQueryWrapper<MpPassLocalUnit>() |
| | | .eq(MpPassLocalUnit::getDelFlag, 0) |
| | | .in(MpPassLocalUnit::getId, localUnitIds)); |
| | | if (units.size() != localUnitIds.size()) { |
| | | throw new BizException(BizErrorCode.CONFIG_NOT_FOUND, "属地单位配置缺失,无法生成审批人"); |
| | | } |
| | | Map<Long, MpPassLocalUnit> unitMap = |
| | | units.stream() |
| | | .collect( |
| | | java.util.stream.Collectors.toMap( |
| | | MpPassLocalUnit::getId, x -> x, (a, b) -> a)); |
| | | if (strict && unitMap.size() != localUnitIds.size()) { |
| | | throw new BizException(BizErrorCode.CONFIG_NOT_FOUND, "属地单位配置缺失,无法生成审批人"); |
| | | } |
| | | |
| | | LinkedHashSet<Long> deptIds = new LinkedHashSet<>(); |
| | | LinkedHashSet<Long> groupIds = new LinkedHashSet<>(); |
| | | LinkedHashMap<String, List<Long>> tempGroups = new LinkedHashMap<>(); |
| | | |
| | | List<LocalUnitApprovalGroup> groups = new ArrayList<>(); |
| | | for (Long unitId : localUnitIds) { |
| | | MpPassLocalUnit unit = unitMap.get(unitId); |
| | | if (unit == null || unit.getApproverType() == null) { |
| | | if (unit == null) { |
| | | if (strict) { |
| | | throw new BizException(BizErrorCode.CONFIG_NOT_FOUND, "属地单位配置缺失,无法生成审批人"); |
| | | } |
| | | continue; |
| | | } |
| | | List<Long> assignees = resolveLocalUnitAssignees(unitId, unit, strict); |
| | | if (assignees.isEmpty()) { |
| | | continue; |
| | | } |
| | | groups.add(new LocalUnitApprovalGroup(unitId, assignees)); |
| | | } |
| | | return groups; |
| | | } |
| | | |
| | | private List<Long> resolveLocalUnitAssignees(Long unitId, MpPassLocalUnit unit, boolean strict) { |
| | | Integer approverType = unit.getApproverType(); |
| | | if (approverType == null) { |
| | | if (strict) { |
| | | throw new BizException(BizErrorCode.CONFIG_NOT_FOUND, "属地单位审批类型缺失: " + unitId); |
| | | } |
| | | if (unit.getApproverType() == LocalUnitApproverType.DEPT) { |
| | | List<Long> ids = parseLongJsonArray(unit.getApproverDeptIds()); |
| | | if (ids.isEmpty()) { |
| | | return List.of(); |
| | | } |
| | | if (approverType == LocalUnitApproverType.DEPT) { |
| | | List<Long> deptIds = parseLongJsonArray(unit.getApproverDeptIds()); |
| | | if (deptIds.isEmpty()) { |
| | | if (strict) { |
| | | throw new BizException(BizErrorCode.CONFIG_NOT_FOUND, "属地单位审批部门未配置: " + unitId); |
| | | } |
| | | deptIds.addAll(ids); |
| | | continue; |
| | | return List.of(); |
| | | } |
| | | if (unit.getApproverType() == LocalUnitApproverType.STAFF_GROUP) { |
| | | Long gid = unit.getApproverGroupId(); |
| | | if (gid == null || gid <= 0) { |
| | | LinkedHashSet<Long> assignees = new LinkedHashSet<>(); |
| | | for (Long deptId : deptIds) { |
| | | List<Long> deptApprovers = listAllActiveEmployeeIdsByDept(deptId); |
| | | if (strict && deptApprovers.isEmpty()) { |
| | | throw new BizException(BizErrorCode.CONFIG_NOT_FOUND, "审批部门无可用审批人: " + deptId); |
| | | } |
| | | assignees.addAll(deptApprovers); |
| | | } |
| | | return assignees.stream().toList(); |
| | | } |
| | | if (approverType == LocalUnitApproverType.STAFF_GROUP) { |
| | | Long groupId = unit.getApproverGroupId(); |
| | | if (groupId == null || groupId <= 0) { |
| | | if (strict) { |
| | | throw new BizException(BizErrorCode.CONFIG_NOT_FOUND, "属地单位审批分组未配置: " + unitId); |
| | | } |
| | | groupIds.add(gid); |
| | | continue; |
| | | return List.of(); |
| | | } |
| | | if (unit.getApproverType() == LocalUnitApproverType.STAFF) { |
| | | List<MpPassLocalUnitMember> members = |
| | | mpPassLocalUnitMemberMapper.selectList( |
| | | new LambdaQueryWrapper<MpPassLocalUnitMember>() |
| | | .eq(MpPassLocalUnitMember::getDelFlag, 0) |
| | | .eq(MpPassLocalUnitMember::getUnitId, unitId) |
| | | .orderByAsc(MpPassLocalUnitMember::getId)); |
| | | LinkedHashSet<Long> mids = new LinkedHashSet<>(); |
| | | for (MpPassLocalUnitMember m : members) { |
| | | if (m.getMpUserId() != null && m.getMpUserId() > 0) { |
| | | mids.add(m.getMpUserId()); |
| | | } |
| | | } |
| | | if (mids.isEmpty()) { |
| | | throw new BizException(BizErrorCode.CONFIG_NOT_FOUND, "属地单位审批人员未配置: " + unitId); |
| | | } |
| | | List<Long> ordered = mids.stream().toList(); |
| | | String sign = buildTempGroupSign(ordered); |
| | | tempGroups.putIfAbsent(sign, ordered); |
| | | continue; |
| | | } |
| | | throw new BizException(BizErrorCode.CONFIG_NOT_FOUND, "属地单位审批类型无效: " + unitId); |
| | | } |
| | | |
| | | int total = 0; |
| | | for (Long deptId : deptIds) { |
| | | List<Long> assignees = listEmployeeIdsByDeptAndLeaderFlag(deptId, true); |
| | | if (assignees.isEmpty()) { |
| | | throw new BizException(BizErrorCode.CONFIG_NOT_FOUND, "审批部门无负责人: " + deptId); |
| | | } |
| | | String key = ApprovalNodeCode.LEVEL3_LOCAL_DEPT_LEADER + ":DEPT:" + deptId; |
| | | total += |
| | | createTasksWithGroupKey( |
| | | instanceId, |
| | | ApprovalNodeCode.LEVEL3_LOCAL_DEPT_LEADER, |
| | | key, |
| | | assignees, |
| | | initialStatus); |
| | | } |
| | | for (Long groupId : groupIds) { |
| | | List<MpStaffGroupMember> members = |
| | | mpStaffGroupMemberMapper.selectList( |
| | | new LambdaQueryWrapper<MpStaffGroupMember>() |
| | |
| | | .eq(MpStaffGroupMember::getGroupId, groupId) |
| | | .orderByAsc(MpStaffGroupMember::getId)); |
| | | LinkedHashSet<Long> mids = new LinkedHashSet<>(); |
| | | for (MpStaffGroupMember m : members) { |
| | | if (m.getMpUserId() != null && m.getMpUserId() > 0) { |
| | | mids.add(m.getMpUserId()); |
| | | for (MpStaffGroupMember member : members) { |
| | | if (member.getMpUserId() != null && member.getMpUserId() > 0) { |
| | | mids.add(member.getMpUserId()); |
| | | } |
| | | } |
| | | List<Long> assignees = filterActiveEmployeeIds(mids.stream().toList()); |
| | | if (assignees.isEmpty()) { |
| | | if (strict && assignees.isEmpty()) { |
| | | throw new BizException(BizErrorCode.CONFIG_NOT_FOUND, "审批分组无有效成员: " + groupId); |
| | | } |
| | | String key = ApprovalNodeCode.LEVEL3_LOCAL_DEPT_LEADER + ":GROUP:" + groupId; |
| | | total += |
| | | createTasksWithGroupKey( |
| | | instanceId, |
| | | ApprovalNodeCode.LEVEL3_LOCAL_DEPT_LEADER, |
| | | key, |
| | | assignees, |
| | | initialStatus); |
| | | return assignees; |
| | | } |
| | | for (Map.Entry<String, List<Long>> e : tempGroups.entrySet()) { |
| | | List<Long> assignees = filterActiveEmployeeIds(e.getValue()); |
| | | if (assignees.isEmpty()) { |
| | | throw new BizException(BizErrorCode.CONFIG_NOT_FOUND, "临时审批组无有效成员"); |
| | | if (approverType == LocalUnitApproverType.STAFF) { |
| | | List<MpPassLocalUnitMember> members = |
| | | mpPassLocalUnitMemberMapper.selectList( |
| | | new LambdaQueryWrapper<MpPassLocalUnitMember>() |
| | | .eq(MpPassLocalUnitMember::getDelFlag, 0) |
| | | .eq(MpPassLocalUnitMember::getUnitId, unitId) |
| | | .orderByAsc(MpPassLocalUnitMember::getId)); |
| | | LinkedHashSet<Long> mids = new LinkedHashSet<>(); |
| | | for (MpPassLocalUnitMember member : members) { |
| | | if (member.getMpUserId() != null && member.getMpUserId() > 0) { |
| | | mids.add(member.getMpUserId()); |
| | | } |
| | | } |
| | | String key = ApprovalNodeCode.LEVEL3_LOCAL_DEPT_LEADER + ":TMP:" + e.getKey(); |
| | | total += |
| | | createTasksWithGroupKey( |
| | | instanceId, |
| | | ApprovalNodeCode.LEVEL3_LOCAL_DEPT_LEADER, |
| | | key, |
| | | assignees, |
| | | initialStatus); |
| | | List<Long> assignees = filterActiveEmployeeIds(mids.stream().toList()); |
| | | if (strict && assignees.isEmpty()) { |
| | | throw new BizException(BizErrorCode.CONFIG_NOT_FOUND, "属地单位审批人员未配置: " + unitId); |
| | | } |
| | | return assignees; |
| | | } |
| | | if (total <= 0) { |
| | | throw new BizException( |
| | | BizErrorCode.CONFIG_NOT_FOUND, |
| | | "节点无审批人: " + ApprovalNodeCode.LEVEL3_LOCAL_DEPT_LEADER); |
| | | if (strict) { |
| | | throw new BizException(BizErrorCode.CONFIG_NOT_FOUND, "属地单位审批类型无效: " + unitId); |
| | | } |
| | | return total; |
| | | return List.of(); |
| | | } |
| | | |
| | | private String buildLocalUnitGroupKey(Long unitId) { |
| | | return ApprovalNodeCode.LEVEL3_LOCAL_DEPT_LEADER + LOCAL_UNIT_GROUP_TOKEN + unitId; |
| | | } |
| | | |
| | | private String resolveNodeName(String nodeCode) { |
| | | if (!StringUtils.hasText(nodeCode)) { |
| | | return "未知节点"; |
| | | } |
| | | return switch (nodeCode) { |
| | | case ApprovalNodeCode.LEVEL1_HANDLER -> "经办人(一级)"; |
| | | case ApprovalNodeCode.LEVEL2_DEPT_LEADER -> "部门负责人(二级)"; |
| | | case ApprovalNodeCode.LEVEL3_LOCAL_DEPT_LEADER -> "属地管理部门领导(三级)"; |
| | | case ApprovalNodeCode.LEVEL4_VISIT_DEPT -> "访客主管部门(四级)"; |
| | | case ApprovalNodeCode.LEVEL5_VISIT_DEPT_LEADER -> "访客主管部门领导(五级)"; |
| | | default -> nodeCode; |
| | | }; |
| | | } |
| | | |
| | | private int createTasksWithGroupKey( |
| | |
| | | return out; |
| | | } |
| | | |
| | | private String buildTempGroupSign(List<Long> memberIds) { |
| | | String joined = memberIds.stream().map(String::valueOf).collect(java.util.stream.Collectors.joining("-")); |
| | | if (joined.length() <= 40) { |
| | | return joined; |
| | | } |
| | | return Integer.toHexString(joined.hashCode()); |
| | | } |
| | | private record LocalUnitApprovalGroup(Long unitId, List<Long> assigneeIds) {} |
| | | } |