Merge branch 'dev' into dev_WMS20260401

# Conflicts:
#	mhd_wms/src/main/java/com/mhd/wms/domain/shelfMaterialDetail/repository/persistence/ShelfMaterialDetailImpl.java
This commit is contained in:
赵辉
2026-04-28 13:41:57 +08:00
20 changed files with 249 additions and 22 deletions
@@ -23,6 +23,8 @@ import com.mhd.wms.domain.materialBaseInfo.repository.facade.IMaterialBaseInfoSe
import com.mhd.wms.domain.materialBaseInfo.repository.po.MaterialBaseInfoPO;
import com.mhd.wms.domain.materialBaseInfo.repository.todo.MaterialBaseInfoDO;
import com.mhd.wms.domain.materialBaseInfo.service.MaterialBaseInfoDomainService;
import com.mhd.wms.domain.materialCommon.repository.facade.IMaterialCommonService;
import com.mhd.wms.domain.materialCommon.repository.po.MaterialCommonPO;
import com.mhd.wms.domain.materialCommon.repository.todo.MaterialCommonDO;
import com.mhd.wms.domain.materialCommon.service.MaterialCommonDomainService;
import com.mhd.wms.domain.materialGoodsRule.entity.MaterialGoodsRule;
@@ -33,6 +35,8 @@ import com.mhd.wms.domain.materialGoodsRule.service.MaterialGoodsRuleDomainServi
import com.mhd.wms.domain.materialInventoryWarning.repository.facade.IMaterialInventoryWarningService;
import com.mhd.wms.domain.materialInventoryWarning.repository.po.MaterialInventoryWarningPO;
import com.mhd.wms.domain.materialInventoryWarning.service.MaterialInventoryWarningDomainService;
import com.mhd.wms.domain.materialWarehouseControl.repository.facade.IMaterialWarehouseControlService;
import com.mhd.wms.domain.materialWarehouseControl.repository.po.MaterialWarehouseControlPO;
import com.mhd.wms.domain.materialWarehouseControl.repository.todo.MaterialWarehouseControlDO;
import com.mhd.wms.domain.materialWarehouseControl.service.MaterialWarehouseControlDomainService;
import com.mhd.wms.interfaces.dto.materialBaseInfo.MaterialBaseInfoDTO;
@@ -88,6 +92,10 @@ public class MaterialBaseInfoApplicationService {
private UserServiceFeign userServiceFeign;
@Autowired
private IMaterialBaseInfoService materialBaseInfoService;
@Autowired
private IMaterialCommonService materialCommonService;
@Autowired
private IMaterialWarehouseControlService materialWarehouseControlService;
/**
* 分页查询物料基础信息列表
@@ -268,20 +276,38 @@ public class MaterialBaseInfoApplicationService {
*/
public Boolean update(MaterialBaseInfoDO materialBaseInfoDO) {
materialBaseInfoDomainService.update(materialBaseInfoDO);
Long materialBaseInfoId = materialBaseInfoDO.getMaterialBaseInfoId();
// 商品/公共/仓控 子表:Feign/前端常只带业务字段、未带子表主键,需按 material_base_info_id 补全后再 update,否则 WHERE xxx_id=? 为 null 导致 Updates: 0
mergeSubEntityPrimaryKeysForMaterialUpdate(materialBaseInfoDO);
//商品规则
MaterialGoodsRuleDO materialGoodsRuleDO = materialBaseInfoDO.getMaterialGoodsRule();
if (materialGoodsRuleDO != null) {
materialGoodsRuleDomainService.update(materialGoodsRuleDO);
if (materialGoodsRuleDO.getMaterialGoodsRuleId() == null && materialBaseInfoId != null) {
materialGoodsRuleDO.setMaterialBaseInfoId(materialBaseInfoId);
materialGoodsRuleDomainService.insert(materialGoodsRuleDO);
} else {
materialGoodsRuleDomainService.update(materialGoodsRuleDO);
}
}
//公共信息
MaterialCommonDO materialCommonDO = materialBaseInfoDO.getMaterialCommon();
if (materialCommonDO != null) {
materialCommonDomainService.update(materialCommonDO);
if (materialCommonDO.getMaterialCommonId() == null && materialBaseInfoId != null) {
materialCommonDO.setMaterialBaseInfoId(materialBaseInfoId);
materialCommonDomainService.insert(materialCommonDO);
} else {
materialCommonDomainService.update(materialCommonDO);
}
}
//仓库控制信息
MaterialWarehouseControlDO materialWarehouseControlDO = materialBaseInfoDO.getMaterialWarehouseControl();
if (materialWarehouseControlDO != null) {
materialWarehouseControlDomainService.update(materialWarehouseControlDO);
if (materialWarehouseControlDO.getMaterialWarehouseControlId() == null && materialBaseInfoId != null) {
materialWarehouseControlDO.setMaterialBaseInfoId(materialBaseInfoId);
materialWarehouseControlDomainService.insert(materialWarehouseControlDO);
} else {
materialWarehouseControlDomainService.update(materialWarehouseControlDO);
}
}
//库存预警
materialInventoryWarningDomainService.batchInsertOrUpdate(materialBaseInfoDO);
@@ -290,6 +316,42 @@ public class MaterialBaseInfoApplicationService {
return true;
}
/**
* 编辑物料时从库中反查子表主键,避免仅传 batchId 等字段时子表主键为 null 无法 UPDATE。
*/
private void mergeSubEntityPrimaryKeysForMaterialUpdate(MaterialBaseInfoDO materialBaseInfoDO) {
if (materialBaseInfoDO == null) {
return;
}
Long mid = materialBaseInfoDO.getMaterialBaseInfoId();
if (mid == null) {
return;
}
MaterialGoodsRuleDO gr = materialBaseInfoDO.getMaterialGoodsRule();
if (gr != null && gr.getMaterialGoodsRuleId() == null) {
MaterialGoodsRule one = materialGoodsRuleMapper.selectOne(new LambdaQueryWrapper<MaterialGoodsRule>()
.eq(MaterialGoodsRule::getMaterialBaseInfoId, mid)
.eq(MaterialGoodsRule::getDelFlag, 1));
if (one != null) {
gr.setMaterialGoodsRuleId(one.getMaterialGoodsRuleId());
}
}
MaterialCommonDO common = materialBaseInfoDO.getMaterialCommon();
if (common != null && common.getMaterialCommonId() == null) {
MaterialCommonPO ex = materialCommonService.getInfoByMaterialBaseInfoIds(mid);
if (ex != null) {
common.setMaterialCommonId(ex.getMaterialCommonId());
}
}
MaterialWarehouseControlDO wh = materialBaseInfoDO.getMaterialWarehouseControl();
if (wh != null && wh.getMaterialWarehouseControlId() == null) {
MaterialWarehouseControlPO ex = materialWarehouseControlService.getInfoByMaterialBaseInfoIds(mid);
if (ex != null) {
wh.setMaterialWarehouseControlId(ex.getMaterialWarehouseControlId());
}
}
}
/**
* 批量删除物料基础信息
*/
@@ -46,6 +46,7 @@ import com.mhd.wms.domain.stockReceiptOrder.repository.todo.NoReceiptOrderDO;
import com.mhd.wms.domain.stockReceiptOrder.repository.todo.StockReceiptOrderDO;
import com.mhd.wms.domain.stockReceiptOrder.service.StockReceiptOrderDomainService;
import com.mhd.wms.interfaces.dto.stockReceiptOrder.StockReceiptOrderDTO;
import com.mhd.wms.util.ReceiptBatchDetailFilter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@@ -224,6 +225,9 @@ public class StockReceiptOrderApplicationService {
if (ajaxResult != null && "200".equals(String.valueOf(ajaxResult.get("code")))) {
List<BatchDetailFeignPO> batchDetailFeignPOList = JSON.parseArray(
JSONObject.toJSONString(ajaxResult.get("data")), BatchDetailFeignPO.class);
// 与物料商品规则中的 batchId 对齐,避免多批次模板的 isDisplay=1 行全部合并成几十条
batchDetailFeignPOList = ReceiptBatchDetailFilter.filterByMaterialGoodsRule(
materialBaseInfoId, batchDetailFeignPOList, materialGoodsRuleService);
if (!CollectionUtils.isEmpty(batchDetailFeignPOList)) {
// 过滤isDisplay=1的属性
List<BatchDetailFeignPO> filteredList = batchDetailFeignPOList.stream()
@@ -346,7 +350,8 @@ public class StockReceiptOrderApplicationService {
if (ajaxResult != null && "200".equals(String.valueOf(ajaxResult.get("code")))) {
List<BatchDetailFeignPO> batchDetailFeignPOList = JSON.parseArray(
JSONObject.toJSONString(ajaxResult.get("data")), BatchDetailFeignPO.class);
batchDetailFeignPOList = ReceiptBatchDetailFilter.filterByMaterialGoodsRule(
materialBaseInfoId, batchDetailFeignPOList, materialGoodsRuleService);
if (!CollectionUtils.isEmpty(batchDetailFeignPOList)) {
// 过滤isDisplay=1的属性
batchDetailFeignPOList.stream()
@@ -49,6 +49,7 @@ import com.mhd.wms.domain.shiftMaterialDetail.repository.todo.ShiftMaterialDetai
import com.mhd.wms.domain.stockShelfOrder.repository.po.StockShelfOrderPO;
import com.mhd.wms.domain.stockShelfOrder.repository.todo.StockShelfOrderDO;
import com.mhd.wms.domain.stockShelfOrder.service.StockShelfOrderDomainService;
import com.mhd.wms.util.ReceiptBatchDetailFilter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@@ -232,6 +233,9 @@ public class StockShelfOrderApplicationService {
if (ajaxResult != null && "200".equals(String.valueOf(ajaxResult.get("code")))) {
List<BatchDetailFeignPO> batchDetailFeignPOList = JSON.parseArray(
JSONObject.toJSONString(ajaxResult.get("data")), BatchDetailFeignPO.class);
// 与物料商品规则中的 batchId 对齐同收货单详情避免多批次 isDisplay=1 并集
batchDetailFeignPOList = ReceiptBatchDetailFilter.filterByMaterialGoodsRule(
materialBaseInfoId, batchDetailFeignPOList, materialGoodsRuleService);
if (!CollectionUtils.isEmpty(batchDetailFeignPOList)) {
// 过滤isDisplay=1的属性
List<BatchDetailFeignPO> filteredList = batchDetailFeignPOList.stream()
@@ -871,10 +871,10 @@ public class MaterialInventoryImpl extends ServiceImpl<MaterialInventoryMapper,
BigDecimal oldFreezeQuantity = materialInventoryPO.getFreezeQuantity();
oldFreezeQuantity = oldFreezeQuantity != null ? oldFreezeQuantity : BigDecimal.ZERO;
//扣减后库存数量
BigDecimal newInventoryQuantity = oldInventoryQuantity.subtract(quantity);
BigDecimal newInventoryQuantity = oldInventoryQuantity.add(quantity);
//扣减后可用数量
BigDecimal newAllocationQuantity = oldAllocationQuantity.subtract(quantity);
BigDecimal newFreezeQuantity = oldFreezeQuantity.subtract(quantity);
BigDecimal newAllocationQuantity = oldAllocationQuantity.add(quantity);
BigDecimal newFreezeQuantity = oldFreezeQuantity.add(quantity);
@@ -895,7 +895,7 @@ public class MaterialInventoryImpl extends ServiceImpl<MaterialInventoryMapper,
BigDecimal newNetWeight = oldNetWeight.add(netWeight);
materialInventoryPO.setInventoryQuantity(newInventoryQuantity);
//materialInventoryPO.setAllocationQuantity(materialInventoryPO.getAllocationQuantity());
materialInventoryPO.setAllocationQuantity(newAllocationQuantity);
materialInventoryPO.setFreezeQuantity(newFreezeQuantity);
materialInventoryPO.setArea(newArea);
materialInventoryPO.setVolume(newVolume);
@@ -17,6 +17,8 @@ import com.mhd.system.api.SystemServiceFeign;
import com.mhd.system.api.domain.BatchDetailFeignPO;
import com.mhd.system.api.model.LoginUser;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.mhd.wms.domain.materialGoodsRule.repository.facade.IMaterialGoodsRuleService;
import com.mhd.wms.util.ReceiptBatchDetailFilter;
import com.mhd.wms.domain.inMaterialDetail.entity.InMaterialDetail;
import com.mhd.wms.domain.inMaterialDetail.repository.facade.IInMaterialDetailService;
import com.mhd.wms.domain.inMaterialDetail.repository.po.InMaterialDetailPO;
@@ -83,6 +85,8 @@ public class ReceiptMaterialDetailImpl extends ServiceImpl<ReceiptMaterialDetail
@Resource
private SystemServiceFeign systemServiceFeign;
@Autowired
private IMaterialGoodsRuleService materialGoodsRuleService;
@Autowired
private IMaterialInventoryService materialInventoryService;
@Autowired
private com.mhd.wms.domain.stockInOrder.repository.facade.IStockInOrderService stockInOrderService;
@@ -259,6 +263,7 @@ public class ReceiptMaterialDetailImpl extends ServiceImpl<ReceiptMaterialDetail
return result;
}
List<BatchDetailFeignPO> batchList = JSON.parseArray(JSONObject.toJSONString(ajaxResult.get("data")), BatchDetailFeignPO.class);
batchList = ReceiptBatchDetailFilter.filterByMaterialGoodsRule(materialBaseInfoId, batchList, materialGoodsRuleService);
result = filterAndConvertToMaterialMoreDetail(batchList);
if (CollectionUtils.isEmpty(result)) {
return result;
@@ -1,8 +1,12 @@
package com.mhd.wms.domain.shelfMaterialDetail.repository.persistence;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mhd.common.core.exception.ServiceException;
import com.mhd.common.core.web.domain.AjaxResult;
import com.mhd.common.security.utils.SecurityUtils;
import com.mhd.system.api.SystemServiceFeign;
import com.mhd.system.api.model.LoginUser;
import com.mhd.wms.domain.inMaterialDetailSerialNumber.entity.InMaterialDetailSerialNumber;
import com.mhd.wms.domain.inMaterialDetailSerialNumber.repository.facade.IInMaterialDetailSerialNumberService;
@@ -15,16 +19,20 @@ import com.mhd.wms.domain.shelfMaterialDetail.repository.facade.IShelfMaterialDe
import com.mhd.wms.domain.shelfMaterialDetail.repository.mapper.ShelfMaterialDetailMapper;
import com.mhd.wms.domain.shelfMaterialDetail.repository.po.ShelfMaterialDetailPO;
import com.mhd.wms.domain.shelfMaterialDetail.repository.todo.ShelfMaterialDetailDO;
import com.mhd.wms.domain.materialGoodsRule.repository.facade.IMaterialGoodsRuleService;
import com.mhd.wms.util.ReceiptBatchDetailFilter;
import com.mhd.wms.domain.stockInOrder.repository.facade.IStockInOrderService;
import com.mhd.wms.domain.stockShelfOrder.repository.facade.IStockShelfOrderService;
import com.mhd.wms.domain.stockShelfOrder.repository.todo.StockShelfOrderDO;
import com.mhd.common.core.utils.StringUtils;
import com.mhd.system.api.domain.BatchDetailFeignPO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Comparator;
@@ -45,6 +53,10 @@ public class ShelfMaterialDetailImpl extends ServiceImpl<ShelfMaterialDetailMapp
private ShelfMaterialDetailMapper shelfMaterialDetailMapper;
@Autowired
private IInMaterialDetailSerialNumberService inMaterialDetailSerialNumberService;
@Resource
private SystemServiceFeign systemServiceFeign;
@Autowired
private IMaterialGoodsRuleService materialGoodsRuleService;
@Autowired
private IMaterialMoreDetailService IMaterialMoreDetailService;
@@ -72,8 +84,8 @@ public class ShelfMaterialDetailImpl extends ServiceImpl<ShelfMaterialDetailMapp
? shelfMaterialDetailPO.getReceiptUniqueId() : shelfMaterialDetailPO.getUniqueId();
materialMoreDetailDO.setMaterialDetailUniqueId(materialDetailUniqueIdForQuery);
List<MaterialMoreDetailPO> materialMoreDetailList = IMaterialMoreDetailService.queryList(materialMoreDetailDO);
if (materialMoreDetailList == null) {
materialMoreDetailList = new ArrayList<>();
if (CollectionUtils.isEmpty(materialMoreDetailList)) {
materialMoreDetailList = loadTemplateMoreFromSystem(shelfMaterialDetailPO.getMaterialBaseInfoId());
}
fillAttributeValueFromShelfMaterialDetail(shelfMaterialDetailPO, materialMoreDetailList);
shelfMaterialDetailPO.setMaterialMoreDetailList(materialMoreDetailList);
@@ -100,8 +112,8 @@ public class ShelfMaterialDetailImpl extends ServiceImpl<ShelfMaterialDetailMapp
? childrenDetailPO.getReceiptUniqueId() : childrenDetailPO.getUniqueId();
materialMoreDetailDO.setMaterialDetailUniqueId(materialDetailUniqueIdForQuery);
List<MaterialMoreDetailPO> materialMoreDetailList = IMaterialMoreDetailService.queryList(materialMoreDetailDO);
if (materialMoreDetailList == null) {
materialMoreDetailList = new ArrayList<>();
if (CollectionUtils.isEmpty(materialMoreDetailList)) {
materialMoreDetailList = loadTemplateMoreFromSystem(childrenDetailPO.getMaterialBaseInfoId());
}
fillAttributeValueFromShelfMaterialDetail(childrenDetailPO, materialMoreDetailList);
childrenDetailPO.setMaterialMoreDetailList(materialMoreDetailList);
@@ -194,6 +206,9 @@ public class ShelfMaterialDetailImpl extends ServiceImpl<ShelfMaterialDetailMapp
? row.getReceiptUniqueId() : row.getUniqueId();
materialMoreDetailDO.setMaterialDetailUniqueId(materialDetailUniqueIdForQuery);
List<MaterialMoreDetailPO> materialMoreDetailList = IMaterialMoreDetailService.queryList(materialMoreDetailDO);
if (CollectionUtils.isEmpty(materialMoreDetailList)) {
materialMoreDetailList = loadTemplateMoreFromSystem(row.getMaterialBaseInfoId());
}
if (materialMoreDetailList == null) {
materialMoreDetailList = new ArrayList<>();
}
@@ -201,6 +216,46 @@ public class ShelfMaterialDetailImpl extends ServiceImpl<ShelfMaterialDetailMapp
row.setMaterialMoreDetailList(materialMoreDetailList);
}
/**
* material_more_detail 时按物料商品规则单一批次拉模板同收货单 {@link com.mhd.wms.util.ReceiptBatchDetailFilter}
*/
private List<MaterialMoreDetailPO> loadTemplateMoreFromSystem(Long materialBaseInfoId) {
if (materialBaseInfoId == null) {
return new ArrayList<>();
}
AjaxResult ajaxResult = systemServiceFeign.getBatchDetailListByMaterialBaseInfoId(materialBaseInfoId);
if (ajaxResult == null || !"200".equals(String.valueOf(ajaxResult.get("code")))) {
return new ArrayList<>();
}
List<BatchDetailFeignPO> batchList = JSON.parseArray(JSONObject.toJSONString(ajaxResult.get("data")), BatchDetailFeignPO.class);
batchList = ReceiptBatchDetailFilter.filterByMaterialGoodsRule(materialBaseInfoId, batchList, materialGoodsRuleService);
return filterAndConvertToMaterialMoreDetail(batchList);
}
/**
* 过滤 isDisplay=1 的批次属性并转换为 MaterialMoreDetailPO与收货/PC 端一致
*/
private List<MaterialMoreDetailPO> filterAndConvertToMaterialMoreDetail(List<BatchDetailFeignPO> batchList) {
List<MaterialMoreDetailPO> result = new ArrayList<>();
if (CollectionUtils.isEmpty(batchList)) {
return result;
}
for (BatchDetailFeignPO po : batchList) {
if (po.getIsDisplay() == null || po.getIsDisplay() != 1) {
continue;
}
MaterialMoreDetailPO mpo = new MaterialMoreDetailPO();
mpo.setBatchId(po.getBatchId());
mpo.setBatchDetailId(po.getBatchDetailId());
mpo.setBatchLabels(po.getBatchLabels());
mpo.setInputControl(po.getInputControl());
mpo.setAttributeFormat(po.getAttributeFormat());
mpo.setAttributeOption(po.getAttributeOption());
result.add(mpo);
}
return result;
}
/**
* 从上架明细中获取收货数量重量体积面积批次属性值并填充到 materialMoreDetailList attributeValue
*/
@@ -46,6 +46,7 @@ import com.mhd.wms.domain.materialMoreDetail.repository.facade.IMaterialMoreDeta
import com.mhd.wms.domain.materialMoreDetail.repository.po.MaterialMoreDetailPO;
import com.mhd.wms.domain.materialMoreDetail.repository.todo.MaterialMoreDetailDO;
import com.mhd.wms.domain.qualityInspection.repository.facade.IQualityInspectionService;
import com.mhd.wms.util.ReceiptBatchDetailFilter;
import com.mhd.wms.domain.qualityInspection.repository.todo.QualityInspectionDO;
import com.mhd.wms.domain.receiptMaterialDetail.entity.ReceiptMaterialDetail;
import com.mhd.wms.domain.receiptMaterialDetail.repository.facade.IReceiptMaterialDetailService;
@@ -319,6 +320,8 @@ public class StockReceiptOrderDomainService {
return materialMoreDetailPOList;
}
List<BatchDetailFeignPO> batchDetailFeignPOList = JSON.parseArray(JSONObject.toJSONString(ajaxResult.get("data")), BatchDetailFeignPO.class);
batchDetailFeignPOList = ReceiptBatchDetailFilter.filterByMaterialGoodsRule(
materialBaseInfoId, batchDetailFeignPOList, materialGoodsRuleService);
if (CollectionUtils.isEmpty(batchDetailFeignPOList)) {
return materialMoreDetailPOList;
}
@@ -0,0 +1,43 @@
package com.mhd.wms.util;
import com.mhd.system.api.domain.BatchDetailFeignPO;
import com.mhd.wms.domain.materialGoodsRule.repository.facade.IMaterialGoodsRuleService;
import com.mhd.wms.domain.materialGoodsRule.repository.po.MaterialGoodsRulePO;
import org.springframework.util.CollectionUtils;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
/**
* 收货单明细批次更多属性与物料商品规则对齐只展示 material_goods_rule 中绑定的 batchId 下的批次属性避免多批次模板并集导致几十条空壳
*/
public final class ReceiptBatchDetailFilter {
private ReceiptBatchDetailFilter() {
}
/**
* 按物料商品规则中的 batchId 过滤 system 返回的批次属性行
* 无商品规则或规则未绑定 batchId 时返回空列表不展示跨批次模板的并集
*/
public static List<BatchDetailFeignPO> filterByMaterialGoodsRule(
Long materialBaseInfoId,
List<BatchDetailFeignPO> fromSystem,
IMaterialGoodsRuleService materialGoodsRuleService) {
if (materialBaseInfoId == null) {
return fromSystem == null ? new ArrayList<>() : fromSystem;
}
if (CollectionUtils.isEmpty(fromSystem)) {
return new ArrayList<>();
}
MaterialGoodsRulePO rule = materialGoodsRuleService.getInfoByMaterialBaseInfoIds(materialBaseInfoId);
if (rule == null || rule.getBatchId() == null) {
return new ArrayList<>();
}
final Long targetBatchId = rule.getBatchId();
return fromSystem.stream()
.filter(b -> b.getBatchId() != null && targetBatchId.equals(b.getBatchId()))
.collect(Collectors.toList());
}
}