|
|
|
|
@ -0,0 +1,230 @@
|
|
|
|
|
package org.dromara.qms.service.impl;
|
|
|
|
|
|
|
|
|
|
import lombok.RequiredArgsConstructor;
|
|
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
|
|
import org.apache.dubbo.config.annotation.DubboReference;
|
|
|
|
|
import org.dromara.common.core.domain.R;
|
|
|
|
|
import org.dromara.common.core.utils.DateUtils;
|
|
|
|
|
import org.dromara.common.core.utils.StringUtils;
|
|
|
|
|
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.service.IQcInspectionMainService;
|
|
|
|
|
import org.dromara.qms.service.IQcInspectionTypeService;
|
|
|
|
|
import org.dromara.qms.service.IQcWmsCallbackService;
|
|
|
|
|
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 服务实现
|
|
|
|
|
* <p>
|
|
|
|
|
* 负责 QMS 质检完成后回调 WMS 更新状态的完整业务流程
|
|
|
|
|
* <p>
|
|
|
|
|
* 说明:
|
|
|
|
|
* 1. 此服务为独立抽离的新文件,不修改现有文件(如 QcPDAServiceImpl)
|
|
|
|
|
* 2. 可复用现有服务方法(如 qcInspectionMainService)
|
|
|
|
|
* 3. 便于维护和调试,支持后续扩展其他回调方式
|
|
|
|
|
*
|
|
|
|
|
* @author zch
|
|
|
|
|
* @date 2026-01-15
|
|
|
|
|
*/
|
|
|
|
|
@Slf4j
|
|
|
|
|
@RequiredArgsConstructor
|
|
|
|
|
@Service
|
|
|
|
|
public class QcWmsCallbackServiceImpl implements IQcWmsCallbackService {
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* WMS 暴露的 Dubbo 回调服务
|
|
|
|
|
* <p>
|
|
|
|
|
* 说明:WMS 模块的 RemoteWmsInspectionCallbackServiceImpl 实现此接口
|
|
|
|
|
*/
|
|
|
|
|
@DubboReference(timeout = 300000)
|
|
|
|
|
private RemoteWmsInstockService remoteWmsInstockService;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 复用现有的质检主表服务
|
|
|
|
|
*/
|
|
|
|
|
private final IQcInspectionMainService qcInspectionMainService;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 复用现有的质检类型服务(用于判断是否为入库检)
|
|
|
|
|
*/
|
|
|
|
|
private final IQcInspectionTypeService qcInspectionTypeService;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 质检完成时回调 WMS(合格场景)
|
|
|
|
|
* <p>
|
|
|
|
|
* 说明:调用方需要添加 @GlobalTransactional 注解开启分布式事务
|
|
|
|
|
*/
|
|
|
|
|
@Override
|
|
|
|
|
public boolean notifyWmsForQualified(QcInspectionMainVo main) {
|
|
|
|
|
// 1. 检查是否来自 WMS 入库
|
|
|
|
|
if (!isFromWmsInspection(main)) {
|
|
|
|
|
log.info("质检单 {} 不是来自 WMS 入库,跳过回调", main.getInspectionNo());
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 2. 检查是否有合格数量
|
|
|
|
|
if (main.getQualifiedQty() == null || main.getQualifiedQty().compareTo(BigDecimal.ZERO) <= 0) {
|
|
|
|
|
log.info("质检单 {} 无合格数量,跳过回调", main.getInspectionNo());
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
// 3. 构建通知参数
|
|
|
|
|
InspectionCompleteNotification notification = (InspectionCompleteNotification) buildNotification(
|
|
|
|
|
main, null, false
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// 4. 调用 WMS Dubbo 接口
|
|
|
|
|
R<Void> 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(), main.getQualifiedQty());
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
log.error("质检单 {} 回调 WMS 失败: {}", main.getInspectionNo(), e.getMessage(), e);
|
|
|
|
|
// 根据业务需求决定是否抛出异常
|
|
|
|
|
// 如果不影响主流程,可以只记录日志
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 让步接收完成时回调 WMS
|
|
|
|
|
* <p>
|
|
|
|
|
* 说明:调用方需要添加 @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<Void> 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;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 构建质检完成通知参数
|
|
|
|
|
* <p>
|
|
|
|
|
* 从 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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 根据质检单号查询质检主表信息
|
|
|
|
|
* <p>
|
|
|
|
|
* 说明:通过 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<QcInspectionMainVo> list = qcInspectionMainService.queryList(queryBo);
|
|
|
|
|
return (list != null && !list.isEmpty()) ? list.get(0) : null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 检查质检主表是否来自 WMS 入库
|
|
|
|
|
* <p>
|
|
|
|
|
* 判断依据:质检类型为"入库检"(typeCode='7')
|
|
|
|
|
*/
|
|
|
|
|
@Override
|
|
|
|
|
public boolean isFromWmsInspection(QcInspectionMainVo main) {
|
|
|
|
|
if (main == null || main.getInspectionType() == null) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 查询质检类型信息
|
|
|
|
|
QcInspectionTypeVo typeVo = qcInspectionTypeService.queryById(main.getInspectionType());
|
|
|
|
|
if (typeVo == null) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 判断是否为入库检(typeCode='7')
|
|
|
|
|
return "7".equals(typeVo.getTypeCode());
|
|
|
|
|
}
|
|
|
|
|
}
|