From 0263258f3e0294aef0cf6c7997519ecc4a86a149 Mon Sep 17 00:00:00 2001 From: "zangch@mesnac.com" Date: Thu, 15 Jan 2026 16:47:18 +0800 Subject: [PATCH] =?UTF-8?q?refactor(qms):=20=E9=87=8D=E6=9E=84=E8=B4=A8?= =?UTF-8?q?=E6=A3=80=E5=9B=9E=E8=B0=83WMS=E6=9C=8D=E5=8A=A1=E4=BB=A5?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E5=A4=9A=E7=A7=8D=E8=B4=A8=E6=A3=80=E5=9C=BA?= =?UTF-8?q?=E6=99=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在InspectionCompleteNotification中新增updateQty字段用于控制数量更新 - 重写IQcWmsCallbackService接口,分离质检完成、让步接收等不同回调场景 - 实现新的回调逻辑,根据质检结果更新WMS的不同inspectionType状态 - 添加对让步接收通过和不通过两种场景的分别处理 - 重构WMS回调服务实现,支持同时更新质检状态和分摊数量 - 弃用旧的回调方法并提供新的统一入口方法 - 优化代码结构,提高可维护性和扩展性 --- .../dto/InspectionCompleteNotification.java | 9 + .../qms/service/IQcWmsCallbackService.java | 134 +++--- .../impl/QcWmsCallbackServiceImpl.java | 414 +++++++++++------- .../WmsInspectionCallbackServiceImpl.java | 103 +++-- 4 files changed, 412 insertions(+), 248 deletions(-) diff --git a/ruoyi-api/hwmom-api-qms/src/main/java/org/dromara/qms/api/dto/InspectionCompleteNotification.java b/ruoyi-api/hwmom-api-qms/src/main/java/org/dromara/qms/api/dto/InspectionCompleteNotification.java index 547f56a2..8094114f 100644 --- a/ruoyi-api/hwmom-api-qms/src/main/java/org/dromara/qms/api/dto/InspectionCompleteNotification.java +++ b/ruoyi-api/hwmom-api-qms/src/main/java/org/dromara/qms/api/dto/InspectionCompleteNotification.java @@ -92,4 +92,13 @@ public class InspectionCompleteNotification implements Serializable { */ private String inspectionEndTime; + /** + * 是否更新数量标记 + *

+ * 可选,0=不更新(默认),1=更新为qualifiedQty + *

+ * 使用场景:让步接收评审不通过时,需要更新入库数量为实际合格数量 + */ + private String updateQty; + } diff --git a/ruoyi-modules/hwmom-qms/src/main/java/org/dromara/qms/service/IQcWmsCallbackService.java b/ruoyi-modules/hwmom-qms/src/main/java/org/dromara/qms/service/IQcWmsCallbackService.java index 55b93acd..bb97c9d4 100644 --- a/ruoyi-modules/hwmom-qms/src/main/java/org/dromara/qms/service/IQcWmsCallbackService.java +++ b/ruoyi-modules/hwmom-qms/src/main/java/org/dromara/qms/service/IQcWmsCallbackService.java @@ -1,80 +1,112 @@ package org.dromara.qms.service; import org.dromara.qms.domain.vo.QcInspectionMainVo; +import org.dromara.qms.domain.vo.QcUnqualifiedReviewVo; + +import java.math.BigDecimal; /** * QMS 回调 WMS 服务接口 *

* 专门负责 QMS 质检完成后回调 WMS 的业务逻辑 - * 独立抽离便于维护和调试,可复用现有服务方法 *

- * 说明:此接口为独立抽离的新文件,不修改现有文件(如 QcPDAServiceImpl) + * 重构说明(2026-01-15): + * 1. 入库由 PDA 扫码完成,QMS 只更新 WMS 的质检状态(inspectionType) + * 2. 回调方法已独立抽离,便于替换为其他 Dubbo 服务或 REST API,或直接注释弃用 + * 3. 支持检测类型判断,当前 WMS 默认传 inspectionType=4(原材料检) + *

+ * 状态说明: + * - inspectionType: 0=未发起, 1=质检中, 2=合格, 3=不合格 + * - inspectionRequest: 0=必检, 1=免检 * * @author zch * @date 2026-01-15 */ public interface IQcWmsCallbackService { - /** - * 质检完成时回调 WMS(合格场景) - *

- * 业务流程: - * 1. 检查是否有合格数量 - * 2. 构建 InspectionCompleteNotification 通知参数 - * 3. 调用 WMS Dubbo 接口更新质检状态 - * 4. 只更新 inspection_type 状态,不创建入库记录 - *

- * 调用时机: - * - PDA 提交质检结果后(QcPDAServiceImpl.submitInspection) - * - 让步接收评审完成后(QcUnqualifiedReviewServiceImpl.completeTask) - *

- * 说明:调用方需要添加 @GlobalTransactional 注解 - * - * @param main 质检主表信息 - * @return true=回调成功,false=回调失败 - */ - boolean notifyWmsForQualified(QcInspectionMainVo main); + // ==================== 质检完成回调 ==================== /** - * 让步接收完成时回调 WMS + * 【核心方法】PDA质检完成后回调WMS *

- * 业务流程: - * 1. 从质检单号获取质检主表信息 - * 2. 构建通知参数(让步接收数量作为合格数量) - * 3. 调用 WMS Dubbo 接口更新质检状态为"合格" - * 4. 保持批次号一致,支持累计入库 + * 根据质检结果更新 WMS 的 inspectionType 状态: + * - 全部合格 (qualifiedQty == inspectionQty) -> inspectionType='2'(合格) + * - 全部不合格 (qualifiedQty == 0) -> inspectionType='3'(不合格) + * - 部分合格部分不合格 -> inspectionType='1'(保持质检中,等待评审) *

- * 调用时机: - * - 不合格品评审完成,评审结果为"让步接收"(reviewResult='4') - *

- * 说明:调用方需要添加 @GlobalTransactional 注解 + * 注意: + * - 只有检测类型为原材料检(4)或入库检(7)时才回调 WMS + * - 入库由 PDA 扫码完成,不在此方法中处理 * - * @param inspectionNo 质检单号 - * @param concessionQty 让步接收数量 - * @param batchCode 批次号 + * @param main 质检主表信息 + * @return true=回调成功或无需回调,false=回调失败 + */ + boolean notifyWmsInspectionComplete(QcInspectionMainVo main); + + /** + * 检查是否需要回调 WMS + *

+ * 判断依据: + * 1. 质检类型为原材料检(qc_inspection_type='4') + * 2. 或质检类型为入库检(qc_inspection_type='7') + * 3. 且 remark 字段存储了入库单号 + * + * @param main 质检主表信息 + * @return true=需要回调WMS,false=不需要 + */ + boolean isFromWmsInspection(QcInspectionMainVo main); + + // ==================== 让步接收回调 ==================== + + /** + * 【可配置】让步接收审核通过后回调WMS + *

+ * 业务逻辑: + * 1. 更新质检主表:累加让步接收数量到合格数量 + * 2. 回调 WMS:更新 inspectionType='2'(合格) + * 3. apportion_qty 保持不变(全部入库) + * + * @param review 不合格品评审记录 * @return true=回调成功,false=回调失败 */ - boolean notifyWmsForConcession(String inspectionNo, java.math.BigDecimal concessionQty, String batchCode); + boolean notifyWmsForConcessionAccepted(QcUnqualifiedReviewVo review); + + /** + * 【可配置】让步接收审核不通过后回调WMS + *

+ * 业务逻辑: + * 1. 回调 WMS:更新 inspectionType='2'(合格,允许合格部分入库) + * 2. 同时更新 apportion_qty 为 qualifiedQty(只入库合格部分) + * + * @param review 不合格品评审记录 + * @param qualifiedQty 合格数量 + * @return true=回调成功,false=回调失败 + */ + boolean notifyWmsForConcessionRejected(QcUnqualifiedReviewVo review, BigDecimal qualifiedQty); + + // ==================== 工具方法 ==================== /** * 构建质检完成通知参数 - *

- * 从 QcInspectionMainVo 转换为 InspectionCompleteNotification - * - * @param main 质检主表信息 - * @param concessionQty 让步接收数量(可选,null表示正常质检合格) - * @param isConcession 是否为让步接收 - * @return 质检完成通知参数 - */ - Object buildNotification(QcInspectionMainVo main, java.math.BigDecimal concessionQty, boolean isConcession); - - /** - * 检查质检主表是否来自 WMS 入库 - *

- * 判断依据:质检类型为"入库检"(typeCode='7') * * @param main 质检主表信息 - * @return true=来自WMS入库,false=不是 + * @param qty 数量(null=使用质检主表数量) + * @param isConcession 是否为让步接收 + * @return InspectionCompleteNotification */ - boolean isFromWmsInspection(QcInspectionMainVo main); + Object buildNotification(QcInspectionMainVo main, BigDecimal qty, boolean isConcession); + + // ==================== 兼容旧接口(保留但标记废弃) ==================== + + /** + * @deprecated 已废弃,请使用 {@link #notifyWmsInspectionComplete(QcInspectionMainVo)} + */ + @Deprecated + boolean notifyWmsForQualified(QcInspectionMainVo main); + + /** + * @deprecated 已废弃,请使用 {@link #notifyWmsForConcessionAccepted(QcUnqualifiedReviewVo)} + */ + @Deprecated + boolean notifyWmsForConcession(String inspectionNo, BigDecimal concessionQty, String batchCode); } diff --git a/ruoyi-modules/hwmom-qms/src/main/java/org/dromara/qms/service/impl/QcWmsCallbackServiceImpl.java b/ruoyi-modules/hwmom-qms/src/main/java/org/dromara/qms/service/impl/QcWmsCallbackServiceImpl.java index 44de2151..9c53c7fb 100644 --- a/ruoyi-modules/hwmom-qms/src/main/java/org/dromara/qms/service/impl/QcWmsCallbackServiceImpl.java +++ b/ruoyi-modules/hwmom-qms/src/main/java/org/dromara/qms/service/impl/QcWmsCallbackServiceImpl.java @@ -10,6 +10,7 @@ import org.dromara.qms.api.dto.InspectionCompleteNotification; import org.dromara.qms.domain.bo.QcInspectionMainBo; import org.dromara.qms.domain.vo.QcInspectionMainVo; import org.dromara.qms.domain.vo.QcInspectionTypeVo; +import org.dromara.qms.domain.vo.QcUnqualifiedReviewVo; import org.dromara.qms.service.IQcInspectionMainService; import org.dromara.qms.service.IQcInspectionTypeService; import org.dromara.qms.service.IQcWmsCallbackService; @@ -17,18 +18,27 @@ import org.dromara.wms.api.RemoteWmsInstockService; import org.springframework.stereotype.Service; import java.math.BigDecimal; -import java.util.Date; import java.util.List; /** - * QMS 回调 WMS 服务实现 + * QMS 回调 WMS 服务实现(重构版) *

- * 负责 QMS 质检完成后回调 WMS 更新状态的完整业务流程 + * 负责 QMS 质检完成后回调 WMS 更新质检状态(inspectionType) *

- * 说明: - * 1. 此服务为独立抽离的新文件,不修改现有文件(如 QcPDAServiceImpl) - * 2. 可复用现有服务方法(如 qcInspectionMainService) - * 3. 便于维护和调试,支持后续扩展其他回调方式 + * 重构说明(2026-01-15): + * 1. 入库由 PDA 扫码完成,QMS 只更新 WMS 的质检状态 + * 2. 回调方法已独立抽离为 private 方法,便于: + * - 替换为其他 Dubbo 服务或 REST API + * - 直接注释掉不使用 + * - 根据检测类型判断是否回调 + * 3. 支持检测类型判断,当前 WMS 默认传 inspectionType=4(原材料检) + *

+ * 状态更新规则: + * - 全部合格 -> inspectionType='2'(合格) + * - 全部不合格 -> inspectionType='3'(不合格) + * - 部分合格部分不合格 -> inspectionType='1'(保持质检中,等待评审) + * - 让步接收通过 -> inspectionType='2'(合格) + * - 让步接收不通过 -> inspectionType='2' + 更新 apportion_qty 为合格数量 * * @author zch * @date 2026-01-15 @@ -39,178 +49,195 @@ import java.util.List; public class QcWmsCallbackServiceImpl implements IQcWmsCallbackService { /** - * WMS 暴露的 Dubbo 回调服务 + * 【可配置】WMS Dubbo 回调服务 *

- * 说明:WMS 模块的 RemoteWmsInspectionCallbackServiceImpl 实现此接口 + * 说明:可替换为其他 Dubbo 服务或 REST API */ @DubboReference(timeout = 300000) private RemoteWmsInstockService remoteWmsInstockService; - /** - * 复用现有的质检主表服务 - */ private final IQcInspectionMainService qcInspectionMainService; - - /** - * 复用现有的质检类型服务(用于判断是否为入库检) - */ private final IQcInspectionTypeService qcInspectionTypeService; + // ==================== 核心方法:质检完成回调 ==================== + /** - * 质检完成时回调 WMS(合格场景) + * 【核心方法】PDA质检完成后回调WMS *

- * 说明:调用方需要添加 @GlobalTransactional 注解开启分布式事务 + * 根据质检结果更新 WMS 的 inspectionType 状态: + * - 全部合格 -> inspectionType='2' + * - 全部不合格 -> inspectionType='3' + * - 部分合格部分不合格 -> inspectionType='1'(保持质检中,等待评审) */ @Override - public boolean notifyWmsForQualified(QcInspectionMainVo main) { - // 1. 检查是否来自 WMS 入库 + public boolean notifyWmsInspectionComplete(QcInspectionMainVo main) { + // 1. 检查是否需要回调 WMS if (!isFromWmsInspection(main)) { log.info("质检单 {} 不是来自 WMS 入库,跳过回调", main.getInspectionNo()); - return false; + return true; // 无需回调视为成功 } - // 2. 检查是否有合格数量 - if (main.getQualifiedQty() == null || main.getQualifiedQty().compareTo(BigDecimal.ZERO) <= 0) { - log.info("质检单 {} 无合格数量,跳过回调", main.getInspectionNo()); - return false; - } + // 2. 获取质检类型(用于判断是否回调) + String qcInspectionType = getQcInspectionType(main); + + // 3. 判断质检结果并调用对应的回调方法 + BigDecimal qualifiedQty = main.getQualifiedQty() != null ? main.getQualifiedQty() : BigDecimal.ZERO; + BigDecimal unqualifiedQty = main.getUnqualifiedQty() != null ? main.getUnqualifiedQty() : BigDecimal.ZERO; + BigDecimal inspectionQty = main.getInspectionQty() != null ? main.getInspectionQty() : BigDecimal.ZERO; + // 全部合格:合格数量等于质检数量 + if (qualifiedQty.compareTo(inspectionQty) >= 0 && unqualifiedQty.compareTo(BigDecimal.ZERO) == 0) { + log.info("质检单 {} 全部合格,回调 WMS 更新为'合格'", main.getInspectionNo()); + return callbackWmsUpdateStatus(main, "2", null, qcInspectionType); + } + // 全部不合格:合格数量为0 + else if (qualifiedQty.compareTo(BigDecimal.ZERO) == 0) { + log.info("质检单 {} 全部不合格,回调 WMS 更新为'不合格'", main.getInspectionNo()); + return callbackWmsUpdateStatus(main, "3", null, qcInspectionType); + } + // 部分合格部分不合格:保持质检中,等待评审 + else { + log.info("质检单 {} 部分合格部分不合格,保持'质检中'等待评审。合格: {}, 不合格: {}", + main.getInspectionNo(), qualifiedQty, unqualifiedQty); + // 不回调 WMS,保持原状态 inspectionType='1' + return true; + } + } + + // ==================== 让步接收回调 ==================== + + /** + * 【可配置】让步接收审核通过后回调WMS + *

+ * 业务逻辑:更新 inspectionType='2',apportion_qty 保持不变 + */ + @Override + public boolean notifyWmsForConcessionAccepted(QcUnqualifiedReviewVo review) { try { - // 3. 构建通知参数 - InspectionCompleteNotification notification = (InspectionCompleteNotification) buildNotification( - main, null, false - ); - - // 4. 调用 WMS Dubbo 接口 - R result = remoteWmsInstockService.completeInstockAfterInspection(notification); - if (result == null || result.getCode() != R.SUCCESS) { - log.error("质检单 {} 回调 WMS 失败: {}", main.getInspectionNo(), result != null ? result.getMsg() : "null"); + // 1. 获取质检主表 + QcInspectionMainVo main = queryByInspectionNo(review.getInspectionNo()); + if (main == null) { + log.error("让步接收回调失败:质检单不存在 {}", review.getInspectionNo()); return false; } - log.info("质检单 {} 回调 WMS 成功,合格数量: {}", main.getInspectionNo(), main.getQualifiedQty()); + if (!isFromWmsInspection(main)) { + log.info("质检单 {} 不是来自 WMS 入库,跳过回调", review.getInspectionNo()); + return true; + } + + String qcInspectionType = getQcInspectionType(main); + + // 2. 回调 WMS:更新状态为'合格',数量不变 + log.info("让步接收通过,质检单 {} 回调 WMS 更新为'合格'", review.getInspectionNo()); + return callbackWmsUpdateStatus(main, "2", null, qcInspectionType); + + } catch (Exception e) { + log.error("让步接收通过回调 WMS 失败: {}", e.getMessage(), e); + return false; + } + } + + /** + * 【可配置】让步接收审核不通过后回调WMS + *

+ * 业务逻辑:更新 inspectionType='2',同时更新 apportion_qty 为合格数量 + */ + @Override + public boolean notifyWmsForConcessionRejected(QcUnqualifiedReviewVo review, BigDecimal qualifiedQty) { + try { + // 1. 获取质检主表 + QcInspectionMainVo main = queryByInspectionNo(review.getInspectionNo()); + if (main == null) { + log.error("让步接收回调失败:质检单不存在 {}", review.getInspectionNo()); + return false; + } + + if (!isFromWmsInspection(main)) { + log.info("质检单 {} 不是来自 WMS 入库,跳过回调", review.getInspectionNo()); + return true; + } + + String qcInspectionType = getQcInspectionType(main); + + // 2. 回调 WMS:更新状态为'合格',同时更新数量为合格数量 + log.info("让步接收不通过,质检单 {} 回调 WMS 更新为'合格',数量更新为: {}", + review.getInspectionNo(), qualifiedQty); + return callbackWmsUpdateStatus(main, "2", qualifiedQty, qcInspectionType); + + } catch (Exception e) { + log.error("让步接收不通过回调 WMS 失败: {}", e.getMessage(), e); + return false; + } + } + + // ==================== 抽离的回调方法(便于替换或注释) ==================== + + /** + * 【可配置】调用 WMS Dubbo 更新质检状态 + *

+ * 说明:此方法已独立抽离,便于: + * 1. 替换为其他 Dubbo 服务或 REST API + * 2. 直接注释掉不使用 + * 3. 根据检测类型判断是否回调 + * + * @param main 质检主表 + * @param targetInspectionType 目标状态(2=合格,3=不合格) + * @param updateQty 需要更新的数量(null=不更新数量) + * @param qcInspectionType 检测类型(4=原材料检,7=入库检) + * @return 是否成功 + */ + private boolean callbackWmsUpdateStatus(QcInspectionMainVo main, String targetInspectionType, + BigDecimal updateQty, String qcInspectionType) { + // 【配置项】只有原材料检(4)或入库检(7)需要回调 WMS + // 可根据业务需求修改此判断条件,或直接注释掉整个方法体 + if (!"4".equals(qcInspectionType) && !"7".equals(qcInspectionType)) { + log.info("检测类型 {} 不需要回调 WMS,跳过", qcInspectionType); + return true; + } + + try { + // 构建通知参数 + InspectionCompleteNotification notification = (InspectionCompleteNotification) + buildNotification(main, updateQty, updateQty != null); + + // 设置目标状态 + notification.setResult("2".equals(targetInspectionType) ? "0" : "1"); // 0=合格, 1=不合格 + + // 如果需要更新数量 + if (updateQty != null) { + notification.setUpdateQty("1"); // 标记需要更新数量 + notification.setQualifiedQty(updateQty); + } + + // 【可替换】调用 WMS Dubbo 接口 + // 可替换为:REST API 调用、其他 Dubbo 服务、或直接注释掉 + R result = remoteWmsInstockService.completeInstockAfterInspection(notification); + + if (result == null || result.getCode() != R.SUCCESS) { + log.error("质检单 {} 回调 WMS 失败: {}", main.getInspectionNo(), + result != null ? result.getMsg() : "null"); + return false; + } + + log.info("质检单 {} 回调 WMS 成功,目标状态: {}", main.getInspectionNo(), targetInspectionType); return true; } catch (Exception e) { log.error("质检单 {} 回调 WMS 失败: {}", main.getInspectionNo(), e.getMessage(), e); - // 根据业务需求决定是否抛出异常 - // 如果不影响主流程,可以只记录日志 return false; } } - /** - * 让步接收完成时回调 WMS - *

- * 说明:调用方需要添加 @GlobalTransactional 注解开启分布式事务 - */ - @Override - public boolean notifyWmsForConcession(String inspectionNo, BigDecimal concessionQty, String batchCode) { - try { - // 1. 获取质检主表信息 - QcInspectionMainVo main = queryByInspectionNo(inspectionNo); - if (main == null) { - log.error("质检单不存在: {}", inspectionNo); - return false; - } - - // 2. 检查是否来自 WMS 入库 - if (!isFromWmsInspection(main)) { - log.info("质检单 {} 不是来自 WMS 入库,跳过回调", inspectionNo); - return false; - } - - // 3. 构建通知参数(让步接收视为合格) - InspectionCompleteNotification notification = (InspectionCompleteNotification) buildNotification( - main, concessionQty, true - ); - - // 4. 调用 WMS Dubbo 接口 - R result = remoteWmsInstockService.completeInstockAfterInspection(notification); - if (result == null || result.getCode() != R.SUCCESS) { - log.error("让步接收回调 WMS 失败: {}", result != null ? result.getMsg() : "null"); - return false; - } - - log.info("让步接收回调 WMS 成功,质检单号: {}, 批次号: {}, 数量: {}", - inspectionNo, batchCode, concessionQty); - return true; - - } catch (Exception e) { - log.error("让步接收回调 WMS 失败: {}", e.getMessage(), e); - return false; - } - } + // ==================== 工具方法 ==================== /** - * 构建质检完成通知参数 + * 检查是否需要回调 WMS *

- * 从 QcInspectionMainVo 转换为 InspectionCompleteNotification - */ - @Override - public Object buildNotification(QcInspectionMainVo main, BigDecimal concessionQty, boolean isConcession) { - InspectionCompleteNotification notification = new InspectionCompleteNotification(); - - // 基本信息 - notification.setInspectionNo(main.getInspectionNo()); - notification.setMaterialCode(main.getMaterialCode()); - - // 获取入库单号(优先从 remark 字段获取) - String instockCode = main.getRemark(); - if (StringUtils.isBlank(instockCode)) { - log.warn("质检单 {} 的 remark 字段为空,无法获取入库单号", main.getInspectionNo()); - } - notification.setInstockCode(instockCode); - - // 批次号(保持一致性) - notification.setBatchCode(main.getBatchNo()); - - // 质检结果 - if (isConcession) { - // 让步接收视为合格 - notification.setResult("0"); // 合格 - notification.setQualifiedQty(concessionQty); - notification.setUnqualifiedQty(BigDecimal.ZERO); - } else { - // 正常质检结果 - notification.setResult(main.getResult()); // 0=合格, 1=不合格 - notification.setQualifiedQty(main.getQualifiedQty()); - notification.setUnqualifiedQty(main.getUnqualifiedQty()); - } - - // 质检状态 - notification.setStatus("1"); // 已完成 - - // 质检完成时间(使用标准日期格式) - notification.setInspectionEndTime(main.getInspectionEndTime() != null - ? DateUtils.formatDateTime(main.getInspectionEndTime()) - : DateUtils.getTime()); - - return notification; - } - - /** - * 根据质检单号查询质检主表信息 - *

- * 说明:通过 queryList 方法实现,因为 IQcInspectionMainService 没有 queryByInspectionNo 方法 - * - * @param inspectionNo 质检单号 - * @return 质检主表信息,不存在则返回 null - */ - private QcInspectionMainVo queryByInspectionNo(String inspectionNo) { - if (StringUtils.isBlank(inspectionNo)) { - return null; - } - QcInspectionMainBo queryBo = new QcInspectionMainBo(); - queryBo.setInspectionNo(inspectionNo); - List list = qcInspectionMainService.queryList(queryBo); - return (list != null && !list.isEmpty()) ? list.get(0) : null; - } - - /** - * 检查质检主表是否来自 WMS 入库 - *

- * 判断依据:质检类型为"入库检"(typeCode='7') + * 判断依据: + * 1. 质检类型为原材料检(qc_inspection_type='4') + * 2. 或质检类型为入库检(qc_inspection_type='7') + * 3. 且 remark 字段存储了入库单号 */ @Override public boolean isFromWmsInspection(QcInspectionMainVo main) { @@ -224,7 +251,96 @@ public class QcWmsCallbackServiceImpl implements IQcWmsCallbackService { return false; } - // 判断是否为入库检(typeCode='7') - return "7".equals(typeVo.getTypeCode()); + // 获取质检类型的 qc_inspection_type 字段 + String qcInspectionType = typeVo.getQcInspectionType(); + + // 判断是否为原材料检(4)或入库检(7) + boolean isWmsType = "4".equals(qcInspectionType) || "7".equals(qcInspectionType); + + // 同时需要 remark 字段存储了入库单号 + boolean hasInstockCode = StringUtils.isNotBlank(main.getRemark()); + + return isWmsType && hasInstockCode; + } + + /** + * 获取质检类型的 qc_inspection_type 字段值 + */ + private String getQcInspectionType(QcInspectionMainVo main) { + if (main == null || main.getInspectionType() == null) { + return null; + } + QcInspectionTypeVo typeVo = qcInspectionTypeService.queryById(main.getInspectionType()); + return typeVo != null ? typeVo.getQcInspectionType() : null; + } + + /** + * 根据质检单号查询质检主表信息 + */ + private QcInspectionMainVo queryByInspectionNo(String inspectionNo) { + if (StringUtils.isBlank(inspectionNo)) { + return null; + } + QcInspectionMainBo queryBo = new QcInspectionMainBo(); + queryBo.setInspectionNo(inspectionNo); + List list = qcInspectionMainService.queryList(queryBo); + return (list != null && !list.isEmpty()) ? list.get(0) : null; + } + + /** + * 构建质检完成通知参数 + */ + @Override + public Object buildNotification(QcInspectionMainVo main, BigDecimal qty, boolean isConcession) { + InspectionCompleteNotification notification = new InspectionCompleteNotification(); + + // 基本信息 + notification.setInspectionNo(main.getInspectionNo()); + notification.setMaterialCode(main.getMaterialCode()); + notification.setInstockCode(main.getRemark()); // remark 存储入库单号 + notification.setBatchCode(main.getBatchNo()); + + // 质检结果 + if (isConcession) { + notification.setResult("0"); // 让步接收视为合格 + notification.setQualifiedQty(qty != null ? qty : main.getQualifiedQty()); + notification.setUnqualifiedQty(BigDecimal.ZERO); + } else { + notification.setResult(main.getResult()); + notification.setQualifiedQty(main.getQualifiedQty()); + notification.setUnqualifiedQty(main.getUnqualifiedQty()); + } + + notification.setStatus("1"); // 已完成 + notification.setInspectionEndTime(main.getInspectionEndTime() != null + ? DateUtils.formatDateTime(main.getInspectionEndTime()) + : DateUtils.getTime()); + + return notification; + } + + // ==================== 兼容旧接口(已废弃) ==================== + + /** + * @deprecated 已废弃,请使用 {@link #notifyWmsInspectionComplete(QcInspectionMainVo)} + */ + @Override + @Deprecated + public boolean notifyWmsForQualified(QcInspectionMainVo main) { + return notifyWmsInspectionComplete(main); + } + + /** + * @deprecated 已废弃,请使用 {@link #notifyWmsForConcessionAccepted(QcUnqualifiedReviewVo)} + */ + @Override + @Deprecated + public boolean notifyWmsForConcession(String inspectionNo, BigDecimal concessionQty, String batchCode) { + log.warn("调用了已废弃的方法 notifyWmsForConcession,请使用 notifyWmsForConcessionAccepted"); + QcInspectionMainVo main = queryByInspectionNo(inspectionNo); + if (main == null) { + return false; + } + return callbackWmsUpdateStatus(main, "2", concessionQty, getQcInspectionType(main)); } } diff --git a/ruoyi-modules/hwmom-wms/src/main/java/org/dromara/wms/service/impl/WmsInspectionCallbackServiceImpl.java b/ruoyi-modules/hwmom-wms/src/main/java/org/dromara/wms/service/impl/WmsInspectionCallbackServiceImpl.java index ce036041..73efca80 100644 --- a/ruoyi-modules/hwmom-wms/src/main/java/org/dromara/wms/service/impl/WmsInspectionCallbackServiceImpl.java +++ b/ruoyi-modules/hwmom-wms/src/main/java/org/dromara/wms/service/impl/WmsInspectionCallbackServiceImpl.java @@ -10,17 +10,20 @@ import org.dromara.wms.service.IWmsInspectionCallbackService; import org.dromara.wms.service.IWmsInstockPrintService; import org.springframework.stereotype.Service; +import java.math.BigDecimal; import java.util.List; /** - * WMS 质检回调服务实现 + * WMS 质检回调服务实现(重构版) *

- * 负责接收 QMS 质检完成通知并更新 WMS 批次状态 + * 负责接收 QMS 质检完成通知并更新 WMS 批次质检状态(inspectionType) *

- * 说明: - * 1. 此服务为本地服务实现,Dubbo 服务由 RemoteWmsInspectionCallbackServiceImpl 单独实现 - * 2. 此服务为独立抽离的新文件,不修改现有文件,便于维护和调试 - * 3. 只更新质检状态,不创建入库记录(入库记录由 PDA 扫码创建) + * 重构说明(2026-01-15): + * 1. 入库由 PDA 扫码完成,此服务只更新质检状态 + * 2. 支持让步接收场景:审核不通过时同时更新 apportion_qty 为合格数量 + *

+ * 状态说明: + * - inspectionType: 0=未发起, 1=质检中, 2=合格, 3=不合格 * * @author zch * @date 2026-01-15 @@ -30,15 +33,15 @@ import java.util.List; @Service public class WmsInspectionCallbackServiceImpl implements IWmsInspectionCallbackService { - /** - * 复用现有的入库打印服务 - */ private final IWmsInstockPrintService instockPrintService; /** * 处理质检完成通知 *

- * 说明:调用方(QMS)需要添加 @GlobalTransactional 注解开启分布式事务 + * 根据通知内容更新 WMS 批次的质检状态: + * - result='0' -> inspectionType='2'(合格) + * - result='1' -> inspectionType='3'(不合格) + * - updateQty='1' -> 同时更新 apportion_qty 为 qualifiedQty */ @Override public boolean handleInspectionComplete(InspectionCompleteNotification notification) { @@ -52,11 +55,13 @@ public class WmsInspectionCallbackServiceImpl implements IWmsInspectionCallbackS String instockCode = notification.getInstockCode(); String batchCode = notification.getBatchCode(); String result = notification.getResult(); + String updateQty = notification.getUpdateQty(); + BigDecimal qualifiedQty = notification.getQualifiedQty(); - log.info("收到 QMS 质检完成回调,质检单号: {}, 入库单号: {}, 批次号: {}, 结果: {}", - notification.getInspectionNo(), instockCode, batchCode, result); + log.info("收到 QMS 质检完成回调,质检单号: {}, 入库单号: {}, 批次号: {}, 结果: {}, 更新数量标记: {}", + notification.getInspectionNo(), instockCode, batchCode, result, updateQty); - // 2. 根据 instockCode + batchCode 精确查询打印记录 + // 2. 精确查询打印记录 WmsInstockPrintVo printVo = queryByInstockAndBatch(instockCode, batchCode); if (printVo == null) { log.error("未找到入库打印记录。入库单号: {}, 批次号: {}", instockCode, batchCode); @@ -64,19 +69,46 @@ public class WmsInspectionCallbackServiceImpl implements IWmsInspectionCallbackS } // 3. 根据质检结果更新状态 - if ("0".equals(result)) { - // 合格 - return updateToQualified(instockCode, batchCode); - } else { - // 不合格 - return updateToUnqualified(instockCode, batchCode); + String targetInspectionType = "0".equals(result) ? "2" : "3"; // 0=合格->2, 1=不合格->3 + + // 4. 判断是否需要更新数量(让步接收不通过场景) + BigDecimal newApportionQty = null; + if ("1".equals(updateQty) && qualifiedQty != null) { + newApportionQty = qualifiedQty; + log.info("让步接收不通过,需同时更新数量为: {}", newApportionQty); } + + return updateInspectionStatus(printVo.getInstockPrintId(), targetInspectionType, newApportionQty); + } + + /** + * 更新质检状态(内部方法) + * + * @param instockPrintId 打印记录ID + * @param inspectionType 目标质检状态(2=合格,3=不合格) + * @param apportionQty 新的分摊数量(null=不更新) + * @return 是否成功 + */ + private boolean updateInspectionStatus(Long instockPrintId, String inspectionType, BigDecimal apportionQty) { + WmsInstockPrintBo updateBo = new WmsInstockPrintBo(); + updateBo.setInstockPrintId(instockPrintId); + updateBo.setInspectionType(inspectionType); + + // 如果需要更新数量 + if (apportionQty != null) { + updateBo.setApportionQty(apportionQty); + } + + boolean result = instockPrintService.updateByBo(updateBo); + if (result) { + log.info("批次质检状态已更新。ID: {}, 状态: {}, 数量: {}", + instockPrintId, inspectionType, apportionQty); + } + return result; } /** * 更新批次质检状态为合格 - *

- * 说明:调用方(QMS)需要添加 @GlobalTransactional 注解开启分布式事务 */ @Override public boolean updateToQualified(String instockCode, String batchCode) { @@ -85,22 +117,11 @@ public class WmsInspectionCallbackServiceImpl implements IWmsInspectionCallbackS log.error("未找到入库打印记录。入库单号: {}, 批次号: {}", instockCode, batchCode); return false; } - - WmsInstockPrintBo updateBo = new WmsInstockPrintBo(); - updateBo.setInstockPrintId(printVo.getInstockPrintId()); - updateBo.setInspectionType("2"); // 合格 - - boolean result = instockPrintService.updateByBo(updateBo); - if (result) { - log.info("批次质检状态已更新为'合格'。入库单号: {}, 批次号: {}", instockCode, batchCode); - } - return result; + return updateInspectionStatus(printVo.getInstockPrintId(), "2", null); } /** * 更新批次质检状态为不合格 - *

- * 说明:调用方(QMS)需要添加 @GlobalTransactional 注解开启分布式事务 */ @Override public boolean updateToUnqualified(String instockCode, String batchCode) { @@ -109,22 +130,11 @@ public class WmsInspectionCallbackServiceImpl implements IWmsInspectionCallbackS log.error("未找到入库打印记录。入库单号: {}, 批次号: {}", instockCode, batchCode); return false; } - - WmsInstockPrintBo updateBo = new WmsInstockPrintBo(); - updateBo.setInstockPrintId(printVo.getInstockPrintId()); - updateBo.setInspectionType("3"); // 不合格 - - boolean result = instockPrintService.updateByBo(updateBo); - if (result) { - log.info("批次质检状态已更新为'不合格'。入库单号: {}, 批次号: {}", instockCode, batchCode); - } - return result; + return updateInspectionStatus(printVo.getInstockPrintId(), "3", null); } /** * 根据入库单号和批次号精确查询打印记录 - *

- * 说明:复用现有 instockPrintService.queryList() 方法 */ @Override public WmsInstockPrintVo queryByInstockAndBatch(String instockCode, String batchCode) { @@ -133,7 +143,6 @@ public class WmsInspectionCallbackServiceImpl implements IWmsInspectionCallbackS return null; } - // 复用现有服务方法查询 WmsInstockPrintBo queryBo = new WmsInstockPrintBo(); queryBo.setInstockCode(instockCode); queryBo.setBatchCode(batchCode); @@ -142,8 +151,6 @@ public class WmsInspectionCallbackServiceImpl implements IWmsInspectionCallbackS if (list == null || list.isEmpty()) { return null; } - - // 精确匹配,应该只有一条记录 return list.get(0); } }