引言
OMS与WMS的集成是供应链系统的核心环节,直接影响订单履约效率。本文将深入探讨OMS-WMS集成的方案设计和技术实现。
1. 集成场景
1.1 出库场景
流程:
1. OMS推送出库指令
↓
2. WMS创建出库单
↓
3. WMS拣货打包
↓
4. WMS出库确认
↓
5. WMS回调OMS(运单号、发货时间)
1.2 入库场景
采购入库:
采购系统 → OMS → WMS创建入库单
退货入库:
OMS创建退货单 → WMS验收入库
2. 接口设计
2.1 出库指令接口
接口定义:
POST /api/wms/outbound/create
Content-Type: application/json
请求体:
{
"orderNo": "OMS202511220001",
"warehouseCode": "WH001",
"priority": "HIGH/NORMAL/LOW",
"timeRequirement": "STANDARD/EXPRESS",
"items": [
{
"sku": "SKU001",
"quantity": 2,
"batchNo": "BATCH001"
}
],
"consignee": {
"name": "张三",
"phone": "13800138000",
"province": "北京市",
"city": "北京市",
"district": "朝阳区",
"address": "XX街道XX号"
}
}
响应体:
{
"code": 200,
"message": "success",
"data": {
"outboundNo": "WMS202511220001",
"status": "PENDING"
}
}
2.2 出库确认回调
接口定义:
POST /api/oms/outbound/callback
Content-Type: application/json
请求体:
{
"orderNo": "OMS202511220001",
"outboundNo": "WMS202511220001",
"waybillNo": "SF1234567890",
"carrier": "顺丰速运",
"actualItems": [
{
"sku": "SKU001",
"quantity": 2,
"batchNo": "BATCH001"
}
],
"shippedTime": "2025-11-22T10:00:00"
}
3. Java实现
3.1 OMS推送出库指令
@Service
public class OutboundPushService {
@Autowired
private WmsApiClient wmsApiClient;
public void pushOutbound(Order order) {
// 构建出库指令
OutboundRequest request = new OutboundRequest();
request.setOrderNo(order.getOrderNo());
request.setWarehouseCode(order.getWarehouseCode());
request.setPriority(order.getPriority());
request.setItems(convertItems(order.getItems()));
request.setConsignee(order.getConsignee());
// 调用WMS接口
OutboundResponse response = wmsApiClient.createOutbound(request);
if (response.isSuccess()) {
// 更新订单状态
order.setStatus("PUSHED_TO_WMS");
order.setOutboundNo(response.getOutboundNo());
orderMapper.updateById(order);
log.info("已推送出库指令: orderNo={}, outboundNo={}",
order.getOrderNo(), response.getOutboundNo());
} else {
log.error("推送出库指令失败: orderNo={}, error={}",
order.getOrderNo(), response.getMessage());
throw new BusinessException("推送出库指令失败");
}
}
}
3.2 WMS回调OMS
@RestController
@RequestMapping("/api/oms/outbound")
public class OutboundCallbackController {
@Autowired
private OutboundCallbackService callbackService;
@PostMapping("/callback")
public ApiResponse callback(@RequestBody OutboundCallbackRequest request) {
try {
callbackService.handleCallback(request);
return ApiResponse.success();
} catch (Exception e) {
log.error("处理出库回调失败", e);
return ApiResponse.error("处理失败");
}
}
}
@Service
public class OutboundCallbackService {
@Transactional
public void handleCallback(OutboundCallbackRequest request) {
// 1. 查询订单
Order order = orderMapper.selectByOrderNo(request.getOrderNo());
if (order == null) {
throw new BusinessException("订单不存在");
}
// 2. 更新订单状态
order.setStatus("SHIPPED");
order.setWaybillNo(request.getWaybillNo());
order.setCarrier(request.getCarrier());
order.setShippedTime(request.getShippedTime());
orderMapper.updateById(order);
// 3. 扣减库存
for (ItemDTO item : request.getActualItems()) {
inventoryService.deduct(item.getSku(), item.getQuantity());
}
// 4. 推送配送信息到TMS
tmsService.pushShipment(order);
log.info("出库回调处理完成: orderNo={}, waybillNo={}",
request.getOrderNo(), request.getWaybillNo());
}
}
4. 数据一致性保障
4.1 幂等性设计
订单号去重:
@Service
public class IdempotentService {
@Autowired
private RedisTemplate<String, String> redisTemplate;
public boolean checkAndSet(String orderNo) {
String key = "outbound:idempotent:" + orderNo;
// 设置key,过期时间24小时
Boolean success = redisTemplate.opsForValue()
.setIfAbsent(key, "1", 24, TimeUnit.HOURS);
return Boolean.TRUE.equals(success);
}
}
4.2 重试机制
指数退避重试:
@Component
public class OutboundRetryTask {
@Scheduled(fixedRate = 60000) // 每分钟
public void retryFailedOutbound() {
List<Order> failedOrders = orderMapper.selectFailed();
for (Order order : failedOrders) {
if (order.getRetryCount() >= 3) {
// 超过最大重试次数,人工介入
alertService.send("出库推送失败: " + order.getOrderNo());
continue;
}
try {
outboundPushService.pushOutbound(order);
order.setRetryCount(0);
} catch (Exception e) {
order.setRetryCount(order.getRetryCount() + 1);
log.error("重试推送出库失败: orderNo={}", order.getOrderNo(), e);
}
orderMapper.updateById(order);
}
}
}
5. 异常处理
5.1 WMS缺货
public void handleOutOfStock(Order order, String sku) {
// 1. 部分发货
if (order.getAllowPartialShip()) {
wmsService.shipAvailableItems(order);
omsService.createBackorder(order, sku); // 创建缺货补单
}
// 2. 取消订单
else if (order.getAllowCancel()) {
omsService.cancelOrder(order.getOrderNo());
inventoryService.releaseReserved(order); // 释放预占库存
}
// 3. 转其他仓库
else {
String alternativeWarehouse = findAlternativeWarehouse(sku);
if (alternativeWarehouse != null) {
order.setWarehouseCode(alternativeWarehouse);
outboundPushService.pushOutbound(order);
}
}
}
6. 总结
OMS-WMS集成是订单履约的核心环节,需要设计完善的接口和异常处理机制。
核心要点:
- 接口设计:出库指令、出库回调
- 一致性保障:幂等性、重试机制
- 异常处理:缺货、超时、人工介入
下一篇文章将探讨WMS-TMS集成方案,敬请期待!