Files
xgy-oa/klp-wms/src/main/java/com/klp/service/impl/WmsApprovalServiceImpl.java
Joshi 584839ec67 refactor(wms): 外出申请默认创建单条任务
- 将通用审批任务创建方法拆分为请假和外出专用方法
- 新增 createOutApprovalTasks 方法处理外出审批流程
- 新增 createLeaveApprovalTasks 方法处理请假审批流程
- 优化导入语句,使用通配符导入 domain 包下的所有类
- 移除未使用的 WmsApproval、WmsLeaveRequest 和 WmsDept 导入
- 为外出审批添加部门领导查询和审批任务创建逻辑
2026-03-02 15:20:38 +08:00

501 lines
20 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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.*;
import com.klp.mapper.*;
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.bo.WmsApprovalTaskBo;
import com.klp.domain.vo.WmsApprovalTaskVo;
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.domain.vo.WmsLeaveRequestVo;
import com.klp.domain.vo.WmsOutRequestVo;
/**
* 通用审批(支持请假/外出等申请的审批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 WmsDeptMapper wmsDeptMapper;
private final SysUserMapper userMapper;
/**
* 查询通用审批(支持请假/外出等申请的审批)
*/
@Override
public Map<String, Object> queryById(Long approvalId){
Map<String, Object> 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<String, String> 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<String, String> 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<Map<String, Object>> queryPageList(WmsApprovalBo bo, PageQuery pageQuery) {
LambdaQueryWrapper<WmsApproval> lqw = buildQueryWrapper(bo);
// 1. 查询审批列表分页数据
Page<WmsApprovalVo> approvalPage = baseMapper.selectVoPage(pageQuery.build(), lqw);
List<WmsApprovalVo> approvalList = approvalPage.getRecords();
if (CollectionUtil.isEmpty(approvalList)) {
Page<Map<String, Object>> 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<Long> approvalIds = approvalList.stream()
.map(WmsApprovalVo::getApprovalId)
.collect(Collectors.toList());
// 2.1 批量查询所有审批任务
List<WmsApprovalTaskVo> allTasks = approvalTaskMapper.selectVoList(
Wrappers.<com.klp.domain.WmsApprovalTask>lambdaQuery()
.in(com.klp.domain.WmsApprovalTask::getApprovalId, approvalIds)
.orderByAsc(com.klp.domain.WmsApprovalTask::getCreateTime)
);
// 2.2 按审批ID分组任务
Map<Long, List<WmsApprovalTaskVo>> tasksMap = allTasks.stream()
.collect(Collectors.groupingBy(WmsApprovalTaskVo::getApprovalId));
// 3. 处理审批列表,拼接请假/外出详情,并收集所有需要转换的创建人账号
List<Map<String, Object>> resultList = new ArrayList<>();
Set<String> userNames = new HashSet<>(); // 存储所有需要查询昵称的账号
for (WmsApprovalVo approval : approvalList) {
Map<String, Object> item = new HashMap<>();
item.put("approval", approval); // 审批基础信息
// 3.1 添加审批任务列表
List<WmsApprovalTaskVo> 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<String, String> nickMap = Collections.emptyMap();
if (!userNames.isEmpty()) {
nickMap = userService.selectNickNameMapByUserNames(new ArrayList<>(userNames));
}
// 6. 遍历填充请假/外出申请的创建人昵称
for (Map<String, Object> 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<Map<String, Object>> 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<WmsApprovalVo> queryList(WmsApprovalBo bo) {
LambdaQueryWrapper<WmsApproval> lqw = buildQueryWrapper(bo);
return baseMapper.selectVoList(lqw);
}
private LambdaQueryWrapper<WmsApproval> buildQueryWrapper(WmsApprovalBo bo) {
Map<String, Object> params = bo.getParams();
LambdaQueryWrapper<WmsApproval> 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) {
createLeaveApprovalTasks(add.getApprovalId(), add.getApplyId(), add.getApplyType(), add.getApprovalType(), bo.getDeptId());
}
if ("out".equals(add.getApplyType()) && add.getApplyId() != null) {
createOutApprovalTasks(add.getApprovalId(), add.getApplyId(), add.getApplyType(), add.getApprovalType(), bo.getDeptId());
}
}
return flag;
}
private void createOutApprovalTasks(Long approvalId, Long applyId, String applyType, String approvalType, Long deptId) {
if (!"out".equals(applyType)) {
return;
}
WmsOutRequest outRequest = outRequestMapper.selectById(applyId);
if (outRequest == null) {
return;
}
WmsApproval updateApproval = new WmsApproval();
updateApproval.setApprovalId(approvalId);
updateApproval.setApprovalType(approvalType);
updateApproval.setRequiredApprovers(1);
// 根据applicantId查询审批人name和id
WmsDept dept = wmsDeptMapper.selectById(deptId);
SysUser leader = userMapper.selectById(dept.getLeader());
if (leader != null) {
WmsApprovalTaskBo taskBo = new WmsApprovalTaskBo();
taskBo.setApprovalId(approvalId);
taskBo.setApproverId(dept.getLeader());
taskBo.setApproverName(leader.getNickName());
taskBo.setTaskStatus("pending");
approvalTaskMapper.insert(BeanUtil.toBean(taskBo, WmsApprovalTask.class));
}
baseMapper.updateById(updateApproval);
}
private void createLeaveApprovalTasks(Long approvalId, Long applyId, String applyType, String approvalType, Long deptId) {
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<Long> leaderUserIds = getDeptLeaders(deptId);
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);
// 根据applicantId查询审批人name和id
WmsDept dept = wmsDeptMapper.selectById(deptId);
SysUser leader = userMapper.selectById(dept.getLeader());
if (leader != null) {
WmsApprovalTaskBo taskBo = new WmsApprovalTaskBo();
taskBo.setApprovalId(approvalId);
taskBo.setApproverId(dept.getLeader());
taskBo.setApproverName(leader.getNickName());
taskBo.setTaskStatus("pending");
approvalTaskMapper.insert(BeanUtil.toBean(taskBo, WmsApprovalTask.class));
}
}
baseMapper.updateById(updateApproval);
}
private List<Long> getDeptLeaders(Long deptId) {
List<Long> leaderUserIds = new ArrayList<>();
if (deptId == null) {
return leaderUserIds;
}
// 获取部门的所有祖先部门ID包括自己
List<Long> ancestorDeptIds = new ArrayList<>();
Long currentDeptId = deptId;
while (currentDeptId != null) {
ancestorDeptIds.add(currentDeptId);
WmsDept currentDept = wmsDeptMapper.selectById(currentDeptId);
if (currentDept != null) {
currentDeptId = currentDept.getParentId();
} else {
break;
}
}
// 查询每个祖先部门的leader字段内容
if (!ancestorDeptIds.isEmpty()) {
List<WmsDept> ancestorDepts = wmsDeptMapper.selectList(new LambdaQueryWrapper<WmsDept>()
.in(WmsDept::getDeptId, ancestorDeptIds));
if (CollectionUtil.isNotEmpty(ancestorDepts)) {
// 提取所有leader字段的内容
leaderUserIds = ancestorDepts.stream()
.map(WmsDept::getLeader)
.filter(Objects::nonNull)
.distinct()
.collect(Collectors.toList());
// // 根据leader名称查询对应的用户ID
// if (!leaderNames.isEmpty()) {
// List<SysUser> leaders = userMapper.selectList(new LambdaQueryWrapper<SysUser>()
// .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<Long> ids, Boolean isValid) {
if(isValid){
//TODO 做一些业务上的校验,判断是否需要校验
}
return baseMapper.deleteBatchIds(ids) > 0;
}
@Override
@Transactional(rollbackFor = Exception.class)
public Map<String, Object> approveTask(Long taskId, String approvalOpinion) {
Map<String, Object> 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<String, Object> rejectTask(Long taskId, String approvalOpinion) {
Map<String, Object> 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;
}
}