20 KiB
批量待分柜数据生成指南
本文说明如何复用 scripts/admin-test-env-acceptance.mjs,通过正式 HTTP 业务接口批量生成停在“测量完成待分柜”的头程订单。生成链路包含客户登录、下单、平台审核、入库、称重、测量、测量审核,不直接写业务数据库,也不模拟成功。
适用范围
- 用于开发、联调或经明确授权的验收环境准备人工操作数据。
- 生成结果固定为入库单
processStatus=WAIT_SPLIT、测量审核APPROVED。 - 单次支持
1-100条;更大批量分多次执行并分别保存报告。 - 基础批量模式不自动执行后续分柜、装柜、订舱、国内出仓、海外入仓或 PDA 收货;需要人工分柜验收时使用本文后半部分的准备与只读核验入口。
- 禁止用于生产环境。对任何共享环境执行前,必须在当前对话明确获得该环境的写数据授权。
固定项与随机项
批量模式可固定以下三个线路字段:
- 国内起运仓名称:
--origin-warehouse-name - 渠道名称:
--channel-name - 渠道编码:
--channel-code
客户通过复用已审核商户账号固定;服务端从登录身份解析客户,脚本不会手填客户 ID。
使用 --order-profile-mode randomized 后,脚本在服务端允许的真实组合中轮换:
- 目的类型:
FBA、OVERSEAS、PRIVATE - 履约类型:
STANDARD、ONE_CLICK_DROPSHIP - 提货方式:
PICKUP、SELF_EXPRESS、SELF_TRUCK - 买单/退税:
BUY_DECLARATION、TAX_REFUND - 报价税制:
TAX_INCLUDED、TAX_EXCLUDED,以固定渠道实际支持项为准 - 装载方式:
LCL、FULL_CONTAINER - 是否查验
- SKU 数、每 SKU 箱数、托数、重量和测量箱型
- FBA/海外仓目的仓:只从固定渠道当前价格簿真实可计价仓库中选择
随机档案是可重复的稳定轮换,不是不可复现的纯随机数。每六条覆盖一次“3 种目的类型 × 2 种履约类型”的核心组合,便于复核覆盖率。
特殊规则:
PRIVATE不引用公共目的仓 ID,必须携带收件人地址;当前契约不对私人地址做自动报价。FBA必须使用真实可计价 FBA 目的仓,并冻结 Amazon 仓码、Shipment ID 和 Reference ID。OVERSEAS必须使用真实可计价海外仓;固定渠道只有一个可用海外仓时允许重复使用,不伪造第二个仓。- 默认
--order-profile-mode fixed仍生成 FBA + STANDARD,不启用上述随机组合。
执行前置
执行前确认:
- 目标 Gateway 和服务已部署当前接口。
- 平台管理员账号可用。
- 复用客户已审核通过,商户账号可登录。
- 客户固定箱型初始化完成。
- 固定国内仓为
ACTIVE且具备收货能力。 - 固定渠道存在当前
ACTIVE价格簿和进仓码前缀。 - FBA/OVERSEAS 至少存在一个与固定渠道价格明细匹配的目的仓。
- File、Order、Firstleg、Warehouse、IAM、Auth 等链路可用。
账号、密码、环境域名和 Token 不得写入本文、源码、提交记录或报告。建议由本地未提交环境文件或当前终端环境变量提供。
PowerShell 命令模板
先在当前终端提供敏感执行参数:
$env:ADMIN_TEST_GATEWAY = '<目标环境国内 Gateway>'
$env:ADMIN_TEST_USERNAME = '<平台管理员账号>'
$env:ADMIN_TEST_PASSWORD = '<平台管理员密码>'
$env:MERCHANT_TEST_USERNAME = '<已审核商户账号>'
$env:MERCHANT_TEST_PASSWORD = '<已审核商户密码>'
从 baiyue-firstleg/ 执行:
node scripts/admin-test-env-acceptance.mjs `
--modules inbound-measurement `
--merchant-username $env:MERCHANT_TEST_USERNAME `
--merchant-password $env:MERCHANT_TEST_PASSWORD `
--origin-warehouse-name '<固定国内仓名称>' `
--channel-name '<固定渠道名称>' `
--channel-code '<固定渠道编码>' `
--order-profile-mode randomized `
--wait-split-count 100 `
--output '<本地报告绝对路径>.json'
inbound-measurement 会自动展开 orders 前置。提供完整商户账号和密码后,总入口会复用该客户并移除自动创建客户的 merchant-qualification-fixture;两个商户参数必须同时提供。
如果需要自动新建并审核一个隔离客户,不传复用商户账号,改用:
node scripts/admin-test-env-acceptance.mjs `
--modules merchant-qualification-fixture,orders,inbound-measurement `
--customer-name '<本轮客户名称>' `
--origin-warehouse-name '<固定国内仓名称>' `
--channel-name '<固定渠道名称>' `
--channel-code '<固定渠道编码>' `
--order-profile-mode randomized `
--wait-split-count 100 `
--output '<本地报告绝对路径>.json'
报告核验
成功报告中的 createdResources.waitSplitFixtures 每条至少应核对:
tenantId、orderId、inboundId、inboundCodeprocessStatus=WAIT_SPLITreviewStatus=APPROVEDreceivingWarehouseName、channelCode、channelNamedestinationType、目的仓字段、fulfillmentTypepickupMethod、taxMode、pricingTaxMode、containerMode、customsInspection- SKU 数、总箱数、托数、毛重、净重和测量档案
建议同时检查:
- fixture 数量等于本轮
--wait-split-count inboundCode去重数等于 fixture 数量- 固定客户、国内仓和渠道只有一个唯一值
failed=0且报告顶层success=true- 随机批次包含预期目的类型和履约类型
报告生成前会扫描密码、Token、文件二进制、base64 和 OCR 原文等敏感内容。报告仍属于本地验收证据,不应提交到源码仓库。
人工分柜验收
1. 生成分柜准备清单
人工分柜模块默认生成 6 票同客户、同起运仓、同渠道的 WAIT_SPLIT 数据,并在报告的 createdResources.manualOrderSplittingFixture 中给出:
- 一票
PARTIAL:只分配部分箱数,固定保留 1 箱; - 两票
FULL_1/FULL_2:整票加入同一个柜,验证多订单拼柜; - 一票
UNASSIGNED_CONTROL:不得加入计划,用于核对未分配对照和候选余量; - 全部订单、入库单、入仓码、箱数、客户、仓库和渠道信息。
复用既有客户时执行:
node scripts/admin-test-env-acceptance.mjs `
--modules manual-order-splitting-fixture `
--merchant-username $env:MERCHANT_TEST_USERNAME `
--merchant-password $env:MERCHANT_TEST_PASSWORD `
--origin-warehouse-name '<固定国内仓名称>' `
--channel-name '<固定渠道名称>' `
--channel-code '<固定渠道编码>' `
--order-profile-mode fixed `
--wait-split-count 6 `
--output '<人工分柜准备报告绝对路径>.json'
manual-order-splitting-fixture 会自动展开 orders → inbound-measurement。本入口通过正式 HTTP 接口写入测试数据,仍需当前对话明确授权目标环境。
2. Admin 人工操作
根据准备报告执行:
- 打开智能装柜页面,创建与清单一致的起运仓、渠道模拟柜。
- 创建智能装柜计划。
- 严格按
assignments[].expectedAllocatedPackageCount分配三票入仓码。 - 不要选择
unassignedControl。 - 保存计划但暂不推送预装,记录页面或接口返回的
loadingPlanId。
此阶段只是“计划分柜”。父子订单和最终实装数量要到 PDA 实装结算后形成,不能在本节点提前宣称已经完成订单拆分。
3. 人工操作后只读核验
node scripts/admin-test-env-acceptance.mjs `
--modules manual-order-splitting-verify `
--manual-split-fixture-report '<人工分柜准备报告绝对路径>.json' `
--manual-split-plan-id '<页面记录的 loadingPlanId>' `
--output '<人工分柜核验报告绝对路径>.json'
核验模块只发送 GET 请求,检查:
- 计划与柜次 ID 有效,计划仍处于可继续验收的
EDITING/LOADING; - 柜次仓库、渠道与准备清单一致;
PARTIAL/FULL_1/FULL_2的计划箱数精确匹配;- 未混入清单外入库单,
UNASSIGNED_CONTROL未被误选; - 候选回查不出现异渠道或异仓入库单;
- 每票分配后的候选剩余箱数满足数量守恒。
核验报告会写入 createdResources.manualOrderSplittingVerification,记录来源 marker、计划、柜次和已核验分配,不保存凭据。
人工推送预装验收
完成上一节人工分柜核验后,继续验证“点击推送预装,但尚无真实柜号、未关联订舱”的节点。
1. 生成推送前操作清单
使用上一节生成的“人工分柜核验报告”:
node scripts/admin-test-env-acceptance.mjs `
--modules manual-preload-push-fixture `
--manual-preload-source-report '<人工分柜核验报告绝对路径>.json' `
--output '<推送预装前准备报告绝对路径>.json'
该模块只发送 GET 请求,并确认:
- 智能装柜计划仍为
EDITING; - 人工分柜明细存在且版本有效;
- 尚未建立预装 bridge;
- 柜次仍为无真实
containerNo、无oceanBookingId的内部模拟柜。
成功后,报告中的 createdResources.manualPreloadPushFixture 会保存推送前计划版本、明细快照和操作说明。
2. Admin 人工推送
在同一智能装柜计划上点击“推送预装”。本节点只做这一项操作:
- 不录入真实集装箱号;
- 不创建或关联订舱;
- 不确认预装计划;
- 不领取或创建 PDA 任务。
推送成功后立即执行下一步只读核验。
3. 推送后只读核验
node scripts/admin-test-env-acceptance.mjs `
--modules manual-preload-push-verify `
--manual-preload-source-report '<推送预装前准备报告绝对路径>.json' `
--output '<推送预装核验报告绝对路径>.json'
核验内容包括:
- 计划仍为
EDITING,版本相对推送前递增,分柜明细没有漂移; - 每票入库单生成
PENDING预装 bridge,箱数与人工分柜一致; - 正式预装清单详情可见;
- 无真实柜号阶段
canConfirm=false、readyForPda=false; - PDA 任务查询返回
A0404; - 推送没有伪造真实柜号、订舱关联或改变稳定柜次身份。
通过后报告写入 createdResources.manualPreloadPushVerification,下一节点再处理订舱放舱、真实柜号关联和整份预装计划确认。
人工订舱关联、预装确认与 PDA 待领取验收
1. 冻结操作前基线
以上一节“推送预装核验报告”为来源:
node scripts/admin-test-env-acceptance.mjs `
--modules manual-pda-ready-fixture `
--manual-pda-source-report '<推送预装核验报告绝对路径>.json' `
--output '<PDA就绪前准备报告绝对路径>.json'
准备模块只发送 GET 请求,确认:
- 已推送计划仍为
EDITING,版本和分柜明细没有变化; - 原柜次仍无真实柜号、无订舱关联;
- 当前
canConfirm=false、readyForPda=false; - PDA 查询仍返回
A0404。
报告的 createdResources.manualPdaReadyFixture 保存柜次、计划、版本和明细基线。
2. Admin 人工操作
严格按以下顺序操作:
- 创建与准备清单客户、起运仓、渠道、柜型一致的海运订舱 DRAFT,并补齐承运船司代码
carrierCode、提单号、船名、航次、ETD、ETA、参与方和柜型需求。 - 点击放舱,使订舱进入
RELEASED。此时不应自动生成真实柜次或 PDA 任务。 - 在原内部柜次上选择该订舱未占用的柜型需求,录入唯一真实
containerNo完成关联;不得新建替代柜次。 - 回到预装详情,确认门禁变为
canConfirm=true,再执行整份预装计划确认。 - 确认成功后不要领取 PDA 任务,记录订舱号和真实柜号并立即执行核验。
3. 只读核验 PDA 待领取状态
node scripts/admin-test-env-acceptance.mjs `
--modules manual-pda-ready-verify `
--manual-pda-source-report '<PDA就绪前准备报告绝对路径>.json' `
--output '<PDA待领取核验报告绝对路径>.json'
核验内容包括:
- 订舱为
RELEASED,且 allocation 唯一指向原containerBookingId; - 真实柜号在原柜次上补全,
cabinetNo/loadingPlanId/items不漂移; - 整份预装为
CONFIRMED、readyForPda=true,并返回唯一pdaTaskId; - PDA task 四元身份正确,
taskStatus=LOADING、workflowStatus=UNASSIGNED; - PDA 计划箱数与人工分柜总箱数一致;
- 尚未领取任务时各来源入库单仍保持
WAIT_SPLIT。
通过后报告写入 createdResources.manualPdaReadyVerification。下一节点进入 PDA 人工领取、扫码、批量提交和待复核验收。
PDA 人工领取、扫码和批量提交验收
1. 冻结 PDA 作业前基线
以上一节“PDA 待领取核验报告”为来源:
node scripts/admin-test-env-acceptance.mjs `
--modules manual-pda-batch-fixture `
--manual-pda-batch-source-report '<PDA待领取核验报告绝对路径>.json' `
--output '<PDA作业前准备报告绝对路径>.json'
准备模块只发送 GET 请求,确认并记录:
- 任务为
UNASSIGNED,尚未绑定作业员; - PDA 待办中只有同一稳定
taskId; - 每条任务明细包含稳定
boxCodes,数量足以覆盖计划箱数; - 库存快照的任务版本和四元身份一致;
- 操作历史尚无
CLAIM/BATCH/REVIEW/COMPLETE_LOADING。
报告的 createdResources.manualPdaBatchFixture.taskItems[].scanBoxCodes 提供本轮应扫描箱码,boxCodes 保留服务端完整下发集合;库存 snapshotToken 不写入报告,PDA 提交前必须实时重新获取。
2. PDA 真机人工操作
- 使用目标仓库作业员进入 PDA 待办并领取任务,确认页面进入作业中。
- 按准备报告对应任务明细,在真机逐箱扫描稳定箱码;同一箱码不能重复扫描。
- 所有明细均按计划箱数完成,本节点不使用
PARTIAL或SKIP。 - 点击提交时由 PDA 重新获取库存快照,并只发送一次原子 batch。
- 成功后停在
AWAITING_REVIEW,不要上传五类证据,不要复核或执行最终完成。
服务端 batch 只接收明细与数量,不保存逐次扫码轨迹。因此自动报告只能证明稳定箱码已下发和服务端数量已收敛,真机逐箱扫码过程必须保留人工证据。
3. 批量提交后只读核验
node scripts/admin-test-env-acceptance.mjs `
--modules manual-pda-batch-verify `
--manual-pda-batch-source-report '<PDA作业前准备报告绝对路径>.json' `
--output '<PDA待复核核验报告绝对路径>.json'
核验内容包括:
- 任务已绑定真实作业员,版本递增;
- 所有明细均为
PICKED,已拣箱数等于计划箱数; - 任务保持
taskStatus=LOADING,工作流进入AWAITING_REVIEW; - pending 与 detail 均显示零条未处理明细;
- 操作历史恰有一次
CLAIM、一次BATCH,没有REVIEW/COMPLETE_LOADING; - 各入库单服务端汇总
expectedCount=pickedCount; - 待复核取证 GET 已开放。
通过后报告写入 createdResources.manualPdaBatchVerification,并明确标记逐次扫码仍需真机证据。下一节点处理五类装柜证据和 PDA 最终完成。
五类装柜证据、PDA 最终完成与 LOADED 验收
1. 冻结最终完成前基线
以上一节“PDA 待复核核验报告”为来源:
node scripts/admin-test-env-acceptance.mjs `
--modules manual-loading-complete-fixture `
--manual-loading-complete-source-report '<PDA待复核核验报告绝对路径>.json' `
--output '<装柜最终完成前准备报告绝对路径>.json'
准备模块只发送 GET 请求,确认:
- PDA 任务为
AWAITING_REVIEW,所有明细已拣齐; - 装柜计划仍为
LOADING/IN_PROGRESS; - 任务审计只有一次
CLAIM和一次BATCH; - 当前证据归属入库单没有 ACTIVE 装柜证据;
- 真实柜号和
RELEASED订舱门禁仍有效。
报告的 createdResources.manualLoadingCompleteFixture 会固定证据归属、五类证据要求和最终完成前版本。
2. PDA 真机人工操作
在同一 PDA 任务内现场完成:
- 拍摄空仓照
PHOTO_STEP_1。 - 拍摄半仓照
PHOTO_STEP_2。 - 拍摄满仓照
PHOTO_STEP_3。 - 拍摄锁仓照
PHOTO_STEP_4。 - 拍摄带锁码照
SEAL,并填写非空锁码。 - 确认五类均为 ACTIVE 后,只点击一次最终完成。
不要调用旧入库单级兼容完成入口;当前唯一正式动作是 PDA task 的最终完成。成功后不要继续修改柜号、计划或证据。
3. LOADED 终态只读核验
node scripts/admin-test-env-acceptance.mjs `
--modules manual-loading-complete-verify `
--manual-loading-complete-source-report '<装柜最终完成前准备报告绝对路径>.json' `
--output '<LOADED终态核验报告绝对路径>.json'
核验内容包括:
- 五类 ACTIVE 证据各一份,SEAL 锁码非空且每张图片可鉴权下载;
- 任务
taskStatus/workflowStatus均为COMPLETED; - 操作历史恰有一次
COMPLETE_LOADING,并保留原 CLAIM/BATCH; - 原装柜计划进入
COMPLETED; - 所有来源入库单进入
LOADED,状态历史包含LOADING → LOADED; - 对应统一订单详情投影为
LOADED; - 柜次实装分片唯一,实装箱数等于 PDA 已拣总箱数;
- 货柜总览聚合 COMPLETED PDA 和五类 ACTIVE 证据。
通过后报告写入 createdResources.manualLoadingCompleteVerification。至此,本指南覆盖的国内人工验收链已经从订单造数连续到装柜 LOADED;后续报关、国内出仓和海外接柜另按对应节点扩展。
失败、重跑与批量拆分
- 批次遇到第一条失败即停止,已经成功创建的订单不会自动删除或回滚。
- 先查看日志和 JSON 报告中最后一个成功 fixture、失败接口的
code/requestId/traceId,修复前置后再运行剩余数量。 - 重跑会生成新业务单号和入仓码,不覆盖旧订单;不要假设跨多次运行的入仓码一定连续。
- 每次运行的随机序列从 1 重新开始;分批执行时组合可能重复,但仍保持固定三项和真实契约。
- 大于 100 条时建议按 50-100 条拆批,并为每批使用独立报告文件名。
- 若固定渠道只有少量目的仓,目的仓重复是合法结果;脚本只保证从真实可计价集合选择,不保证每批目的仓均匀分布。
常见阻断
| 现象 | 核对项 |
|---|---|
| 未找到固定起运仓 | 仓库名称是否精确一致、状态是否 ACTIVE、类型是否 DOMESTIC |
| 未找到固定物流渠道 | 渠道编码/名称是否精确一致、价格簿是否 ACTIVE、起运仓是否匹配 |
| 没有可计价目的仓 | 价格簿目的类型、目的仓映射、报价税制和仓库状态 |
| 私人地址创建失败 | destinationWarehouseId 必须为空,收件人字段必须完整 |
| 测量审核未到 WAIT_SPLIT | 称重图片、托数、净重、总箱数和测量箱数是否精确核平 |
| 报告数量不足 | 查看首个失败模块;已成功数据不会因后续失败回滚 |
离线验证
修改生成器或本文关联参数后,至少运行:
node --check scripts/admin-test-env-acceptance.mjs
node --check scripts/admin-test-env-modules/orders.mjs
node --check scripts/admin-test-env-modules/manual-order-splitting-fixture.mjs
node --check scripts/admin-test-env-modules/manual-order-splitting-verify.mjs
node --check scripts/admin-test-env-modules/manual-preload-push-fixture.mjs
node --check scripts/admin-test-env-modules/manual-preload-push-verify.mjs
node --check scripts/admin-test-env-modules/manual-pda-ready-fixture.mjs
node --check scripts/admin-test-env-modules/manual-pda-ready-verify.mjs
node --check scripts/admin-test-env-modules/manual-pda-batch-fixture.mjs
node --check scripts/admin-test-env-modules/manual-pda-batch-verify.mjs
node --check scripts/admin-test-env-modules/manual-loading-complete-fixture.mjs
node --check scripts/admin-test-env-modules/manual-loading-complete-verify.mjs
node --test scripts/admin-test-env-modules/merchant-qualification-fixture-contract.test.mjs scripts/admin-test-env-modules/inbound-measurement-box-code-contract.test.mjs scripts/admin-test-env-modules/manual-order-splitting-contract.test.mjs scripts/admin-test-env-modules/manual-preload-push-contract.test.mjs scripts/admin-test-env-modules/manual-pda-ready-contract.test.mjs scripts/admin-test-env-modules/manual-pda-batch-contract.test.mjs scripts/admin-test-env-modules/manual-loading-complete-contract.test.mjs
git diff --check
离线检查不访问环境,也不代表 HTTP 批量生成已经通过。真实生成必须另行获得目标环境写数据授权。