From bc9d77f6061a5c7f7deceaabc7c5ed6c17ad8c2f Mon Sep 17 00:00:00 2001
From: gaoluyang <2820782392@qq.com>
Date: 星期一, 12 十月 2026 14:19:37 +0800
Subject: [PATCH] fix(wm/productissue): 修复物料匹配校验逻辑并迁移至 MDM 物料服务
---
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productissue/MesWmProductIssueDetailServiceImpl.java | 30 +++++++++++----
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productissue/MesWmProductIssueServiceImpl.java | 10 ++--
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productissue/MesWmProductIssueLineController.java | 18 ++++----
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productissue/MesWmProductIssueLineServiceImpl.java | 38 +++++++++++++++----
4 files changed, 66 insertions(+), 30 deletions(-)
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productissue/MesWmProductIssueLineController.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productissue/MesWmProductIssueLineController.java
index 0e329aa..5523d77 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productissue/MesWmProductIssueLineController.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productissue/MesWmProductIssueLineController.java
@@ -12,14 +12,14 @@
import cn.iocoder.yudao.module.mes.controller.admin.wm.productissue.vo.line.MesWmProductIssueLineSaveReqVO;
import cn.iocoder.yudao.module.mdm.api.item.MdmItemModelApi;
import cn.iocoder.yudao.module.mdm.api.item.dto.MdmItemModelRespDTO;
-import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.md.unitmeasure.MesMdUnitMeasureDO;
+import cn.iocoder.yudao.module.mes.dal.dataobject.mdm.MesMdmItemDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.pro.task.MesProTaskDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.pro.workorder.MesProWorkOrderBomDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productissue.MesWmProductIssueDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productissue.MesWmProductIssueLineDO;
-import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
import cn.iocoder.yudao.module.mes.service.md.unitmeasure.MesMdUnitMeasureService;
+import cn.iocoder.yudao.module.mes.service.mdm.MesMdmItemService;
import cn.iocoder.yudao.module.mes.service.pro.task.MesProTaskService;
import cn.iocoder.yudao.module.mes.service.pro.workorder.MesProWorkOrderBomService;
import cn.iocoder.yudao.module.mes.service.wm.productissue.MesWmProductIssueLineService;
@@ -58,7 +58,7 @@
@Resource
private MesProWorkOrderBomService workOrderBomService;
@Resource
- private MesMdItemService mdmItemService;
+ private MesMdmItemService mdmItemService;
@Resource
private MesMdUnitMeasureService unitMeasureService;
@Resource
@@ -143,12 +143,12 @@
requiredQtyMap.merge(bom.getItemId(), quantity, BigDecimal::add);
}
// 3. 鎵归噺鑾峰彇鐗╂枡涓庡崟浣嶄俊鎭紝鎷兼帴 VO
- Map<Long, MesMdItemDO> itemMap = mdmItemService.getItemMap(requiredQtyMap.keySet());
+ Map<Long, MesMdmItemDO> itemMap = mdmItemService.getItemMap(requiredQtyMap.keySet());
Map<Long, MesMdUnitMeasureDO> unitMeasureMap = unitMeasureService.getUnitMeasureMap(
- convertSet(itemMap.values(), MesMdItemDO::getUnitMeasureId));
+ convertSet(itemMap.values(), MesMdmItemDO::getUnitMeasureId));
List<MesWmProductIssueBomItemRespVO> result = new ArrayList<>(requiredQtyMap.size());
requiredQtyMap.forEach((itemId, requiredQuantity) -> {
- MesMdItemDO item = itemMap.get(itemId);
+ MesMdmItemDO item = itemMap.get(itemId);
if (item == null) {
return;
}
@@ -178,10 +178,10 @@
return Collections.emptyList();
}
// 1. 鑾峰緱鍏宠仈鏁版嵁
- Map<Long, MesMdItemDO> itemMap = mdmItemService.getItemMap(
+ Map<Long, MesMdmItemDO> itemMap = mdmItemService.getItemMap(
convertSet(list, MesWmProductIssueLineDO::getItemId));
// 鐗╂枡涓诲崟浣嶄笌褰曞叆鍗曚綅閮借瑙f瀽鍚嶇О
- Set<Long> unitMeasureIds = new HashSet<>(convertSet(itemMap.values(), MesMdItemDO::getUnitMeasureId));
+ Set<Long> unitMeasureIds = new HashSet<>(convertSet(itemMap.values(), MesMdmItemDO::getUnitMeasureId));
unitMeasureIds.addAll(convertSet(list, MesWmProductIssueLineDO::getEnterUnitMeasureId));
Map<Long, MesMdUnitMeasureDO> unitMeasureMap = unitMeasureService.getUnitMeasureMap(unitMeasureIds);
Map<Long, MdmItemModelRespDTO> itemModelMap = mdmItemModelApi.getItemModelMap(
@@ -191,7 +191,7 @@
// 2. 鏋勫缓缁撴灉
return BeanUtils.toBean(list, MesWmProductIssueLineRespVO.class, vo -> {
MapUtils.findAndThen(itemMap, vo.getItemId(), item -> {
- vo.setItemCode(item.getCode()).setItemName(item.getName()).setSpecification(item.getSpecification()).setMdmItemId(item.getMdmItemId());
+ vo.setItemCode(item.getCode()).setItemName(item.getName()).setSpecification(item.getSpecification()).setMdmItemId(item.getId());
vo.setUnitMeasureId(item.getUnitMeasureId());
MapUtils.findAndThen(unitMeasureMap, item.getUnitMeasureId(),
unit -> vo.setUnitMeasureName(unit.getName()));
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productissue/MesWmProductIssueDetailServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productissue/MesWmProductIssueDetailServiceImpl.java
index 86e1de8..f9691d5 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productissue/MesWmProductIssueDetailServiceImpl.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productissue/MesWmProductIssueDetailServiceImpl.java
@@ -4,23 +4,23 @@
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
import cn.iocoder.yudao.module.mes.controller.admin.wm.productissue.vo.detail.MesWmProductIssueDetailSaveReqVO;
-import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO;
+import cn.iocoder.yudao.module.mes.dal.dataobject.mdm.MesMdmItemDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productissue.MesWmProductIssueDetailDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productissue.MesWmProductIssueDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productissue.MesWmProductIssueLineDO;
import cn.iocoder.yudao.module.mes.dal.mysql.wm.productissue.MesWmProductIssueDetailMapper;
import cn.iocoder.yudao.module.mes.enums.wm.MesWmProductIssueStatusEnum;
-import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
import cn.iocoder.yudao.module.mes.service.mdm.MesMdmItemService;
import cn.iocoder.yudao.module.mes.service.wm.materialstock.MesWmMaterialStockService;
import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseAreaService;
import jakarta.annotation.Resource;
-import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import java.util.List;
+
+import cn.iocoder.yudao.framework.common.exception.ServiceException;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*;
@@ -46,7 +46,7 @@
@Resource
private MesWmMaterialStockService materialStockService;
@Resource
- private MesMdItemService mesMdItemService;
+ private MesMdmItemService mdmItemService;
@Override
public Long createProductIssueDetail(MesWmProductIssueDetailSaveReqVO createReqVO) {
@@ -128,7 +128,6 @@
private void validateProductIssueDetailSaveData(MesWmProductIssueDetailSaveReqVO reqVO) {
// 鏍¢獙鐖舵暟鎹瓨鍦�
MesWmProductIssueLineDO line = issueLineService.validateProductIssueLineExists(reqVO.getLineId());
- MesMdItemDO item = mesMdItemService.getItem(line.getItemId());
if (ObjUtil.notEqual(line.getIssueId(), reqVO.getIssueId())) {
throw exception(WM_PRODUCT_ISSUE_DETAIL_LINE_NOT_MATCH);
}
@@ -137,8 +136,8 @@
if (ObjUtil.notEqual(MesWmProductIssueStatusEnum.APPROVING.getStatus(), issue.getStatus())) {
throw exception(WM_PRODUCT_ISSUE_STATUS_INVALID);
}
- // 鏍¢獙鐗╂枡鍖归厤锛堟槑缁� itemId 蹇呴』涓庤 itemId 涓�鑷达級
- validateDetailItemMatch(reqVO.getItemId(), item.getMdmItemId());
+ // 鏍¢獙鐗╂枡鍖归厤锛堟槑缁� itemId 蹇呴』涓庤 itemId 涓�鑷达紝涓よ�呴兘鏄� MDM 鐗╂枡涓绘暟鎹� mdm_item.id锛�
+ validateDetailItemMatch(reqVO.getItemId(), line.getItemId());
// 鏍¢獙浠撳簱銆佸簱鍖恒�佸簱浣嶇殑鍏宠仈鍏崇郴
warehouseAreaService.validateWarehouseAreaExists(
reqVO.getWarehouseId(), reqVO.getLocationId(), reqVO.getAreaId());
@@ -153,8 +152,23 @@
*/
private void validateDetailItemMatch(Long detailItemId, Long lineItemId) {
if (ObjUtil.notEqual(detailItemId, lineItemId)) {
- throw exception(WM_PRODUCT_ISSUE_DETAIL_ITEM_MISMATCH);
+ // 鍚嶇О瑙f瀽鏀惧湪寮傚父鍒嗘敮锛岄伩鍏嶆甯镐繚瀛樻椂澶氭煡琛�
+ throw new ServiceException(WM_PRODUCT_ISSUE_DETAIL_ITEM_MISMATCH.getCode(),
+ "鎷h揣鏄庣粏鐨勭墿鏂欎笌棰嗘枡鍑哄簱鍗曡鐨勭墿鏂欎笉涓�鑷达細鏄庣粏鐗╂枡[" + describeItem(detailItemId)
+ + "]锛屽崟鎹鐗╂枡[" + describeItem(lineItemId) + "]銆�"
+ + "璇烽噸鏂伴�夋嫨璇ヨ鐨勭墿鏂欏悗閲嶈瘯锛屾垨鍒犻櫎鏈潯鏄庣粏鍚庨噸鏂版坊鍔犮��");
}
}
+ /**
+ * 鎻忚堪鐗╂枡锛岀敤浜庡紓甯告彁绀猴細浼樺厛缁欏嚭銆岀紪鐮� 鍚嶇О銆嶏紝鏌ヤ笉鍒版椂鍥為��涓虹墿鏂欑紪鍙�
+ */
+ private String describeItem(Long itemId) {
+ if (itemId == null) {
+ return "鏈�夋嫨";
+ }
+ MesMdmItemDO item = mdmItemService.getItem(itemId);
+ return item != null ? item.getCode() + " " + item.getName() : "鐗╂枡缂栧彿 ID=" + itemId;
+ }
+
}
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productissue/MesWmProductIssueLineServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productissue/MesWmProductIssueLineServiceImpl.java
index 2b84d90..1551481 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productissue/MesWmProductIssueLineServiceImpl.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productissue/MesWmProductIssueLineServiceImpl.java
@@ -9,16 +9,16 @@
import cn.iocoder.yudao.module.mes.controller.admin.wm.productissue.vo.line.MesWmProductIssueLineRespVO;
import cn.iocoder.yudao.module.mes.controller.admin.wm.productissue.vo.line.MesWmProductIssueLineReturnableRespVO;
import cn.iocoder.yudao.module.mes.controller.admin.wm.productissue.vo.line.MesWmProductIssueLineSaveReqVO;
-import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.md.unitmeasure.MesMdUnitMeasureDO;
+import cn.iocoder.yudao.module.mes.dal.dataobject.mdm.MesMdmItemDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.pro.workorder.MesProWorkOrderBomDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productissue.MesWmProductIssueDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productissue.MesWmProductIssueLineDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.returnissue.MesWmReturnIssueLineDO;
import cn.iocoder.yudao.module.mes.dal.mysql.wm.productissue.MesWmProductIssueLineMapper;
import cn.iocoder.yudao.module.mes.enums.wm.MesWmProductIssueStatusEnum;
-import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
import cn.iocoder.yudao.module.mes.service.md.unitmeasure.MesMdUnitMeasureService;
+import cn.iocoder.yudao.module.mes.service.mdm.MesMdmItemService;
import cn.iocoder.yudao.module.mes.service.pro.workorder.MesProWorkOrderBomService;
import cn.iocoder.yudao.module.mes.service.wm.productissue.MesWmProductIssueDetailService;
import cn.iocoder.yudao.module.mes.service.wm.productissue.MesWmProductIssueLineService;
@@ -35,6 +35,8 @@
import java.util.Collections;
import java.util.List;
import java.util.Map;
+
+import cn.iocoder.yudao.framework.common.exception.ServiceException;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*;
@@ -53,7 +55,7 @@
@Lazy
private MesWmProductIssueService issueService;
@Resource
- private MesMdItemService mdmItemService;
+ private MesMdmItemService mdmItemService;
@Resource
@Lazy
private MesWmReturnIssueLineService returnIssueLineService;
@@ -158,10 +160,30 @@
private void validateProductIssueLineSaveData(MesWmProductIssueLineSaveReqVO reqVO) {
// 鏍¢獙鐖舵暟鎹瓨鍦� + 鑽夌鐘舵�佹墠鍏佽鏂板/淇敼琛�
issueService.validateProductIssueExistsAndPrepare(reqVO.getIssueId());
+ // 鏍¢獙鐗╂枡瀛樺湪涓斿惎鐢紙itemId 鍙e緞涓� MDM 鐗╂枡涓绘暟鎹� mdm_item.id锛�
+ validateIssueItemExistsAndEnable(reqVO.getItemId());
// 鏍¢獙鐗╂枡鍦ㄥ伐鍗� BOM 涓�
validateItemInWorkOrderBom(reqVO.getIssueId(), reqVO.getItemId());
- // 鏍¢獙鐗╂枡瀛樺湪
- mdmItemService.validateItemExists(reqVO.getItemId());
+ }
+
+ /**
+ * 鏍¢獙棰嗘枡鐗╂枡鍦� MDM 鐗╂枡涓绘暟鎹腑瀛樺湪涓斿凡鍚敤
+ *
+ * 鍒嗗埆缁欏嚭銆屾煡涓嶅埌璇ョ墿鏂欍�嶃�岀墿鏂欏凡鍋滅敤銆嶄袱绉嶅叿浣撳師鍥狅紝骞跺甫涓婄墿鏂欑殑涓氬姟鏍囪瘑涓庝笅涓�姝ュ姩浣滐紝
+ * 閬垮厤缁熶竴鎶涘嚭绗肩粺鐨勨�滅墿鏂欎笉瀛樺湪鈥濊鐢ㄦ埛鏃犱粠鍒ゆ柇銆�
+ */
+ private void validateIssueItemExistsAndEnable(Long itemId) {
+ MesMdmItemDO item = mdmItemService.getItem(itemId);
+ if (item == null) {
+ throw new ServiceException(MD_ITEM_NOT_EXISTS.getCode(),
+ "棰嗘枡鍑哄簱鍗曡鐗╂枡涓嶅瓨鍦細鎻愪氦鐨勭墿鏂欑紪鍙穂ID=" + itemId + "]鍦� MDM 鐗╂枡涓绘暟鎹腑鏌ヤ笉鍒般��"
+ + "璇烽噸鏂伴�夋嫨鐗╂枡锛涜嫢璇ョ墿鏂欏凡琚垹闄わ紝璇锋敼閫夊叾瀹冪墿鏂欍��");
+ }
+ if (item.getStatus() != null && item.getStatus() == 1) {
+ throw new ServiceException(MD_ITEM_IS_DISABLE.getCode(),
+ "棰嗘枡鍑哄簱鍗曡鐗╂枡宸插仠鐢細鐗╂枡[" + item.getCode() + " " + item.getName() + "]褰撳墠涓哄仠鐢ㄧ姸鎬侊紝涓嶈兘棰嗘枡鍑哄簱銆�"
+ + "璇峰厛鍦ㄣ�屽熀纭�鏁版嵁 - MDM 鐗╂枡銆嶄腑鍚敤璇ョ墿鏂欙紝鎴栨敼閫夊叾瀹冨凡鍚敤鐨勭墿鏂欍��");
+ }
}
private void validateItemInWorkOrderBom(Long issueId, Long itemId) {
@@ -206,10 +228,10 @@
}
// 4. 鎵归噺鏌ヨ鐗╂枡鍜屽崟浣嶄俊鎭�
- Map<Long, MesMdItemDO> itemMap = mdmItemService.getItemMap(
+ Map<Long, MesMdmItemDO> itemMap = mdmItemService.getItemMap(
CollectionUtils.convertSet(lines, MesWmProductIssueLineDO::getItemId));
Map<Long, MesMdUnitMeasureDO> unitMap = unitMeasureService.getUnitMeasureMap(
- CollectionUtils.convertSet(itemMap.values(), MesMdItemDO::getUnitMeasureId));
+ CollectionUtils.convertSet(itemMap.values(), MesMdmItemDO::getUnitMeasureId));
// 5. 缁勮缁撴灉锛岃繃婊ゅ彲閫�鏁伴噺 > 0 鐨勮
List<MesWmProductIssueLineReturnableRespVO> result = new ArrayList<>();
@@ -226,7 +248,7 @@
vo.setQuantity(returnableQty);
// 濉厖鐗╂枡淇℃伅
- MesMdItemDO item = itemMap.get(line.getItemId());
+ MesMdmItemDO item = itemMap.get(line.getItemId());
if (item != null) {
vo.setItemCode(item.getCode());
vo.setItemName(item.getName());
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productissue/MesWmProductIssueServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productissue/MesWmProductIssueServiceImpl.java
index 0b52b25..cbcaf18 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productissue/MesWmProductIssueServiceImpl.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productissue/MesWmProductIssueServiceImpl.java
@@ -8,7 +8,7 @@
import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
import cn.iocoder.yudao.module.mes.controller.admin.wm.productissue.vo.MesWmProductIssuePageReqVO;
import cn.iocoder.yudao.module.mes.controller.admin.wm.productissue.vo.MesWmProductIssueSaveReqVO;
-import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO;
+import cn.iocoder.yudao.module.mes.dal.dataobject.mdm.MesMdmItemDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.pro.task.MesProTaskDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.pro.task.MesProTaskIssueDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productissue.MesWmProductIssueDetailDO;
@@ -20,8 +20,8 @@
import cn.iocoder.yudao.module.mes.enums.wm.MesWmProductIssueStatusEnum;
import cn.iocoder.yudao.module.mes.enums.wm.MesWmStockReserveBizTypeEnum;
import cn.iocoder.yudao.module.mes.enums.wm.MesWmTransactionTypeEnum;
-import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
import cn.iocoder.yudao.module.mes.service.md.workstation.MesMdWorkstationService;
+import cn.iocoder.yudao.module.mes.service.mdm.MesMdmItemService;
import cn.iocoder.yudao.module.mes.service.pro.task.MesProTaskIssueService;
import cn.iocoder.yudao.module.mes.service.pro.task.MesProTaskService;
import cn.iocoder.yudao.module.mes.service.pro.workorder.MesProWorkOrderService;
@@ -72,7 +72,7 @@
@Resource
private MesProTaskIssueMapper taskIssueMapper;
@Resource
- private MesMdItemService mdmItemService;
+ private MesMdmItemService mdmItemService;
@Resource
private MesWmTransactionService wmTransactionService;
@Resource
@@ -275,7 +275,7 @@
}
// 鎵归噺鏌ヨ鐗╂枡淇℃伅锛堣幏鍙� unitMeasureId锛�
- Map<Long, MesMdItemDO> itemMap = mdmItemService.getItemMap(
+ Map<Long, MesMdmItemDO> itemMap = mdmItemService.getItemMap(
CollectionUtils.convertSet(lines, MesWmProductIssueLineDO::getItemId));
// 鑾峰彇鏄庣粏鍒楄〃锛岀敤浜庢彁鍙� batchCode
@@ -291,7 +291,7 @@
}
// 鑾峰彇鐗╂枡鍗曚綅
- MesMdItemDO item = itemMap.get(line.getItemId());
+ MesMdmItemDO item = itemMap.get(line.getItemId());
Long unitMeasureId = item != null ? item.getUnitMeasureId() : null;
// 鑾峰彇鎵规鍙凤細鍙栬琛岀涓�涓槑缁嗙殑 batchCode
--
Gitblit v1.9.3