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 queryPageList(WmsTransferOrderBo bo, PageQuery pageQuery) { LambdaQueryWrapper lqw = buildQueryWrapper(bo); Page result = baseMapper.selectVoPage(pageQuery.build(), lqw); return TableDataInfo.build(result); } /** * 查询调拨单主列表 */ @Override public List queryList(WmsTransferOrderBo bo) { LambdaQueryWrapper lqw = buildQueryWrapper(bo); return baseMapper.selectVoList(lqw); } private LambdaQueryWrapper buildQueryWrapper(WmsTransferOrderBo bo) { Map params = bo.getParams(); LambdaQueryWrapper 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 ids, Boolean isValid) { if(isValid){ //TODO 做一些业务上的校验,判断是否需要校验 } // 先删除关联的调拨单明细记录 if (ids != null && !ids.isEmpty()) { LambdaQueryWrapper 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 itemWrapper = new LambdaQueryWrapper<>(); itemWrapper.eq(WmsTransferOrderItem::getTransferId, orderId); List items = wmsTransferOrderItemMapper.selectList(itemWrapper); if (items == null || items.isEmpty()) { return; } // 2. 构建coilId到明细项的映射 Map coilToItemMap = items.stream() .filter(item -> item.getCoilId() != null) .collect(Collectors.toMap( WmsTransferOrderItem::getCoilId, v -> v, (a, b) -> a )); // 3. 收集所有coilId List coilIds = new ArrayList<>(coilToItemMap.keySet()); if (coilIds.isEmpty()) { return; } // 4. 批量查询钢卷并校验存在性 List coils = coilMapper.selectBatchIds(coilIds); if (coils.size() != coilIds.size()) { throw new RuntimeException("部分钢卷不存在"); } // 5. 收集所有需要校验的itemId(使用调拨后的值) List itemIdsToValidate = items.stream() .map(WmsTransferOrderItem::getItemIdAfter) .filter(itemId -> itemId != null) .distinct() .collect(Collectors.toList()); // 6. 按物料类型分组校验itemId是否存在 validateItemIds(items, itemIdsToValidate); // 7. 批量更新钢卷信息 List 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 itemIds = items.stream() .map(WmsTransferOrderItem::getOrderItemId) .filter(Objects::nonNull) .collect(Collectors.toList()); if (!itemIds.isEmpty()) { LambdaUpdateWrapper updateWrapper = new LambdaUpdateWrapper<>(); updateWrapper.in(WmsTransferOrderItem::getOrderItemId, itemIds); updateWrapper.set(WmsTransferOrderItem::getIsTransferred, 1); wmsTransferOrderItemMapper.update(null, updateWrapper); } } /** * 校验itemId是否存在 */ private void validateItemIds(List items, List itemIdsToValidate) { if (itemIdsToValidate.isEmpty()) { return; } // 按物料类型分组 Map> 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 rawMaterialIds = materialTypeGroupMap.get(1L).stream().distinct().collect(Collectors.toList()); List rawMaterials = rawMaterialMapper.selectBatchIds(rawMaterialIds); if (rawMaterials.size() != rawMaterialIds.size()) { throw new RuntimeException("部分原材料不存在"); } } // 校验成品 if (materialTypeGroupMap.containsKey(2L)) { List productIds = materialTypeGroupMap.get(2L).stream().distinct().collect(Collectors.toList()); List products = productMapper.selectBatchIds(productIds); if (products.size() != productIds.size()) { throw new RuntimeException("部分产品不存在"); } } } }