🔗 GOMS ECMS 全流程文档

仓网查询 → 创建订单 | 分支: test-20260601 | 2026-06-03

📋 目录 一、整体业务流程 二、仓网查询接口 /base/warehouse/query 三、仓网查询与订单创建的关联 四、创建订单完整调用链 五、仓库 & 库位选择逻辑(重点) 六、订单状态流转(重点) 七、使用的数据库表(重点) 八、创建订单详细业务逻辑 九、关键设计要点

1整体业务流程(ECMS 视角)

ECMS 系统
  │
  ├─ ① 调用 /goms/open-api/base/warehouse/query
  │    传入: province, district, centerCode
  │    获得: 按市/县分组的仓库列表 + 库位 + 优先级
  │
  ├─ ② ECMS 根据返回结果选择仓库和库位
  │    根据 priority 选择优先级最高的仓库
  │    选择具体的 location 库位编码
  │
  └─ ③ 调用 /goms/open-api/order/create
       将选定的 location 填入订单行
       GOMS 根据 location 反查仓库并创建订单

2仓网查询接口

请求参数

字段类型必填说明
regionCodeString国家编码(默认 VN)
tenantCodeString租户编码(默认 HAIER)
areaCodeString区域简码
provinceString府/州简码
districtString市/县简码
centerCodeString贸易公司编码
typeString类型

返回结构

BaseWarehouseEcmsDataVO
├── areaName / areaCode           // 区域
├── provinceName / provinceCode   // 府/州
├── districtName / districtCode   // 市/县
├── coverProvinceName             // 覆盖范围
└── warehouseList[]
    ├── priority                  // 优先级
    ├── warehouseCode             // 仓库编码
    ├── warehouseName             // 仓库名称
    └── locationList[]
        ├── location              // ← 这个值填入订单行!
        └── locationName

查询涉及的表

表名用途查询条件
oms_base_warehouse_route仓网线路表country_code + tenant_code + province_name + center_code
oms_base_warehouse仓库主数据country_code + tenant_code + area_code + district_code + warehouse_code IN(...)
oms_base_warehouse_location库位数据warehouse_code IN(...)

3仓网查询与订单创建的关联

⚠️ 关键连接点:库位(location)
订单创建接口不会直接调用仓网查询,调用方(ECMS)必须先查询仓网,再将 location 填入订单行。
仓网查询返回
warehouseList
├ priority=1
├ warehouseCode=W001
└ locationList
  ├ L001  ← 选中
  └ L002
订单行入参
OpenOrderLineCreateParam
├ materialCode: SKU001
├ qty: 10
└ location: "L001"
GOMS 内部
location "L001"
→ location_mapping 映射
→ warehouse_location
→ 回填 warehouseCode
  + warehouseId

4创建订单完整调用链

POST /goms/open-api/order/create
│
├─ [1] OrderController.createOrder()
│   └─ 提取 eventId,填充到参数
│
├─ [2] OmsOrderServiceImpl.createOrder()
│   └─ 日志记录 + 转发
│
├─ [3] OmsOrderServiceStubImpl.createOrder()
│   ├─ JSR303 参数校验
│   ├─ OpenOrderCreateParam → OrderCreateParam 转换
│   ├─ 设置履约模式 (PICKUP / NON_INTEGRATED)
│   ├─ 解密敏感信息 (手机号、地址 - DES)
│   ├─ 处理订单行 (仓库编码继承、赠品标记)
│   └─ 调用 FulfillmentOrderClient.createOrder() [Feign RPC]
│
├─ [4] FulfillmentOrderServiceStubImpl.createOrder()
│   ├─ ★ completeWarehouseInfo() ← 仓库补全
│   │   ├─ 从第一条订单行取 location
│   │   ├─ 查 oms_base_location_mapping 做映射
│   │   ├─ 查 oms_base_warehouse_location 取仓库
│   │   └─ 回填 warehouseCode + warehouseId
│   ├─ standardizeOrderParams() 参数标准化
│   │
│   ├─ [分支A: sourceDataValidate=true 校验模式]
│   │   ├─ checkIfOrderExist() 去重校验
│   │   ├─ updateMaterialStock() 库存预校验
│   │   ├─ 发送 MQ 消息
│   │   └─ 保存入池记录 (SUCCESS/ERROR)
│   │
│   └─ [分支B: sourceDataValidate=false 创建模式]
│       ├─ ★ 创建订单 (Redis 分布式锁)
│       │   ├─ 生成订单号: OL + 时间戳 + 5位序号
│       │   ├─ INSERT oms_order_outbound
│       │   ├─ INSERT oms_order_line_outbound
│       │   └─ INSERT oms_order_outbound_shipping_provider
│       ├─ 查询已创建订单
│       ├─ ★ createDownstreamAssets()
│       │   ├─ tryCreateWarehouseOrder() → 仓储单
│       │   ├─ tryCreateShippingOrder() → 运单
│       │   └─ tryCreateUserInfo() → 用户敏感信息
│       ├─ 更新库存关联记录
│       ├─ MQ 同步物流状态到 ECMS
│       └─ 入池状态更新为 MQ_SUCCESS

5仓库 & 库位选择逻辑(重点)

5.1 仓库补全流程 completeWarehouseInfo()

Step 1:从第一条订单行取 location
String locationCode = firstOrderParam.getOpenOrderLineCreateList().get(0).getLocation();
Step 2:查 oms_base_location_mapping 做映射转换
baseLocationMappingClient.getBySrc(locationCode) → location_target
Step 3:查 oms_base_warehouse_location 获取仓库信息
warehouseLocationClient.getInfoByCode(targetLocationCode) → warehouse_code, warehouse_id
Step 4:回填到所有订单参数
orderParam.setWarehouseCode(...)
orderParam.setWarehouseId(...)
💡 规则:
• 如果订单行已有 warehouseCode → 保留不覆盖
• 如果 warehouseCode 为空 → 通过 location 反查回填
• 如果 location 映射不存在 → 直接用原始 location 编码查

5.2 库位映射表作用

oms_base_location_mapping 用于库位编码的映射转换:

字段说明
location_sourceECMS 传入的原始库位编码
location_targetGOMS 内部的标准库位编码

ECMS 和 GOMS 可能使用不同的库位编码体系,此表做桥接。

6订单状态流转(重点)

6.1 OrderStatusEnum 订单状态枚举

编码状态说明
01INVOICE发票待导入
02PENDING待分配 新订单初始
03ASSIGNED已分配
04SHIPPING发货中
05RETURN收货中
06COMPLETED已完成
07CANCELLED已取消
08FAILURE拆包失败
09EXCEPTION_WAIT异常待处理
10SIGNED签收
11REJECTED拒签
12PARTIALLY_SIGNED部分签收

6.2 创建时的初始状态

✅ 正常订单
status = 02 (PENDING)
warehouse_status = DRAFT
shipping_status = DRAFT
accounting_status = UN_BOOKKEEPING
📜 历史订单 (oldOrder=1)
status = 06 (COMPLETED)
accounting_status = BOOKKEEPING_FINISH
❌ 库存校验失败
status = 09 (EXCEPTION_WAIT)
warehouse_status = EXCEPTION_TO_BE_PROCESSED

6.3 状态流转图

              ┌──────────────┐
              │ 01 INVOICE   │
              └──────┬───────┘
                     ▼
┌────────────────────────────────────────────┐
│ 02 PENDING ──→ 03 ASSIGNED ──→ 04 SHIPPING │
└───────┬───────────────────────────┬────────┘
        │                           │
        │ 库存校验失败                ▼
        ▼                   ┌───────────────┐
┌─────────────────┐         │ 10 SIGNED     │
│ 09 EXCEPTION    │         │ 11 REJECTED   │
│    _WAIT        │         │ 12 PART_SIGN  │
└─────────────────┘         └───────┬───────┘
                                    ▼
                            ┌───────────────┐
                            │ 06 COMPLETED  │
                            └───────────────┘

07 CANCELLED — 任意阶段可取消
08 FAILURE   — 拆包失败

6.4 入池状态(Inbound Pool)

状态说明
SUCCESS源数据校验通过,已保存
ERROR校验失败,原始数据已归档
MQ_SUCCESS订单创建完成,MQ 已发送

7使用的数据库表(重点)

7.1 核心订单表

表名用途关键字段
oms_order_outbound正向订单主表order_code, external_order_code, status, warehouse_code, warehouse_id, location, center_code
oms_order_line_outbound订单行明细order_id, order_code, material_code, qty, location, warehouse_code
oms_order_outbound_shipping_provider订单承运商order_id, order_code, shipping_provider_code

7.2 仓储相关表

表名用途关键字段
oms_warehouse_order仓储操作单warehouse_order_code, order_code, status, warehouse_code
oms_warehouse_order_line仓储单行warehouse_order_code, material_code, qty
oms_base_warehouse仓库主数据warehouse_code, warehouse_name, stock_switch
oms_base_warehouse_route仓网线路warehouse_code, country_code, center_code, priority
oms_base_warehouse_location库位主数据location_code, warehouse_code, warehouse_id
oms_base_location_mapping库位映射location_source, location_target

7.3 物流相关表

表名用途关键字段
oms_shipping_order运单主表shipping_code, order_code, status
oms_shipping_order_line运单行shipping_code, order_code, material_code

7.4 库存相关表

表名用途关键字段
oms_material_stock库存主表warehouse_code, material_code, stock_qty, locked_qty
oms_material_stock_change_records库存变更日志external_order_code, order_code, operation_type
oms_base_material物料主数据material_code, material_name

7.5 辅助表

表名用途关键字段
oms_inbound_ecms_order入池数据归档outer_no, raw_data, status, data_validate_status
oms_base_user_info用户敏感信息order_code, receiver_name, receiver_mobile, receiver_address
oms_base_center贸易公司center_code, country_code

8创建订单详细业务逻辑(按阶段)

阶段一:openapi 层预处理

1. 提取 eventId
从 HTTP Header 读取 ECMS_EVENT_ID,填充到每条订单参数 → 全链路追踪标识
2. JSR303 参数校验
校验 externalOrderCode、orderSource、paymentType 等必填字段
失败 → 入池(ERROR)
3. 参数转换
OpenOrderCreateParam → OrderCreateParam,映射 OrderSourceCodeMappingEnum
4. 设置履约模式
PICKUP(自提)/ NON_INTEGRATED(非集成)
5. 解密敏感信息
receiverMobilereceiverAddress — DES 加密传输
6. 订单行处理
• 行级 warehouseCode 继承订单头
• 销售单位标准化("SET" → "PC")
• 赠品标记继承(套装商品)
• 初始化数量字段为 0(actualDeliveryQty, returnQty, actualReceiveQty)
7. 国家编码查询
centerCode → BaseCenterClient → countryCode
特殊处理:TikTok VN 订单,districtName 与 cityName 相同时清空

阶段二:fulfillment 层核心逻辑

8. ★ 仓库补全 completeWarehouseInfo()
location → mapping → warehouse_location → 回填 warehouseCode + warehouseId
9. 参数标准化
district 值为 "0" 时清空
10. 分支A:校验模式 (sourceDataValidate=true)
├─ 去重校验(externalOrderCode + orderType + tenant + region)
├─ 库存预校验(stock_switch 开启时查 oms_material_stock)
│ └─ 失败 → status=09, warehouse_status=EXCEPTION
├─ 发送 MQ 消息
└─ 入池状态 = SUCCESS
11. 分支B:创建模式 (sourceDataValidate=false)
├─ Redis 分布式锁(key: externalOrderCode2)
├─ 生成订单号:OL + yyyyMMddHHmmss + 5位序号
├─ INSERT oms_order_outbound(主订单)
├─ INSERT oms_order_line_outbound(订单行)
├─ INSERT oms_order_outbound_shipping_provider(承运商)
├─ 释放锁
├─ 查询已创建订单
├─ 创建下游资产:
│ ├─ 仓储单 (isWarehouse=1)
│ ├─ 运单 (isWarehouse=1 或 isPickup=1)
│ │ ├─ 自提模式:每个行项每个数量单位一个运单
│ │ └─ 普通模式:按 externalOrderCode2 分组 + 合包策略
│ └─ 用户敏感信息
├─ 更新库存关联记录
├─ MQ 同步物流状态到 ECMS
├─ 入池状态更新为 MQ_SUCCESS
└─ 自动分配承运商(可选,按 centerCode 配置)

9关键设计要点

🏗️ 架构设计

要点说明
两级模块架构openapi 层负责对外接口、参数校验、格式转换;base/fulfillment 层负责核心业务逻辑和数据库操作。两层通过 Feign RPC 通信。
两种执行模式校验模式 (sourceDataValidate=true):仅校验 + 保存原始数据 + 发 MQ
创建模式 (sourceDataValidate=false):实际创建订单
幂等保障Redis 分布式锁防止重复创建;复合键唯一性检查(externalOrderCode + orderType + tenant + region)
错误处理校验失败 → 入池(ERROR) 保存原始数据
创建失败 → 发送异常事件 + 通知第三方
下游资产创建失败不回滚主订单(最终一致性)
读写分离查询操作使用从库 @UseDataSource(SLAVE)
逻辑删除所有核心表使用 deleted 字段(isLogicDelete=true
国家编码补全未传 regionCode 默认 VN,再通过 centerCode 查询真实国家编码并覆盖
线路优先仓网查询先查线路表确定覆盖关系,优先级来自线路表而非仓库表
订单号生成Redis 原子自增5位序号,Key 1秒过期。格式:OL2026060314302500001
敏感数据手机号、地址 DES 加密传输,用户信息单独存储到 oms_base_user_info

📊 涉及的模块总览

模块职责
goms-access-openapi对外开放接口层,承接 ECMS 请求
goms-agg-fulfillment订单履约聚合层,仓库补全 + 订单创建 + 下游资产
goms-biz-order订单业务层,订单入库 + 订单号生成
goms-platform-base基础平台层,仓库/库位/物料等主数据
goms-biz-warehouse仓储业务层,仓储操作单
goms-biz-shipping物流业务层,运单管理

🔀 分支 A:校验模式(sourceDataValidate = true)— 销售出库单

📌 模式说明

sourceDataValidate = true 时,系统不创建实际订单,仅执行数据校验、库存预占用并发送 MQ 消息。实际的订单创建在 MQ 消费端以 sourceDataValidate = false 模式异步完成。

ECMS 调用 API(sourceDataValidate=true)
       │
       ▼
  ┌──────────────────────────────────────┐
  │  goms-access-openapi 层              │
  │  1. JSR303 参数校验                  │
  │  2. 订单数据转换                     │
  │  3. 敏感信息解密(手机/地址)         │
  └──────────────┬───────────────────────┘
                 │ 调用履约服务
                 ▼
  ┌──────────────────────────────────────┐
  │  goms-agg-fulfillment 层             │
  │  1. 补齐仓库与库位映射信息            │
  │  2. 标准化处理入参字段               │
  │  3. 校验是否重复建单                 │
  │  4. 库存预占用校验                   │
  │     └─ 失败:标记异常待处理,继续     │
  │  5. 发送 MQ(源数据同步)            │
  │  6. 落库接单池(成功记录)           │
  └──────────────┬───────────────────────┘
                 │ 返回成功
                 ▼
    ┌─────────────────────────┐
    │  oms_inbound_ecms_order │
    │  status = SUCCESS (1)   │
    │  dataValidateStatus = 1 │
    └────────────┬────────────┘
                 │
                 │  (异步消费 MQ)
                 ▼
  ┌──────────────────────────────────────┐
  │  MQ 消费端(sourceDataValidate=false)│
  │  1. 创建销售出库订单                 │
  │  2. 创建仓储作业单                   │
  │  3. 创建运输作业单                   │
  │  4. 创建用户基础信息                 │
  │  5. 更新库存关联字段                 │
  │  6. 同步 ECMS 发货状态               │
  │  7. 更新接单池状态为 MQ_SUCCESS      │
  └──────────────────────────────────────┘

📨 发送 MQ 前的处理

步骤操作说明
1补齐仓库信息通过 baseLocationMappingClient 查询库位映射,若未命中则通过 warehouseLocationClient 获取仓库编码和 ID
2校验重复建单调用 bizOmsOrderClient.existByOrderSn() 校验订单号是否已存在,若重复则保存错误记录并抛出异常
3库存预占用校验检查仓库 stockSwitch 开关,若开启则调用 materialStockClient.batchUpdateStock() 预扣库存
失败处理:标记订单状态为 EXCEPTION_WAIT,仓储状态为 EXCEPTION_TO_BE_PROCESSED,发送异常事件和第三方通知,但不中断流程
4组装接单池对象 rawData = 完整请求 JSON
outerNo = 外部订单号(DN 号)
requestId = eventId
businessDes = 订单业务类型 + 履约模式

📤 发送 MQ 详情

属性
Topicgoms_inbound_order_source
Tagtag_inbound_order_source
消息体List<OpenApiOrderCreateParam>(JSON 序列化)
消息 Key"DN:" + 排序后的外部订单号逗号分隔
发送方式InboundSourceDataValidateSender.sendInboundSourceDataSyncGoms()
发送类InboundSourceDataValidateSenderImpl(goms-agg-fulfillment 模块)

✅ 发送 MQ 成功后 — 落库接单池

调用 saveSuccessInboundEcmsOrderInfo(inboundOrderCreateParam),写入表 oms_inbound_ecms_order

字段说明
raw_data原始请求 JSON完整保存 ECMS 推送的原始数据
outer_no外部订单号(DN 号)用于后续更新匹配
request_ideventId请求追踪 ID
receive_time当前时间接单时间
status1(SUCCESS)MQ 发送成功
data_validate_status1(SUCCESS)数据校验通过
business_des业务描述订单业务类型 + 履约模式
error_msgnull无错误
return_msgnull无返回消息

❌ 发送 MQ 失败怎么办?

⚠️ 当前代码存在明显缺陷:

问题详情
无 try-catchMQ 发送调用 inboundSourceDataValidateSender.sendInboundSourceDataSyncGoms() 没有被 try-catch 包裹,位于 handleSourceDataValidateMode() 方法的第 273 行
无错误落库MQ 发送失败时,后续的 saveSuccessInboundEcmsOrderInfo() 不会被执行,接单池无任何记录
无重试机制代码中没有任何重试逻辑,失败即终止
异常向上抛出异常会沿调用链向上传播到 createOrder() 的外层 catch 块,最终抛出 BizException(ORDER_CREAT_ERROR),但数据库中无迹可查

💡 建议改进:在 MQ 发送外层加 try-catch,失败时调用 saveErrorInboundEcmsOrderInfo(inboundOrderCreateParam, errorMsg, returnMsg) 记录失败数据,并考虑加入重试机制。

🔄 MQ 消费后处理(sourceDataValidate = false)

MQ 消息被 InboundSourceDataValidateConsumer 消费后(匹配 tag tag_inbound_order_source),以 sourceDataValidate=false 模式调用 omsOrderService.createOrder(),执行实际订单创建:

步骤操作涉及表异常处理
1 创建销售出库订单
bizOmsOrderClient.create()
oms_order_outbound(主表)
oms_order_line_outbound(行明细)
Feign 调用失败抛出异常
2 查询完整订单信息
bizOmsOrderClient.selectByOrderCodeList()
3 初始化日志上下文
4a 创建仓储作业单
bizWarehouseOrderClient.create()
oms_warehouse_order_outbound
oms_warehouse_order_line_outbound
try-catch 捕获异常
发送异常事件
发送第三方通知(仓储系统异常)
4b 创建运输作业单
bizShippingOrderClient.create()
oms_shipping_order_outbound
oms_shipping_order_line_outbound
try-catch 捕获异常
发送异常事件
发送第三方通知(运输系统异常)
4c 创建用户基础信息
baseUserInfoClient.createBatch()
oms_base_user_info try-catch 捕获异常
发送异常事件
5 更新库存关联字段
materialStockChangeRecordsClient.updateByExternalOrderCodes()
oms_material_stock_change_records try-catch 捕获异常
发送库存异常事件
6 同步 ECMS 发货状态
fulfillmentShippingTrackingEventSender.sendOrderCodeList()
历史订单跳过
7 更新接单池状态
omsInboundEcmsOrderClient.updateByOuterNo()
oms_inbound_ecms_order
status → 2(MQ_SUCCESS)

消费失败处理:若 MQ 消费端抛出异常,InboundSourceDataValidateConsumer 会调用 omsInboundEcmsOrderClient.updateByOuterNo() 将接单池状态更新为 MQ_FAILED

🗃️ 创建订单涉及的数据库表汇总(销售出库)

表名类型说明创建关系
oms_order_outbound主表销售出库订单主表1 个 DN → 1 条记录
oms_order_line_outbound明细表销售订单行明细订单行项目对应
oms_warehouse_order_outbound仓储主表仓储作业单主表订单:仓单 = 1:1(需 isWarehouse=YES)
oms_warehouse_order_line_outbound仓储明细表仓储作业单行明细物料级别
oms_shipping_order_outbound运输主表运输作业单主表订单:运单 = 1:N(按 SN 拆分,可能合并包裹)
oms_shipping_order_line_outbound运输明细表运输作业单行明细物料级别
oms_base_user_info用户信息表收件人敏感信息客户编码 + 姓名 + 手机 + 地址
oms_material_stock库存表物料库存(预占用)校验阶段预扣,建单后更新关联订单号
oms_material_stock_change_records库存变更记录表库存变更流水建单后更新 externalOrderCode → orderCode
oms_inbound_ecms_order接单池ECMS 接单池(更新状态)status 更新为 2(MQ_SUCCESS)

📊 接单池状态流转

oms_inbound_ecms_order.status 状态值:

  0 (ERROR)        数据校验未通过 / 校验阶段异常
  1 (SUCCESS)      MQ 发送成功(校验阶段写入)
  2 (MQ_SUCCESS)   MQ 消费成功(订单创建完成后更新)
  3 (MQ_FAILED)    MQ 消费失败(消费端异常时更新)

oms_inbound_ecms_order.data_validate_status 状态值:

  0 (ERROR)        校验失败
  1 (SUCCESS)      校验成功

🔑 关键代码位置

类名模块说明
OmsOrderServiceStubImplgoms-access-openapiOpenAPI 层入口:接收 ECMS 请求,参数校验,数据转换
FulfillmentOrderServiceStubImplgoms-agg-fulfillment核心实现:sourceDataValidate 分支判断 + 订单创建
InboundSourceDataValidateSenderImplgoms-agg-fulfillmentMQ 发送实现
InboundSourceDataValidateConsumergoms-access-openapiMQ 消费端:根据 tag 路由到不同服务
OmsInboundEcmsOrderClientgoms-biz-inbound接单池 CRUD 客户端
BizOmsOrderClientgoms-biz-order销售出库订单 CRUD
BizWarehouseOrderClientgoms-biz-warehouse仓储作业单 CRUD
BizShippingOrderClientgoms-biz-shipping运输作业单 CRUD
BaseUserInfoClientgoms-platform-base用户信息 CRUD
MaterialStockClientgoms-biz-warehouse库存预占用和更新

📄 GOMS ECMS 全流程文档 | 分支: test-20260601 | 更新时间: 2026-06-03