fix(oms,wms): WMS出库明细uniqueId撞键修复+推单返回值校验

- WMS反审/取消下发软删出库明细时置空uniqueId(表唯一约束不含del_flag)
- omsOrderAddDetail推单前自愈: 按本次推送uniqueId值跨执行单清归档行, 反审重发不再撞键
- OMS推单三处(单头/明细/配送明细)校验返回值, 失败报WMS真实原因, 不再静默吞掉后伪装成可用库存为0
- WmsServiceFeign三方法void改AjaxResult, 控制器与降级工厂同步
This commit is contained in:
rcx
2026-09-11 16:07:21 +08:00
parent 796bb99a8b
commit b86ab75dcf
5 changed files with 52 additions and 14 deletions
@@ -74,21 +74,21 @@ public interface WmsServiceFeign {
*/
@ApiOperation("oms下发单保存")
@PostMapping(value = "/stockOutOrderApi/omsOutOrderAdd")
public void omsOutOrderAdd(@RequestBody StockOutOrder stockOutOrder);
public AjaxResult omsOutOrderAdd(@RequestBody StockOutOrder stockOutOrder);
/**
* oms下发单明细保存
*/
@ApiOperation("oms下发单明细保存")
@PostMapping(value = "/stockOutOrderApi/omsOutOrderAddDetail")
public void omsOutOrderAddDetail(@RequestBody List<OutMaterialDetail> outMaterialDetails);
public AjaxResult omsOutOrderAddDetail(@RequestBody List<OutMaterialDetail> outMaterialDetails);
/**
* oms下发单明细保存
*/
@ApiOperation("oms下发单明细保存")
@PostMapping(value = "/stockOutOrderApi/omsOutOrderAddDeliveryDetailsLink")
public void omsOutOrderAddDeliveryDetailsLink(@RequestBody List<DeliveryDetailsLink> deliveryDetailsLinks);
public AjaxResult omsOutOrderAddDeliveryDetailsLink(@RequestBody List<DeliveryDetailsLink> deliveryDetailsLinks);
/**
@@ -57,16 +57,19 @@ public class RemoteWmsFallbackFactory implements FallbackFactory<WmsServiceFeign
}
@Override
public void omsOutOrderAdd(StockOutOrder stockOutOrder) {
public AjaxResult omsOutOrderAdd(StockOutOrder stockOutOrder) {
//返回错误而非静默成功: 降级吞掉会让OMS继续走分配, 残留"有单无明细"的垃圾单
return AjaxResult.error("WMS下发单保存失败(服务降级):" + cause.getMessage());
}
@Override
public void omsOutOrderAddDetail(List<OutMaterialDetail> outMaterialDetails) {
public AjaxResult omsOutOrderAddDetail(List<OutMaterialDetail> outMaterialDetails) {
return AjaxResult.error("WMS下发单明细保存失败(服务降级):" + cause.getMessage());
}
@Override
public void omsOutOrderAddDeliveryDetailsLink(List<DeliveryDetailsLink> deliveryDetailsLinks) {
public AjaxResult omsOutOrderAddDeliveryDetailsLink(List<DeliveryDetailsLink> deliveryDetailsLinks) {
return AjaxResult.error("WMS下发单配送明细保存失败(服务降级):" + cause.getMessage());
}
@Override
@@ -534,7 +534,12 @@ public class ExecutionStockOutOrderDomainService {
stockOutOrder.setOrganizationId(orgId);
stockOutOrder.setOrganizationName(orgName);
stockOutOrder.setTopOrganizationId(topOrgId);
wmsServiceFeign.omsOutOrderAdd(stockOutOrder);
//单头/配送明细推送同样校验返回值: 降级吞掉会残留"有单无明细"等半截单
AjaxResult orderAddResult = wmsServiceFeign.omsOutOrderAdd(stockOutOrder);
if (orderAddResult == null || !"200".equals(String.valueOf(orderAddResult.get("code")))) {
throw new ServiceException("出库单[" + currentOrderNumber + "]WMS出库单推送失败:"
+ (orderAddResult == null ? "WMS服务不可用或已降级" : orderAddResult.get("msg")));
}
List<ReservationDeliveryDetailsLink> list = deliveryDetailsLinkService.list(new QueryWrapper<ReservationDeliveryDetailsLink>().lambda().eq(ReservationDeliveryDetailsLink::getOrderNumber, byId.getOutOrderNumber()));
List<DeliveryDetailsLink> deliveryDetailsLinkList = new ArrayList<>();
@@ -544,7 +549,11 @@ public class ExecutionStockOutOrderDomainService {
deliveryDetailsLink.setOmsId(reservationDeliveryDetailsLink.getId());
deliveryDetailsLinkList.add(deliveryDetailsLink);
}
wmsServiceFeign.omsOutOrderAddDeliveryDetailsLink(deliveryDetailsLinkList);
AjaxResult linkAddResult = wmsServiceFeign.omsOutOrderAddDeliveryDetailsLink(deliveryDetailsLinkList);
if (linkAddResult == null || !"200".equals(String.valueOf(linkAddResult.get("code")))) {
throw new ServiceException("出库单[" + currentOrderNumber + "]WMS配送明细推送失败:"
+ (linkAddResult == null ? "WMS服务不可用或已降级" : linkAddResult.get("msg")));
}
String inOrderNumber = stockOutOrder.getOutOrderNumber();
@@ -558,7 +567,12 @@ public class ExecutionStockOutOrderDomainService {
outMaterialDetail.setTopOrganizationId(topOrgId);
outMaterialDetailList.add(outMaterialDetail);
}
wmsServiceFeign.omsOutOrderAddDetail(outMaterialDetailList);
//明细推送必须校验返回值: 失败被降级吞掉时WMS会残留"有单无明细"的出库单, 自动分配报"可用库存为0"难定位
AjaxResult detailAddResult = wmsServiceFeign.omsOutOrderAddDetail(outMaterialDetailList);
if (detailAddResult == null || !"200".equals(String.valueOf(detailAddResult.get("code")))) {
throw new ServiceException("出库单[" + currentOrderNumber + "]WMS出库明细推送失败:"
+ (detailAddResult == null ? "WMS服务不可用或已降级" : detailAddResult.get("msg")));
}
String outOrderNumber = byId.getOutOrderNumber();
com.mhd.system.api.domain.StockOutOrderDTO stockOutOrderDTO = new com.mhd.system.api.domain.StockOutOrderDTO();
@@ -2632,6 +2632,8 @@ public class StockOutOrderDomainService {
.eq(InventoryAdjustmentRecord::getRelateNo, relateNo));
//逻辑删除出库单明细
materialDetail.setDelFlag(2);
// 归档行置空uniqueId: 明细表唯一约束不含del_flag, 保留原值会与重新下发推单时同一uniqueId的新明细撞键
materialDetail.setUniqueId(null);
outMaterialDetailService.updateById(materialDetail);
}
//逻辑删除出库单(用按单号查出的DB对象更新:OMS补偿清理只传单号,传入对象无主键,直接updateById不生效)
@@ -2772,6 +2774,8 @@ public class StockOutOrderDomainService {
}
//逻辑删除出库单明细
materialDetail.setDelFlag(2);
// 归档行置空uniqueId: 明细表唯一约束不含del_flag, 保留原值会与重新下发推单时同一uniqueId的新明细撞键
materialDetail.setUniqueId(null);
materialDetail.setReverseFlag(1);
outMaterialDetailService.updateById(materialDetail);
}
@@ -2845,11 +2849,25 @@ public class StockOutOrderDomainService {
if (CollectionUtils.isEmpty(outMaterialDetails)) {
return;
}
//幂等保护:重复下发时先逻辑删除同单号已存在的活动明细,避免重复插入导致分配/拣货数据错乱
//幂等保护:重复下发时本单已有活动明细统一软删(1→2)并置空uniqueId
outMaterialDetailService.update(new UpdateWrapper<OutMaterialDetail>().lambda()
.set(OutMaterialDetail::getDelFlag, 2)
.set(OutMaterialDetail::getUniqueId, null)
.eq(OutMaterialDetail::getOutOrderNumber, outMaterialDetails.get(0).getOutOrderNumber())
.eq(OutMaterialDetail::getDelFlag, 1));
//自愈:反审/取消下发的历史归档明细(del_flag=2, 含其他执行单残留)若仍占用本次推送的uniqueId, 置空释放键位
//(表唯一约束不含del_flag; 反审后重新下发会复用同一库存行的uniqueId, 跨执行单也要清, 否则明细插入撞唯一约束)
List<Long> pushedUniqueIds = outMaterialDetails.stream()
.map(OutMaterialDetail::getUniqueId)
.filter(java.util.Objects::nonNull)
.distinct()
.collect(Collectors.toList());
if (!pushedUniqueIds.isEmpty()) {
outMaterialDetailService.update(new UpdateWrapper<OutMaterialDetail>().lambda()
.set(OutMaterialDetail::getUniqueId, null)
.eq(OutMaterialDetail::getDelFlag, 2)
.in(OutMaterialDetail::getUniqueId, pushedUniqueIds));
}
outMaterialDetailService.saveBatch(outMaterialDetails);
autoAuditOmsOutOrder(outMaterialDetails.get(0).getOutOrderNumber());
}
@@ -521,8 +521,9 @@ public class StockOutOrderApi extends BaseController {
*/
@ApiOperation("oms下发单保存")
@PostMapping(value = "/omsOutOrderAdd")
public void omsOutOrderAdd(@RequestBody StockOutOrder stockOutOrder) {
public AjaxResult omsOutOrderAdd(@RequestBody StockOutOrder stockOutOrder) {
stockOutOrderApplicationService.omsOrderAdd(stockOutOrder);
return AjaxResult.success();
}
/**
@@ -550,8 +551,9 @@ public class StockOutOrderApi extends BaseController {
*/
@ApiOperation("oms下发单明细保存")
@PostMapping(value = "/omsOutOrderAddDetail")
public void omsOutOrderAddDetail(@RequestBody List<OutMaterialDetail> outMaterialDetails) {
public AjaxResult omsOutOrderAddDetail(@RequestBody List<OutMaterialDetail> outMaterialDetails) {
stockOutOrderApplicationService.omsOrderAddDetail(outMaterialDetails);
return AjaxResult.success();
}
/**
@@ -587,8 +589,9 @@ public class StockOutOrderApi extends BaseController {
*/
@ApiOperation("oms下发单配送明细保存")
@PostMapping(value = "/omsOutOrderAddDeliveryDetailsLink")
public void omsOutOrderAddDeliveryDetailsLink(@RequestBody List<DeliveryDetailsLink> deliveryDetailLinks) {
public AjaxResult omsOutOrderAddDeliveryDetailsLink(@RequestBody List<DeliveryDetailsLink> deliveryDetailLinks) {
stockOutOrderApplicationService.omsOrderAddDeliveryDetailsLink(deliveryDetailLinks);
return AjaxResult.success();
}
@ApiOperation("出库单提货单打印")