diff --git a/ruoyi-modules/hwmom-wms/src/main/java/org/dromara/wms/service/IWmsInspectionInitiationService.java b/ruoyi-modules/hwmom-wms/src/main/java/org/dromara/wms/service/IWmsInspectionInitiationService.java new file mode 100644 index 00000000..caea21a1 --- /dev/null +++ b/ruoyi-modules/hwmom-wms/src/main/java/org/dromara/wms/service/IWmsInspectionInitiationService.java @@ -0,0 +1,64 @@ +package org.dromara.wms.service; + +import org.dromara.wms.domain.bo.WmsInstockPrintBo; + +import java.util.List; +import java.util.Map; + +/** + * WMS 质检发起服务接口 + *
+ * 专门负责 WMS 向 QMS 发起质检任务的业务逻辑 + * 独立抽离便于维护和调试,可复用现有服务方法 + * + * @author zch + * @date 2026-01-15 + */ +public interface IWmsInspectionInitiationService { + + /** + * 批量发起质检任务 + *
+ * 业务流程: + * 1. 过滤:只处理 inspectionRequest='0'(必检)且 inspectionType='0'(未发起)的批次 + * 2. 调用 QMS Dubbo 接口创建质检任务 + * 3. 更新打印记录状态:inspectionType='1'(质检中) + * 4. 返回每个批次的处理结果 + *
+ * 说明:调用方(Controller)需要添加 @GlobalTransactional 注解
+ *
+ * @param prints 选中的打印记录列表
+ * @return Map<批次号, 质检单号或错误信息>
+ */
+ Map
+ * 说明:调用方(Controller)需要添加 @GlobalTransactional 注解
+ *
+ * @param print 单个打印记录
+ * @return 质检单号
+ */
+ String createInspectionForSingle(WmsInstockPrintBo print);
+
+ /**
+ * 校验批次是否可以发起质检
+ *
+ * 校验规则:
+ * 1. inspectionRequest 必须为 '0'(必检)
+ * 2. inspectionType 必须为 '0' 或 null(未发起)
+ *
+ * @param print 打印记录
+ * @return true=可以发起,false=不可以发起
+ */
+ boolean canInitiateInspection(WmsInstockPrintBo print);
+
+ /**
+ * 获取不能发起质检的原因
+ *
+ * @param print 打印记录
+ * @return 错误原因描述,如果可以发起则返回 null
+ */
+ String getCannotInitiateReason(WmsInstockPrintBo print);
+}
diff --git a/ruoyi-modules/hwmom-wms/src/main/java/org/dromara/wms/service/impl/WmsInspectionInitiationServiceImpl.java b/ruoyi-modules/hwmom-wms/src/main/java/org/dromara/wms/service/impl/WmsInspectionInitiationServiceImpl.java
new file mode 100644
index 00000000..0cb951e6
--- /dev/null
+++ b/ruoyi-modules/hwmom-wms/src/main/java/org/dromara/wms/service/impl/WmsInspectionInitiationServiceImpl.java
@@ -0,0 +1,202 @@
+package org.dromara.wms.service.impl;
+
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.dubbo.config.annotation.DubboReference;
+import org.dromara.common.core.exception.ServiceException;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.qms.api.RemoteQmsInspectionService;
+import org.dromara.qms.api.dto.WmsInspectionTaskRequest;
+import org.dromara.wms.domain.bo.WmsInstockPrintBo;
+import org.dromara.wms.service.IWmsInspectionInitiationService;
+import org.dromara.wms.service.IWmsInstockPrintService;
+import org.springframework.stereotype.Service;
+
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * WMS 质检发起服务实现
+ *
+ * 负责 WMS 向 QMS 发起质检任务的完整业务流程
+ *
+ * 说明:此服务为独立抽离的新文件,不修改现有文件,便于维护和调试
+ *
+ * @author zch
+ * @date 2026-01-15
+ */
+@Slf4j
+@RequiredArgsConstructor
+@Service
+public class WmsInspectionInitiationServiceImpl implements IWmsInspectionInitiationService {
+
+ /**
+ * 引用 QMS Dubbo 服务(创建质检任务)
+ */
+ @DubboReference(timeout = 300000)
+ private RemoteQmsInspectionService remoteQmsInspectionService;
+
+ /**
+ * 复用现有的入库打印服务
+ */
+ private final IWmsInstockPrintService instockPrintService;
+
+ /**
+ * 批量发起质检任务
+ *
+ * 说明:调用方(Controller)需要添加 @GlobalTransactional 注解开启分布式事务
+ */
+ @Override
+ public Map
+ * 说明:调用方(Controller)需要添加 @GlobalTransactional 注解开启分布式事务
+ */
+ @Override
+ public String createInspectionForSingle(WmsInstockPrintBo print) {
+ String batchCode = print.getBatchCode();
+ String instockCode = print.getInstockCode();
+
+ // 1. 构建质检任务请求参数
+ WmsInspectionTaskRequest request = buildInspectionRequest(print);
+
+ // 2. 调用 QMS Dubbo 接口创建质检任务
+ String inspectionNo;
+ try {
+ inspectionNo = remoteQmsInspectionService.createInspectionTaskForWMS(request);
+ } catch (ServiceException e) {
+ // 直接抛出 ServiceException
+ throw e;
+ } catch (RuntimeException e) {
+ // Dubbo 跨服务调用时,ServiceException 会被包装成 RuntimeException
+ // 解析原始异常信息并抛出 ServiceException
+ String message = e.getMessage();
+ if (message != null && message.contains("ServiceException")) {
+ // 提取 ServiceException 中的 message 部分
+ int msgStart = message.indexOf("message=");
+ if (msgStart != -1) {
+ int msgEnd = message.indexOf(",", msgStart);
+ if (msgEnd == -1) {
+ msgEnd = message.indexOf(")", msgStart);
+ }
+ if (msgEnd != -1) {
+ String extractedMsg = message.substring(msgStart + 8, msgEnd);
+ throw new ServiceException(extractedMsg);
+ }
+ }
+ }
+ throw new ServiceException("QMS 创建质检任务失败: " + message);
+ }
+
+ if (StringUtils.isBlank(inspectionNo)) {
+ throw new ServiceException("QMS 返回质检单号为空");
+ }
+
+ log.info("批次 {} 质检任务创建成功,质检单号: {}, 入库单号: {}", batchCode, inspectionNo, instockCode);
+
+ // 3. 更新本地打印记录状态(只有远程调用成功才更新)
+ WmsInstockPrintBo updateBo = new WmsInstockPrintBo();
+ updateBo.setInstockPrintId(print.getInstockPrintId());
+ updateBo.setInspectionType("1"); // 质检中
+ instockPrintService.updateByBo(updateBo);
+
+ log.info("批次 {} 质检状态已更新为'质检中'", batchCode);
+
+ return inspectionNo;
+ }
+
+ /**
+ * 校验批次是否可以发起质检
+ */
+ @Override
+ public boolean canInitiateInspection(WmsInstockPrintBo print) {
+ return getCannotInitiateReason(print) == null;
+ }
+
+ /**
+ * 获取不能发起质检的原因
+ */
+ @Override
+ public String getCannotInitiateReason(WmsInstockPrintBo print) {
+ String inspectionRequest = print.getInspectionRequest();
+ String inspectionType = print.getInspectionType();
+
+ // 校验1:是否必检
+ if (!"0".equals(inspectionRequest)) {
+ return "该批次为免检,不需要质检";
+ }
+
+ // 校验2:是否已发起
+ if (StringUtils.isNotBlank(inspectionType) && !"0".equals(inspectionType)) {
+ switch (inspectionType) {
+ case "1":
+ return "该批次质检中,请勿重复发起";
+ case "2":
+ return "该批次已质检合格";
+ case "3":
+ return "该批次质检不合格";
+ default:
+ return "该批次质检状态异常";
+ }
+ }
+
+ return null; // 可以发起
+ }
+
+ /**
+ * 构建质检任务请求参数
+ *
+ * 从 WmsInstockPrintBo 转换为 WmsInspectionTaskRequest
+ * 支持通过 inspectionTypeParam 动态指定检验类型
+ */
+ private WmsInspectionTaskRequest buildInspectionRequest(WmsInstockPrintBo print) {
+ WmsInspectionTaskRequest request = new WmsInspectionTaskRequest();
+ request.setInstockCode(print.getInstockCode()); // 入库单号
+ request.setMaterialCode(print.getMaterialCode()); // 物料编码
+ request.setMaterialName(print.getMaterialName()); // 物料名称
+ request.setInspectionQty(print.getApportionQty()); // 质检数量(分包数量)
+ request.setBatchCode(print.getBatchCode()); // 批次号
+ // 检验类型:优先使用前端传入的参数,默认为"4"(原材料检)
+ //首检=0, 专检=1, 自检=2, 互检=3, 原材料检=4, 抽检=5, 成品检=6, 入库检=7,出库检=8
+ String inspectionType = StringUtils.isNotBlank(print.getInspectionTypeParam())
+ ? print.getInspectionTypeParam() : "4";
+ request.setInspectionType(inspectionType);
+ // 以下字段可预留扩展
+ request.setStationName(null); // 工位名称(WMS入库无需工位)
+ request.setProcessCode(null); // 工序编码(WMS入库无需工序)
+ request.setSupplierName(null); // 供应商名称(可从入库单获取)
+ request.setProductionOrder(null); // 生产订单号(可从入库单获取)
+ request.setWorkshop(null); // 车间(可从入库单获取)
+ return request;
+ }
+}