47 KiB
领星 WMS 一件代发与产品库存接口联调手册
本手册是后续开发的外部 API 入口,说明请求方式、参数、字段映射、实测差异和验收方法。业务同步、表结构、统计口径和开发顺序以一期方案为准。本期只使用 WMS 一件代发出库单和 SKU 产品库存,不接整箱中转出库单或整箱库存,不做箱数到件数的推算。
接口体系为领星 WMS 管理后台的“自研系统/服务商内部系统对接”,官方文档站为 OMP。不要换成 OMS 货主端或 WMS 智能设备的路径和签名。
当前执行边界与数量来源以一期方案的持续 BUSINESS 自动采集及“出库件数”规则为准。2026-10-14 用户确认列表优先、仅缺商品行/SKU/数量的具体订单补详情;本手册下文数量对照是历史验证依据,不再是采用列表数量的前置门禁,也不表示已经证明列表量与实际量始终相等。历史 TEST 小样本次数及时间限制只对应当次 VALIDATION,不覆盖已授权持续 BUSINESS。实际部署、采集及验收状态只看测试环境主契约。
时间口径已确认:2026-10-12 用户说明领星返回时间已转换为北京时间。 本期两个仓库均按 Asia/Shanghai 解析出库时间和统计日期,直接使用有效返回日期;查询 startTime/endTime 同样按北京时间传参。不要再按洛杉矶、纽约或仓库资料中的 timeZone 二次转换。08:00/20:00 出库同步、建议的每日 08:00 库存同步及五种图表自然周期均采用北京时间;分仓任务、覆盖与时效继续独立。
原始时间字符串保持不变,业务日期直接取其日期;内部 UTC 字段按既有存储规范标准化,不使用 UTC 日期替代业务日。认证包络的 Unix 秒级 timestamp 仍按当前时间点生成,不能因业务时间为北京时间而手动加减 8 小时。完整实现与验收见一期方案的同步时间和统计日期。
接口和当前实现
| 用途 | 方法与路径 | 返回主体 | 本地 Java 当前能力 |
|---|---|---|---|
| 发现正常仓库 | POST /openapi/v2/warehouse/page |
data.records[] |
已有内部仓库目录接口源码;外部接口已直接 HTTP 联调 |
| 一件代发已出库单目录 | POST /openapi/v2/order/delivery/page |
data.records[] |
已有只读内部分页摘要接口 |
| 一件代发单的实际 SKU 明细 | POST /openapi/v2/order/delivery/detail |
data |
已有内部详情接口及 SKU 数量 DTO 源码;外部接口已直接 HTTP 联调 |
| 产品库存 | POST /openapi/v2/stock/stockSku/page |
data.records[] |
已有内部产品库存接口源码;外部接口已直接 HTTP 联调 |
当前 Java 已有五个内部 POST 入口,共用 /internal/integrations/lingxing/wms 前缀并要求内部服务令牌:/warehouses/query、/outbound-orders/query、/outbound-orders/locate、/outbound-orders/detail、/product-inventory/query。出库发现与按单定位接口同时传递 productList[].productSku/productName/qty;列表字段完整时直接用于统计,缺项时才补该单详情,数量为零不属于缺项。接口职责和字段见一期方案的接口约定。外部直接 HTTP 联调或源码核对不代表 Java 入口已运行验收。本地启动说明
认证和请求格式
基础地址为 https://api.xlwms.com;所有请求使用 HTTPS POST,Content-Type: application/json; charset=UTF-8,响应按 JSON 解析。认证参数放在请求体中,不需要 OAuth 获取 Token 的前置调用。
| 包络字段 | 类型 | 约束 |
|---|---|---|
appKey |
string | 自研系统的 App Key,官方长度 32 |
timestamp |
string | 当前 Unix 秒时间戳,官方为 10 位数字;不是毫秒 |
data |
object | 对应接口的业务参数 |
sign |
string | HMAC-SHA256 小写十六进制,64 位 |
领星凭据按用户在开发总控对话中的确认配置为 LINGXING_OMS_APP_KEY 和 LINGXING_OMS_APP_SECRET,应用、示例及 Compose 已采用这两个名称;产品仍为 WMS OMP,真实出口开关仍为 LINGXING_WMS_ENABLED。真实值仅通过私有环境配置/Jenkins 凭据注入,不复制到文档。本地私有配置由 Git 忽略;Spring 不会自动加载 .env.local,运行前按上述 README 核对变量名和加载方式,不输出凭据值。内部服务令牌是本平台自身的调用保护,与领星凭据分开。
{
"appKey": "<运行时注入>",
"data": {"current": 1, "size": 2, "whCode": "WH-DEMO", "isHideInventory": 0},
"timestamp": "<当前秒时间戳>",
"sign": "<本次计算的签名>"
}
以上占位符不是可直接发送的凭据。先确定业务参数与路径,再为每次请求重新生成时间戳和签名,不能把分页接口的签名复用于详情或库存。官方加签算法的当前参数拼接为:
待签名串 = appSecret + path
+ "appKey" + appKey
+ "data" + data的Map/List字符串表示
+ "timestamp" + timestamp
+ appSecret
sign = hexLower(HMAC_SHA256(key=appSecret, message=待签名串, UTF-8))
库存例子的 data 表示:{current=1, size=2, whCode=WH-DEMO, isHideInventory=0}
不是 JSON:{"current":1,"size":2,"whCode":"WH-DEMO","isHideInventory":0}
保留业务对象的插入顺序,使用同一数据对象参与签名和实际发送;对象以 k=v、逗号加空格连接,数组也按 Map/List 规则递归表示。path 包括 /openapi/v2/...,不包括域名和查询串。Java 已有 LingxingWmsSigner,后续优先复用它,避免新增第二份签名实现:
Map<String, Object> data = new LinkedHashMap<>();
data.put("current", 1);
data.put("size", 2);
data.put("whCode", warehouseCode); // 来自已配置仓库,不能用文档占位值
data.put("isHideInventory", 0);
var signed = signer.sign(appKey, appSecret,
"/openapi/v2/stock/stockSku/page", data, Instant.now());
// POST signed.body();不可打印请求体、签名、密钥或原始响应。
客户端使用超时、HTTPS、禁止重定向及受控并发;认证错误不能盲目重试。现有本地适配器请求间隔为 1 秒,这只是保护配置,不表示领星承诺 1 QPS。正式初始化前确认账号配额和详情调用量,使用统一账号级限流。
一件代发出库分页
官方 WMS 分页说明明确对应管理端的一件代发出库单列表。
一期使用的 data 参数如下;首采固定起止时刻,后续翻页不能移动窗口:
| 参数 | 类型 | 本期值与说明 |
|---|---|---|
current |
integer | 从 1 开始 |
size |
integer | 官方默认 10、最大 1000;联调先 1 |
timeType |
string | 固定 outboundTime;不用创建时间代替出库时间 |
startTime、endTime |
string | yyyy-MM-dd HH:mm:ss,按已确认的北京时间口径传入,与返回的出库时间保持一致。2026-10-12 已出库单样本观察到起点、终点均包含,见后文边界验证;不能外推为全部仓库/时间类型的保证 |
status |
integer | 100 已出库;99 已取消。已知单的修订复查走详情,不只查状态 100 |
customerCodes |
string | 官方类型为字符串、描述为客户编码;不是已确认的数组,多货主拼接方式未验证。本期账号全集省略该参数;与库存单数 customerCode 名称不同 |
deliveryNo |
string | 官方描述“发货单单号”;已验证正常单和取消单省略时间/状态可定位,本期默认新单发现不传。仍须校验单号完全一致与货主身份,不能假定所有输入均精确匹配 |
公开分页入参没有 whCode 或 whCodeList。因此出库目录按账号共享发现,再用返回的 whCode 路由至每仓独立任务和统计范围;不得发送未声明字段并假定已经按仓过滤,也不为每个仓重复抓取全账号目录。详情可使用仓库标识,已知单的复查按所属仓执行;跨仓修订必须同时处理旧、新仓贡献。
{
"current": 1,
"size": 1,
"timeType": "outboundTime",
"startTime": "2026-09-12 08:00:00",
"endTime": "2026-10-12 08:00:00",
"status": 100
}
正式任务按已确认账号全集读取,不传 customerCodes。用户已确认当前可见全部 70 个货主、2 个仓库均为自营统计范围,货主数量不作为硬编码上限。若后续加入货主子集筛选,应先实测该字符串参数,不能依据复数名称自行发送 JSON 数组。
目录保留 deliveryNo、sourceNo、customerCode、whCode、status、createTime、outboundTime,并保留商品列表的 SKU、名称与 qty;统计取值按一期方案“出库件数”的列表优先规则执行。
一件代发出库详情
官方详情说明的业务参数仅有以下三个字符串。Schema 未声明 required,但本平台合同要求三个值齐全,全部来自同一条已验证分页记录:
{
"whCode": "WH-DEMO",
"customerCode": "CUSTOMER-DEMO",
"deliveryNo": "DO-DEMO-001"
}
不要用来源单号 sourceNo 代替出库单号 deliveryNo,也不要从单号格式推断货主或仓库。
| 响应路径 | 含义与处理 |
|---|---|
data.deliveryNo/customerCode/whCode |
必须与查询主体相符;同单仓库变更进入修订核对 |
data.status |
当前状态;以当前事实决定是否计入 |
data.orderCreateTime |
详情的创建时间字段名;分页中对应 createTime,不能照搬 DTO 名称 |
data.outboundTime |
实际出库时间,已由领星转换为北京时间;保留源字符串,按 Asia/Shanghai 解析并直接使用其业务日期,不再转美国时间 |
data.skuVOList[].productSku |
SKU;货主和仓库从详情主体继承 |
data.skuVOList[].actualDeliveryQty |
实际出库量;官方 integer,实测为 JSON number;Java 使用 BigDecimal 统一保留精度 |
data.skuVOList[].deliveryQty |
预报出库量,只作对照,不用于销量替代 |
data.packageList[].skuList[] |
包裹维度重复明细,不与 skuVOList 累加;其 actualDeliveryQty 官方类型是 string |
同单同 SKU 多行先归并。完整详情缺失、数量无法解析或身份不符时,不能把该单视为零销量后推进完整水位。原始响应可能含面单链接、物流信息等,日志和持久化只能保留本期白名单字段。
列表数量与实际数量对照的证据缺口
2026-10-13 按用户要求只读检查 TEST 已保存数据,目标是寻找预报量与实际量不同的一件代发出库单。检查在只读事务中执行,单条 SELECT 限时5秒;本次没有向领星发起请求,没有修改采集任务或统计数据。
- 当前查得12,823条有效出库暂存、12,740个不同订单业务键;预报量字段检查命中0。核对最新完整载荷及代码,商品行仅保留
skuCode,productName,quantityUnit,actualQuantity。Integration 的详情 DTO 虽有deliveryQty,Lastleg 转为统计载荷时未保留它,订单事实也不保存预报量。 - 同时查询已出库状态100、商品实际量为0的候选,结果为空;不能据此推断所有订单预报量等于实际量。
- Integration 列表映射只保留订单头,不返回
productList[].qty。所以当前库不能直接筛选预报/实出差异,现有内部列表接口也不能完成三值对照。当前检索结果是“缺比较字段”,不是“已证明一致”。
下一步最小验证应优先附着正常采集已经收到的响应,采集少量白名单对照证据:同一账号、仓库、货主、出库单、SKU 的列表 qty、详情 deliveryQty、详情 actualDeliveryQty,订单状态/出库时间及列表、详情观测时间。按同 SKU 汇总后比较,同时核对 SKU 集合完整性。一次授权累计最多选择100个 LIST 候选,缺失配对不补选;首次三值任一已知差异、未知量或 SKU 集合不一致即停止诊断。不额外创建历史采集,不输出面单、收件信息、签名或凭据。当前有界诊断实现及发布边界见下节。
命中预报量不等于实际量时,优先使用同次配对的列表证据;若列表/详情时点相差或订单被修订,则仅针对该订单在现有账号预算和统一出口内最多补一次列表与一次详情核验,限流即停止。已保存匹配证据不重新请求。
验收判定:列表量等于预报且不等于实际量,可否定“列表直接替代实际量”;列表量等于实际量且不等于预报,只证明该差异样本支持替代方向,还需确认 SKU 完整性、修订与取消边界;三值相同不能区分语义。未取得差异样本时明确保留未验证,不停用详情链路。
下一自动 root 的一次性有界诊断
当前实现通过 Lastleg 内部 quantity-diagnostics/arm、status、observe、stop 管理单次授权,四个入口均校验内部服务令牌,不经 Gateway 公开。旧固定 root/30 分钟配置及 /orders 协议已替换,Integration、Lastleg 必须成对更新。默认两端诊断开关关闭;完成契约核验后才能显式 arm,不因重启、会话终止或 root 切换自动重新授权。
arm冻结诊断 ID、账号、允许仓库、货主及当时实际当前自动 root。客户端传入的排除 root 必须与服务端只读查询一致;当前没有已开始且未结束的自动 root 时传空,发现多个则拒绝。已结束的历史 root 不能冒充当前 root。- 最多等待 6 小时,接收时刻及原始 LIST 观测时刻均须在绑定截止前。只绑定随后正常
OUTBOUND_QUERY的自动历史出库 root,排除 LOCATE、DETAIL 首绑定、验证与手工任务。root 可以提前规划,不能用创建时间晚于授权作为条件。账号、root 自动属性和selfop-<root>会话由服务端核验,延迟回调不依赖已经清除的瞬时 permit。 - 采样开始取首次 LIST 原始
observedAt,最多再采 4 小时,同时绝不晚于授权后 10 小时;网络延迟、重试和排空均不顺延。会话终态不自动绑定下一个 root。 - 同一会话在诊断行锁内串行选择累计最多 100 个候选。唯一业务键为账号、仓库、货主、出库单;LIST 先存入独立 pending 表,DETAIL 再与首次 LIST 配对。未选中的 early DETAIL 忽略;两侧原始时间、attempt、SKU 数量保持不变。相同规范载荷重传幂等,包含终态重传;新 attempt 或改写载荷不能覆盖首次证据。
- 新授权的持久证据将数量编码为无指数、去除尾零的十进制字符串,读取时严格恢复 BigDecimal;哈希、字节额度与重复比较使用同一规范编码,避免数据库 JSON 数字归一化造成精度损失。未知仍为 null,负数拒绝。此编码只用于诊断存储,外部回调仍传数值并精确解析;JSON 列及历史证据不变,不增加旧数值证据读取分支。
- pending 与最终配对共同累计最多 2000 个保留 SKU 行、2 MiB 规范证据(含配对包装预留),提升为最终证据不返还额度,不通过删除或换候选重新获得预算。未知量或 SKU 不齐为
INCONCLUSIVE;三值任意已知差异为QUANTITY_DIFFERENCE,与证据同事务关闭诊断。100 个完整配对且无观察丢失才为COMPLETED,全相等也不证明列表与实际量语义一致。 - 接收线性化点为 Lastleg 会话锁下持久化成功;Integration 本地入队不算已接收。root 结束进入
DRAINING,禁止新 LIST 候选,只排空已选候选的在途 DETAIL。Integration 停止入队、依次发送已入队观察后,才提交 drained 确认。少于 100 个完整配对明确为ROOT_ENDED_INSUFFICIENT;有未配对或观察可能丢失则为INCOMPLETE;硬截止始终优先。 - Integration 重启可从持久候选恢复,但未持久化的内存尾部不可证明无损,因此替换 producer 会设置
deliveryUncertain,旧 producer 被隔离,最终不能报完整成功。回调不可用、队列满或诊断失败只关闭诊断,不影响正常采集返回,不补发领星请求。 - 正常出口线程只做有界白名单快照和
tryLock入队,不解析/序列化整个原始响应,不等待诊断 HTTP。队列最多100项、2000行和2 MiB保守内存记账;独立单工作线程发送。Lastleg 在获取连接前非等待准入,诊断专用池最多1条连接、借用超时250ms,事务3秒及语句2秒限制;初始化失败只让诊断 API 不可用,不阻止业务服务启动,也不关闭主池。请求/响应均流式限制262144字节。
配置只保留 Integration 的 quantity-capture.enabled/source-account,以及 Lastleg 的 quantity-diagnostics.enabled/source-account/warehouse-codes。这些是启动时配置,不具备热启用能力;若以 enabled=false 启动,之后改配置不能直接 arm,需重新加载对应进程。本轮总控选择一次成对发布:旧版本窗口已过期且无在途诊断作为变更前停止证据;新版本以能力 enabled=true、无新授权启动,核验带内部令牌的 status 返回 null、active_slot 无活动且 pending 为空,再释放维护、显式 arm。未授权时观察器不接收或留存样本,只查询内部授权状态。不做 OFF→ON 二次重启,也不得把“未授权”与“配置关闭”混称。授权参数与时限留在诊断会话,不通过修改 Nacos、重启或每次 root 发布代码重新启用。源 DDL 为 lastleg-service/src/main/resources/db/selfop-quantity-diagnostics.sql:原会话表、配对表以及一张 pending 表,只写诊断证据,不改业务表。该文件是最终空库结构基线,不自动执行。已有表只需会话表增加 active_slot/state_json 两个可空字段及活动授权唯一索引,root/session标识允许授权未绑定时为空,另建 pending 表;原配对表结构和全部已有证据保留。原 stop_reason/accepted_orders/accepted_sku_rows/accepted_bytes 列仍为终态及计数的唯一事实来源,根标识、开始与截止也使用原列;state_json 只补授权范围、绑定截止、producer、候选数、root结束及丢失标记,不另存一份终态或计数。历史会话 state_json 为空,不参与新授权协议,不能复用旧 ID arm;不回填、不改写旧证据。发布前由负责发布者先只读导出并核对原证据哈希,再逐项审查已有表的必要 ALTER,不在同名表上运行整份 CREATE,也不执行 DROP。
本地合成测试只证明边界实现;没有执行环境 SQL、发布、arm 或真实取样,不能据此宣称已取得新样本、诊断无物理开销或列表量可替代详情实际量。1200ms 出口间隔、原采集任务、统计来源及业务表保持原逻辑。
数量对照验证的采集保护与开发交接
2026-10-13 用户指定已有对话 开启新对话 实施本次有界验证,要求不影响采集。仅接管数量对照与所需只读状态判断,不恢复其他对话已暂停的开发、服务或采集。业务销量继续以详情实际量为准;验证通过前不切换统计来源。
开发先核对当前代码、运行版本及改动归属。只读状态使用实际生效配置、账号预算/冷却/暂停原因、未完成请求许可、任务/执行尝试/租约和真实进度观测时间联合判断,不凭聊天状态、“无活动任务”、页面等待文案或心跳正常推断可发请求。前后两次轻量只读观测可识别正常推进与证据变化,不轮询原始订单或 SKU 明细。
| 状态证据 | 对照行为 |
|---|---|
| 正常采集运行,有有效租约/在途请求或成功数量推进 | 只附着正在发生的正常响应保留白名单字段;不发独立扫描或插队详情,不调整并发 |
| 等待间隔/自动冷却/预算耗尽/授权失效 | 按实际原因展示等待或不可验证;不缩短间隔、清零预算、延长期限或自动重试探测 |
| 人工暂停、模式OFF、复核暂停、服务正在切换 | 保留暂停;允许准备代码和离线对照,运行取样等后续启用,不为验证开启采集或重启服务 |
| 证据缺失/前后冲突/许可结果未知/版本不一致 | 返回“状态待确认”和缺失证据,禁止主动核验;不把未知解释为安全空闲 |
| 已确认空闲且无在途/遗留未结许可,账号预算及授权均有效 | 如确需补验,只通过现有持久账号预算和统一出口领取一次性许可,最多一单的列表+详情共2次;空闲检查不能代替发请求时的原子许可校验 |
旁路取样必须默认关闭,使用一次有上限的验证会话。会话冻结范围、开始/截止时间、最多100个完整配对订单、接收记录及字节上限;建议最长30分钟,到期或首次预报/实出差异即结束本次捕获,没有差异也按“未命中”结束。不能每次轮询、翻页、重试或重启重置额度。字段来自同一次来源采集代次,配对键至少包含账号/仓库/货主/单号/SKU与观测证据;同单同SKU多行以十进制数量汇总,缺值保留未知,不能按总件数相等掩盖SKU替换或缺行。
诊断字段与业务事实分离,不改变业务内容摘要、修订号、任务就绪条件、归并、发布或现有返回状态。捕获失败、配对超时、存储满时停止诊断并记录脱敏原因,不能让正常采集失败,也不能无限缓存或同步写大量日志。不得保存原始全响应、面单、地址或凭据;三值与必要业务身份仅留在受控诊断存储,文档和报告使用样本别名。
最小代码范围是 Integration 列表/详情响应映射旁的白名单观察、独立有界配对组件及直接测试。优先在 Integration 层完成三值观察,避免为了找样本修改 Lastleg 业务事实表;如必须新增字段传递或内部诊断合同,先声明精确 DTO/调用方/OpenAPI 影响,再由唯一写者同步。不改 Egress 的预算、许可、限流逻辑或已经冻结的持续采集候选,不新增公开绕过出口的接口。开发可以在当前工作区完成,发布需另按当前授权协调;不能把“新增代码不影响运行”扩大成“重启后无损”。
交付须分别给出:采集状态证据和是否具备取样条件;三值对照的有界实现与离线测试;真实差异样本是否命中;额外供应商请求数;是否可以替代及尚未覆盖的边界。至少测试预报10/实际8且列表分别为10和8、SKU集合不一致、重复行、部分字段缺失、跨代次拒配、取消单、会话到期/上限、诊断失败不影响业务返回、暂停/429/许可未知不发请求。没有真实差异样本时只能交付验证能力,不能宣称字段语义已证实。
已实测当前取消单可查详情,且正常单、取消单均可按单号重新定位;实际改仓后的旧三标识行为尚无样本。若旧仓三标识无法取得详情,使用出库分页的按单重新定位方式,以下为合成业务参数:
{"current": 1, "size": 10, "deliveryNo": "DO-DEMO-001"}
官方业务 Schema 没有将时间参数和 status 列为必填。2026-10-12 的正常、取消两个样本均省略这些字段,分别返回唯一同货主、同单号记录;样本未受到默认已出库过滤。必须读完返回页、逐条校验单号完全一致及货主身份,再取当前仓库查详情;不能只按模糊单号命中就迁移事实。无结果、权限失败、多个身份冲突均进入待核对,不认定取消、不清零。
当前 Java 已有独立的 /outbound-orders/locate 入口和按单定位请求 DTO,不传时间/状态条件;默认摘要发现接口仍用于状态 100 的新单发现,不能用它替代取消定位。新单发现和已知单修订复核使用不同查询意图,仍共用账号限流和签名器。该源码能力仍须完成内部 HTTP 和编排验收。当前取消样本的详情仍有实际数量 1,但 outboundTime 为空;必须先按状态和有效出库时间判定,不因数量大于零计入销量,也不能据此证明该单过去已经出库。
仓库发现和分仓配置
用户已确认按仓库分别采集和管理时效。先调用 正常仓库列表:
{"current": 1, "size": 1000}
请求路径为 /openapi/v2/warehouse/page,业务入参 current 默认 1、size 默认 10、最大 1000。可按 whCode、whNameCn、countryCode 筛选,但一期发现当前全部正常仓库时不传过滤。接口没有 status 请求参数,也不要因为业务是“自营”就添加 warehouseType=0,自营商品可能存放在代理仓。
响应分页字段是 data.page/pageSize/pages/total,不是产品库存的 current/size;2026-10-12 已实测这一差异。每行保留 whCode、whNameCn、warehouseType、status、timeZone;不用仓库地址、联系人或联系方式。warehouseType 为 0 自营仓、1 代理仓;status 为 0 正常、1 停用、2 冻结,但该接口只返回正常仓库,缺失仓不能解释为“库存归零”。
仓库编号是任务、快照、时效与未来预警规则的必需维度。每仓保存来源时区、报表时区、出库计划、库存计划及过期阈值;本期两个时区字段均已确认填写 Asia/Shanghai,每天北京时间 08:00/20:00 出库、建议每天北京时间 08:00 库存。返回的 timeZone 只是仓库所在地资料,不覆盖领星已转换好的北京时间。某仓失败不阻止另一仓发布完整库存,不能用成功仓的采集时间刷新失败仓。
产品库存分页
官方产品库存说明与管理端「产品库存-库存信息」口径一致。库存接口没有日期筛选,也不使用出库的最近两个月窗口。
正式任务必须按仓发送 whCode,以下是单仓全量产品库存 data 模板:
{
"current": 1,
"size": 1000,
"whCode": "WH-DEMO",
"isHideInventory": 0
}
对每个已确认仓库独立从第 1 页读完,每页只增加 current,同仓其他参数保持一致。不传 productQuality,采集正品和次品;不设置 SKU、数量、预警或品类过滤。 该仓全部货主均纳入,正常全量不传 customerCode;它只用于定向核验。每仓独立记录执行状态、覆盖范围、采集起止和发布版本,统计只使用正品 productQuality=0 的可用库存。
| 参数 | 类型 | 官方规则与使用方式 |
|---|---|---|
current、size |
integer | 默认 1、10;每页最大 1000 |
customerCode、whCode |
string | 官方均未标必填,实测可省略;本平台分仓采集要求 whCode 必填,customerCode 可省略读取该仓全部货主 |
whCodeList |
string[] | 仓库列表,最多 500;不要同时混用单仓与多仓参数,优先关系未核验 |
productQuality |
integer | 0 正品、1 次品;全量不传,专题查询可传 |
isHideInventory |
integer | 0 保留零库存,1 隐藏;正式全量必须为 0 |
barcode、barcodeAccurate、barcodeList |
string、string、string[] | 模糊/精确检索;列表最多 500。官方名称 Barcode 与列表说明“SKU”不一致,未经单 SKU 实测不得用于生产过滤;全量不传 |
productName、categoryIdList |
string、string[] | 商品名、品类过滤;品类最多 500;全量不传 |
stockValueType、startValue、endValue |
string | 数量过滤;类型为 stkQty/freezeQty/useStkQty,边界开闭未说明;全量不传 |
sortName、sortOrder |
string | 数量排序,方向 asc/desc;无稳定快照或唯一排序保证,不能靠排序解决翻页期间变动 |
stockStatus |
integer | 0 无预警、1 预警;全量不传 |
返回是 data.records[],分页元数据是 data.current/size/total/pages。主体字段都在每条记录的第一层:
| 字段 | 类型与映射 |
|---|---|
customerCode、whCode、productSku |
string;与来源账号、品质一起构成候选业务键 |
productName |
string;展示信息,不作为唯一键 |
productQuality |
integer;分别保存正品、次品 |
stkQty |
number;实物库存 |
freezeQty |
number;冻结库存 |
useStkQty |
number;可用库存,正品该值用作可售量,不再次扣冻结 |
transitQty |
number;在途,单独保存,不计入当前可售量 |
innerBatchNo、outBatchNo |
string;批次线索,空字符串保留为空;不能未经核验据其拆分库存粒度 |
uniqueKey4tenant |
string;只作来源核对,不拆解它替代明确维度 |
stockCompare |
object;代理仓对比信息,不与本行数量相加;其中 refreshTime 不是主体库存采集时间 |
数量使用 BigDecimal/数据库 DECIMAL;不能强转 int、截断小数或将 ""、null、缺字段自动转换为 0。官方统一空值规则可能把数值 null 输出成空串或 0,API 数值 0 仅能证明“接口报告零”,首次正式验收仍须与领星页面核对。接口缺行不证明库存为零。
后续库龄数据入口
官方批次库存分页公开 POST /openapi/v2/stock/batch/page,对应 SKU 批次库存,不是整箱库存。可作为后续真实库龄核验入口,已核对的公开字段如下:
| 字段 | 官方含义与类型 |
|---|---|
stockAge |
integer,库龄天数 |
putawayDate |
string,上架日期 |
stkQty |
number,在库数量 |
customerCode、whCode、productSku、productQuality |
货主、仓库、SKU 与品质;前三者为 string,品质为 integer |
sysBatchNo、batchNo、innerBatchNo、outBatchNo、relateOrderNo |
string,系统批次、上架批次、内部/外部批次及关联入库单号 |
该接口尚未实测账号权限、字段非空覆盖和分页完整性;还需确认库龄起算、移仓/退货是否重置、不同视图及库位是否重复汇总,并按同一货主、仓库、SKU、品质与产品库存对账。现有产品库存样本的批次字段为空,不能代替此接口验证,也不能用首次同步日补造真实库龄。领星 stockAgeStatus 的规则尚未核准,不直接作为本平台的滞销判断或评级。
本节仅登记后续待核验能力,不是本轮一期必交代码,不默认接入生产;一期仍使用现有出库与产品库存链路,本次不新增真实请求。后续核验沿用账号独占、同一会话共享请求预算及遇限流即停规则,不另开预算或自动全量补采。用途仍为自营业务内部评估与仓储成本分摊,不用于对外客户收费。
成功、失败和契约差异
2026-10-12 出库分页、详情和产品库存已观察到成功包络为数值 code=200、data 和 msg,没有 success,与官方 BaseResponse 的 required 声明不同。解析规则为:
- HTTP 200 只是传输成功;仍检查 JSON
code为数值 200。 success缺失时继续校验数据结构;存在时必须是布尔 true,false、null 或字符串均拒绝。- 分页必须有有效
records数组和可核验分页元数据;详情必须是对象并核验主体身份与 SKU 明细。当前 JavamappedPage已要求total/current/size/pages并校验页数和本页行数;完整批次仍须由 Lastleg 跨页检查唯一业务键、页间总数变化及应有页数,不能由单页适配成功推定全量成功。 - 官方认证错误可使用字符串错误码;保留数值错误码和固定错误分类,原始
msg不直接输出日志或用户界面。认证失败不当作空页。 - 测试验证遇 HTTP 429/明确限流码立即停止整轮会话,不自动重试;正式任务交回账号协调器统一冷却后有限退避,不由各接口独立重试。超时等失败也消耗原预算;权限与验签错误停止盲目重试。没有验证的配额与历史限制保留为待确认项。
出库分页空结果的已验证例外:请求 current=1,size=100、时间窗口明确不包含目标单时,成功响应为 records=[]、total=0、pages=0、current=1、size=10。它把空页条数恢复为默认 10。可仅在这组完整空结果条件同时成立、且本次请求为第一页时归一化内部 size 为请求值,保留源分页元数据作为诊断;不能因此判失败。非空页、总数缺失、后续页异常或其他结构错误仍严格拒绝;未经验证不能把例外推广到库存或仓库接口。首次探针因严格回显检查中止,针对空结果核验后完成后续测试,这不是供应商业务请求失败。
成功响应示例为合成数据,展示的不是实际业务记录:
{
"code": 200,
"msg": "操作成功",
"data": {
"current": 1, "size": 1000, "total": 1, "pages": 1,
"records": [{
"customerCode": "CUSTOMER-DEMO", "whCode": "WH-DEMO",
"productSku": "SKU-DEMO", "productQuality": 0,
"stkQty": 120.0, "freezeQty": 20.0,
"useStkQty": 100.0, "transitQty": 30.0
}]
}
}
这里的 total 是供应商 JSON number;经过现有平台 Long 序列化后,本地内部 API 的 total 为字符串,这是平台响应格式,不能据此要求供应商返回字符串。
联调证据与复现验收
2026-10-14 客户名称与商品资料权限核验
用户明确要求核验当前 key 是否可读取客户列表、货主名称和商品。15:37(北京时间)使用 TEST Integration 当前容器中的同一组凭据,只读请求以下两个官方 OMP 接口各一次,间隔1.3秒,无自动重试;请求前后只读检查账号无活动任务、运行或占用租约。没有暂停采集、重启、配置发布、SQL数据写入或业务数据导入。本次是独立有界接口权限验证,不表示已有正式主数据同步能力。
| 接口 | 本次实际结果 | 后续接入边界 |
|---|---|---|
客户列表,POST /openapi/v2/customer/list,current=1,size=1000 |
HTTP200、业务码200;total=85、单页返回85条,85条均有 customerCode/customerName,用户截图中的编码与名称对应核验通过 |
85是该key当前可见客户目录数,不等于有库存或销量的货主数;正式保存账号+客户编码对应名称,保留编码作为关联键,不能用名称连接销量。无需重拉历史出库 |
商品分页,POST /openapi/v2/product/page,current=1,size=5 |
HTTP200、业务码200;total=8536,本次仅读取5条,均有 customerCode/sku/productName 和正数 length/width/height,sizeUnit=cm;5条 wmsLength/wmsWidth/wmsHeight/wmsSizeUnit 均为空字符串 |
官方每页最多100,8536条按当前总数预计86页,尚未执行全量。不得从5条推定全部尺寸有效;普通资料尺寸可用于标明来源的估算,不能冒充仓库实测体积或历史出库包裹体积 |
两个资料接口的请求分页参数均为 current/size,响应分页字段均为 data.page/pageSize/pages/total;不能套用产品库存接口的响应 current/size。2026-10-14 对照官方两个接口 Schema 再次确认这一差异;先前有界样本保存的 current/size=null 也不应被视为有效页码。Integration 按正式响应字段严格核对当前页、页大小、总页数及行数,向 Lastleg 统一输出内部 current/size,不增加两套响应字段兼容回退。客户响应 status 为字符串;商品实测尺寸空字符串继续表示未知。
客户名称映射和5条商品白名单样本只保存在本机受控私有证据文件,未保存联系人、电话、邮箱或完整原始响应;不将真实客户资料提交仓库。临时验证程序为后端忽略目录 target/selfop-masterdata-key-probe.mjs。此次只读核验时的业务采集 DTO 尚未接入客户名称和商品尺寸。后续接入契约见《领星一件代发数据统计一期方案》页首“客户名称与商品资料接入”;接口权限证据不代表实际部署、全量同步和体积口径已验收。
截至 2026-10-12,出库分页通过本地 Java 服务验证;详情、仓库发现和库存使用同一组凭据及 OMP 签名直接执行只读 HTTPS 请求。临时探针与脱敏报告放在被 Git 忽略的 integration-service/target/lingxing-local/,只保留字段类型、数量、分页计数和核验结论,不保存密钥、签名或完整原始响应。这些临时文件可被构建清理,开发依据以本手册记录为准。
| 项目 | 已验证内容 | 不能由此推定 |
|---|---|---|
| 一件代发分页 | 本地 Java 已取得一条状态 100 的摘要;使用出库时间最近一个月窗口 | 整月已完成采集、时间区间完整 |
| 一件代发详情 | 对同一单传齐仓库、货主、出库单号,HTTP 200、业务码 200;skuVOList 返回一行,实出和预报数量均为数值 1 |
所有单都单 SKU、预报永远等于实出;北京时间口径来自后续用户确认,不由 HTTP 成功推定 |
| 产品库存样本 | 不传货主、仓库、品质,current=1,size=2,isHideInventory=0 返回两行;四种数量是 JSON number,零库存能返回 |
所有空值语义、同一时刻快照;自营范围由用户另外确认 |
| 产品库存两轮全集核验 | 北京时间 15:30:32—15:32:24,每轮 7 页、6,635 条;两轮业务键与四种数量一致 | 永久稳定排序、跨页原子快照、已持久化业务库存 |
| 正常仓库发现 | 返回 2 个仓库;分页元数据为 page/pageSize,仓库资料有 timeZone |
接口时间必定使用仓库时区、未来停用仓可直接清零 |
| 定向库存筛选 | 用样本货主+仓库查询,返回记录均属于所请求的货主与仓库 | 同仓全量只需该货主,或其他货主不属于自营 |
| 按仓全分页 | 分别带两个实际 whCode 查询,每页 1000,合计 7 页、6,635 条;每行都属于所请求仓库,分别通过总数与业务键核验 |
跨仓为同一原子时刻、时区已完成业务对账 |
全集核验的 6,635 是“货主+仓库+SKU+品质”库存记录数,不是商品件数,也不等于去重后的 SKU 数。两轮均为正品 6,293 行、次品 342 行;实物为零 3,278 行、实物大于零 3,357 行。未观察到重复业务键、缺失主体身份、四种数量类型异常或负数;样本全集的批次字段均为空,stockCompare 均为空对象,因此非空批次和代理仓对比仍待专项样本。用户随后确认全部 70 个货主、2 个仓库纳入自营,并要求正式采集按仓执行。
2026-10-12 北京时间 15:43:18—15:44:09 的按仓结果如下。仓库 A/B 是文档脱敏别名,不可作为请求中的 whCode;实际编码必须从仓库目录或受控配置读取。
| 仓库 | 仓库资料时区 | 页数 | 库存记录 | 正品/次品记录 | 零实物记录 | 涉及货主 |
|---|---|---|---|---|---|---|
| A | America/New_York |
1 | 894 | 892/2 | 280 | 15 |
| B | America/Los_Angeles |
6 | 5,741 | 5,401/340 | 2,998 | 69 |
表中美国时区为接口实际返回的仓库资料,保留原值作为证据;两仓的出库返回时间和本期统计口径仍统一为用户确认的北京时间,不按这两个资料值分别转换。
两仓合计与先前账号全集相符;货主可跨仓出现,15+69 不能作为去重货主数。首次分仓尝试遇到临时网络错误,未视为成功;随后重跑完整分仓读取成功。正式同步必须同样区分失败尝试和已发布完整批次。以上核验只读入内存并保存脱敏统计,没有导入业务表,也没有新增 Java 库存 API。
2026-10-12 追加前置验证
用户要求继续验证后,本轮继续直接串行请求 OMP,最小请求起始间隔 1.1 秒,不制造业务变更、不做限流压测。以下 API 验证发生时尚未取得用户的时区确认,也未完成页面对账;用户随后确认领星返回值已是北京时间,当前按本手册开头的 Asia/Shanghai 口径执行。该用户确认与下列只读实测证据分别记录。
| 验证项 | 本次结果 | 保留的限制 |
|---|---|---|
| 正常单按号定位 | 省略时间与状态,返回唯一同货主、同单号的状态 100 记录;三标识详情一致 | 不保证模糊输入或同号跨货主也唯一,仍须逐条核验 |
| 出库不同页大小 | 源字符串窗口 2026-10-10 01:00:00 至 02:00:00,size=124/125 均 3 页、372 个唯一单据;两轮单号集合及仓库/状态/出库时间摘要相同 |
不是 UTC 区间证明,也不是原子快照或永久稳定分页承诺;没有页面导出对账 |
| 秒级边界 | 一个已出库样本:宽窗前后复读均命中;以该时刻为起点、终点均命中;严格前一秒与后一秒窗口均不命中。六次结果均全量、唯一且单号准确 | 仅观察到该样本两端包含;尚未覆盖另一仓、其他时间类型或北京时间午夜边界 |
| 空结果分页 | 两个不相交窗口都返回 records=[]、total=0、pages=0、current=1、size=10,请求 size=100 |
仅按前述严格条件归一化;不能放宽非空页、库存页或后续页 |
| 多 SKU 详情 | 另取 5 条已出库单,分别有 4、4、3、3、2 个 SKU;身份、数量类型与列表出库时间一致,实际量均等于预报量 | 未观察到同 SKU 多行、实出少于预报或部分出库,不把缺少样本标为通过;单位仍需业务核对 |
| 当前取消单 | 近月创建时间查询的取消目录报告 163 条;抽查列表的 20 行均状态99,读取其中1条详情也为99,按号无时间/状态定位仍唯一命中 | 该样本实际数量1、出库时间为空,不能证明过去已出库;改仓及“出库后再撤销”仍无前后证据 |
| 详情耗时 | 7 次详情耗时约 1.09—2.63 秒,平均约 1.57 秒 | 只是小样本观测,不是配额、容量或首采完成时间承诺 |
| 实际限流与退避 | 串行、最小起始间隔1.1秒下,仍观察到1次出库分页 HTTP429;有限退避后的第二次请求为 HTTP200、业务码200 | 未刻意压测;不能由一次429反推准确阈值,也不能将1.1秒间隔视为已确认的安全持续速率 |
| A 仓库存分页 | size=298/299 各3页、各894个唯一业务键,集合和四种数量一致 | 仍为采集区间观测 |
| B 仓库存反例 | size=999 时6页、5,741个唯一键;随后 size=1000 返回5,741行,但只有5,740个唯一键,发现1个重复键,两轮集合不同 | 该次尝试完整性失败,不能发布。 原因尚不能区分业务变化与非稳定排序,不删除异常证据 |
| B 仓完整重试 | 再从第一页以 size=1000 完整读取两轮,各6页、5,741个唯一键;无重复、集合和四种数量一致 | 证明本次可恢复,不证明供应商分页永久稳定;不是将前后数据拼起来凑齐 |
出库与详情验证于北京时间 16:25:37—16:26:31 完成;两仓不同页大小核验于 16:27:57—16:29:22 完成;B 仓完整重读于 16:32:40 完成。脱敏报告分别为忽略目录中的 prerequisites-20261012T082631Z.json、prerequisites-20261012T082922Z.json、prerequisites-20261012T083240Z.json;前一次空页严格校验中止记录另保留,不能混记为成功。
验收必须覆盖两个实际用例:出库合法空页不误报失败;库存总数与返回行数相同、但唯一键少 1 时仍整批拒绝并重试。当前 LingxingWmsClient 已包含限定的出库空页例外:请求首分页 size=100,来源 current=1,size=10,total=0,pages=0,records=[] 时允许通过,其余页大小不匹配仍拒绝。此处仅更新源码事实,未重新运行 Java 或批次验收;既有直接 HTTP 联调证据与当前适配器验证应分别记录。
公开官方资料专项核对未找到账号 QPS/每日配额、时间戳容许误差、源出库时区、历史保留或最大更正期限的明确值。官方 requestDeliveryTime 的北京时间说明不能单独外推给 outboundTime;本期出库北京时间口径采用用户的明确确认,不再列为待选时区。供应商仍需补充列表/详情保留期限、已出库后撤销与改仓是否允许及查询方式、账号请求配额,以及稳定分页能力。当前低频调用成功不能代替这些确认。
后续复验先检查账号独占和整轮预算;不直接开启当前会自动规划正式首采的执行开关:
- 先完成离线签名、异常脱敏、预算耗尽及用途隔离测试,确认原采集环境已停止且在途请求排空。在独占验证窗口内只读读取配置、不回显值,用
size=1的出库分页和size=2的产品库存开始,足够即停。保存业务参数模板、时间、HTTP/业务码、字段类型和已用预算。 - 用分页同一行的三个业务标识查详情,核对实际 SKU 数量和创建/出库时间字段;与领星页面同单对账。禁止把包裹数量重复累加。
- 以已确认的当前账号全部 70 个货主、2 个仓库建立范围版本;按仓库目录取得实际编码,核验带
whCode返回的每行仓库一致。仓库目录或业务范围变化要重新验证覆盖,不将 70/2 固定在代码中。 - 测试只在原会话预算内翻少量页、读取有限详情,并记录
total/pages、实际行数、唯一键与停止原因;达到预算或遇到限流即停止,不为凑齐某种样本继续搜索。不完整库存不得发布、补零或触发缺行占位。 - 重复键、缺页、总量变化、断点恢复、事实归并和版本发布先用离线合成数据验证。2026-10-13 用户确认库存按每仓一轮完整分页观测,取消两轮数量完全一致的发布前提;正式受控任务保存每仓真实采集区间和完整性证据。所有页、唯一业务键、总量、范围及数量校验仍须通过,不拼接失败批次,不承诺跨页原子快照。历史两轮核验仅证明当次观测结果,出库目录规则不变。
- 对本次预算内已有的正品、零库存、次品、冻结、在途样本进行相同筛选的页面核对;未取到的场景留待合成用例或正式生产验收,不追加无上限查询。结束验证后关闭该环境真实出口,再交还账号给正式采集。
来源与统计时区已确认采用北京时间;实现仍需验证北京时间午夜边界与内部 UTC 存储不改变业务日期,订单历史修正期限、稳定分页和实际账号限流仍需供应商或人工对账确认。库存 API 没有历史时点参数,不能用当前查询补造昨日库存。开发可以从适配、暂存及分仓任务开始;正式启用标准统一见一期方案的开发准入与正式启用门槛,本手册的成功样本不替代这些门槛。