Files
klp-oa/klp-wms/src/main/java/com/klp/service/impl/WmsDeliveryPlanServiceImpl.java
Joshi 83b11860cc feat(delivery): 实现发货计划和发货明细的级联删除功能
- 在WmsDeliveryPlanServiceImpl中添加LambdaUpdateWrapper导入
- 为发货计划删除操作添加级联删除逻辑,遍历计划ID并删除相关发货单及明细
- 新增cascadeDeleteDeliveryWaybillsByPlanId方法处理发货单及其明细的级联删除
- 在WmsDeliveryWaybillServiceImpl中添加WmsDeliveryWaybillDetail和WmsDeliveryWaybillDetailMapper依赖
- 为发货单删除操作添加级联删除发货单明细的功能
- 使用LambdaQueryWrapper构建查询条件删除关联的发货单明细记录
2026-01-28 11:00:32 +08:00

336 lines
13 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 com.klp.common.core.domain.entity.SysUser;
import com.klp.common.core.page.TableDataInfo;
import com.klp.common.core.domain.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.klp.common.exception.ServiceException;
import com.klp.common.utils.StringUtils;
import com.klp.domain.*;
import com.klp.domain.vo.*;
import com.klp.mapper.*;
import com.klp.system.service.ISysUserService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import com.klp.domain.bo.WmsDeliveryPlanBo;
import com.klp.service.IWmsDeliveryPlanService;
import java.util.*;
import java.util.stream.Collectors;
/**
* 发货计划Service业务层处理
*
* @author klp
* @date 2025-11-25
*/
@RequiredArgsConstructor
@Service
public class WmsDeliveryPlanServiceImpl implements IWmsDeliveryPlanService {
private final WmsDeliveryPlanMapper baseMapper;
private final ISysUserService userService;
private final WmsMaterialCoilMapper coilMapper;
private final WmsDeliveryWaybillMapper waybillMapper;
private final WmsDeliveryWaybillDetailMapper waybillDetailMapper;
private final WmsCoilPendingActionMapper coilPendingActionMapper;
/**
* 查询发货计划
*/
@Override
public WmsDeliveryPlanVo queryById(Long planId){
return baseMapper.selectVoById(planId);
}
/**
* 查询发货计划列表
*/
@Override
public TableDataInfo<WmsDeliveryPlanVo> queryPageList(WmsDeliveryPlanBo bo, PageQuery pageQuery) {
LambdaQueryWrapper<WmsDeliveryPlan> lqw = buildQueryWrapper(bo);
Page<WmsDeliveryPlanVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
List<WmsDeliveryPlanVo> records = result.getRecords();
Set<String> userNames = records.stream()
.flatMap(v -> java.util.stream.Stream.of(v.getCreateBy(), v.getUpdateBy()))
.filter(StringUtils::isNotBlank)
.collect(Collectors.toSet());
if (!userNames.isEmpty()) {
Map<String, String> nickMap = userService.selectNickNameMapByUserNames(records.stream()
.flatMap(v -> java.util.stream.Stream.of(v.getCreateBy(), v.getUpdateBy()))
.filter(StringUtils::isNotBlank)
.distinct()
.collect(Collectors.toList()));
records.forEach(item -> {
if (StringUtils.isNotBlank(item.getCreateBy())) {
item.setCreateByName(nickMap.getOrDefault(item.getCreateBy(), item.getCreateBy()));
}
if (StringUtils.isNotBlank(item.getUpdateBy())) {
item.setUpdateByName(nickMap.getOrDefault(item.getUpdateBy(), item.getUpdateBy()));
}
});
}
return TableDataInfo.build(result);
}
/**
* 查询发货计划列表
*/
@Override
public List<WmsDeliveryPlanVo> queryList(WmsDeliveryPlanBo bo) {
LambdaQueryWrapper<WmsDeliveryPlan> lqw = buildQueryWrapper(bo);
return baseMapper.selectVoList(lqw);
}
private LambdaQueryWrapper<WmsDeliveryPlan> buildQueryWrapper(WmsDeliveryPlanBo bo) {
Map<String, Object> params = bo.getParams();
LambdaQueryWrapper<WmsDeliveryPlan> lqw = Wrappers.lambdaQuery();
lqw.like(StringUtils.isNotBlank(bo.getPlanName()), WmsDeliveryPlan::getPlanName, bo.getPlanName());
lqw.eq(bo.getPlanDate() != null, WmsDeliveryPlan::getPlanDate, bo.getPlanDate());
lqw.eq(bo.getPlanType() != null, WmsDeliveryPlan::getPlanType, bo.getPlanType());
lqw.eq(bo.getAuditStatus() != null, WmsDeliveryPlan::getAuditStatus, bo.getAuditStatus());
// 计划根据plan_date降序排序最新的放在最前面
lqw.orderByDesc(WmsDeliveryPlan::getPlanDate);
return lqw;
}
/**
* 新增发货计划
*/
@Override
public Boolean insertByBo(WmsDeliveryPlanBo bo) {
WmsDeliveryPlan add = BeanUtil.toBean(bo, WmsDeliveryPlan.class);
validEntityBeforeSave(add);
boolean flag = baseMapper.insert(add) > 0;
if (flag) {
bo.setPlanId(add.getPlanId());
}
return flag;
}
/**
* 修改发货计划
*/
@Override
public Boolean updateByBo(WmsDeliveryPlanBo bo) {
WmsDeliveryPlan update = BeanUtil.toBean(bo, WmsDeliveryPlan.class);
validEntityBeforeSave(update);
return baseMapper.updateById(update) > 0;
}
/**
* 保存前的数据校验
*/
private void validEntityBeforeSave(WmsDeliveryPlan entity){
//TODO 做一些数据校验,如唯一约束
}
/**
* 批量删除发货计划
*/
@Override
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
if (isValid) {
// 检查是否有关联的收货计划明细actionType为401的操作记录
for (Long planId : ids) {
// 查询与该计划关联的待操作记录
List<WmsCoilPendingAction> pendingActions = coilPendingActionMapper.selectList(
Wrappers.<WmsCoilPendingAction>lambdaQuery()
.eq(WmsCoilPendingAction::getActionType, 401)
.eq(WmsCoilPendingAction::getWarehouseId, planId)
.eq(WmsCoilPendingAction::getDelFlag, 0)
);
// 如果有待操作记录,检查这些记录关联的钢卷是否至少有一个还存在
if (!pendingActions.isEmpty()) {
boolean hasValidCoil = false;
for (WmsCoilPendingAction pendingAction : pendingActions) {
// 检查关联的钢卷是否还存在(未被删除)
WmsMaterialCoil coil = coilMapper.selectOne(
Wrappers.<WmsMaterialCoil>lambdaQuery()
.eq(WmsMaterialCoil::getCoilId, pendingAction.getCoilId())
.eq(WmsMaterialCoil::getDelFlag, 0)
);
// 如果存在任意一个未被删除的钢卷,标记为不允许删除
if (coil != null) {
hasValidCoil = true;
break; // 只要有一个存在就无需继续检查
}
}
// 只要有一个关联的钢卷还存在,就不允许删除计划
if (hasValidCoil) {
throw new ServiceException("计划下存在有效明细,无法删除");
}
}
}
}
// 对于发货计划planType = 0需要先级联删除相关的发货单及明细
// 遍历所有要删除的计划,对发货计划进行级联删除
for (Long planId : ids) {
WmsDeliveryPlan plan = baseMapper.selectById(planId);
if (plan != null && plan.getPlanType() != null && plan.getPlanType() == 0) { // 发货计划
// 删除关联的发货单及明细
cascadeDeleteDeliveryWaybillsByPlanId(planId);
}
}
return baseMapper.deleteBatchIds(ids) > 0;
}
/**
* 获取发货计划统计信息
*
* @param planId 计划ID可选
* @return 统计信息列表
*/
public List<WmsDeliveryPlanStatisticsVo> getDeliveryPlanStatistics(Long planId) {
return baseMapper.selectDeliveryPlanStatistics(planId);
}
/**
* 获取发货报表统计信息
*
* @param startTime 开始时间
* @param endTime 结束时间
* @return 报表统计信息(包含汇总和按类型统计)
*/
public WmsDeliveryReportResultVo getDeliveryReport(Date startTime, Date endTime) {
WmsDeliveryReportResultVo result = new WmsDeliveryReportResultVo();
// 获取汇总数据
WmsDeliveryReportSummaryVo summary = baseMapper.selectDeliveryReportSummary(startTime, endTime);
result.setSummary(summary);
// 获取按钢卷类型分类的数据
List<WmsDeliveryReportByTypeVo> details = baseMapper.selectDeliveryReportByType(startTime, endTime);
result.setDetails(details);
return result;
}
/**
* 获取收货报表统计信息
*/
@Override
public WmsReceivingReportResultVo getReceivingReport(Date startTime, Date endTime) {
WmsReceivingReportResultVo result = new WmsReceivingReportResultVo();
WmsReceivingReportSummaryVo summary = baseMapper.selectReceivingReportSummary(startTime, endTime);
result.setSummary(summary);
List<WmsReceivingReportByTypeVo> details = baseMapper.selectReceivingReportByType(startTime, endTime);
result.setDetails(details);
return result;
}
@Override
public List<WmsMaterialCoilVo> getSelectableCoilsByPlanId(Long planId) {
if (planId == null) {
return Collections.emptyList();
}
WmsDeliveryPlanVo planVo = baseMapper.selectVoById(planId);
if (planVo == null || StringUtils.isBlank(planVo.getCoil())) {
return Collections.emptyList();
}
Set<Long> planCoilIds = Arrays.stream(planVo.getCoil().split(","))
.map(String::trim)
.filter(StringUtils::isNotBlank)
.map(Long::valueOf)
.collect(Collectors.toSet());
if (planCoilIds.isEmpty()) {
return Collections.emptyList();
}
List<WmsDeliveryWaybill> waybills = waybillMapper.selectList(
Wrappers.<WmsDeliveryWaybill>lambdaQuery().eq(WmsDeliveryWaybill::getPlanId, planId)
);
if (waybills == null || waybills.isEmpty()) {
return queryCoilsByIds(planCoilIds);
}
Set<Long> waybillIds = waybills.stream().map(WmsDeliveryWaybill::getWaybillId).collect(Collectors.toSet());
if (waybillIds.isEmpty()) {
return queryCoilsByIds(planCoilIds);
}
List<WmsDeliveryWaybillDetail> details = waybillDetailMapper.selectList(
Wrappers.<WmsDeliveryWaybillDetail>lambdaQuery().in(WmsDeliveryWaybillDetail::getWaybillId, waybillIds)
);
Set<Long> usedCoilIds = details == null ? Collections.emptySet() : details.stream()
.map(WmsDeliveryWaybillDetail::getCoilId)
.filter(Objects::nonNull)
.collect(Collectors.toSet());
planCoilIds.removeAll(usedCoilIds);
if (planCoilIds.isEmpty()) {
return Collections.emptyList();
}
return queryCoilsByIds(planCoilIds);
}
private List<WmsMaterialCoilVo> queryCoilsByIds(Set<Long> coilIds) {
if (coilIds == null || coilIds.isEmpty()) {
return Collections.emptyList();
}
QueryWrapper<WmsMaterialCoil> qw = new QueryWrapper<>();
qw.in("mc.coil_id", coilIds);
qw.eq("mc.del_flag", 0);
//根据创建时间倒叙
qw.orderByDesc("mc.create_time");
// 使用动态联查以返回更完整的钢卷信息
return coilMapper.selectVoListWithDynamicJoin(qw);
}
/**
* 级联删除发货单及其明细数据
*
* @param planId 计划ID
*/
private void cascadeDeleteDeliveryWaybillsByPlanId(Long planId) {
// 先查询该计划下的所有发货单
List<WmsDeliveryWaybill> waybills = waybillMapper.selectList(
Wrappers.<WmsDeliveryWaybill>lambdaQuery()
.eq(WmsDeliveryWaybill::getPlanId, planId)
.eq(WmsDeliveryWaybill::getDelFlag, 0)
);
if (!waybills.isEmpty()) {
// 获取所有发货单ID
List<Long> waybillIds = waybills.stream()
.map(WmsDeliveryWaybill::getWaybillId)
.collect(Collectors.toList());
// 先删除发货单明细
if (!waybillIds.isEmpty()) {
LambdaQueryWrapper<WmsDeliveryWaybillDetail> detailWrapper =
Wrappers.<WmsDeliveryWaybillDetail>lambdaQuery()
.in(WmsDeliveryWaybillDetail::getWaybillId, waybillIds)
.eq(WmsDeliveryWaybillDetail::getDelFlag, 0);
// 直接删除
waybillDetailMapper.delete(detailWrapper);
}
// 再删除发货单主表
LambdaQueryWrapper<WmsDeliveryWaybill> waybillWrapper =
Wrappers.<WmsDeliveryWaybill>lambdaQuery()
.in(WmsDeliveryWaybill::getWaybillId, waybillIds)
.eq(WmsDeliveryWaybill::getDelFlag, 0);
waybillMapper.delete(waybillWrapper);
}
}
}