Files
docs/入库测量与计费/入库测量与计费需求优化版-v2-测量计费入库主流程.md
T
2026-09-10 17:13:05 +08:00

22 KiB
Raw Blame History

虫虫出海入库测量与计费需求优化版 V2:测量、计费、托盘入库闭环

形成日期:2026-08-01 文档状态:待业务审核 依据:入库测量与计费原型、现有入库测量与计费需求优化稿及 2026-08-01 新增流程说明 本文只定义入库测量与计费范围和业务契约,不代表功能已经开发完成。

主体模型:本文业务数据中的“租户”历史术语与 tenantId / tenant_id 字段,当前均按客户归属兼容语义理解;产品只有“平台—客户”两级。tenant_id=0 是平台身份、RBAC 和平台公共仓储资源技术作用域,客户往来单位、订单、文件和费用使用所属客户 tenant_id>0。入库测量与计费不引入真实租户层。

技术实现状态更新(2026-08-04):任务 019fc6f9-8dcf-74e1-bc68-d42f15d7802a 已完成核心正常主链路开发,并通过本地测试 MySQL 和隔离端口真实 API 回归。产品/业务待确认项仍以第九章和《入库测量与计费 V2 需求确认清单》为准。

订单衔接规则更新(2026-08-07,已确认):草稿不生成入仓码;订单提交进入待审核时立即生成并固定唯一入仓码。平台审核无需先选择承运商;审核通过后才创建正式入库单并沿用该码,承运商可在后续履约或计费前补充。

一、结论

入库测量与计费主流程应从原来的“人工测量—测量审核—接收审核—人工计费—填写一个库位”调整为:

订单与客户头程订单提交待审核
  → 生成并固定唯一入仓码
  → 平台审核通过(承运商不是审核前置条件)
  → 创建正式入库单并沿用该入仓码
  → 第三方测量设备按入仓码回传长宽高
  → 上传称重图片并由 OCR 识别重量
  → 人工校正 OCR 结果并汇总实际重量
  → 测量数据审核
  → 按客户规则、船司和 FBA 目的仓自动试算
  → 人工确认费用
  → 点击“发送费用给客户”
  → 拆分托盘并分配库位
  → 占用库位、入库成功、费用对客户可见
  → 异步通知客户

“发送费用给客户”是入库测量与计费业务完成节点,也是入库成功节点。原方案中的独立“接收审核”不再作为入库前置节点;如页面需要保留,可改名为“入库确认”,其核心动作就是确认费用并完成托盘、库位占用。

入库测量与计费不新增微服务:

  • 入库单、测量数据、审核、计费试算和费用快照放在头程服务。
  • 托盘基础资料、库位及库位占用放在仓库服务。
  • 测量图、称重图继续使用文件服务。
  • 客户通知通过现有事件桥接服务发送,不在入库事务中同步调用外部消息渠道。
  • 权限继续复用 IAM,所有后台按钮做到客户归属、企业、仓库数据范围校验。

二、核心业务规则

2.1 测量审核失败是否允许入库

保留 Nacos 动态开关,默认关闭:

firstleg:
  inbound:
    allow-rejected-measurement: false

建议配置归属:

  • Data ID:firstleg-${spring.profiles.active}.yaml
  • Group:BAIYUE
  • 默认值:代码和 Nacos 均为 false,避免 Nacos 配置缺失时意外放行。

开关语义:

配置值 规则
false 只有测量审核通过,才能确认费用、发送费用和入库;审核失败必须修正后重新提交。
true 测量审核失败的入库单允许由有“异常放行”权限的人员继续;必须填写放行原因。

即使开关开启,也不能让所有失败单自动入库。后端还必须同时校验按钮权限 firstleg:inbound:exception-release,记录操作人、原因、审核失败原因、开关当时值和时间。作废单、缺少费用快照或没有可用库位的单据始终不得放行。

2.2 第三方长宽高测量

第三方设备只通过入仓码绑定入库单,不接受第三方直接传内部数据库主键。一个入仓码可回传多条箱规测量明细,每条回传必须带第三方事件号以保证幂等。

建议开放接口:

POST /openapi/v1/inbound-measurements

请求头:

X-App-Key: 分配给测量服务商的应用标识
X-Timestamp: Unix 毫秒时间戳
X-Nonce: 随机串
X-Signature: HMAC-SHA256 签名
Idempotency-Key: 第三方事件号

请求示例:

{
  "eventNo": "M202608010001",
  "warehouseCode": "CN-YW-01",
  "inboundCode": "RK202608010001",
  "deviceCode": "DEVICE-01",
  "measuredAt": "2026-08-01T10:30:00+08:00",
  "items": [
    {
      "itemNo": "001",
      "lengthCm": 50.20,
      "widthCm": 40.10,
      "heightCm": 30.00,
      "quantity": 5,
      "sourceImageUrl": null
    }
  ]
}

统一响应示例:

{
  "code": "0",
  "message": "成功",
  "data": {
    "eventNo": "M202608010001",
    "inboundCode": "RK202608010001",
    "accepted": true
  },
  "requestId": "...",
  "timestamp": 1785541800000
}

接口校验:

  • 入仓码必须存在,且属于请求中的仓库和客户归属关系。
  • 入库单必须处于待测量或测量被驳回状态;已入库、已作废、费用已发送的数据不得覆盖。
  • 长宽高必须大于 0,单位统一为厘米;数量必须为正整数。
  • 同一个 appKey + eventNo 重复请求返回第一次结果,不重复新增明细。
  • 第三方原始报文、签名主体、处理结果和请求时间单独留档,业务表保存标准化后的数据。
  • 回调接口只接收测量结果,不直接审核、计费、占用库位或改变入库状态。

建议同时提供查询接口,供设备确认处理结果:

GET /openapi/v1/inbound-measurements/events/{eventNo}

2.3 OCR 重量识别与人工校正

重量数据来自称重图片,而不是长宽高设备。前端先把图片上传文件中心,再把 fileId 提交给头程服务识别,避免业务服务接收和长期保存大文件。

建议接口:

POST /api/platform/inbounds/{inboundId}/weight-images/recognize
PUT  /api/platform/inbounds/{inboundId}/weight-results/{resultId}
POST /api/platform/inbounds/{inboundId}/weight-results/confirm

识别请求只传文件标识:

{
  "fileIds": ["file-001", "file-002"]
}

每张图片形成一条结果,至少保存:图片、OCR 原始文本、OCR 原始重量、置信度、修正后重量、修正人、修正原因、确认状态。总实际重量由所有“已确认且有效”的修正后重量累加,禁止前端直接传一个不可追溯的总重量。

规则:

  • OCR 结果允许人工修改,但不得覆盖原始识别值。
  • 无法识别、置信度过低或单位不明时标记为“待人工确认”。
  • 支持公斤和磅,服务端统一换算成 KG,原单位和原值必须保留。
  • 同一图片不得重复计重;替换、删除图片必须留下操作记录。
  • 测量提交审核前,至少上传并确认一张称重图片;即使整票只有一箱也不得免称重。所有称重图片必须已确认,且总重量大于 0。

2.4 FBA 计费范围

入库测量与计费只支持 FBA 目的仓计费,不做完整财务、账单、收付款、核销和利润模块。

计费匹配顺序:

  1. 根据客户归属、业务客户和生效时间选择客户计费规则版本;两类客户含义必须按字段契约区分。
  2. 根据起运仓、渠道/计费类型、船司、FBA 目的仓和生效时间匹配船司价格。
  3. 计算实测体积、实重和折算量。
  4. 按客户规则确定 KG 或 CBM 计费口径,并取实际量与折算量中的较大值。
  5. 生成费用试算明细,人工确认后形成不可变费用快照。

包税、按 KG 计费:

体积重(kg) = 实测体积(CBM) × 167
计费重量(kg) = max(实际重量(kg), 体积重(kg))
基础费用 = 计费重量 × KG 单价

不包税、按 CBM 计费:

重量折算体积(CBM) = 实际重量(kg) ÷ 363
计费体积(CBM) = max(实测体积(CBM), 重量折算体积(CBM))
基础费用 = 计费体积 × CBM 单价

其中 167、363 只是当前业务给出的默认示例,必须配置在客户规则版本中,不得硬编码。金额还可叠加船司价格表中明确配置的附加费;入库测量与计费头程/FBA 计费不支持阶梯价、组合优惠和复杂表达式。Warehouse 服务中的海外仓客户级天数阶梯仓储费仅为基础资料 CRUD,当前不参与本流程自动计费。

费用单必须保存以下快照,避免基础资料后续修改影响历史订单:

  • 客户规则 ID、版本、计费类型、换算系数和舍入规则。
  • 船司价格 ID、版本、船司、起运仓、FBA 目的仓、有效期和币种。
  • 实测体积、实际重量、折算量、最终计费量、单价、附加费和总金额。
  • 试算人、确认人、确认时间,以及是否异常放行。

无法唯一匹配客户规则或船司价格时,不允许发送费用和入库;返回明确错误,交由运营补充配置。

2.5 发送费用与入库成功

后台按钮:发送费用给客户。建议权限码:firstleg:inbound:send-fee。

点击前必须满足:

  • 入库单未作废、未入库、费用未发送。
  • 长宽高测量数据完整,重量图片均已确认。
  • 测量审核通过;或异常放行开关开启、操作人有权限且填写原因。
  • 费用已按当前有效规则重新试算并由操作人确认。
  • 已选择足够数量的可用托盘和库位。

成功后一次业务操作应产生以下结果:

  1. 锁定费用快照,不再允许原地覆盖。
  2. 生成托盘分配明细。
  3. 在仓库服务预占并确认库位占用。
  4. 入库单状态变为 INBOUNDED,记录入库人和入库时间。
  5. 费用状态变为 SENT,客户侧可只读查看。
  6. 写入“费用已发送”领域事件,由事件桥接服务异步通知客户。

客户消息发送失败不能回滚已经完成的实物入库和库位占用。事件通过 Outbox 重试,并在后台显示“通知失败/待重试”;禁止因用户重复点击产生重复费用、重复托盘或重复占位。

2.6 托盘拆分与库位占用

托盘数量按总体积和选定托盘可用容积向上取整:

托盘数量 = ceil(入库单实际总体积 ÷ 单托盘可用容积)

示例:总体积 20 CBM,托盘可用容积 2 CBM,需要 10 个托盘;默认一个托盘绑定一个库位,因此需要占用 10 个库位。若总体积为 20.1 CBM,则需要 11 个托盘,最后一个托盘保存剩余分配体积。

注意:业务含义应是“10 个托盘分别绑定 10 个库位”,不是“一个托盘同时绑定 10 个库位”。如果实际仓库允许同一库位存多个托盘,后续再增加库位容量模型;入库测量与计费默认一托一位,以避免占用口径不清。

拆分规则:

  • 托盘容积取托盘基础资料快照,历史分配不随托盘资料修改。
  • 托盘编号由仓库服务生成,禁止前端自行拼接。
  • 后端校验库位属于当前仓库、启用且未占用。
  • 多人同时选同一库位时,以数据库唯一约束或乐观锁保证只有一个请求成功。
  • 已入库后的换位、释放和重新上架不属于本次主流程;如确有需要,应作为 P1 的库位调整功能单独验收。

三、状态模型

建议把“流程状态”“审核状态”“费用状态”“通知状态”分开保存,避免一个状态字段组合爆炸。

3.1 入库单流程状态

状态 说明
WAIT_MEASURE 等待第三方长宽高和称重图片。
MEASURING 已接收部分测量或 OCR 数据,尚未确认完整。
MEASURE_PENDING 测量已提交,等待审核。
MEASURE_REJECTED 审核失败,等待修正;默认不能继续入库。
WAIT_PRICING 测量审核通过,等待计费试算。
FEE_CONFIRMING 已试算,等待人工确认并发送。
INBOUNDING 正在预占托盘和库位,防止重复操作。
INBOUNDED 费用已确认并发送,托盘和库位已占用,入库成功。
VOIDED 已作废。

3.2 子状态

  • 测量审核:PENDING / APPROVED / REJECTED。
  • 费用:UNPRICED / CALCULATED / CONFIRMED / SENT / VOIDED。
  • 客户通知:NOT_CREATED / PENDING / SUCCESS / FAILED。

四、服务与数据边界

服务 入库测量与计费职责 主要新增数据
头程服务 入库单、第三方测量接入、OCR 结果业务管理、测量审核、计费匹配、费用快照、入库编排 入库单、测量批次/明细、OCR 重量结果、审核记录、客户规则、船司价格、费用快照、托盘分配引用
仓库服务 托盘资料、库位资料、可用库位查询、预占/确认/释放 托盘、库位、库位占用、预占记录
文件服务 称重图片、测量图片和附件 文件元数据和对象存储引用
事件桥接服务 客户通知的可靠投递 Outbox 消费记录、通知结果
IAM 客户归属、企业、仓库范围和按钮权限 新增入库测量与计费权限资源,不新增业务数据

头程与仓库分库,不能依赖跨库事务。采用“仓库库位预占 → 头程确认入库 → 仓库确认占用”的幂等 Saga;补偿只释放仍处于预占状态的库位,已经完成实物入库的记录不得被通知失败反向释放。

五、建议新增的核心接口

5.1 平台后台接口

GET  /api/platform/inbounds
GET  /api/platform/inbounds/{id}
POST /api/platform/inbounds/{id}/measurements/submit
POST /api/platform/inbounds/{id}/measurements/approve
POST /api/platform/inbounds/{id}/measurements/reject
POST /api/platform/inbounds/{id}/weight-images/recognize
PUT  /api/platform/inbounds/{id}/weight-results/{resultId}
POST /api/platform/inbounds/{id}/weight-results/confirm
POST /api/platform/inbounds/{id}/fees/calculate
POST /api/platform/inbounds/{id}/fees/confirm
POST /api/platform/inbounds/{id}/send-fee-and-inbound
GET  /api/platform/inbounds/{id}/pallet-allocations
GET  /api/platform/inbounds/{id}/operation-logs

5.2 仓库内部接口

GET  /internal/warehouses/{warehouseId}/locations/available
POST /internal/location-reservations
POST /internal/location-reservations/{reservationNo}/confirm
POST /internal/location-reservations/{reservationNo}/release

所有写接口必须支持幂等键;所有查询由后端基于登录上下文注入客户归属和企业范围,禁止单独相信前端传入的 tenantId;该参数当前表示目标客户 ID。

六、页面范围

P0 页面

  • 入库单列表和详情。
  • 入库单测量:第三方数据展示、称重图片、OCR 原值/修正值和总重量。
  • 测量数据审核:客户下单、第三方长宽高、OCR 重量三组信息和驳回原因。
  • 费用试算与确认:客户规则、船司价格、FBA 目的仓、计费过程和费用快照预览。
  • 托盘/库位分配:托盘数量、每托盘体积、候选库位、占用结果。
  • 客户订单详情:只读显示已发送费用和入库结果。
  • 客户计费规则、船司价格表、托盘管理和库位管理。

P1 页面/功能

  • 通知失败人工重试。
  • 入库后库位调整。
  • 测量视频。
  • 单票导出。

七、入库测量与计费开发任务重排

ID 模块 交付内容 优先级
P2-01 契约、状态与权限 状态机、错误码、按钮权限、客户/企业/仓库数据范围 P0
P2-02 入库单 列表、详情、入仓码和操作历史 P0
P2-03 第三方测量 签名、幂等、长宽高回传、原始报文留档和查询 P0
P2-04 OCR 称重 图片关联、OCR、人工校正、单位换算、确认和重量汇总 P0
P2-05 测量审核 原单/设备/OCR 对比、通过、驳回和异常放行开关 P0
P2-06 客户计费规则 KG/CBM 类型、换算系数、舍入、生效期和版本 P0
P2-07 船司 FBA 价格 起运仓、船司、FBA 目的仓、单价、币种、附加费和有效期 P0
P2-08 自动试算与费用快照 规则匹配、取大计算、人工确认、费用发送和历史快照 P0
P2-09 托盘与库位 托盘资料、向上拆分、库位可用查询、预占和确认占用 P0
P2-10 入库编排 发送费用、入库成功、跨服务 Saga、幂等和失败补偿 P0
P2-11 客户通知与展示 Outbox 通知、失败重试、客户侧费用和入库结果只读展示 P0
P2-12 文件与审计 称重/测量图片鉴权、第三方调用日志和全操作审计 P0
P2-13 回归与发布 正常、驳回、放行、并发占位、重复提交、越权和异常恢复 P0

八、验收主流程

8.1 正常流程

  1. 客户订单提交待审核时生成唯一入仓码,审核通过后创建正式入库单并沿用该码。
  2. 第三方用入仓码回传多条长宽高,同一事件重复回传不产生重复数据。
  3. 操作员上传多张称重图片,OCR 识别后可逐条修正,系统正确累加 KG。
  4. 审核员通过测量,系统按客户规则、船司、FBA 目的仓匹配唯一有效价格。
  5. 系统按 KG 或 CBM 口径取大计算,页面展示完整计算过程。
  6. 操作员确认后点击发送费用,系统生成正确托盘数并占用相同数量的可用库位。
  7. 入库单变为已入库,客户能看到已发送费用;通知异步成功。

8.2 必须覆盖的异常流程

  • 默认开关关闭时,测量审核失败不能计费发送和入库。
  • 开关开启但无异常放行权限,仍不能入库;有权限且填写原因时才可放行。
  • 无客户规则、无船司价格、价格过期或匹配多条时禁止发送费用。
  • OCR 图片重复、单位不明、未确认或总重为零时禁止提交审核。
  • 库位数量不足、被并发抢占或已停用时,入库失败且不能留下半完成费用/占用。
  • 重复点击发送费用只产生一份费用快照、一组托盘和一次入库结果。
  • 客户通知失败时入库状态不回滚,系统自动重试并可查失败原因。
  • 跨客户、跨企业、跨仓库查询和操作全部拒绝,并记录安全审计;具体使用 HTTP 状态还是业务码以接口统一响应契约为准。

九、仍需业务最终确认的事项

  1. 包税是否固定采用 CBM × 167 转 KG,不包税是否固定采用 KG ÷ 363 转 CBM;不同客户能否配置不同系数。
  2. “根据客户规则然后根据船司计算”是只生成客户应收费用,还是同时保存船司成本。本文默认入库测量与计费只向客户发送应收费用,船司价格作为计价基础,不进入应付和利润闭环。
  3. 船司价格唯一匹配所需维度是否就是:起运仓、渠道/类型、船司、FBA 目的仓和有效期。
  4. 托盘是否始终一托一库位。本文按一托一位设计;若一个库位可放多个托盘,需要补充库位容积、承重和剩余容量规则。
  5. 托盘分配是只按体积平均拆分,还是还要拆到具体 SKU/箱数。本文入库测量与计费只分配体积和箱数汇总,不做完整 SKU 库存。
  6. 点击发送费用前是否还需要第二人复核。本文默认测量审核完成后由有发送权限的操作员确认,不再增加独立接收审核。
  7. OCR 服务商、图片格式、单图大小、识别时限和失败重试次数需要在技术接入前确定。

十、本次相对上一版的变更

  • 第三方长宽高测量从“不纳入”改为入库测量与计费 P0,并定义按入仓码接入的开放接口。
  • OCR 称重从“不纳入”改为入库测量与计费 P0,支持多图累加和人工修正。
  • 人工简单计费改为客户规则加船司 FBA 目的仓自动试算。
  • 新增 KG/CBM 换算取大和费用规则/价格快照。
  • 新增 Nacos 审核失败异常放行开关,默认关闭。
  • 原“接收审核通过即入库”改为“发送费用给客户即入库成功”。
  • 原“只填一个库位”改为按托盘容积向上拆分,并一托一位占用库位。
  • 托盘管理从“不纳入”改为入库测量与计费必要基础能力,但不扩展为完整 WMS。

十一、实现与验收状态(2026-08-04)

11.1 已实现并通过真实 API 验证

  • 订单提交待审核时生成唯一入仓码;审核通过后创建正式入库单并沿用该码,审核不强制选择承运商。
  • 平台测量草稿、箱规明细、尺寸证据图片绑定。
  • 称重图片上传、OCR 失败状态、人工修正、重量确认和多重量汇总。
  • 测量提交、托盘拆分、库位预占及确认占用。
  • 客服测量审核通过后自动计费、发送费用并完成入库。
  • FBA 目的仓计费按实重和体积重取大,本轮 20kg 与 40.08kg 取 40.08kg。
  • 入库详情、费用快照、托盘和库位分配结果查询。
  • 公共收货仓的公共主数据技术归属与商户订单的客户归属分别校验;这只是当前兼容实现,不形成真实租户层。

11.2 最终验证数据

项目 结果
入库单 2084549769916538881
入仓码 RK-2084549604719718402
测量批次 2084556854154715137
最终状态 INBOUNDED / APPROVED / SENT
计费 40.08kg × 11 CNY/kg = 440.68 CNY
托盘 / 库位 2084561214309851137 / 2084561214452457473
预占单 LR2084562525306675202,状态 CONFIRMED

11.3 已落地配置与数据快照

公共仓主数据技术归属配置(配置名保留历史 tenant 命名):

firstleg:
  inbound:
    warehouse-resource-tenant-id: ${WAREHOUSE_RESOURCE_TENANT_ID:0}

公共仓库、快递公司、托盘和库位当前统一使用平台技术作用域 tenant_id=0,不得绑定客户 10001 或其他客户 ID。客户往来单位、订单、文件和费用仍使用所属客户 tenant_id>0。托盘分配快照继续保存历史字段 warehouse_resource_tenant_id 和 reservation_no,其中公共资源归属值应为 0,避免配置变化后无法追溯历史资源归属。

11.4 尚未关闭的环境验收项

  • 接入真实 OCR 供应商凭证后,以现场秤图验证识别准确率、超时和重试。
  • 前端浏览器完成登录、权限按钮、403、跨客户拒绝、重复提交、空态和移动端体验验收。
  • C1-C8 产品结论仍需产品/业务负责人正式填写,技术实现通过不等于代替产品确认。