From 84ac2b6b12bc3e5de072661fb25e87877c01d0d7 Mon Sep 17 00:00:00 2001
From: 云 <2163098428@qq.com>
Date: 星期六, 18 七月 2026 13:41:35 +0800
Subject: [PATCH] feat(crm): 添加客户权限过滤功能并实现销售订单客户权限控制
---
yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/sale/listener/ErpSaleOrderStatusListener.java | 160 +++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 160 insertions(+), 0 deletions(-)
diff --git a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/sale/listener/ErpSaleOrderStatusListener.java b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/sale/listener/ErpSaleOrderStatusListener.java
new file mode 100644
index 0000000..f068d75
--- /dev/null
+++ b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/sale/listener/ErpSaleOrderStatusListener.java
@@ -0,0 +1,160 @@
+package cn.iocoder.yudao.module.erp.service.sale.listener;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.iocoder.yudao.module.bpm.api.event.BpmProcessInstanceStatusEvent;
+import cn.iocoder.yudao.module.bpm.enums.task.BpmTaskStatusEnum;
+import cn.iocoder.yudao.module.erp.dal.dataobject.sale.ErpSaleOrderDO;
+import cn.iocoder.yudao.module.erp.dal.dataobject.sale.ErpSaleOrderItemDO;
+import cn.iocoder.yudao.module.erp.dal.mysql.sale.ErpSaleOrderItemMapper;
+import cn.iocoder.yudao.module.erp.dal.mysql.sale.ErpSaleOrderMapper;
+import cn.iocoder.yudao.module.erp.enums.ErpAuditStatus;
+import cn.iocoder.yudao.module.mdm.api.item.MdmItemApi;
+import cn.iocoder.yudao.module.mdm.api.item.dto.MdmItemRespDTO;
+import cn.iocoder.yudao.module.mes.api.mps.MesProMpsApi;
+import cn.iocoder.yudao.module.mes.api.mps.dto.MesProMpsCreateReqDTO;
+import jakarta.annotation.Resource;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Component;
+
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.List;
+
+/**
+ * 閿�鍞鍗曞鎵圭姸鎬佺洃鍚櫒
+ *
+ * 鐩戝惉 BPM 娴佺▼瀹炰緥鐘舵�佸彉鏇翠簨浠讹紝瀹℃牳閫氳繃鏃惰嚜鍔ㄥ垱寤� MPS
+ *
+ * @author 鑺嬮亾婧愮爜
+ */
+@Component
+@Slf4j
+public class ErpSaleOrderStatusListener extends cn.iocoder.yudao.module.bpm.api.event.BpmProcessInstanceStatusEventListener {
+
+ /**
+ * 閿�鍞鍗曞鎵规祦绋嬪畾涔� Key
+ */
+ private static final String PROCESS_DEFINITION_KEY = "sale_order_approve";
+
+ @Resource
+ private ErpSaleOrderMapper saleOrderMapper;
+ @Resource
+ private ErpSaleOrderItemMapper saleOrderItemMapper;
+ @Resource
+ private MesProMpsApi mpsApi;
+ @Resource
+ private MdmItemApi mdmItemApi;
+
+ @Override
+ protected String getProcessDefinitionKey() {
+ return PROCESS_DEFINITION_KEY;
+ }
+
+ @Override
+ protected void onEvent(BpmProcessInstanceStatusEvent event) {
+ Long orderId;
+ try {
+ orderId = Long.parseLong(event.getBusinessKey());
+ } catch (NumberFormatException e) {
+ log.warn("[onEvent] businessKey({}) 涓嶆槸鏈夋晥鐨勯攢鍞鍗曠紪鍙�", event.getBusinessKey());
+ return;
+ }
+
+ log.info("[onEvent] 鏀跺埌 BPM 瀹℃壒浜嬩欢锛宱rderId={}, status={}", orderId, event.getStatus());
+
+ // 鍙湁瀹℃壒閫氳繃鎵嶅垱寤� MPS
+ if (!BpmTaskStatusEnum.APPROVE.getStatus().equals(event.getStatus())) {
+ return;
+ }
+
+ try {
+ // 1. 鑾峰彇閿�鍞鍗�
+ ErpSaleOrderDO saleOrder = saleOrderMapper.selectById(orderId);
+ if (saleOrder == null) {
+ log.warn("[onEvent] 閿�鍞鍗曚笉瀛樺湪锛宱rderId={}", orderId);
+ return;
+ }
+
+ // 2. 鑾峰彇閿�鍞鍗曟槑缁�
+ List<ErpSaleOrderItemDO> items = saleOrderItemMapper.selectListByOrderId(orderId);
+ if (CollUtil.isEmpty(items)) {
+ log.info("[onEvent] 閿�鍞鍗�({}) 娌℃湁鏄庣粏锛屾棤闇�鍒涘缓 MPS", orderId);
+ return;
+ }
+
+ // 3. 鏇存柊璁㈠崟鐘舵�佷负宸插鏍�
+ saleOrderMapper.updateById(new ErpSaleOrderDO()
+ .setId(orderId)
+ .setStatus(ErpAuditStatus.APPROVE.getStatus()));
+
+ // 4. 閬嶅巻鏄庣粏锛屼负闇�瑕佺敓浜х殑鏄庣粏鍒涘缓 MPS
+ int mpsCount = 0;
+ for (ErpSaleOrderItemDO item : items) {
+ if (item.getNeedProduction() == null || item.getNeedProduction() != 1) {
+ continue;
+ }
+ try {
+ Long mpsId = createMpsForSaleOrderItem(saleOrder, item);
+ if (mpsId != null) {
+ mpsCount++;
+ // 鏇存柊閿�鍞鍗曟槑缁嗙殑 MPS 鍏宠仈
+ saleOrderItemMapper.updateById(new ErpSaleOrderItemDO()
+ .setId(item.getId())
+ .setMpsId(mpsId));
+ }
+ } catch (Exception e) {
+ log.error("[onEvent] 鍒涘缓 MPS 澶辫触锛宻aleOrderItemId={}", item.getId(), e);
+ }
+ }
+
+ log.info("[onEvent] 閿�鍞鍗�({}) 瀹℃壒瀹屾垚锛屽垱寤� MPS {} 鏉�", orderId, mpsCount);
+ } catch (Exception e) {
+ log.error("[onEvent] 澶勭悊閿�鍞鍗曞鎵逛簨浠跺け璐ワ紝orderId={}", orderId, e);
+ }
+ }
+
+ /**
+ * 涓洪攢鍞鍗曟槑缁嗗垱寤� MPS
+ *
+ * 娉ㄦ剰锛氶攢鍞鍗曟槑缁嗙殑 productId 鏄� MDM 鐗╂枡 ID锛岄渶瑕佹槧灏勫埌 MES 浜у搧
+ */
+ private Long createMpsForSaleOrderItem(ErpSaleOrderDO saleOrder, ErpSaleOrderItemDO item) {
+ // 鑾峰彇 MDM 鐗╂枡淇℃伅锛堢敤浜庤幏鍙栦骇鍝佸悕绉帮級
+ String productName = null;
+ try {
+ MdmItemRespDTO mdmItem = mdmItemApi.getItem(item.getProductId()).getCheckedData();
+ if (mdmItem != null) {
+ productName = mdmItem.getName();
+ }
+ } catch (Exception e) {
+ log.warn("[createMpsForSaleOrderItem] 鑾峰彇 MDM 鐗╂枡淇℃伅澶辫触锛宲roductId={}", item.getProductId(), e);
+ }
+
+ MesProMpsCreateReqDTO createReqDTO = new MesProMpsCreateReqDTO();
+ createReqDTO.setSaleOrderId(saleOrder.getId());
+ createReqDTO.setSaleOrderNo(saleOrder.getNo());
+ createReqDTO.setSaleOrderItemId(item.getId());
+ createReqDTO.setMdmItemId(item.getProductId()); // 閿�鍞鍗曟槑缁嗙殑 productId 鏄� MDM 鐗╂枡 ID
+ createReqDTO.setProductName(productName); // 浜у搧鍚嶇О鐢ㄤ簬閿欒鎻愮ず
+ createReqDTO.setQuantity(item.getCount());
+ createReqDTO.setClientId(saleOrder.getCustomerId());
+ createReqDTO.setRequestDate(formatRequestDate(saleOrder.getOrderTime()));
+ createReqDTO.setRemark("鑷姩鐢熸垚锛屾潵鑷攢鍞鍗曪細" + saleOrder.getNo());
+
+ Long mpsId = mpsApi.createMps(createReqDTO);
+ log.info("[createMpsForSaleOrderItem] MPS 鍒涘缓鎴愬姛锛宮psId={}, saleOrderItemId={}", mpsId, item.getId());
+ return mpsId;
+ }
+
+ /**
+ * 鏍煎紡鍖栭渶姹傛棩鏈�
+ */
+ private String formatRequestDate(LocalDateTime dateTime) {
+ if (dateTime == null) {
+ return null;
+ }
+ return dateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
+ }
+
+}
\ No newline at end of file
--
Gitblit v1.9.3