feat(wms): 支持库存检验任务回调并完善来料检验数据结构

- 新增库存检验任务回调相关QO类和服务,支持向WMS系统发送库存检验结果
- 扩展来料检验任务VO,添加仓库、储位和存储时长字段
- 修改数据库映射文件,增加仓库、储位和存储时长字段映射
- 新增WMS外部接口调用服务,封装HTTP请求及异常处理
- 修改测试用例中有效物料编号,保证测试数据有效性
- 引入延迟加载注解优化服务依赖注入
- 统一日志记录和响应校验,提升接口调用的可靠性和可追踪性
This commit is contained in:
曹鹏飞 2026-04-28 15:40:41 +08:00
parent dbfa45498c
commit 08a14a4f3a
8 changed files with 371 additions and 2 deletions

View File

@ -21,6 +21,7 @@ import org.apache.commons.lang3.tuple.Pair;
import org.slf4j.MDC;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
@ -105,6 +106,7 @@ public class IncomingInspectionTaskControllerService {
@Resource
private IFileUploadRecordService fileUploadRecordService;
@Lazy
@Resource
private QmsIssueTicketControllerService issueTicketControllerService;

View File

@ -0,0 +1,70 @@
package com.nflg.qms.admin.service;
import cn.hutool.json.JSONUtil;
import com.nflg.wms.common.pojo.ApiResult;
import com.nflg.wms.common.util.VUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import jakarta.annotation.Resource;
import java.util.Objects;
/**
* WMS外部接口调用服务
* 封装对WMS系统的HTTP调用包含日志记录和响应校验
*/
@Slf4j
@Service
public class WmsApiService {
@Value("${wms.host}")
private String host;
@Resource
private RestTemplate restTemplate;
/**
* 向WMS系统发送POST请求
*
* @param path 接口路径
* @param body 请求体
* @param bizDesc 业务描述用于日志和异常提示
* @param <T> 请求体类型
* @return 响应结果
*/
public <T> ApiResult<Object> post(String path, T body, String bizDesc) {
String fullUrl = host + path;
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<T> requestEntity = new HttpEntity<>(body, headers);
log.info("{}URL: {},数据: {}", bizDesc, fullUrl, JSONUtil.toJsonStr(body));
ResponseEntity<ApiResult<Object>> response = restTemplate.exchange(
fullUrl,
HttpMethod.POST,
requestEntity,
new ParameterizedTypeReference<>() {
}
);
log.info("{}结果,状态码: {},响应: {}",
bizDesc, response.getStatusCode().value(), JSONUtil.toJsonStr(response.getBody()));
VUtil.trueThrowBusinessError(!response.getStatusCode().is2xxSuccessful()
|| Objects.isNull(response.getBody())
|| response.getBody().getCode() != 200)
.throwMessage(bizDesc + "失败");
return response.getBody();
}
}

View File

@ -0,0 +1,112 @@
package com.nflg.qms.admin.service;
import com.nflg.wms.common.pojo.qo.WmsIncomingInspectionTaskCallbackQO;
import com.nflg.wms.common.pojo.qo.WmsInventoryInspectionTaskCallbackQO;
import com.nflg.wms.common.pojo.vo.QmsIncomingInspectionTaskVO;
import com.nflg.wms.repository.entity.QmsIncomingInspectionTaskRecord;
import com.nflg.wms.repository.service.IQmsIncomingInspectionTaskRecordService;
import com.nflg.wms.repository.service.IQmsIncomingInspectionTaskService;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* Wms来料检验任务回调服务
*/
@Slf4j
@Service
public class WmsIncomingInspectionTaskCallbackService {
@Value("${wms.incoming.inspection.task.callback.url}")
private String incomingUrl;
@Value("${wms.inventory.inspection.task.callback.url}")
private String inventoryUrl;
@Resource
private IQmsIncomingInspectionTaskService incomingInspectionTaskService;
@Resource
private IQmsIncomingInspectionTaskRecordService incomingInspectionTaskRecordService;
@Resource
private WmsApiService wmsApiService;
/**
* 向WMS系统发送来料检验任务回调
*/
public void incoming(Long taskId) {
QmsIncomingInspectionTaskVO taskVO = incomingInspectionTaskService.getDetail(taskId);
WmsIncomingInspectionTaskCallbackQO qo = new WmsIncomingInspectionTaskCallbackQO()
.setTaskNo(taskVO.getTaskNo())
.setInspectionType(taskVO.getInspectionType())
.setMaterialNo(taskVO.getMaterialNo())
.setSupplierCode(taskVO.getSupplierCode())
.setSupplierName(taskVO.getSupplierName())
.setDeliveryOrderNo(taskVO.getDeliveryOrderNo())
.setDeliveryOrderLine(taskVO.getDeliveryOrderLine())
.setPurchaseOrderNo(taskVO.getPurchaseOrderNo())
.setPurchaseOrderLine(taskVO.getPurchaseOrderLine())
.setFactory(taskVO.getFactory())
.setInspectionQty(taskVO.getInspectionQty())
.setQualifiedQty(taskVO.getQualifiedQty())
.setUnqualifiedQty(taskVO.getUnqualifiedQty())
.setInspectionResult(taskVO.getInspectionResult())
.setPurchaseGroup(taskVO.getPurchaseGroup());
List<QmsIncomingInspectionTaskRecord> records = incomingInspectionTaskRecordService.lambdaQuery()
.select(QmsIncomingInspectionTaskRecord::getMaterialUniqueNo, QmsIncomingInspectionTaskRecord::getQualified)
.eq(QmsIncomingInspectionTaskRecord::getTaskId, taskId)
.list();
qo.setQualifiedMaterialUniqueNo(records.stream()
.filter(QmsIncomingInspectionTaskRecord::getQualified)
.map(QmsIncomingInspectionTaskRecord::getMaterialUniqueNo)
.toList()
);
qo.setUnqualifiedMaterialUniqueNo(records.stream()
.filter(record -> !record.getQualified())
.map(QmsIncomingInspectionTaskRecord::getMaterialUniqueNo)
.toList()
);
wmsApiService.post(incomingUrl, qo, "来料检验任务回调WMS");
}
/**
* 向WMS系统发送库存检验任务回调
*/
public void inventory(Long taskId) {
QmsIncomingInspectionTaskVO taskVO = incomingInspectionTaskService.getDetail(taskId);
WmsInventoryInspectionTaskCallbackQO qo = new WmsInventoryInspectionTaskCallbackQO()
.setTaskNo(taskVO.getTaskNo())
.setMaterialNo(taskVO.getMaterialNo())
.setFactory(taskVO.getFactory())
.setWarehouse(taskVO.getWarehouse())
.setStorageLocation(taskVO.getStorageLocation())
.setStorageDays(taskVO.getStorageDays())
.setInspectionQty(taskVO.getInspectionQty())
.setQualifiedQty(taskVO.getQualifiedQty())
.setUnqualifiedQty(taskVO.getUnqualifiedQty())
.setInspectionResult(taskVO.getInspectionResult());
List<QmsIncomingInspectionTaskRecord> records = incomingInspectionTaskRecordService.lambdaQuery()
.select(QmsIncomingInspectionTaskRecord::getMaterialUniqueNo, QmsIncomingInspectionTaskRecord::getQualified)
.eq(QmsIncomingInspectionTaskRecord::getTaskId, taskId)
.list();
qo.setQualifiedMaterialUniqueNo(records.stream()
.filter(QmsIncomingInspectionTaskRecord::getQualified)
.map(QmsIncomingInspectionTaskRecord::getMaterialUniqueNo)
.toList()
);
qo.setUnqualifiedMaterialUniqueNo(records.stream()
.filter(record -> !record.getQualified())
.map(QmsIncomingInspectionTaskRecord::getMaterialUniqueNo)
.toList()
);
wmsApiService.post(inventoryUrl, qo, "库存检验任务回调WMS");
}
}

View File

@ -31,7 +31,7 @@ public class ExternalInventoryInspectionApplyApiTest {
/** 当前登录用户的 token需手动配置 */
private static final String TOKEN = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJsb2dpblR5cGUiOiJsb2dpbiIsImxvZ2luSWQiOjEsInJuU3RyIjoidVFwSWM2R3RJeUoxcFNSczBadzJzb1hvMUZLZXB3czkiLCJuYW1lIjoi6LaF57qn566h55CG5ZGYIiwiY29kZSI6ImFkbWluIiwicm9sZXMiOlsiU3VwZXJBZG1pbiJdLCJ0eXBlIjoxfQ.FtQ2uVwvuxsjAFbXnB006hV1pODtRhZT0z_9nfuR0So";
/** 有效的物料编号数据库中已存在且有已发布检验标准和绑定的IQE */
private static final String VALID_MATERIAL_NO = "2200052100";
private static final String VALID_MATERIAL_NO = "2200047982";
/** 有效的所属工厂 */
private static final String VALID_FACTORY = "1010";
/** 有效的所属仓库 */

View File

@ -0,0 +1,96 @@
package com.nflg.wms.common.pojo.qo;
import lombok.Data;
import lombok.experimental.Accessors;
import java.util.List;
@Data
@Accessors(chain = true)
public class WmsIncomingInspectionTaskCallbackQO {
/**
* 检测单号
*/
private String taskNo;
/**
* 检验类型0来料检测
*/
private Integer inspectionType;
/**
* 物料编号
*/
private String materialNo;
/**
* 供应商编号
*/
private String supplierCode;
/**
* 供应商名称
*/
private String supplierName;
/**
* 送货单号
*/
private String deliveryOrderNo;
/**
* 送货单行号
*/
private String deliveryOrderLine;
/**
* 采购单号
*/
private String purchaseOrderNo;
/**
* 采购单行号
*/
private String purchaseOrderLine;
/**
* 所属工厂
*/
private String factory;
/**
* 检验数量即送检数量
*/
private Integer inspectionQty;
/**
* 合格数量
*/
private Integer qualifiedQty;
/**
* 不合格数量
*/
private Integer unqualifiedQty;
/**
* 检验结果true=合格false=不合格
*/
private Boolean inspectionResult;
/**
* 采购组
*/
private String purchaseGroup;
/**
* 合格物料唯一编号列表
*/
private List<String> qualifiedMaterialUniqueNo;
/**
* 不合格物料唯一编号列表
*/
private List<String> unqualifiedMaterialUniqueNo;
}

View File

@ -0,0 +1,71 @@
package com.nflg.wms.common.pojo.qo;
import lombok.Data;
import lombok.experimental.Accessors;
import java.util.List;
@Data
@Accessors(chain = true)
public class WmsInventoryInspectionTaskCallbackQO {
/**
* 检测单号
*/
private String taskNo;
/**
* 物料编号
*/
private String materialNo;
/**
* 所属工厂
*/
private String factory;
/**
* 所属仓库
*/
private String warehouse;
/**
* 所属储位
*/
private String storageLocation;
/**
* 存储时长单位
*/
private Integer storageDays;
/**
* 检验数量即送检数量
*/
private Integer inspectionQty;
/**
* 合格数量
*/
private Integer qualifiedQty;
/**
* 不合格数量
*/
private Integer unqualifiedQty;
/**
* 检验结果true=合格false=不合格
*/
private Boolean inspectionResult;
/**
* 合格物料唯一编号列表
*/
private List<String> qualifiedMaterialUniqueNo;
/**
* 不合格物料唯一编号列表
*/
private List<String> unqualifiedMaterialUniqueNo;
}

View File

@ -82,6 +82,21 @@ public class QmsIncomingInspectionTaskVO {
*/
private String factory;
/**
* 所属仓库
*/
private String warehouse;
/**
* 所属储位
*/
private String storageLocation;
/**
* 存储时长单位
*/
private Integer storageDays;
/**
* 检测类型0来料检测1盘库检测
*/

View File

@ -206,7 +206,10 @@
t.update_user_id,
t.update_user_name,
t.update_time,
t.purchase_group
t.purchase_group,
t.warehouse,
t.storage_location,
t.storage_days
FROM qms_incoming_inspection_task t
LEFT JOIN qms_qc_material m ON t.material_id = m.id
LEFT JOIN qms_inspection_standard s ON t.inspection_standard_id = s.id