From b29d86d9ed34fd890eb14cb7a75f6ae4f7148865 Mon Sep 17 00:00:00 2001
From: 云 <2163098428@qq.com>
Date: 星期二, 01 九月 2026 13:58:03 +0800
Subject: [PATCH] feat(mes): 新增防伪防窜货功能模块
---
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productsales/MesWmProductSalesServiceImpl.java | 52 ++++++++++++++++++++++++++++++++++++++++++++--------
1 files changed, 44 insertions(+), 8 deletions(-)
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productsales/MesWmProductSalesServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productsales/MesWmProductSalesServiceImpl.java
index c2a2cc6..a54a1eb 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productsales/MesWmProductSalesServiceImpl.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productsales/MesWmProductSalesServiceImpl.java
@@ -6,6 +6,7 @@
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
+import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
import cn.iocoder.yudao.module.mes.controller.admin.wm.productsales.vo.MesWmProductSalesPageReqVO;
import cn.iocoder.yudao.module.mes.controller.admin.wm.productsales.vo.MesWmProductSalesSaveReqVO;
import cn.iocoder.yudao.module.mes.controller.admin.wm.productsales.vo.MesWmProductSalesShippingReqVO;
@@ -14,6 +15,7 @@
import cn.iocoder.yudao.module.mes.dal.dataobject.pro.bagcode.MesProBagCodeDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.pro.pallet.MesProPalletDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.pro.batch.MesProBatchDO;
+import cn.iocoder.yudao.module.mes.dal.dataobject.wm.batch.MesWmBatchDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.materialstock.MesWmMaterialStockDO;
import cn.iocoder.yudao.module.mes.dal.mysql.wm.productsales.MesWmProductSalesDetailMapper;
import cn.iocoder.yudao.module.mes.service.pro.bagcode.MesProBagCodeService;
@@ -31,9 +33,12 @@
import cn.iocoder.yudao.module.mes.enums.wm.MesWmStockReserveBizTypeEnum;
import cn.iocoder.yudao.module.mes.enums.wm.MesWmTransactionTypeEnum;
import cn.iocoder.yudao.module.crm.api.customer.CrmCustomerApi;
+import cn.iocoder.yudao.module.crm.api.customer.dto.CrmCustomerRespDTO;
import cn.iocoder.yudao.module.mes.service.wm.materialstock.MesWmMaterialStockService;
import cn.iocoder.yudao.module.mes.service.wm.salesnotice.MesWmSalesNoticeService;
import cn.iocoder.yudao.module.mes.service.pro.batch.MesProBatchService;
+import cn.iocoder.yudao.module.mes.service.trace.integrity.MesTraceIntegrityService;
+import cn.iocoder.yudao.module.mes.service.wm.batch.MesWmBatchService;
import cn.iocoder.yudao.module.mes.service.wm.stockreserve.MesWmStockReserveService;
import cn.iocoder.yudao.module.mes.service.wm.transaction.MesWmTransactionService;
import cn.iocoder.yudao.module.mes.service.wm.transaction.dto.MesWmTransactionSaveReqDTO;
@@ -75,7 +80,9 @@
@Resource
private MesProPalletService palletService;
@Resource
- private MesProBatchService wmBatchService;
+ private MesProBatchService proBatchService;
+ @Resource
+ private MesWmBatchService mesWmBatchService;
@Resource
private MesWmProductSalesLineService productSalesLineService;
@@ -94,6 +101,9 @@
@Resource
@Lazy
private MesQcOqcService oqcService;
+
+ @Resource
+ private MesTraceIntegrityService integrityService;
@Resource
private ErpSaleOrderApi saleOrderApi;
@@ -228,6 +238,10 @@
if (pallet == null && bag == null) {
throw exception(WM_MATERIAL_STOCK_NOT_EXISTS);
}
+ // 鏈粦瀹氱敓浜ф壒娆$殑涓存椂鎵樼洏涓嶅厑璁稿弬涓庨攢鍞嚭搴�
+ if (pallet != null && pallet.getBatchId() == null) {
+ throw exception(PRO_PALLET_NOT_BIND_BATCH);
+ }
Long codeId = pallet != null ? pallet.getId() : bag.getId();
MesWmProductSalesDetailDO existed = pallet != null
? productSalesDetailMapper.selectBySalesIdAndPalletCodeId(reqVO.getSalesId(), codeId)
@@ -237,9 +251,14 @@
.setCodeId(codeId).setScanContent(reqVO.getScanContent()).setAlreadyScanned(true)
.setDetailId(existed.getId()).setOutboundQuantity(existed.getQuantity()).setMessage("璇ョ爜宸叉壂鎻�");
}
- Long batchId = pallet != null ? pallet.getBatchId() : bag.getBatchId();
- MesProBatchDO batch = wmBatchService.getBatch(batchId);
+ Long proBatchId = pallet != null ? pallet.getBatchId() : bag.getBatchId();
+ MesProBatchDO batch = proBatchService.getBatch(proBatchId);
if (batch == null) {
+ throw exception(WM_TRANSACTION_BATCH_NOT_EXISTS);
+ }
+ // 鐢熶骇鎵规妗ユ帴浠撳簱鎵规锛氭壂鐮佸叆搴撳啓鍏ョ殑鏄粨搴撴壒娆★紙mes_wm_batch锛夛紝姝ゅ蹇呴』鐢ㄤ粨搴撴壒娆� id 鏌ュ簱瀛�
+ MesWmBatchDO wmBatch = mesWmBatchService.getOrCreateByProBatch(batch);
+ if (wmBatch == null) {
throw exception(WM_TRANSACTION_BATCH_NOT_EXISTS);
}
List<MesWmProductSalesLineDO> lines = productSalesLineService.getProductSalesLineListBySalesId(reqVO.getSalesId());
@@ -251,7 +270,7 @@
if (quantity == null) {
quantity = line.getQuantity();
}
- List<MesWmMaterialStockDO> stocks = materialStockService.getMaterialStockListByItemAndBatch(batch.getItemId(), batchId);
+ List<MesWmMaterialStockDO> stocks = materialStockService.getMaterialStockListByItemAndBatch(batch.getItemId(), wmBatch.getId());
BigDecimal outboundQuantity = quantity;
MesWmMaterialStockDO stock = stocks.stream().filter(item -> item.getQuantity().compareTo(outboundQuantity) >= 0).findFirst().orElse(null);
if (stock == null) {
@@ -264,13 +283,13 @@
}
MesWmProductSalesDetailDO detail = new MesWmProductSalesDetailDO().setLineId(line.getId())
.setSalesId(reqVO.getSalesId()).setItemId(batch.getItemId()).setQuantity(quantity)
- .setMaterialStockId(stock.getId()).setBatchId(batchId).setBatchCode(batch.getCode())
+ .setMaterialStockId(stock.getId()).setBatchId(wmBatch.getId()).setBatchCode(wmBatch.getCode())
.setWarehouseId(stock.getWarehouseId()).setLocationId(stock.getLocationId()).setAreaId(stock.getAreaId())
.setBagCodeId(pallet == null ? codeId : null).setPalletCodeId(pallet != null ? codeId : null);
productSalesDetailMapper.insert(detail);
return new MesWmProductSalesScanRespVO().setScanType(pallet != null ? "PALLET" : "BAG")
.setCodeId(codeId).setScanContent(reqVO.getScanContent()).setItemId(batch.getItemId())
- .setBatchId(batchId).setBatchCode(batch.getCode()).setMaterialStockId(stock.getId())
+ .setBatchId(wmBatch.getId()).setBatchCode(wmBatch.getCode()).setMaterialStockId(stock.getId())
.setAvailableQuantity(stock.getQuantity()).setScanQuantity(quantity).setOutboundQuantity(quantity)
.setAlreadyScanned(false).setDetailId(detail.getId()).setWarehouseId(stock.getWarehouseId())
.setLocationId(stock.getLocationId()).setAreaId(stock.getAreaId()).setMessage("鎵爜鎴愬姛");
@@ -359,9 +378,14 @@
// 3. 閬嶅巻鎵�鏈夋槑缁嗭紝鍒涘缓搴撳瓨浜嬪姟锛堟墸鍑忓簱瀛� + 璁板綍娴佹按锛�
createTransactionList(sales);
- // 4. 鏇存柊鍑哄簱鍗曠姸鎬�
+ // 4. 鍥哄寲缁忛攢鍟嗕笌瀹為檯鍑哄簱鎿嶄綔淇℃伅
+ CrmCustomerRespDTO customer = customerApi.getCustomer(sales.getClientId());
productSalesMapper.updateById(new MesWmProductSalesDO()
- .setId(id).setStatus(MesWmProductSalesStatusEnum.FINISHED.getStatus()));
+ .setId(id)
+ .setClientName(customer != null ? customer.getName() : null)
+ .setOutboundTime(java.time.LocalDateTime.now())
+ .setOutboundUserId(SecurityFrameworkUtils.getLoginUserId())
+ .setStatus(MesWmProductSalesStatusEnum.FINISHED.getStatus()));
// 5. 鏇存柊鍏宠仈鐨勫彂璐ч�氱煡鍗曞嚭搴撴暟閲忓拰鐘舵��
if (sales.getNoticeId() != null) {
@@ -370,6 +394,18 @@
// 6. 鍥炲啓 ERP 閿�鍞鍗曠殑鍑哄簱鏁伴噺鍜岀姸鎬�
updateErpSaleOrderOutCount(sales);
+
+ // 7. 鍥炲啓琚嬬爜/鎵樼洏鍑哄簱鍘诲悜锛堜緵绐滆揣绋芥煡瀹氫綅缁忛攢鍟嗗湴鍖猴級锛屽苟鐢熸垚鍑哄簱瀹屾暣鎬ф憳瑕�
+ List<MesWmProductSalesDetailDO> outDetails = productSalesDetailService.getProductSalesDetailListBySalesId(id);
+ for (MesWmProductSalesDetailDO detail : outDetails) {
+ if (detail.getBagCodeId() != null) {
+ bagCodeService.markOutbound(detail.getBagCodeId(), id);
+ }
+ if (detail.getPalletCodeId() != null) {
+ palletService.markOutbound(detail.getPalletCodeId(), id);
+ }
+ }
+ integrityService.recordSalesIntegrity(id);
}
/**
--
Gitblit v1.9.3