diff --git a/klp-wms/src/main/java/com/klp/domain/bo/WmsMaterialCoilBo.java b/klp-wms/src/main/java/com/klp/domain/bo/WmsMaterialCoilBo.java index 43f13438..a1e43560 100644 --- a/klp-wms/src/main/java/com/klp/domain/bo/WmsMaterialCoilBo.java +++ b/klp-wms/src/main/java/com/klp/domain/bo/WmsMaterialCoilBo.java @@ -189,6 +189,17 @@ public class WmsMaterialCoilBo extends BaseEntity { private Boolean onlyUnshippedAndUnplanned; + /** + * 是否排除已被发货单明细绑定的钢卷(true=列表不返回已绑定钢卷) + */ + private Boolean excludeBound; + + /** + * 是否在列表中返回“发货单明细绑定信息”(true=返回 bound + 绑定来源信息) + * 默认不返回,避免不需要的场景变慢。 + */ + private Boolean includeBindInfo; + //销售id private Long saleId; diff --git a/klp-wms/src/main/java/com/klp/domain/vo/WmsCoilBindInfoVo.java b/klp-wms/src/main/java/com/klp/domain/vo/WmsCoilBindInfoVo.java new file mode 100644 index 00000000..78423ff9 --- /dev/null +++ b/klp-wms/src/main/java/com/klp/domain/vo/WmsCoilBindInfoVo.java @@ -0,0 +1,31 @@ +package com.klp.domain.vo; + +import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; +import lombok.Data; + +import java.io.Serializable; +import java.util.Date; + +/** + * 钢卷绑定信息(发货单明细 -> 发货单 -> 发货计划) + * 用于快速标记钢卷是否已被发货单明细占用,并返回占用来源信息。 + */ +@Data +@ExcelIgnoreUnannotated +public class WmsCoilBindInfoVo implements Serializable { + + private static final long serialVersionUID = 1L; + + private Long coilId; + + private Long detailId; + + private Long waybillId; + private String waybillNo; + private String waybillName; + + private Long planId; + private String planName; + private Date planDate; +} + diff --git a/klp-wms/src/main/java/com/klp/domain/vo/WmsMaterialCoilVo.java b/klp-wms/src/main/java/com/klp/domain/vo/WmsMaterialCoilVo.java index a1366784..c0000795 100644 --- a/klp-wms/src/main/java/com/klp/domain/vo/WmsMaterialCoilVo.java +++ b/klp-wms/src/main/java/com/klp/domain/vo/WmsMaterialCoilVo.java @@ -333,5 +333,24 @@ public class WmsMaterialCoilVo extends BaseEntity { * 独占状态(0=未独占,1=特殊分卷中) */ private Integer exclusiveStatus; + + // ========== 发货绑定信息(由发货单明细占用) ========== + + /** + * 是否已被发货单明细绑定(true=不可再次绑定) + */ + private Boolean bound; + + private Long bindDetailId; + + private Long bindWaybillId; + private String bindWaybillNo; + private String bindWaybillName; + + private Long bindPlanId; + private String bindPlanName; + + @JsonFormat(pattern = "yyyy-MM-dd") + private Date bindPlanDate; } diff --git a/klp-wms/src/main/java/com/klp/mapper/WmsDeliveryWaybillDetailMapper.java b/klp-wms/src/main/java/com/klp/mapper/WmsDeliveryWaybillDetailMapper.java index 2bbc1f3e..7a25ff4a 100644 --- a/klp-wms/src/main/java/com/klp/mapper/WmsDeliveryWaybillDetailMapper.java +++ b/klp-wms/src/main/java/com/klp/mapper/WmsDeliveryWaybillDetailMapper.java @@ -1,8 +1,13 @@ package com.klp.mapper; import com.klp.domain.WmsDeliveryWaybillDetail; +import com.klp.domain.vo.WmsCoilBindInfoVo; import com.klp.domain.vo.WmsDeliveryWaybillDetailVo; import com.klp.common.core.mapper.BaseMapperPlus; +import org.apache.ibatis.annotations.Param; + +import java.util.Collection; +import java.util.List; /** * 发货单明细Mapper接口 @@ -12,4 +17,13 @@ import com.klp.common.core.mapper.BaseMapperPlus; */ public interface WmsDeliveryWaybillDetailMapper extends BaseMapperPlus { + /** + * 按钢卷ID批量查询绑定来源信息(明细->发货单->发货计划) + */ + List selectBindInfoByCoilIds(@Param("coilIds") Collection coilIds); + + /** + * 按钢卷ID查询绑定来源信息(明细->发货单->发货计划) + */ + WmsCoilBindInfoVo selectBindInfoByCoilId(@Param("coilId") Long coilId); } diff --git a/klp-wms/src/main/java/com/klp/service/impl/WmsDeliveryWaybillDetailServiceImpl.java b/klp-wms/src/main/java/com/klp/service/impl/WmsDeliveryWaybillDetailServiceImpl.java index 93cd4176..3b370e1f 100644 --- a/klp-wms/src/main/java/com/klp/service/impl/WmsDeliveryWaybillDetailServiceImpl.java +++ b/klp-wms/src/main/java/com/klp/service/impl/WmsDeliveryWaybillDetailServiceImpl.java @@ -7,11 +7,13 @@ 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.common.utils.StringUtils; +import com.klp.common.exception.ServiceException; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import com.klp.domain.bo.WmsDeliveryWaybillDetailBo; import com.klp.domain.vo.WmsDeliveryWaybillDetailVo; import com.klp.domain.WmsDeliveryWaybillDetail; +import com.klp.domain.vo.WmsCoilBindInfoVo; import com.klp.mapper.WmsDeliveryWaybillDetailMapper; import com.klp.service.IWmsDeliveryWaybillDetailService; @@ -105,7 +107,32 @@ public class WmsDeliveryWaybillDetailServiceImpl implements IWmsDeliveryWaybillD * 保存前的数据校验 */ private void validEntityBeforeSave(WmsDeliveryWaybillDetail entity){ - //TODO 做一些数据校验,如唯一约束 + if (entity == null || entity.getCoilId() == null) { + return; + } + + // 同一个钢卷只能被一个发货单明细绑定(排除当前记录) + LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); + lqw.eq(WmsDeliveryWaybillDetail::getCoilId, entity.getCoilId()); + lqw.eq(WmsDeliveryWaybillDetail::getDelFlag, 0); + lqw.ne(entity.getDetailId() != null, WmsDeliveryWaybillDetail::getDetailId, entity.getDetailId()); + lqw.last("LIMIT 1"); + WmsDeliveryWaybillDetail exists = baseMapper.selectOne(lqw); + if (exists == null) { + return; + } + + // 拼接提示:在哪个计划/发货单下已被绑定 + WmsCoilBindInfoVo bindInfo = baseMapper.selectBindInfoByCoilId(entity.getCoilId()); + if (bindInfo != null) { + throw new ServiceException( + "该钢卷已被绑定,不能重复选择;" + + "发货计划:" + bindInfo.getPlanName() + + ",发货单:" + bindInfo.getWaybillNo() + + "(" + bindInfo.getWaybillName() + ")" + ); + } + throw new ServiceException("该钢卷已被绑定,不能重复选择"); } /** diff --git a/klp-wms/src/main/java/com/klp/service/impl/WmsMaterialCoilServiceImpl.java b/klp-wms/src/main/java/com/klp/service/impl/WmsMaterialCoilServiceImpl.java index 54e6a333..6e92c7ef 100644 --- a/klp-wms/src/main/java/com/klp/service/impl/WmsMaterialCoilServiceImpl.java +++ b/klp-wms/src/main/java/com/klp/service/impl/WmsMaterialCoilServiceImpl.java @@ -70,6 +70,7 @@ public class WmsMaterialCoilServiceImpl implements IWmsMaterialCoilService { private final WmsDeliveryPlanMapper deliveryPlanMapper; private final WmsProductMapper productMapper; private final WmsRawMaterialMapper rawMaterialMapper; + private final WmsDeliveryWaybillDetailMapper deliveryWaybillDetailMapper; /** * 查询钢卷物料表 @@ -305,6 +306,47 @@ public class WmsMaterialCoilServiceImpl implements IWmsMaterialCoilService { return TableDataInfo.build(result); } + // 批量查询当前页钢卷的“发货单明细绑定”信息(用于禁选/置灰/提示来源) + // 仅当前端明确需要时才查询,避免不必要的性能开销 + if (Boolean.TRUE.equals(bo.getIncludeBindInfo())) { + try { + List coilIds = records.stream() + .map(WmsMaterialCoilVo::getCoilId) + .filter(Objects::nonNull) + .distinct() + .collect(Collectors.toList()); + + if (!coilIds.isEmpty()) { + Map bindMap = deliveryWaybillDetailMapper + .selectBindInfoByCoilIds(coilIds) + .stream() + .collect(Collectors.toMap( + WmsCoilBindInfoVo::getCoilId, + v -> v, + (a, b) -> a + )); + + for (WmsMaterialCoilVo vo : records) { + WmsCoilBindInfoVo bind = bindMap.get(vo.getCoilId()); + if (bind != null) { + vo.setBound(Boolean.TRUE); + vo.setBindDetailId(bind.getDetailId()); + vo.setBindWaybillId(bind.getWaybillId()); + vo.setBindWaybillNo(bind.getWaybillNo()); + vo.setBindWaybillName(bind.getWaybillName()); + vo.setBindPlanId(bind.getPlanId()); + vo.setBindPlanName(bind.getPlanName()); + vo.setBindPlanDate(bind.getPlanDate()); + } else { + vo.setBound(Boolean.FALSE); + } + } + } + } catch (Exception ignore) { + // 绑定信息属于增强字段,查询失败时不影响钢卷列表主流程 + } + } + Set userNames = records.stream() .flatMap(v -> java.util.stream.Stream.of(v.getCreateBy(), v.getUpdateBy(), v.getExportBy())) .filter(StringUtils::isNotBlank) @@ -408,6 +450,11 @@ public class WmsMaterialCoilServiceImpl implements IWmsMaterialCoilService { qw.in("mc.quality_status", java.util.Arrays.asList("C+", "C", "C-", "D+", "D", "D-")); } + // 排除已被发货单明细绑定的钢卷(SQL级过滤,分页总数准确) + if (Boolean.TRUE.equals(bo.getExcludeBound())) { + qw.apply("NOT EXISTS (SELECT 1 FROM wms_delivery_waybill_detail d WHERE d.del_flag = 0 AND d.coil_id = mc.coil_id)"); + } + // 组合 item_id 条件:改为使用 EXISTS 子查询,替代预查询 + IN boolean hasSelectType = StringUtils.isNotBlank(bo.getSelectType()); boolean hasAnyItemFilter = StringUtils.isNotBlank(bo.getItemMaterial()) diff --git a/klp-wms/src/main/resources/mapper/klp/WmsDeliveryWaybillDetailMapper.xml b/klp-wms/src/main/resources/mapper/klp/WmsDeliveryWaybillDetailMapper.xml index 7f3bf89e..ae6bb403 100644 --- a/klp-wms/src/main/resources/mapper/klp/WmsDeliveryWaybillDetailMapper.xml +++ b/klp-wms/src/main/resources/mapper/klp/WmsDeliveryWaybillDetailMapper.xml @@ -27,5 +27,53 @@ + + + + + + + + + + + + + +