Files
klp-oa/klp-wms/src/main/java/com/klp/service/impl/WmsTransferOrderServiceImpl.java
Joshi 57b07885e3 refactor(wms): 优化调拨订单和钢卷信息更新逻辑
- 使用LambdaUpdateWrapper替代直接对象更新,支持显式设置NULL值
- 在审批通过时设置调拨状态为1
- 修复钢卷信息批量更新逻辑,使用updateBatchById提高性能
- 添加调拨后物料ID和类型校验,确保数据一致性
- 批量更新调拨明细的isTransferred字段标记为已调拨
- 过滤条件从调拨前值改为调拨后值进行验证
- 添加空值检查避免无效更新操作
2026-04-10 15:07:29 +08:00

313 lines
12 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.page.TableDataInfo;
import com.klp.common.core.domain.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
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.utils.StringUtils;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.klp.common.helper.LoginHelper;
import com.klp.domain.bo.WmsTransferOrderBo;
import com.klp.domain.vo.WmsTransferOrderVo;
import com.klp.domain.WmsTransferOrder;
import com.klp.domain.WmsTransferOrderItem;
import com.klp.domain.WmsMaterialCoil;
import com.klp.domain.WmsRawMaterial;
import com.klp.domain.WmsProduct;
import com.klp.mapper.WmsTransferOrderMapper;
import com.klp.mapper.WmsTransferOrderItemMapper;
import com.klp.mapper.WmsMaterialCoilMapper;
import com.klp.mapper.WmsRawMaterialMapper;
import com.klp.mapper.WmsProductMapper;
import com.klp.service.IWmsTransferOrderService;
import com.klp.service.IWmsTransferOrderItemService;
import java.util.*;
import java.util.stream.Collectors;
/**
* 调拨单主Service业务层处理
*
* @author klp
* @date 2026-03-27
*/
@RequiredArgsConstructor
@Service
public class WmsTransferOrderServiceImpl implements IWmsTransferOrderService {
private final WmsTransferOrderMapper baseMapper;
private final WmsTransferOrderItemMapper wmsTransferOrderItemMapper;
private final IWmsTransferOrderItemService wmsTransferOrderItemService;
private final WmsMaterialCoilMapper coilMapper;
private final WmsRawMaterialMapper rawMaterialMapper;
private final WmsProductMapper productMapper;
/**
* 查询调拨单主
*/
@Override
public WmsTransferOrderVo queryById(Long orderId){
return baseMapper.selectVoById(orderId);
}
/**
* 查询调拨单主列表
*/
@Override
public TableDataInfo<WmsTransferOrderVo> queryPageList(WmsTransferOrderBo bo, PageQuery pageQuery) {
LambdaQueryWrapper<WmsTransferOrder> lqw = buildQueryWrapper(bo);
Page<WmsTransferOrderVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
return TableDataInfo.build(result);
}
/**
* 查询调拨单主列表
*/
@Override
public List<WmsTransferOrderVo> queryList(WmsTransferOrderBo bo) {
LambdaQueryWrapper<WmsTransferOrder> lqw = buildQueryWrapper(bo);
return baseMapper.selectVoList(lqw);
}
private LambdaQueryWrapper<WmsTransferOrder> buildQueryWrapper(WmsTransferOrderBo bo) {
Map<String, Object> params = bo.getParams();
LambdaQueryWrapper<WmsTransferOrder> lqw = Wrappers.lambdaQuery();
lqw.eq(StringUtils.isNotBlank(bo.getTransferNo()), WmsTransferOrder::getTransferNo, bo.getTransferNo());
lqw.like(StringUtils.isNotBlank(bo.getTransferName()), WmsTransferOrder::getTransferName, bo.getTransferName());
lqw.eq(bo.getTransferStatus() != null, WmsTransferOrder::getTransferStatus, bo.getTransferStatus());
lqw.eq(bo.getTransferTime() != null, WmsTransferOrder::getTransferTime, bo.getTransferTime());
lqw.like(StringUtils.isNotBlank(bo.getTransferType()), WmsTransferOrder::getTransferType, bo.getTransferType());
lqw.like(StringUtils.isNotBlank(bo.getApproveBy()), WmsTransferOrder::getApproveBy, bo.getApproveBy());
lqw.eq(bo.getApproveStatus() != null, WmsTransferOrder::getApproveStatus, bo.getApproveStatus());
lqw.eq(bo.getApproveTime() != null, WmsTransferOrder::getApproveTime, bo.getApproveTime());
return lqw;
}
/**
* 新增调拨单主
*/
@Override
public Boolean insertByBo(WmsTransferOrderBo bo) {
WmsTransferOrder add = BeanUtil.toBean(bo, WmsTransferOrder.class);
validEntityBeforeSave(add);
boolean flag = baseMapper.insert(add) > 0;
if (flag) {
bo.setOrderId(add.getOrderId());
}
return flag;
}
/**
* 修改调拨单主
*/
@Override
public Boolean updateByBo(WmsTransferOrderBo bo) {
WmsTransferOrder update = BeanUtil.toBean(bo, WmsTransferOrder.class);
validEntityBeforeSave(update);
return baseMapper.updateById(update) > 0;
}
/**
* 保存前的数据校验
*/
private void validEntityBeforeSave(WmsTransferOrder entity){
//TODO 做一些数据校验,如唯一约束
}
/**
* 批量删除调拨单主
*/
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
if(isValid){
//TODO 做一些业务上的校验,判断是否需要校验
}
// 先删除关联的调拨单明细记录
if (ids != null && !ids.isEmpty()) {
LambdaQueryWrapper<WmsTransferOrderItem> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.in(WmsTransferOrderItem::getTransferId, ids);
wmsTransferOrderItemMapper.delete(queryWrapper);
}
// 再删除调拨单主记录
return baseMapper.deleteBatchIds(ids) > 0;
}
/**
* 审批调拨单
*/
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean approve(Long orderId, Integer approveStatus) {
// 1. 查询并校验调拨单
WmsTransferOrder order = baseMapper.selectById(orderId);
if (order == null) {
throw new RuntimeException("调拨单不存在");
}
if (order.getApproveStatus() != null && order.getApproveStatus() != 1) {
throw new RuntimeException("该调拨单已审批,不能重复审批");
}
// 2. 更新审批状态
order.setApproveStatus(approveStatus);
order.setApproveBy(LoginHelper.getUsername());
order.setApproveTime(new Date());
order.setTransferStatus(1L);
boolean updateResult = baseMapper.updateById(order) > 0;
// 3. 如果审批通过,批量更新钢卷信息
if (updateResult && approveStatus != null && approveStatus == 2) {
batchUpdateCoilsOnApprove(orderId, order.getTransferType());
}
return updateResult;
}
/**
* 审批通过时批量更新钢卷信息 需要测试是否报错以及明细isTransfer字段是否改成1 钢卷是否被修改如果不改类型和逻辑库区钢卷的更新人时间就不会变
*/
private void batchUpdateCoilsOnApprove(Long orderId, String transferType) {
// 1. 批量查询调拨明细
LambdaQueryWrapper<WmsTransferOrderItem> itemWrapper = new LambdaQueryWrapper<>();
itemWrapper.eq(WmsTransferOrderItem::getTransferId, orderId);
List<WmsTransferOrderItem> items = wmsTransferOrderItemMapper.selectList(itemWrapper);
if (items == null || items.isEmpty()) {
return;
}
// 2. 构建coilId到明细项的映射
Map<Long, WmsTransferOrderItem> coilToItemMap = items.stream()
.filter(item -> item.getCoilId() != null)
.collect(Collectors.toMap(
WmsTransferOrderItem::getCoilId,
v -> v,
(a, b) -> a
));
// 3. 收集所有coilId
List<Long> coilIds = new ArrayList<>(coilToItemMap.keySet());
if (coilIds.isEmpty()) {
return;
}
// 4. 批量查询钢卷并校验存在性
List<WmsMaterialCoil> coils = coilMapper.selectBatchIds(coilIds);
if (coils.size() != coilIds.size()) {
throw new RuntimeException("部分钢卷不存在");
}
// 5. 收集所有需要校验的itemId使用调拨后的值
List<Long> itemIdsToValidate = items.stream()
.map(WmsTransferOrderItem::getItemIdAfter)
.filter(itemId -> itemId != null)
.distinct()
.collect(Collectors.toList());
// 6. 按物料类型分组校验itemId是否存在
validateItemIds(items, itemIdsToValidate);
// 7. 批量更新钢卷信息
List<WmsMaterialCoil> coilsToUpdate = coils.stream()
.map(coil -> {
// 从映射中快速找到对应的明细项
WmsTransferOrderItem item = coilToItemMap.get(coil.getCoilId());
if (item == null) {
return null;
}
// 使用调拨后的值更新钢卷
Long finalItemId = item.getItemIdAfter();
Long finalMaterialType = item.getMaterialTypeAfter();
Long finalWarehouseId = item.getWarehouseIdAfter();
// 如果调拨后的值为空,则不修改该钢卷
if (finalItemId == null && finalMaterialType == null && finalWarehouseId == null) {
return null;
}
// 如果不为空必须itemId和itemType都不为空才能修改
if ((finalItemId != null || finalMaterialType != null)
&& (finalItemId == null || finalMaterialType == null)) {
// itemId和materialType只有一个有值不符合要求跳过
return null;
}
// 计算itemType
String finalItemType = finalMaterialType != null && finalMaterialType == 1 ? "raw_material" : "product";
// 更新钢卷信息
coil.setItemId(finalItemId);
coil.setItemType(finalItemType);
coil.setMaterialType(finalMaterialType != null && finalMaterialType == 1 ? "原料" : "成品");
coil.setWarehouseId(finalWarehouseId);
coil.setTransferType(transferType);
return coil;
})
.filter(Objects::nonNull)
.collect(Collectors.toList());
// 8. 批量更新钢卷数据库
if (!coilsToUpdate.isEmpty()) {
coilMapper.updateBatchById(coilsToUpdate);
}
// 9. 批量更新明细的isTransferred字段为1已调拨
List<Long> itemIds = items.stream()
.map(WmsTransferOrderItem::getOrderItemId)
.filter(Objects::nonNull)
.collect(Collectors.toList());
if (!itemIds.isEmpty()) {
LambdaUpdateWrapper<WmsTransferOrderItem> updateWrapper = new LambdaUpdateWrapper<>();
updateWrapper.in(WmsTransferOrderItem::getOrderItemId, itemIds);
updateWrapper.set(WmsTransferOrderItem::getIsTransferred, 1);
wmsTransferOrderItemMapper.update(null, updateWrapper);
}
}
/**
* 校验itemId是否存在
*/
private void validateItemIds(List<WmsTransferOrderItem> items, List<Long> itemIdsToValidate) {
if (itemIdsToValidate.isEmpty()) {
return;
}
// 按物料类型分组
Map<Long, List<Long>> materialTypeGroupMap = items.stream()
.filter(item -> item.getItemIdAfter() != null && item.getMaterialTypeAfter() != null)
.collect(Collectors.groupingBy(
WmsTransferOrderItem::getMaterialTypeAfter,
Collectors.mapping(WmsTransferOrderItem::getItemIdAfter, Collectors.toList())
));
// 校验原料
if (materialTypeGroupMap.containsKey(1L)) {
List<Long> rawMaterialIds = materialTypeGroupMap.get(1L).stream().distinct().collect(Collectors.toList());
List<WmsRawMaterial> rawMaterials = rawMaterialMapper.selectBatchIds(rawMaterialIds);
if (rawMaterials.size() != rawMaterialIds.size()) {
throw new RuntimeException("部分原材料不存在");
}
}
// 校验成品
if (materialTypeGroupMap.containsKey(2L)) {
List<Long> productIds = materialTypeGroupMap.get(2L).stream().distinct().collect(Collectors.toList());
List<WmsProduct> products = productMapper.selectBatchIds(productIds);
if (products.size() != productIds.size()) {
throw new RuntimeException("部分产品不存在");
}
}
}
}