package com.klp.service.impl; import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.collection.CollectionUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.klp.common.core.domain.model.LoginUser; import com.klp.common.core.page.TableDataInfo; import com.klp.common.core.domain.PageQuery; import com.klp.common.core.domain.entity.SysDept; import com.klp.common.core.domain.entity.SysUser; import com.klp.common.core.service.UserService; import com.klp.common.helper.LoginHelper; import com.klp.common.utils.StringUtils; import com.klp.domain.WmsApprovalTask; import com.klp.system.mapper.SysDeptMapper; import com.klp.system.mapper.SysUserMapper; import com.klp.system.service.ISysUserService; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import com.klp.domain.bo.WmsApprovalBo; import com.klp.domain.vo.WmsApprovalVo; import com.klp.domain.WmsApproval; import com.klp.domain.bo.WmsApprovalTaskBo; import com.klp.domain.vo.WmsApprovalTaskVo; import com.klp.mapper.WmsApprovalMapper; import com.klp.mapper.WmsApprovalTaskMapper; import com.klp.service.IWmsApprovalService; import com.klp.service.IWmsApprovalTaskService; import java.math.BigDecimal; import java.util.*; import java.util.stream.Collectors; import com.klp.mapper.WmsLeaveRequestMapper; import com.klp.mapper.WmsOutRequestMapper; import com.klp.domain.vo.WmsLeaveRequestVo; import com.klp.domain.vo.WmsOutRequestVo; import com.klp.domain.WmsLeaveRequest; /** * 通用审批(支持请假/外出等申请的审批)Service业务层处理 * * @author klp * @date 2026-01-20 */ @RequiredArgsConstructor @Service public class WmsApprovalServiceImpl implements IWmsApprovalService { private final WmsApprovalMapper baseMapper; private final WmsApprovalTaskMapper approvalTaskMapper; private final WmsLeaveRequestMapper leaveRequestMapper; private final WmsOutRequestMapper outRequestMapper; private final ISysUserService userService; private final SysDeptMapper deptMapper; private final SysUserMapper userMapper; /** * 查询通用审批(支持请假/外出等申请的审批) */ @Override public Map queryById(Long approvalId){ Map result = new HashMap<>(); WmsApprovalVo approval = baseMapper.selectVoById(approvalId); if (approval == null) { return result; } result.put("approval", approval); String type = approval.getApplyType(); Long applyId = approval.getApplyId(); if (StringUtils.isNotBlank(type) && applyId != null) { if ("leave".equalsIgnoreCase(type)) { WmsLeaveRequestVo detail = leaveRequestMapper.selectVoById(applyId); // 详情接口也可以补充昵称转换(可选) if (detail != null && StringUtils.isNotBlank(detail.getCreateBy())) { Map nickMap = userService.selectNickNameMapByUserNames(Collections.singletonList(detail.getCreateBy())); detail.setCreateByName(nickMap.getOrDefault(detail.getCreateBy(), detail.getCreateBy())); } result.put("detail", detail); result.put("applyType", "leave"); } else if ("out".equalsIgnoreCase(type)) { WmsOutRequestVo outDetail = outRequestMapper.selectVoById(applyId); // 详情接口也可以补充昵称转换(可选) if (outDetail != null && StringUtils.isNotBlank(outDetail.getCreateBy())) { Map nickMap = userService.selectNickNameMapByUserNames(Collections.singletonList(outDetail.getCreateBy())); outDetail.setCreateByName(nickMap.getOrDefault(outDetail.getCreateBy(), outDetail.getCreateBy())); } result.put("detail", outDetail); result.put("applyType", "out"); } } return result; } /** * 查询通用审批列表(含请假/外出详情+创建人昵称转换+审批任务) */ @Override public TableDataInfo> queryPageList(WmsApprovalBo bo, PageQuery pageQuery) { LambdaQueryWrapper lqw = buildQueryWrapper(bo); // 1. 查询审批列表分页数据 Page approvalPage = baseMapper.selectVoPage(pageQuery.build(), lqw); List approvalList = approvalPage.getRecords(); if (CollectionUtil.isEmpty(approvalList)) { Page> emptyResultPage = new Page<>(); emptyResultPage.setRecords(new ArrayList<>()); emptyResultPage.setTotal(approvalPage.getTotal()); emptyResultPage.setSize(approvalPage.getSize()); emptyResultPage.setCurrent(approvalPage.getCurrent()); emptyResultPage.setPages(approvalPage.getPages()); return TableDataInfo.build(emptyResultPage); } // 2. 收集所有审批ID,用于查询审批任务 List approvalIds = approvalList.stream() .map(WmsApprovalVo::getApprovalId) .collect(Collectors.toList()); // 2.1 批量查询所有审批任务 List allTasks = approvalTaskMapper.selectVoList( Wrappers.lambdaQuery() .in(com.klp.domain.WmsApprovalTask::getApprovalId, approvalIds) .orderByAsc(com.klp.domain.WmsApprovalTask::getCreateTime) ); // 2.2 按审批ID分组任务 Map> tasksMap = allTasks.stream() .collect(Collectors.groupingBy(WmsApprovalTaskVo::getApprovalId)); // 3. 处理审批列表,拼接请假/外出详情,并收集所有需要转换的创建人账号 List> resultList = new ArrayList<>(); Set userNames = new HashSet<>(); // 存储所有需要查询昵称的账号 for (WmsApprovalVo approval : approvalList) { Map item = new HashMap<>(); item.put("approval", approval); // 审批基础信息 // 3.1 添加审批任务列表 List tasks = tasksMap.getOrDefault(approval.getApprovalId(), new ArrayList<>()); item.put("tasks", tasks); String applyType = approval.getApplyType(); Long applyId = approval.getApplyId(); Object detail = null; // 4. 查询请假/外出详情,并收集创建人账号 if (StringUtils.isNotBlank(applyType) && applyId != null) { if ("leave".equalsIgnoreCase(applyType)) { WmsLeaveRequestVo leaveDetail = leaveRequestMapper.selectVoById(applyId); detail = leaveDetail; // 收集请假申请的创建人账号 if (leaveDetail != null && StringUtils.isNotBlank(leaveDetail.getCreateBy())) { userNames.add(leaveDetail.getCreateBy()); } item.put("applyType", "leave"); } else if ("out".equalsIgnoreCase(applyType)) { WmsOutRequestVo outDetail = outRequestMapper.selectVoById(applyId); detail = outDetail; // 收集外出申请的创建人账号 if (outDetail != null && StringUtils.isNotBlank(outDetail.getCreateBy())) { userNames.add(outDetail.getCreateBy()); } item.put("applyType", "out"); } item.put("detail", detail); } resultList.add(item); } // 5. 批量查询昵称映射 Map nickMap = Collections.emptyMap(); if (!userNames.isEmpty()) { nickMap = userService.selectNickNameMapByUserNames(new ArrayList<>(userNames)); } // 6. 遍历填充请假/外出申请的创建人昵称 for (Map item : resultList) { Object detail = item.get("detail"); if (detail == null || nickMap.isEmpty()) { continue; } // 区分请假/外出类型,填充创建人昵称 if ("leave".equals(item.get("applyType"))) { WmsLeaveRequestVo leaveDetail = (WmsLeaveRequestVo) detail; if (StringUtils.isNotBlank(leaveDetail.getCreateBy())) { // 填充创建人昵称 leaveDetail.setCreateByName(nickMap.getOrDefault(leaveDetail.getCreateBy(), leaveDetail.getCreateBy())); } } else if ("out".equals(item.get("applyType"))) { WmsOutRequestVo outDetail = (WmsOutRequestVo) detail; if (StringUtils.isNotBlank(outDetail.getCreateBy())) { outDetail.setCreateByName(nickMap.getOrDefault(outDetail.getCreateBy(), outDetail.getCreateBy())); } } } // 7. 构建分页返回结果 Page> resultPage = new Page<>(); resultPage.setRecords(resultList); resultPage.setTotal(approvalPage.getTotal()); resultPage.setSize(approvalPage.getSize()); resultPage.setCurrent(approvalPage.getCurrent()); resultPage.setPages(approvalPage.getPages()); return TableDataInfo.build(resultPage); } /** * 查询通用审批(支持请假/外出等申请的审批)列表 */ @Override public List queryList(WmsApprovalBo bo) { LambdaQueryWrapper lqw = buildQueryWrapper(bo); return baseMapper.selectVoList(lqw); } private LambdaQueryWrapper buildQueryWrapper(WmsApprovalBo bo) { Map params = bo.getParams(); LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); lqw.eq(StringUtils.isNotBlank(bo.getApplyType()), WmsApproval::getApplyType, bo.getApplyType()); lqw.eq(bo.getApplyId() != null, WmsApproval::getApplyId, bo.getApplyId()); lqw.like(StringUtils.isNotBlank(bo.getApproverName()), WmsApproval::getApproverName, bo.getApproverName()); lqw.eq(StringUtils.isNotBlank(bo.getApprovalStatus()), WmsApproval::getApprovalStatus, bo.getApprovalStatus()); lqw.eq(StringUtils.isNotBlank(bo.getApprovalOpinion()), WmsApproval::getApprovalOpinion, bo.getApprovalOpinion()); lqw.eq(bo.getApprovalTime() != null, WmsApproval::getApprovalTime, bo.getApprovalTime()); // 根据创建时间倒叙 lqw.orderByDesc(WmsApproval::getCreateTime); return lqw; } /** * 新增通用审批(支持请假/外出等申请的审批) */ @Override @Transactional(rollbackFor = Exception.class) public Boolean insertByBo(WmsApprovalBo bo) { WmsApproval add = BeanUtil.toBean(bo, WmsApproval.class); validEntityBeforeSave(add); if (add.getApprovalType() == null) { add.setApprovalType("single"); } if (add.getRequiredApprovers() == null) { add.setRequiredApprovers(0); } if (add.getCurrentApprovers() == null) { add.setCurrentApprovers(0); } if (add.getFinalStatus() == null) { add.setFinalStatus("pending"); } boolean flag = baseMapper.insert(add) > 0; if (flag) { bo.setApprovalId(add.getApprovalId()); if ("leave".equals(add.getApplyType()) && add.getApplyId() != null) { createApprovalTasks(add.getApprovalId(), add.getApplyId(), add.getApplyType(),add.getApprovalType()); } } return flag; } private void createApprovalTasks(Long approvalId, Long applyId, String applyType, String approvalType) { if (!"leave".equals(applyType)) { return; } WmsLeaveRequest leaveRequest = leaveRequestMapper.selectById(applyId); if (leaveRequest == null) { return; } boolean isMultiLevel = approvalType.equals("multi"); WmsApproval updateApproval = new WmsApproval(); updateApproval.setApprovalId(approvalId); updateApproval.setApprovalType(approvalType); if (isMultiLevel) { List leaderUserIds = getDeptLeaders(leaveRequest.getApplicantDeptName()); updateApproval.setRequiredApprovers(leaderUserIds.size()); for (Long leaderUserId : leaderUserIds) { SysUser leaderUser = userMapper.selectById(leaderUserId); if (leaderUser != null) { WmsApprovalTaskBo taskBo = new WmsApprovalTaskBo(); taskBo.setApprovalId(approvalId); taskBo.setApproverId(leaderUserId); taskBo.setApproverName(leaderUser.getNickName()); taskBo.setTaskStatus("pending"); approvalTaskMapper.insert(BeanUtil.toBean(taskBo, WmsApprovalTask.class)); } } } else { updateApproval.setRequiredApprovers(1); LoginUser currentUser = LoginHelper.getLoginUser(); if (currentUser != null) { WmsApprovalTaskBo taskBo = new WmsApprovalTaskBo(); taskBo.setApprovalId(approvalId); taskBo.setApproverId(LoginHelper.getUserId()); taskBo.setApproverName(LoginHelper.getNickName()); taskBo.setTaskStatus("pending"); approvalTaskMapper.insert(BeanUtil.toBean(taskBo, WmsApprovalTask.class)); } } baseMapper.updateById(updateApproval); } private List getDeptLeaders(String applicantDeptName) { List leaderUserIds = new ArrayList<>(); if (StringUtils.isBlank(applicantDeptName)) { return leaderUserIds; } // 根据部门名称查询部门信息 SysDept dept = deptMapper.selectOne(new LambdaQueryWrapper() .eq(SysDept::getDeptName, applicantDeptName)); if (dept == null) { return leaderUserIds; } // 获取部门的所有祖先部门ID(包括自己) List ancestorDeptIds = new ArrayList<>(); Long currentDeptId = dept.getDeptId(); while (currentDeptId != null) { ancestorDeptIds.add(currentDeptId); SysDept currentDept = deptMapper.selectById(currentDeptId); if (currentDept != null) { currentDeptId = currentDept.getParentId(); } else { break; } } // 查询每个祖先部门的leader字段内容 if (!ancestorDeptIds.isEmpty()) { List ancestorDepts = deptMapper.selectList(new LambdaQueryWrapper() .in(SysDept::getDeptId, ancestorDeptIds)); if (CollectionUtil.isNotEmpty(ancestorDepts)) { // 提取所有leader字段的内容 List leaderNames = ancestorDepts.stream() .map(SysDept::getLeader) .filter(StringUtils::isNotBlank) .distinct() .collect(Collectors.toList()); // 根据leader名称查询对应的用户ID if (!leaderNames.isEmpty()) { List leaders = userMapper.selectList(new LambdaQueryWrapper() .in(SysUser::getNickName, leaderNames)); if (CollectionUtil.isNotEmpty(leaders)) { leaderUserIds = leaders.stream() .map(SysUser::getUserId) .distinct() .collect(Collectors.toList()); } } } } return leaderUserIds; } /** * 修改通用审批(支持请假/外出等申请的审批) */ @Override public Boolean updateByBo(WmsApprovalBo bo) { WmsApproval update = BeanUtil.toBean(bo, WmsApproval.class); validEntityBeforeSave(update); return baseMapper.updateById(update) > 0; } /** * 保存前的数据校验 */ private void validEntityBeforeSave(WmsApproval entity){ //TODO 做一些数据校验,如唯一约束 } /** * 批量删除通用审批(支持请假/外出等申请的审批) */ @Override public Boolean deleteWithValidByIds(Collection ids, Boolean isValid) { if(isValid){ //TODO 做一些业务上的校验,判断是否需要校验 } return baseMapper.deleteBatchIds(ids) > 0; } @Override @Transactional(rollbackFor = Exception.class) public Map approveTask(Long taskId, String approvalOpinion) { Map result = new HashMap<>(); com.klp.domain.WmsApprovalTask task = approvalTaskMapper.selectById(taskId); if (task == null) { result.put("success", false); result.put("message", "审批任务不存在"); return result; } if (!"pending".equals(task.getTaskStatus())) { result.put("success", false); result.put("message", "该任务已审批,不能重复审批"); return result; } task.setTaskStatus("approved"); task.setApprovalOpinion(approvalOpinion); task.setApprovalTime(new Date()); approvalTaskMapper.updateById(task); WmsApproval approval = baseMapper.selectById(task.getApprovalId()); if (approval != null) { int currentApprovers = (approval.getCurrentApprovers() != null ? approval.getCurrentApprovers() : 0) + 1; approval.setCurrentApprovers(currentApprovers); if (currentApprovers >= approval.getRequiredApprovers()) { approval.setApprovalStatus("已同意"); approval.setFinalStatus("all_approved"); } baseMapper.updateById(approval); } result.put("success", true); result.put("message", "审批通过"); return result; } @Override @Transactional(rollbackFor = Exception.class) public Map rejectTask(Long taskId, String approvalOpinion) { Map result = new HashMap<>(); com.klp.domain.WmsApprovalTask task = approvalTaskMapper.selectById(taskId); if (task == null) { result.put("success", false); result.put("message", "审批任务不存在"); return result; } if (!"pending".equals(task.getTaskStatus())) { result.put("success", false); result.put("message", "该任务已审批,不能重复审批"); return result; } task.setTaskStatus("rejected"); task.setApprovalOpinion(approvalOpinion); task.setApprovalTime(new Date()); approvalTaskMapper.updateById(task); WmsApproval approval = baseMapper.selectById(task.getApprovalId()); if (approval != null) { approval.setApprovalStatus("已驳回"); approval.setFinalStatus("rejected"); baseMapper.updateById(approval); } result.put("success", true); result.put("message", "审批驳回"); return result; } }