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.toolkit.Wrappers; import com.klp.domain.bo.WmsMaterialCoilBo; import com.klp.domain.vo.WmsMaterialCoilVo; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import com.klp.domain.bo.WmsTransferOrderItemBo; import com.klp.domain.vo.WmsTransferOrderItemVo; import com.klp.domain.WmsTransferOrderItem; import com.klp.domain.WmsRawMaterial; import com.klp.domain.WmsProduct; import com.klp.domain.WmsMaterialCoil; import com.klp.mapper.WmsTransferOrderItemMapper; import com.klp.mapper.WmsRawMaterialMapper; import com.klp.mapper.WmsProductMapper; import com.klp.mapper.WmsMaterialCoilMapper; import com.klp.service.IWmsTransferOrderItemService; import com.klp.service.IWmsMaterialCoilService; import com.klp.service.IWmsWarehouseService; import org.springframework.transaction.annotation.Transactional; import java.util.*; import java.util.stream.Collectors; /** * 调拨单明细Service业务层处理 * * @author klp * @date 2026-03-27 */ @RequiredArgsConstructor @Service public class WmsTransferOrderItemServiceImpl implements IWmsTransferOrderItemService { private final WmsTransferOrderItemMapper baseMapper; private final WmsRawMaterialMapper rawMaterialMapper; private final WmsProductMapper productMapper; private final WmsMaterialCoilMapper coilMapper; private final IWmsMaterialCoilService coilService; private final IWmsWarehouseService warehouseService; /** * 查询调拨单明细 */ @Override public WmsTransferOrderItemVo queryById(Long itemId){ WmsTransferOrderItemVo vo = baseMapper.selectVoById(itemId); if (vo != null) { fillDetailInfo(vo); } return vo; } /** * 查询调拨单明细列表 */ @Override public TableDataInfo queryPageList(WmsTransferOrderItemBo bo, PageQuery pageQuery) { LambdaQueryWrapper lqw = buildQueryWrapper(bo); Page result = baseMapper.selectVoPage(pageQuery.build(), lqw); List records = result.getRecords(); String collect = records.stream() .map(WmsTransferOrderItemVo::getCoilId) .filter(Objects::nonNull) .distinct() .map(String::valueOf) .collect(Collectors.joining(","));// 收集结果 if (!collect.isEmpty()) { WmsMaterialCoilBo coilBo = new WmsMaterialCoilBo(); coilBo.setCoilIds(collect); List coilList = coilService.queryList(coilBo); Map coilMap = coilList.stream() .collect(Collectors.toMap(WmsMaterialCoilVo::getCoilId, v -> v, (oldVal, newVal) -> oldVal)); for (WmsTransferOrderItemVo vo : records) { WmsMaterialCoilVo coilVo = coilMap.get(vo.getCoilId()); if (coilVo != null) { vo.setCoil(coilVo); } } } if (!records.isEmpty()) { for (WmsTransferOrderItemVo vo : records) { fillDetailInfo(vo); } } return TableDataInfo.build(result); } /** * 查询调拨单明细列表 */ @Override public List queryList(WmsTransferOrderItemBo bo) { LambdaQueryWrapper lqw = buildQueryWrapper(bo); List list = baseMapper.selectVoList(lqw); String coilIdsStr = list.stream() .map(WmsTransferOrderItemVo::getCoilId) .filter(Objects::nonNull) // 过滤 null .distinct() // 去重 .map(String::valueOf) // Long 转 String .collect(Collectors.joining(",")); // 直接拼接成逗号字符串 if (!coilIdsStr.isEmpty()) { WmsMaterialCoilBo coilBo = new WmsMaterialCoilBo(); coilBo.setCoilIds(coilIdsStr); List coilList = coilService.queryList(coilBo); Map coilMap = coilList.stream() .collect(Collectors.toMap(WmsMaterialCoilVo::getCoilId, v -> v)); for (WmsTransferOrderItemVo vo : list) { WmsMaterialCoilVo coilVo = coilMap.get(vo.getCoilId()); if (coilVo != null) { vo.setCoil(coilVo); } } } if (!list.isEmpty()) { for (WmsTransferOrderItemVo vo : list) { fillDetailInfo(vo); } } return list; } private void fillDetailInfo(WmsTransferOrderItemVo vo) { // 填充改之前物料信息 fillMaterialInfo(vo, vo.getItemIdBefore(), vo.getMaterialTypeBefore(), "Before"); // 填充改之后物料信息 fillMaterialInfo(vo, vo.getItemIdAfter(), vo.getMaterialTypeAfter(), "After"); // 填充库区名称 if (vo.getWarehouseIdBefore() != null) { try { vo.setWarehouseNameBefore(warehouseService.queryById(vo.getWarehouseIdBefore()).getWarehouseName()); } catch (Exception e) { // 忽略 } } if (vo.getWarehouseIdAfter() != null) { try { vo.setWarehouseNameAfter(warehouseService.queryById(vo.getWarehouseIdAfter()).getWarehouseName()); } catch (Exception e) { // 忽略 } } // 填充物料类型名称 vo.setMaterialTypeBeforeName(vo.getMaterialTypeBefore() != null ? (vo.getMaterialTypeBefore() == 1 ? "原料" : "成品") : null); vo.setMaterialTypeAfterName(vo.getMaterialTypeAfter() != null ? (vo.getMaterialTypeAfter() == 1 ? "原料" : "成品") : null); } private void fillMaterialInfo(WmsTransferOrderItemVo vo, Long itemId, Long materialType, String suffix) { if (itemId == null || materialType == null) { return; } if (materialType == 1) { WmsRawMaterial raw = rawMaterialMapper.selectById(itemId); if (raw != null) { vo.setMaterialNameBefore(raw.getRawMaterialName()); vo.setSpecificationBefore(raw.getSpecification()); vo.setMaterialBefore(raw.getMaterial()); vo.setSurfaceTreatmentBefore(raw.getSurfaceTreatmentDesc()); vo.setManufacturerBefore(raw.getManufacturer()); vo.setZincLayerBefore(raw.getZincLayer()); } } else if (materialType == 2) { WmsProduct product = productMapper.selectById(itemId); if (product != null) { vo.setMaterialNameAfter(product.getProductName()); vo.setSpecificationAfter(product.getSpecification()); vo.setMaterialAfter(product.getMaterial()); vo.setSurfaceTreatmentAfter(product.getSurfaceTreatmentDesc()); vo.setManufacturerAfter(product.getManufacturer()); vo.setZincLayerAfter(product.getZincLayer()); } } } private LambdaQueryWrapper buildQueryWrapper(WmsTransferOrderItemBo bo) { Map params = bo.getParams(); LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); lqw.eq(bo.getTransferId() != null, WmsTransferOrderItem::getTransferId, bo.getTransferId()); lqw.eq(bo.getCoilId() != null, WmsTransferOrderItem::getCoilId, bo.getCoilId()); lqw.eq(bo.getItemIdBefore() != null, WmsTransferOrderItem::getItemIdBefore, bo.getItemIdBefore()); lqw.eq(bo.getItemIdAfter() != null, WmsTransferOrderItem::getItemIdAfter, bo.getItemIdAfter()); lqw.eq(bo.getMaterialTypeBefore() != null, WmsTransferOrderItem::getMaterialTypeBefore, bo.getMaterialTypeBefore()); lqw.eq(bo.getMaterialTypeAfter() != null, WmsTransferOrderItem::getMaterialTypeAfter, bo.getMaterialTypeAfter()); lqw.eq(bo.getWarehouseIdBefore() != null, WmsTransferOrderItem::getWarehouseIdBefore, bo.getWarehouseIdBefore()); lqw.eq(bo.getWarehouseIdAfter() != null, WmsTransferOrderItem::getWarehouseIdAfter, bo.getWarehouseIdAfter()); return lqw; } /** * 新增调拨单明细 */ @Override public Boolean insertByBo(WmsTransferOrderItemBo bo) { WmsTransferOrderItem add = BeanUtil.toBean(bo, WmsTransferOrderItem.class); validEntityBeforeSave(add); boolean flag = baseMapper.insert(add) > 0; if (flag) { bo.setOrderItemId(add.getOrderItemId()); } return flag; } /** * 修改调拨单明细 */ @Override public Boolean updateByBo(WmsTransferOrderItemBo bo) { WmsTransferOrderItem update = BeanUtil.toBean(bo, WmsTransferOrderItem.class); validEntityBeforeSave(update); return baseMapper.updateById(update) > 0; } /** * 保存前的数据校验 */ private void validEntityBeforeSave(WmsTransferOrderItem entity){ //TODO 做一些数据校验,如唯一约束 } /** * 批量删除调拨单明细 */ @Override public Boolean deleteWithValidByIds(Collection ids, Boolean isValid) { if(isValid){ //TODO 做一些业务上的校验,判断是否需要校验 } return baseMapper.deleteBatchIds(ids) > 0; } /** * 根据itemId和itemType匹配或新增物料 * itemType: raw_material-原料, product-成品 */ @Override @Transactional(rollbackFor = Exception.class) public Long matchOrCreateMaterial(Long itemId, String itemType) { if (Objects.equals(itemType, "raw_material")) { return matchOrCreateFromRawMaterial(itemId); } else if (Objects.equals(itemType, "product")) { return matchOrCreateFromProduct(itemId); } throw new IllegalArgumentException("无效的itemType: " + itemType); } private Long matchOrCreateFromRawMaterial(Long itemId) { WmsRawMaterial rawMaterial = rawMaterialMapper.selectById(itemId); if (rawMaterial == null) { throw new IllegalArgumentException("原料不存在: " + itemId); } LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); wrapper.eq(WmsProduct::getProductName, rawMaterial.getRawMaterialName()) .eq(WmsProduct::getSpecification, rawMaterial.getSpecification()) .eq(WmsProduct::getManufacturer, rawMaterial.getManufacturer()) .eq(WmsProduct::getMaterial, rawMaterial.getMaterial()) .eq(WmsProduct::getSurfaceTreatmentDesc, rawMaterial.getSurfaceTreatmentDesc()) .eq(WmsProduct::getZincLayer, rawMaterial.getZincLayer()) .last("LIMIT 1"); WmsProduct existProduct = productMapper.selectOne(wrapper); if (existProduct != null) { return existProduct.getProductId(); } WmsProduct newProduct = new WmsProduct(); newProduct.setProductName(rawMaterial.getRawMaterialName()); newProduct.setSpecification(rawMaterial.getSpecification()); newProduct.setManufacturer(rawMaterial.getManufacturer()); newProduct.setMaterial(rawMaterial.getMaterial()); newProduct.setSurfaceTreatmentDesc(rawMaterial.getSurfaceTreatmentDesc()); newProduct.setZincLayer(rawMaterial.getZincLayer()); newProduct.setDelFlag(0); productMapper.insert(newProduct); return newProduct.getProductId(); } private Long matchOrCreateFromProduct(Long itemId) { WmsProduct product = productMapper.selectById(itemId); if (product == null) { throw new IllegalArgumentException("产品不存在: " + itemId); } LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); wrapper.eq(WmsRawMaterial::getRawMaterialName, product.getProductName()) .eq(WmsRawMaterial::getSpecification, product.getSpecification()) .eq(WmsRawMaterial::getManufacturer, product.getManufacturer()) .eq(WmsRawMaterial::getMaterial, product.getMaterial()) .eq(WmsRawMaterial::getSurfaceTreatmentDesc, product.getSurfaceTreatmentDesc()) .eq(WmsRawMaterial::getZincLayer, product.getZincLayer()) .last("LIMIT 1"); WmsRawMaterial existRawMaterial = rawMaterialMapper.selectOne(wrapper); if (existRawMaterial != null) { return existRawMaterial.getRawMaterialId(); } WmsRawMaterial newRawMaterial = new WmsRawMaterial(); newRawMaterial.setRawMaterialName(product.getProductName()); newRawMaterial.setSpecification(product.getSpecification()); newRawMaterial.setManufacturer(product.getManufacturer()); newRawMaterial.setMaterial(product.getMaterial()); newRawMaterial.setSurfaceTreatmentDesc(product.getSurfaceTreatmentDesc()); newRawMaterial.setZincLayer(product.getZincLayer()); newRawMaterial.setDelFlag(0); rawMaterialMapper.insert(newRawMaterial); return newRawMaterial.getRawMaterialId(); } /** * 批量新增调拨单明细 */ @Override @Transactional(rollbackFor = Exception.class) public Boolean batchInsert(WmsTransferOrderItemBo bo) { Long transferId = bo.getTransferId(); List coilIds = bo.getCoilIds(); if (transferId == null || coilIds == null || coilIds.isEmpty()) { throw new IllegalArgumentException("transferId和coilIds不能为空"); } // 检查同一调拨单下是否已存在相同的coilId LambdaQueryWrapper existWrapper = new LambdaQueryWrapper<>(); existWrapper.eq(WmsTransferOrderItem::getTransferId, transferId) .in(WmsTransferOrderItem::getCoilId, coilIds); List existItems = baseMapper.selectList(existWrapper); if (!existItems.isEmpty()) { List existCoilIds = existItems.stream() .map(WmsTransferOrderItem::getCoilId) .filter(Objects::nonNull) .collect(Collectors.toList()); List wmsMaterialCoils = coilMapper.selectBatchIds(existCoilIds); throw new IllegalArgumentException("当前钢卷号" + wmsMaterialCoils.stream().map(WmsMaterialCoil::getCurrentCoilNo).collect(Collectors.joining(",")) + " 已在该调拨单中存在"); } List coils = coilMapper.selectBatchIds(coilIds); if (coils.isEmpty()) { throw new IllegalArgumentException("钢卷不存在"); } List items = new ArrayList<>(); for (WmsMaterialCoil coil : coils) { WmsTransferOrderItem item = new WmsTransferOrderItem(); item.setTransferId(transferId); item.setCoilId(coil.getCoilId()); item.setItemIdBefore(coil.getItemId()); // 根据 itemType 设置 materialType: raw_material -> 1, product -> 2 if ("raw_material".equals(coil.getItemType())) { item.setMaterialTypeBefore(1L); } else if ("product".equals(coil.getItemType())) { item.setMaterialTypeBefore(2L); } item.setWarehouseIdBefore(coil.getWarehouseId()); items.add(item); } return baseMapper.insertBatch(items); } /** * 确认调拨 */ @Override @Transactional(rollbackFor = Exception.class) public Boolean confirmTransfer(WmsTransferOrderItemBo bo) { Long transferId = bo.getTransferId(); Long coilId = bo.getCoilId(); Long itemId = bo.getItemIdAfter(); String itemType = bo.getMaterialTypeAfter() != null ? (bo.getMaterialTypeAfter() == 1 ? "raw_material" : "product") : null; Long warehouseId = bo.getWarehouseIdAfter(); if (coilId == null) { throw new IllegalArgumentException("coilId不能为空"); } WmsMaterialCoil coil = coilMapper.selectById(coilId); if (coil == null) { throw new IllegalArgumentException("钢卷不存在"); } // 如果传了才修改钢卷 if (itemId != null) { coil.setItemId(itemId); } if (itemType != null) { coil.setItemType(itemType); } if (warehouseId != null) { coil.setWarehouseId(warehouseId); } coilMapper.updateById(coil); LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); wrapper.eq(WmsTransferOrderItem::getCoilId, coilId); wrapper.eq(WmsTransferOrderItem::getTransferId, transferId); WmsTransferOrderItem item = baseMapper.selectOne(wrapper); if (item != null) { // 如果没传itemIdAfter则用itemIdBefore的值 item.setItemIdAfter(itemId != null ? itemId : item.getItemIdBefore()); // 如果没传materialTypeAfter则用materialTypeBefore的值 if (bo.getMaterialTypeAfter() != null) { item.setMaterialTypeAfter(bo.getMaterialTypeAfter()); } else { item.setMaterialTypeAfter(item.getMaterialTypeBefore()); } // 如果没传warehouseIdAfter则用warehouseIdBefore的值 item.setWarehouseIdAfter(warehouseId != null ? warehouseId : item.getWarehouseIdBefore()); baseMapper.updateById(item); } return true; } /** * 取消调拨 */ @Override @Transactional(rollbackFor = Exception.class) public Boolean cancelTransfer(Long orderItemId) { WmsTransferOrderItem item = baseMapper.selectById(orderItemId); if (item == null) { throw new IllegalArgumentException("明细记录不存在"); } Long coilId = item.getCoilId(); Long originalItemId = item.getItemIdBefore(); Long originalMaterialType = item.getMaterialTypeBefore(); Long originalWarehouseId = item.getWarehouseIdBefore(); WmsMaterialCoil coil = coilMapper.selectById(coilId); if (coil != null) { coil.setItemId(originalItemId); coil.setItemType(originalMaterialType == 1 ? "raw_material" : "product"); coil.setWarehouseId(originalWarehouseId); coilMapper.updateById(coil); } baseMapper.deleteById(orderItemId); return true; } }