12 Commits
Author SHA1 Message Date
ouyangxq 407abd634c 优化 2026-09-29 19:55:27 +08:00
ouyangxq 606abeb2c6 优化 2026-09-29 18:47:39 +08:00
ouyangxq 16ecfae84d 优化 2026-09-29 18:06:20 +08:00
ouyangxq 19943112c0 优化 2026-09-29 17:55:58 +08:00
admin e579ca2d3a Merge pull request 'Test' (#1) from test into main
Reviewed-on: #1
2026-09-28 16:01:15 +08:00
ouyangxq df6f434550 docs: align firstleg release contracts and add sailing plans 2026-09-28 15:04:36 +08:00
ouyangxq a4c9ca162a 优化 2026-09-24 17:02:32 +08:00
ouyangxq 5b9f6dc3c1 优化 2026-09-24 14:09:45 +08:00
ouyangxq d8be2ccdef 优化 2026-09-24 13:43:53 +08:00
ouyangxq 6116ad61e1 优化 2026-09-24 09:39:55 +08:00
ouyangxq 005c14a960 优化 2026-09-23 18:26:07 +08:00
ouyangxq 37b143cc2e 优化 2026-09-23 17:47:52 +08:00
48 changed files with 2529 additions and 599 deletions
+1 -1
View File
@@ -28,7 +28,7 @@
## 联调、部署与数据库 ## 联调、部署与数据库
- 默认只准备代码、验证结果和人工部署步骤,不触发 Jenkins、不启动本地 Java/Nacos/数据库。开发全流程总控可按 `开发环境独立任务协作登记.md` 的授权操作开发数据库、部署开发环境并执行开发环境真实 HTTP;登记专项可按 `独立任务协作登记.md` 的持续授权查询和修改用户指定的测试数据库。两类授权不得跨环境复用,也不得自动扩大到 Jenkins 或生产环境。 - 默认只准备代码、验证结果和人工部署步骤,不触发 Jenkins、不启动本地 Java/Nacos/数据库。开发全流程总控可按 `开发环境独立任务协作登记.md` 的授权操作开发数据库、部署开发环境并执行开发环境真实 HTTP;登记专项可按 `独立任务协作登记.md` 的持续授权查询和修改用户指定的测试数据库。两类授权不得跨环境复用,也不得自动扩大到 Jenkins 或生产环境。
- 只有用户在当前轮明确授权指定环境、服务和提交时,才可部署或执行 HTTP 验收;测试数据库的读写例外仅适用于登记表中已持续授权的总控与专项,并遵守其中的职责和破坏性操作门禁。 - 只有用户在当前轮明确授权指定环境、服务和提交时,才可部署或执行 HTTP 验收;同一环境和服务的非破坏性写入可复用本轮授权,删除、重置、执行 SQL、部署或发布仍逐项授权。测试数据库的读写例外仅适用于登记表中已持续授权的总控与专项,并遵守其中的职责和破坏性操作门禁。
- 环境地址、凭据和 Token 不写入源码或 `AGENTS.md`。接口不可用或契约不一致时记录路径、状态、错误码、`requestId`/`traceId` 和阻断原因,不回退到模拟成功。 - 环境地址、凭据和 Token 不写入源码或 `AGENTS.md`。接口不可用或契约不一致时记录路径、状态、错误码、`requestId`/`traceId` 和阻断原因,不回退到模拟成功。
- 测试环境联调、部署和验收命令读取 `测试环境Jenkins部署指南.md`;开发全流程只按 `开发环境独立任务协作登记.md` 的授权与目标项目指引执行,不把测试 Jenkins 流程当作开发部署入口。 - 测试环境联调、部署和验收命令读取 `测试环境Jenkins部署指南.md`;开发全流程只按 `开发环境独立任务协作登记.md` 的授权与目标项目指引执行,不把测试 Jenkins 流程当作开发部署入口。
+16 -6
View File
@@ -1,6 +1,9 @@
# 虫虫出海文档索引 # 虫虫出海文档索引
项目交付文档按业务域组织。当前开发环境以端到端全流程为统一范围;历史规划、确认和验收记录保留在对应业务域目录,仅用于追溯决策,不构成功能边界。 项目交付文档按业务域组织。当前只有测试环境,以端到端全流程为统一范围;历史规划、确认和验收记录保留在对应业务域目录,仅用于追溯决策,不构成功能边界。
- [测试环境单机部署与配置契约](测试环境单机部署与配置契约.md):唯一环境、部署配置、整体切换与验收。
- [统一认证与服务通信契约](统一认证与服务通信契约.md):统一入口、权限撤销、逐事件投递与幂等。
## 业务域文档 ## 业务域文档
@@ -9,6 +12,7 @@
- [订单与客户](订单与客户/README.md):登录认证、客户与企业、权限、头程订单和客户工作台。 - [订单与客户](订单与客户/README.md):登录认证、客户与企业、权限、头程订单和客户工作台。
- [入库测量与计费](入库测量与计费/README.md):预约取货、到仓收货、箱码与箱唛、测量、尺寸策略、计价和入库费用。 - [入库测量与计费](入库测量与计费/README.md):预约取货、到仓收货、箱码与箱唛、测量、尺寸策略、计价和入库费用。
- [国内货柜履约](国内货柜履约/README.md):分柜与同柜、智能排柜、订舱、拖车、PDA 拣货、装柜、报关和国内出仓。 - [国内货柜履约](国内货柜履约/README.md):分柜与同柜、智能排柜、订舱、拖车、PDA 拣货、装柜、报关和国内出仓。
- [船期日历功能规划](国内货柜履约/船期日历功能规划.md):渠道、周模板、单次船期、收货截止时间和按渠道货量统计的独立日历规划。
- [海外仓业务](海外仓业务/README.md):船节点、海外接柜、入仓、库存、托盘、换标、转运、废弃、退货、排车、PDA 出库、派送、异常退回、客户回访、一件代发及海外本土业务。 - [海外仓业务](海外仓业务/README.md):船节点、海外接柜、入仓、库存、托盘、换标、转运、废弃、退货、排车、PDA 出库、派送、异常退回、客户回访、一件代发及海外本土业务。
- [船节点标准化契约](海外仓业务/船节点标准化契约.md):统一船司原始状态、标准节点、预计/实际时间、异常事实、还柜停止规则和新增船司接入门禁。 - [船节点标准化契约](海外仓业务/船节点标准化契约.md):统一船司原始状态、标准节点、预计/实际时间、异常事实、还柜停止规则和新增船司接入门禁。
- [财务管理](财务管理/README.md):应收、应付、费用池、账单、收款、成本、核销、凭证以及国内外业务费用来源。 - [财务管理](财务管理/README.md):应收、应付、费用池、账单、收款、成本、核销、凭证以及国内外业务费用来源。
@@ -16,11 +20,16 @@
## 全流程公共契约 ## 全流程公共契约
- [头程下单到尾程出库全流程操作手册](头程下单到尾程出库全流程操作手册.md):从客户头程下单、国内收货测量、分柜装柜和国内出仓,贯通跨区尾程建单、海外接柜入仓、排车、PDA 拣货与尾程出库的角色、操作、状态、编号、门禁和异常处理。 ### 当前流程入口(收尾变更只看这里)
- [头程下单到尾程出库现状流程全景清单](头程下单到尾程出库现状流程全景清单.md):以 F01~F40 盘点现有主链、并行流程、条件分支和异常流,明确操作人、入口/出口状态、单据、编号、数据交接和评审项;应先评审本清单,再进入优化。
- [头程到尾程分阶段流程](头程到尾程分阶段流程/README.md):F01~F40 六个阶段现状文档已全部完成,逐阶段记录操作、字段、状态、数据流、异常、完成判定和上下游交接条件,可按阶段评审并进入优化。 - [头程到尾程当前维护入口](头程到尾程/README.md):集中进入总览、六个阶段、货柜入口、报关专题,以及页面和需求参考。
- [头程到尾程 AI 流程优化上下文包](头程到尾程AI流程优化上下文包.md):统一 AI 分析所需的术语、流程变体、RACI、阶段合同、阻断分类、问题证据、指标口径、优化卡模板和完成定义。
- [头程下单到尾程出库流程易用性与数据流转优化方案](头程下单到尾程出库流程易用性与数据流转优化方案.md):基于已走通主链梳理现状操作问题,提出统一进度、下一动作、操作回执、数据归属、跨区可观测、PDA 易用性、P0-P2 优先级和验收指标。 ### 历史与参考(保留,不作为日常流程入口)
- [头程到尾程历史文档](归档/头程到尾程/README.md):全流程操作手册、旧现状全景、AI 上下文和易用性方案。
- [国内货柜履约历史记录](国内货柜履约/归档/README.md):开发规划、进度、门禁、验收矩阵、审计和旧确认材料。
以上文件继续保留,分别用于历史现状、操作说明和方案追溯;开发规划、进度、门禁和验收记录也按业务域保留,不再与当前节点总表同步改写。
- [跨区域认证与服务通信契约](跨区域认证与服务通信契约.md):统一账号、国内/海外 Token、双区域 API、JWKS、Outbox/Inbox 与服务身份边界。 - [跨区域认证与服务通信契约](跨区域认证与服务通信契约.md):统一账号、国内/海外 Token、双区域 API、JWKS、Outbox/Inbox 与服务身份边界。
- [双区域部署与 Nacos 规划](双区域部署与Nacos规划.md):开发/测试同机共置、生产国内/海外独立控制面、Nacos、数据库及 Event Bridge 部署边界。 - [双区域部署与 Nacos 规划](双区域部署与Nacos规划.md):开发/测试同机共置、生产国内/海外独立控制面、Nacos、数据库及 Event Bridge 部署边界。
- [平台、客户层级与权限契约](平台客户层级与权限契约.md):平台/客户两级产品语义、列表包含详情的只读权限和跨层同步要求。 - [平台、客户层级与权限契约](平台客户层级与权限契约.md):平台/客户两级产品语义、列表包含详情的只读权限和跨层同步要求。
@@ -56,6 +65,7 @@
## 维护规则 ## 维护规则
- 新文档按业务域归档,不新增以开发批次编号命名的目录、文件、标题、任务或范围标签。 - 新文档按业务域归档,不新增以开发批次编号命名的目录、文件、标题、任务或范围标签。
- 已完成开发阶段的流程手册、规划、进度和验收资料统一放入 `归档/`;后续流程变更只从[头程到尾程当前维护入口](头程到尾程/README.md)进入。
- 当前交付范围始终按端到端全流程理解;业务域目录只用于检索和职责归属,不用于排除上下游流程。 - 当前交付范围始终按端到端全流程理解;业务域目录只用于检索和职责归属,不用于排除上下游流程。
- 范围、字段或流程冲突时,按“当前对话确认 > 正式契约与确认记录 > 项目指引与代码 > 原型 > 历史记录”判断。 - 范围、字段或流程冲突时,按“当前对话确认 > 正式契约与确认记录 > 项目指引与代码 > 原型 > 历史记录”判断。
- 新增或修改业务能力时,同步更新业务域 README、跨端契约、接口、权限、SQL、测试和验收入口。 - 新增或修改业务能力时,同步更新业务域 README、跨端契约、接口、权限、SQL、测试和验收入口。
+16 -2
View File
@@ -2,12 +2,23 @@
本文件按需检索,不作为启动必读文档。以下路径均按工作区根目录或表内注明的应用源码根目录起算,不相对于 docs/。 本文件按需检索,不作为启动必读文档。以下路径均按工作区根目录或表内注明的应用源码根目录起算,不相对于 docs/。
架构/环境/部署查[测试环境单机部署与配置契约](测试环境单机部署与配置契约.md);网关/Token/会话撤销/事件通信查[统一认证与服务通信契约](统一认证与服务通信契约.md)。下文旧区域服务路径用于定位现有实现,目标规则以这两份主契约为准。
## 常用说法与歧义分流 ## 常用说法与歧义分流
仓储转运审核、转运驳回:Admin 尾程订单 `apps/admin-web/src/modules/overseas-warehouse/pages/LastMileOrdersView.vue` → `apps/admin-web/src/modules/overseas-warehouse/components/WarehouseTransferReviewDialog.vue`;权限、状态及 API 见该模块 `AGENTS.md` 的“仓储转运审核、通过与驳回”。不要按“审核”误入头程订单审核,也不要按“转运”误入排车转派送。 仓储转运审核、转运驳回:Admin 尾程订单 `apps/admin-web/src/modules/overseas-warehouse/pages/LastMileOrdersView.vue` → `apps/admin-web/src/modules/overseas-warehouse/components/WarehouseTransferReviewDialog.vue`;权限、状态及 API 见该模块 `AGENTS.md` 的“仓储转运审核、通过与驳回”。不要把该入口当作头程订单审单,也不要按“转运”误入排车转派送。
先从任务中取“终端 + 业务对象 + 动作”,如“海外 PDA + 柜号 + 收货”。下面是检索提示,不替代业务契约;代码路径均从工作区根起算。用短词检索,不拿整句自然语言做精确匹配。 先从任务中取“终端 + 业务对象 + 动作”,如“海外 PDA + 柜号 + 收货”。下面是检索提示,不替代业务契约;代码路径均从工作区根起算。用短词检索,不拿整句自然语言做精确匹配。
### 高频任务最小读取集
- 订单审核:根 `AGENTS.md` → `docs/业务快速索引.md` 本节 → `apps/admin-web/src/modules/unified-orders/` → `baiyue-firstleg/order/AGENTS.md`;只有审核门禁跨到履约时才增加 `firstleg/AGENTS.md`。不读海外仓审核或全量权限 SQL。
- PDA 出库:根 `AGENTS.md` → `apps/pda-overseas-uniapp/AGENTS.md` → `src/pages/dispatch/` 和 `src/api/fulfillment.js` → `lastleg-service/AGENTS.md`;只有网关路径或 Token 失败才增加 `gateway-overseas/AGENTS.md`。不读 Admin 排车配置,除非问题涉及平台转派送资格。
- 客户账单:根 `AGENTS.md` → Client `apps/client-web/AGENTS.md` → `src/modules/finance/` → `baiyue-firstleg/finance/AGENTS.md`;平台账单才切换 Admin Finance。不要因“账单”自动加载柜费分摊或海外费用契约。
- 退货、异常、拖车:先用终端、阶段和动作分流;无法确定时只读取本节对应行,不全文加载海外仓 README 或 Lastleg 全部业务索引。
每个入口同时标出排除范围,避免把相邻生命周期当作同一业务。普通任务默认最多读取根指引、一个终端/模块指引和目标代码命中段;跨服务时再增加直接消费者或提供者。
| 常用说法 | 区分依据 | 首个定位范围 | | 常用说法 | 区分依据 | 首个定位范围 |
|---|---|---| |---|---|---|
| 没有报价、价格未命中、人工定价、手工报价 | FBA 单票费用的显式人工报价,不是价格簿上传或静默回退 | Admin `apps/admin-web/src/modules/inbounds/fee/api.ts` 的 `createManualInboundQuote`;Backend `baiyue-firstleg/firstleg/src/main/java/com/baiyue/firstleg/service/FbaPricingService.java` 的 `manualQuote`,联查 `PlatformFbaPricingController`、`fba-pricing-v1.yaml`;Client 快照类型 `apps/client-web/src/modules/first-leg/types/inboundBilling.ts` | | 没有报价、价格未命中、人工定价、手工报价 | FBA 单票费用的显式人工报价,不是价格簿上传或静默回退 | Admin `apps/admin-web/src/modules/inbounds/fee/api.ts` 的 `createManualInboundQuote`;Backend `baiyue-firstleg/firstleg/src/main/java/com/baiyue/firstleg/service/FbaPricingService.java` 的 `manualQuote`,联查 `PlatformFbaPricingController`、`fba-pricing-v1.yaml`;Client 快照类型 `apps/client-web/src/modules/first-leg/types/inboundBilling.ts` |
@@ -19,10 +30,12 @@
| 接柜、卸柜、收货、签收 | 海外 PDA 柜号认领、照片、实收 | `apps/pda-overseas-uniapp/src/pages/operation/operation.vue`;后端查 `ReceivingContainerService` | | 接柜、卸柜、收货、签收 | 海外 PDA 柜号认领、照片、实收 | `apps/pda-overseas-uniapp/src/pages/operation/operation.vue`;后端查 `ReceivingContainerService` |
| 入仓计划、生成计划、按柜生成 | 平台尾程订单预览与确认,不是现场实收 | `apps/admin-web/src/modules/overseas-warehouse/pages/LastMileOrdersView.vue`;后端查 `ContainerInboundPlanConversionCoordinator` | | 入仓计划、生成计划、按柜生成 | 平台尾程订单预览与确认,不是现场实收 | `apps/admin-web/src/modules/overseas-warehouse/pages/LastMileOrdersView.vue`;后端查 `ContainerInboundPlanConversionCoordinator` |
| 审核、审单、批量审核 | 客户头程订单待审核 | `apps/admin-web/src/modules/unified-orders/`;后端查 `BatchOrderReviewPreviewService` | | 审核、审单、批量审核 | 客户头程订单待审核 | `apps/admin-web/src/modules/unified-orders/`;后端查 `BatchOrderReviewPreviewService` |
| 订单审核、头程订单审核、批量审单 | 平台审核客户头程订单,状态以 Order `SUBMITTED` 和服务端 `canApprove/blockReason` 为准;不要按仓储转运审核定位 | Admin `apps/admin-web/src/modules/unified-orders/`;Client 只读订单状态查 `apps/client-web/src/modules/first-leg/`;Backend `baiyue-firstleg/order/` 的 `BatchOrderReviewPreviewService`、`PlatformFirstLegOrderController` |
| 审核、测量审核、实测审核 | 仓库测量结果审核 | `baiyue-firstleg/firstleg/AGENTS.md` 中“审核与初始计价”;页面先查 Admin 入库模块 | | 审核、测量审核、实测审核 | 仓库测量结果审核 | `baiyue-firstleg/firstleg/AGENTS.md` 中“审核与初始计价”;页面先查 Admin 入库模块 |
| 费用、运费、报价、计费、船期价格表、价格簿 | 单票入仓计价、客户专属报价或调价 | `apps/admin-web/src/modules/inbounds/fee/`、`apps/admin-web/src/modules/fba-pricing/carrier-rates/pages/CarrierRatesView.vue`(列表/上传)、`apps/admin-web/src/modules/fba-pricing/carrier-rates/pages/CarrierRateDetailView.vue`(版本详情/映射确认);后端查 `FbaPricingService` | | 费用、运费、报价、计费、船期价格表、价格簿 | 单票入仓计价、客户专属报价或调价 | `apps/admin-web/src/modules/inbounds/fee/`、`apps/admin-web/src/modules/fba-pricing/carrier-rates/pages/CarrierRatesView.vue`(列表/上传)、`apps/admin-web/src/modules/fba-pricing/carrier-rates/pages/CarrierRateDetailView.vue`(版本详情/映射确认);后端查 `FbaPricingService` |
| 柜费、公共费用、分摊 | 国内柜费来源归 Firstleg;海外柜费来源归 Lastleg;账单与结算结果归 Finance | 业务路由查“财务管理与柜级公共费用分摊”或“海外业务费用来源与客户财务”,按实际请求区分 | | 柜费、公共费用、分摊 | 国内柜费来源归 Firstleg;海外柜费来源归 Lastleg;账单与结算结果归 Finance | 业务路由查“财务管理与柜级公共费用分摊”或“海外业务费用来源与客户财务”,按实际请求区分 |
| 充值、余额、授信、账单、核销 | 客户自助与平台管理先按终端区分 | Client `apps/client-web/src/modules/finance/`;Admin `apps/admin-web/src/modules/finance/` | | 充值、余额、授信、账单、核销 | 客户自助与平台管理先按终端区分 | Client `apps/client-web/src/modules/finance/`;Admin `apps/admin-web/src/modules/finance/` |
| 客户账单、客户对账单、账单确认 | 客户查看和确认本企业账单,不是平台柜费分摊或充值审核 | Client `apps/client-web/src/modules/finance/views/FinanceBillsView.vue`;Admin 平台账单查 `apps/admin-web/src/modules/finance/`;Backend `baiyue-firstleg/finance/` 的 Client Finance Controller |
| 自动生成托盘、托盘码没生成、计划齐全、重试生成托盘码 | 海外入库计划保存后资源生成,不是国内托盘标签打印 | Admin `apps/admin-web/src/modules/overseas-warehouse/pages/LastMileOrdersView.vue`;Backend `baiyue-firstleg/lastleg-service/docs/business-index.md` 的“人工计划自动生成托盘与资源重试”,执行规则先读该服务 `AGENTS.md` | | 自动生成托盘、托盘码没生成、计划齐全、重试生成托盘码 | 海外入库计划保存后资源生成,不是国内托盘标签打印 | Admin `apps/admin-web/src/modules/overseas-warehouse/pages/LastMileOrdersView.vue`;Backend `baiyue-firstleg/lastleg-service/docs/business-index.md` 的“人工计划自动生成托盘与资源重试”,执行规则先读该服务 `AGENTS.md` |
| 托盘码、托盘标签、补打 | 先区分散货装柜、一件代发和海外实体托盘 | 散货 `apps/admin-web/src/modules/loading-lists/components/PalletLabelPrintDialog.vue`;一件代发 `apps/admin-web/src/modules/inbounds/core/DropshipPalletPrintPanel.vue`,从订单“托盘打印”页签进入;海外单张打印 `apps/admin-web/src/modules/overseas-warehouse/pages/PalletsView.vue`,详见各应用/模块指引 | | 托盘码、托盘标签、补打 | 先区分散货装柜、一件代发和海外实体托盘 | 散货 `apps/admin-web/src/modules/loading-lists/components/PalletLabelPrintDialog.vue`;一件代发 `apps/admin-web/src/modules/inbounds/core/DropshipPalletPrintPanel.vue`,从订单“托盘打印”页签进入;海外单张打印 `apps/admin-web/src/modules/overseas-warehouse/pages/PalletsView.vue`,详见各应用/模块指引 |
| 箱码、箱唛、箱标、单箱扫码 | 单箱身份与测量,不是托盘或库位 | 业务路由查“箱唛、箱码与单箱测量”;后端查 `InboundCartonLabelService` | | 箱码、箱唛、箱标、单箱扫码 | 单箱身份与测量,不是托盘或库位 | 业务路由查“箱唛、箱码与单箱测量”;后端查 `InboundCartonLabelService` |
@@ -30,6 +43,7 @@
| 拖车、派车、提柜、还柜 | 国内订舱拖车与目的港码头车队是不同业务;海外配送排车另属 Lastleg | 国内 `apps/admin-web/src/modules/trucking/`;目的港 `apps/admin-web/src/modules/container-loading/api/terminalDrayages.ts`;配送查“海外出库、排车” | | 拖车、派车、提柜、还柜 | 国内订舱拖车与目的港码头车队是不同业务;海外配送排车另属 Lastleg | 国内 `apps/admin-web/src/modules/trucking/`;目的港 `apps/admin-web/src/modules/container-loading/api/terminalDrayages.ts`;配送查“海外出库、排车” |
| 报关资料、退税资料、完成文件 | 平台整柜操作与客户订单上传先按终端区分 | Admin `apps/admin-web/src/modules/container-loading/components/ContainerCustomsPanel.vue`;Client `apps/client-web/src/modules/first-leg/components/CustomsDocumentsDialog.vue` | | 报关资料、退税资料、完成文件 | 平台整柜操作与客户订单上传先按终端区分 | Admin `apps/admin-web/src/modules/container-loading/components/ContainerCustomsPanel.vue`;Client `apps/client-web/src/modules/first-leg/components/CustomsDocumentsDialog.vue` |
| 退货、退货预报、退货换标、退货签收、退货合箱 | 客户退货预报及签收库存,区别于派送异常退回 | Client `apps/client-web/src/modules/overseas-warehouse/views/ReturnOrdersView.vue`;Admin `apps/admin-web/src/modules/overseas-warehouse/pages/ReturnInventoryManagementView.vue`;PDA `apps/pda-overseas-uniapp/AGENTS.md`;Lastleg `returnreceipt/`,见下文“退货预报、签收、库存与合箱” | | 退货、退货预报、退货换标、退货签收、退货合箱 | 客户退货预报及签收库存,区别于派送异常退回 | Client `apps/client-web/src/modules/overseas-warehouse/views/ReturnOrdersView.vue`;Admin `apps/admin-web/src/modules/overseas-warehouse/pages/ReturnInventoryManagementView.vue`;PDA `apps/pda-overseas-uniapp/AGENTS.md`;Lastleg `returnreceipt/`,见下文“退货预报、签收、库存与合箱” |
| PDA 出库、PDA 发车、扫码出库、整托出库 | 海外 PDA 执行排车和出库,不是平台排车配置或客户派送查询 | 海外 PDA `apps/pda-overseas-uniapp/src/pages/dispatch/dispatch.vue`、`src/api/fulfillment.js`;Backend `baiyue-firstleg/lastleg-service/dispatch/pda/`;统一经 `gateway-overseas/` |
| 异常、退回、退仓、回访 | 派送异常退回与库存退货业务不可混用 | 派送查 `apps/admin-web/src/modules/overseas-warehouse/pages/ExceptionOrdersView.vue`;退货预报/库存查 Lastleg `returnreceipt/` | | 异常、退回、退仓、回访 | 派送异常退回与库存退货业务不可混用 | 派送查 `apps/admin-web/src/modules/overseas-warehouse/pages/ExceptionOrdersView.vue`;退货预报/库存查 Lastleg `returnreceipt/` |
## 定位步骤与反馈 ## 定位步骤与反馈
@@ -85,6 +99,6 @@
| 海外仓库与通用资料 | `docs/海外仓业务/README.md` | 全部仓库主档进入 Admin `modules/warehouses/` 与国内 `warehouse/`;海外库位/托盘/锁进入 `warehouse-overseas-service/` 并引用国内 warehouseId;报价、汇率、车辆按海外服务实际契约 | | 海外仓库与通用资料 | `docs/海外仓业务/README.md` | 全部仓库主档进入 Admin `modules/warehouses/` 与国内 `warehouse/`;海外库位/托盘/锁进入 `warehouse-overseas-service/` 并引用国内 warehouseId;报价、汇率、车辆按海外服务实际契约 |
| 国内出仓后船节点 | `docs/海外仓业务/README.md` | Admin `modules/port-schedules/`、`ocean-bookings/`、货柜详情;Backend `firstleg/portschedule/`、`integration-service/`;从确认国内出仓查询至目的港到达、提柜和还柜。节点按 `containerBookingId` 柜级聚合,跨区事件使用 `tenantId=0` 平台技术范围,不携带或校验客户 | | 国内出仓后船节点 | `docs/海外仓业务/README.md` | Admin `modules/port-schedules/`、`ocean-bookings/`、货柜详情;Backend `firstleg/portschedule/`、`integration-service/`;从确认国内出仓查询至目的港到达、提柜和还柜。节点按 `containerBookingId` 柜级聚合,跨区事件使用 `tenantId=0` 平台技术范围,不携带或校验客户 |
| 海外出库、排车、派送、异常与回访 | 当前海外履约契约 | Admin `modules/overseas-warehouse/pages/OutboundsView.vue`、`DeliveryOrdersView.vue`、`ExceptionOrdersView.vue`、`CustomerVisitsView.vue`;Backend `lastleg-service/dispatch/`、`delivery/`、`dropship/`、`exceptionorder/`、`customervisit/`;统一经 `gateway-overseas/`。异常单按 `PENDING → PROCESSING → COMPLETED` 流转,处理完成必须引用归属为 `OVERSEAS_EXCEPTION_EVIDENCE` 的证据;派送退回只从原出库拣货事实选择可退明细,退回海外仓时先把实收恢复到指定真实托盘/库位,再原子完成异常单并将派送置为 `RETURNED` | | 海外出库、排车、派送、异常与回访 | 当前海外履约契约 | Admin `modules/overseas-warehouse/pages/OutboundsView.vue`、`DeliveryOrdersView.vue`、`ExceptionOrdersView.vue`、`CustomerVisitsView.vue`;Backend `lastleg-service/dispatch/`、`delivery/`、`dropship/`、`exceptionorder/`、`customervisit/`;统一经 `gateway-overseas/`。异常单按 `PENDING → PROCESSING → COMPLETED` 流转,处理完成必须引用归属为 `OVERSEAS_EXCEPTION_EVIDENCE` 的证据;派送退回只从原出库拣货事实选择可退明细,退回海外仓时先把实收恢复到指定真实托盘/库位,再原子完成异常单并将派送置为 `RETURNED` |
| 海外业务费用来源与客户财务 | 财务契约、`docs/跨区域认证与服务通信契约.md` | 海外入仓、采购、美国卡车、本土散板和海外仓服务费由 `lastleg-service/financefee/` 校验真实业务归属并版本化审核;通过 `BUSINESS_FEE_SOURCE_CHANGED` 完整快照、`event-bridge-service/` 和国内 Finance `/internal/finance/v1/business-fee-source-events` 可靠入池。`PAYABLE + DIRECT_PAID` 进入已确认成本且不得再次进入 AP 待结算;Client 仍从 `modules/finance/` 读取获准客户财务,不自动开放平台费用来源维护页 | | 海外业务费用来源与客户财务 | 当前实现查财务契约与跨区域通信契约;阶段 0A—0E 开发再读 `docs/财务管理/海外仓费用统一接入阶段0技术契约.md` | 当前 V1 由 `lastleg-service/financefee/` 校验海外入仓、采购、美国卡车、本土散板和海外仓服务费,通过完整快照、Event Bridge 和 Finance 内部入口入池;阶段 0 目标改为收费身份/候选版本、Finance 接受或拒绝结果事件及版本化资金计划。必须沿代码确认落地范围,不把技术契约当成已实现状态;Client 仍只读取获准客户财务 |
散货托盘码生成、打印与跨区传递:Admin `modules/loading-lists/components/PalletLabelPrintDialog.vue`;Firstleg `LoadingPalletLabelService`、`LoadingCompletedOutboxService`;Lastleg `LastlegSourcePalletMapper`、`InboundPlanService`。从各项目最近指引继续定位;散货 FBA 标签与一件代发实装托盘分别取各自冻结事实。 散货托盘码生成、打印与跨区传递:Admin `modules/loading-lists/components/PalletLabelPrintDialog.vue`;Firstleg `LoadingPalletLabelService`、`LoadingCompletedOutboxService`;Lastleg `LastlegSourcePalletMapper`、`InboundPlanService`。从各项目最近指引继续定位;散货 FBA 标签与一件代发实装托盘分别取各自冻结事实。
+3 -164
View File
@@ -1,166 +1,5 @@
# 双区域部署与 Nacos 规划 # 双区域部署与 Nacos 规划(已替代)
## 1. 适用范围与结论 自 2026-09-29 起,不再规划开发/测试/生产与 CN/OVERSEAS 双区域。当前唯一目标为单一测试环境、所有服务同机部署。唯一部署主契约见[测试环境单机部署与配置契约](测试环境单机部署与配置契约.md),认证通信见[统一认证与服务通信契约](统一认证与服务通信契约.md)。
本文冻结国内头程与海外仓服务在开发、测试和生产环境中的部署拓扑、Nacos、数据库及 Event Bridge 边界。账号、Token、API 路由和事件语义继续以《跨区域认证与服务通信契约》为准。 此文件仅保留旧链接入口,不再定义有效规则。运行配置切换仍待实施与验证。
当前结论:
- 开发、测试采用单宿主机共置:同一环境内同时部署国内 Compose 与海外 Compose,通过独立容器、网络、端口、Nacos Namespace 和数据库 Schema 隔离。
- 生产采用国内、海外两套独立区域控制面:各自使用本区域 Nacos 集群、数据库和 Redis,不允许海外服务跨境依赖国内 Nacos、MySQL 或 Redis。
- 跨区域只开放双区域 API、JWKS 公钥和 Event Bridge 接收入口,不使用跨区域服务发现。
## 2. 环境拓扑
| 环境 | 宿主与网络 | Nacos | 数据库 | 适用目的 |
|---|---|---|---|---|
| development | 单宿主机共置国内/海外 Compose | 一套开发 Nacos,国内/海外独立 Namespace | 可共用一个开发 MySQL 实例,但必须使用独立 Schema | 日常开发联调 |
| test | 单宿主机共置国内/海外 Compose | 一套测试 Nacos,国内/海外独立 Namespace | 可共用一个测试 MySQL 实例,但必须使用独立 Schema | 集成测试和验收 |
| production-cn | 国内独立部署单元 | 国内高可用 Nacos 集群 | 国内独立 MySQL/Redis | Auth、IAM、头程、国内仓和 Finance |
| production-overseas | 海外独立部署单元 | 海外高可用 Nacos 集群 | 海外独立 MySQL/Redis | 海外 Gateway、Lastleg 和海外 Warehouse |
如果开发与测试实际共用同一套 Nacos 实例,必须创建四个 Namespace,不得复用:
```text
development-cn
development-overseas
test-cn
test-overseas
```
Namespace 名称不是服务名。环境变量必须填写 Nacos 实际 Namespace ID;控制台自动生成 UUID 时使用 UUID,不使用展示名称代替。
## 3. 服务归属
### 3.1 国内区域
- `gateway`、`auth-service`、`iam-service`
- `firstleg-service`、`order-service`、`finance-service`
- 国内 `warehouse-service`、`file-service`、`audit-service` 等公共服务
- 国内 Event Bridge,用于接收目标区域为 `CN` 的事件并投递本地 Firstleg
### 3.2 海外区域
- `gateway-overseas`
- `lastleg-service`,同时持有 `baiyue_lastleg` 内的 IAM 安全事件 Inbox/投影,并开放内部事件接收和实时校验端点
- `warehouse-overseas-service`
- 海外 `file-service`,独占海外 RDS 中的 `baiyue_file`,只访问海外本区域私有 OSS Bucket;详细边界见《[阿里云 OSS 文件中心接入设计与评审](阿里云OSS文件中心接入设计与评审.md)》
- 海外 Event Bridge,用于接收目标区域为 `OVERSEAS` 的事件;业务事件和三类 IAM 安全事件按事件类型投递 Lastleg 的不同内部入口
海外浏览器请求直接进入海外 Gateway,不经过国内 Gateway。Auth 仍只部署在国内;海外服务通过受控 JWKS 地址验证 Auth 签发的短时海外 Token,不访问国内 Redis。
## 4. Nacos 规划
### 4.1 开发与测试
非生产环境允许一套 Nacos 实例承载多个 Namespace。国内配置发布自 `baiyue-firstleg/config/nacos/cn/`,海外配置发布自 `baiyue-firstleg/config/nacos/overseas/`,相同 Data ID 依靠 Namespace 隔离。
国内环境变量:
```dotenv
NACOS_SERVER_ADDR=<当前环境Nacos地址>
NACOS_NAMESPACE=<当前环境国内Namespace ID>
REGION_CODE=CN
DEPLOYMENT_CELL=<environment>-cn
DATA_RESIDENCY=CN
```
海外环境变量:
```dotenv
OVERSEAS_NACOS_SERVER_ADDR=<当前环境Nacos地址>
OVERSEAS_NACOS_NAMESPACE=<当前环境海外Namespace ID>
OVERSEAS_DEPLOYMENT_CELL=<environment>-overseas
```
海外 Compose 必须强制传入 `REGION_CODE=OVERSEAS` 和 `DATA_RESIDENCY=OVERSEAS`,不得继承共享文件中的国内默认值。
### 4.2 生产
生产国内、海外分别部署本区域 Nacos 集群。服务只注册到本区域,不同步或复制临时服务注册表,也不通过公网访问另一地区 Nacos。
```dotenv
# 国内生产凭据
NACOS_SERVER_ADDR=<国内Nacos内网地址>
NACOS_NAMESPACE=<production-cn Namespace ID>
# 海外生产凭据
OVERSEAS_NACOS_SERVER_ADDR=<海外Nacos内网地址>
OVERSEAS_NACOS_NAMESPACE=<production-overseas Namespace ID>
```
生产 Nacos 必须启用认证、网络 ACL 和持久化;不暴露公网管理端口。数据库密码、JWT 私钥、内部服务 Token 和第三方密钥不得写入 Nacos 明文,继续由 Jenkins Credentials 或生产密钥管理系统注入。
## 5. 数据库隔离
开发、测试即使共用一个 MySQL 实例,也必须保持以下 Schema 独立:
| 区域 | 服务 | Schema |
|---|---|---|
| 国内 | Event Bridge | `baiyue_event_bridge` |
| 海外 | Event Bridge | `baiyue_event_bridge_overseas` |
| 海外 | Lastleg | `baiyue_lastleg` |
| 海外 | Warehouse | `baiyue_lastlag_warehouse` |
生产必须进一步使用区域内独立数据库实例或集群。国内服务不得查询海外 Schema,海外服务不得查询国内 Schema;跨区域事实只通过版本化事件或已确认的受保护内部接口传递。
## 6. Event Bridge 双实例
每个区域部署一个相同制品、独立数据库的 Event Bridge:
```text
Firstleg Outbox
-> 海外 Event Bridge Inbox
-> Lastleg 本地消费者
Lastleg Outbox
-> 国内 Event Bridge Inbox
-> Firstleg 本地消费者
```
国内 Firstleg 配置海外 Bridge 基础地址,Feign 自动追加接收路径:
```dotenv
LASTLEG_EVENT_BRIDGE_URL=<海外Event Bridge基础地址>
```
海外 Lastleg 配置国内 Bridge 基础地址:
```dotenv
FIRSTLEG_EVENT_BRIDGE_URL=<国内Event Bridge基础地址>
```
区域内消费者使用本地服务地址:
```dotenv
# 海外 Bridge
EVENT_CONSUMER_URL=http://lastleg-service:9303/internal/lastleg/events
# 国内 Bridge
FIRSTLEG_CONTAINER_EVENT_CONSUMER_URL=http://firstleg:9202/internal/firstleg/v1/container-events
```
跨区域 Bridge 接收入口使用 TLS、内部服务身份、网络白名单和幂等校验;不得暴露数据库或消费者内部接口。
## 7. Jenkins 与环境文件
开发、测试可以各用一份 Secret File,同时包含国内和海外非敏感路由变量;Compose 负责选择本区域变量。生产必须拆分凭据:
```text
firstleg-production-cn-env
firstleg-production-overseas-env
```
生产海外部署不得读取国内数据库、Redis 或 Nacos 地址。Event Bridge 同一制品需要按 `CN`、`OVERSEAS` 两个部署单元分别发布,使用不同 Compose Project、容器名、端口和数据库。
## 8. 当前仓库实施差距
目标架构已冻结,但当前部署代码仍需完成以下收敛:
1. `docker-compose.overseas.yml` 当前仍从 `NACOS_SERVER_ADDR` 取值,应改为显式使用 `OVERSEAS_NACOS_SERVER_ADDR`。
2. `deploy/scripts/deploy-built-service.sh` 与 `deploy-services.sh` 的海外服务门禁应校验 `OVERSEAS_NACOS_SERVER_ADDR`。
3. Jenkins 生产配置需要拆分国内/海外 Secret File,并为 Event Bridge 提供明确区域部署参数或独立 Job。
4. 海外 Nacos Namespace 创建、配置发布、JWKS 可达性和双向 Event Bridge 真实投递必须分别验收,不能以容器健康检查代替。
5. 海外 Gateway 和 Nacos 已存在 File Service 入口,但海外统一 SQL 与部署清单尚未包含海外 `file-service`、`baiyue_file`;OSS 接入实施前必须补齐并完成区域内真实上传、下载和双实例读取验收。
这些差距未完成前,不得声称生产双区域部署已就绪。
+28 -40
View File
@@ -1,51 +1,39 @@
# 国内货柜履约文档 # 国内货柜履约
国内货柜履约以国内头程后程作业为范围,完成从排柜、订舱、拖车和仓内拣货,到装柜证据齐全并进入 `LOADED`/装柜完成的业务闭环。`DELIVERED`/派送完成由到达海外仓后的可信回传推进,不属于国内国内货柜履约操作范围。 本目录负责国内分柜、订舱、拖车、拣货、装柜、装柜后的报关协同、送港、进港和甩柜事实。整体货柜流程进入收尾,**报关协同代码尚未完成**;当前只在这里查找流程节点,报关开发请转到交接清单。
> 范围更正:国内货柜履约只维护订舱和出仓前所需的船名航次、港口、ETD/ETA 等资料。柜子确认离开国内仓库后的 `CarrierScheduleQuery`、六家船公司查询、每 3 天/最多 3 次、来源/过期标识和后续定时船节点查询整体归海外仓业务,见 `../海外仓业务/README.md`。国内货柜履约不再建设或验收这套查询。 ## 当前流程入口
## 当前主体模型与开工禁令 - [头程到尾程流程节点梳理](../头程到尾程流程节点梳理.md):三大业务块总览和 F01-F40 节点总表。
- [阶段三:国内货柜履约与出仓](../头程到尾程分阶段流程/阶段三-国内货柜履约与出仓.md):分柜、订舱、拖车、拣货、装柜、报关和国内出仓的详细操作。
- [阶段四:海运、目的港与尾程计划](../头程到尾程分阶段流程/阶段四-海运目的港与尾程计划.md):实际开船后的海运、目的港和尾程计划衔接。
- [报关资料与船期价格接入梳理](报关资料与船期价格接入梳理.md):报关资料、报关行回执、客户确认/打回、正式申报、海关结果和船期价格专题。
- [船期日历功能规划](船期日历功能规划.md):渠道、周模板、单次船期、收货截止时间和按渠道货量统计的独立日历规划。
- [报关代码开发交接清单](../头程到尾程/报关代码开发交接清单.md):报关代码当前未完成时,下一开发对话使用的范围和验收条件。
- 国内货柜履约继续按业务单租户、“平台—客户”两级开发,客户之间严格隔离。Java 与接口中的业务 `tenant_id > 0` / `tenantId` 当前表示客户 ID;`tenant_id=0` 是平台身份、平台 RBAC 和平台公共仓库、快递公司、托盘、库位等公共资源技术作用域。客户往来单位、订单、文件和费用仍归属客户 `tenant_id>0`。 ## 货柜关键节点
- 国内货柜履约不得新增租户主表、租户选择器、客户所属租户配置、租户切换、租户级 RBAC 或租户级配置,也不得把当前 `tenant_id` 从客户 ID 改义为上级租户 ID。
- `tenant`、`Tenant*`、`merchant`、接口路径和字段属于历史兼容命名,继续保留;真实租户能力必须等未来独立需求、数据迁移和跨服务契约方案确认后再实施。
## 文档 ```text
分柜/订舱/拖车 → 拣货 → 装柜完成(LOADED)
├─ 报关协同:资料 → 报关行回执 → 客户确认/打回重做
│ → 全部客户确认 → 整柜提交 → 正式申报 → 海关结果
↓ 报关完成
进入待发区
↓
送港运输:离仓 → 送港 → 进港 → 甩柜/改配(如发生)
↓
船舶实际开航后进入海运节点
```
- [国内货柜履约闭环审计报告(2026-08-08)](国内货柜履约闭环审计报告-2026-08-08.md):基于当前代码、接口、自动化和测试环境证据的闭环审计,列出阻断项、优先级和 GO 准入标准。 报关完成是进入待发区的门槛。进入待发区后再推进离仓、送港、进港和船期;甩柜/改配只改变运输船次,不影响已完成的报关资料、回执和客户确认。报关行回执、客户确认、正式申报、海关放行、进港、甩柜和实际开船分别记录,不能用其中一个节点代替另一个节点。
- [国内货柜履约装柜闭环产品确认表(2026-08-08)](国内货柜履约装柜闭环产品确认表-2026-08-08.md):提供给产品直接填写的纯业务确认表,不包含技术实现细节。
- [国内货柜履约装柜闭环开发前确认单(2026-08-08)](国内货柜履约装柜闭环开发前确认单-2026-08-08.md):用于产品确认直接开发前的状态、门禁、PDA 取证、冲正和验收细节。
- [国内货柜履约开发规划:国内出仓](国内货柜履约开发规划.md)
- [国内货柜履约开发进度表](国内货柜履约开发进度表.md):参考订单与客户采用“大任务 → 详细任务 → 里程碑 → 未确认事项 → 开工准入 → 验收”结构维护。
- [虫虫出海国内货柜履约开发进度表(Excel)](虫虫出海国内货柜履约开发进度表.xlsx):可筛选、可下拉维护并使用公式汇总的项目进度工作簿。
- [国内货柜履约需求确认表](国内货柜履约需求确认表.md):集中跟踪 P3-Q1~P3-Q13、负责人和最终结论。
- [国内货柜履约开工门禁](国内货柜履约开工门禁.md):维护已确认范围、跨端硬边界和局部阻断项;模块指引引用本文件,不重复维护阶段状态。
- [国内货柜履约页面与原型清单](国内货柜履约页面与原型清单.md):按管理后台、企业客户端和 PDA 维护页面范围及原型状态。
- [国内货柜履约验收任务拆分与待确认清单](国内货柜履约验收任务拆分与待确认清单.md):真实 HTTP/真机验收覆盖、coverageGap 解除条件和并行任务入口。
- `参考资料/出仓流程.png`:本期 9 个核心动作及业务终点的原始参考图。
## 当前状态 费用确认属于头程下单块的并行事项,不阻断排柜、拣货或装柜;装柜完成时仍未确认的当前有效费用按系统默认确认并保留来源。这个默认确认只适用于费用,不适用于报关资料的客户确认。
国内货柜履约已进入分模块部署联调。已确认不新建独立出仓单,现有订单列表/详情承载主状态;支持一单多柜、一个柜拼多个订单,并采用“父订单→子订单→柜次”关系,已装载数量形成子订单,未装载数量自动生成后续子订单。进入 `LOADED`/装柜完成前,订舱完成、拖车完成、报关放行回执、PDA 拣货完成及五类证据完整均为服务端硬门禁;`LOADED` 后错误统一线下人工处理,国内 Admin/PDA 不提供在线冲正或手工推进 `DELIVERED`。当前不能因子链路已通过而宣告整期完成,最终结论以真实 HTTP 全链路验收为准。 ## 当前变更相关文档
柜子出仓后的船公司/船节点查询已重新归入海外仓业务。国内货柜履约报关首版不做系统对接,全部由人工整理、线下提交和人工上传回执。仓库初始化角色包括操作员、拣货员、理货员,具体权限矩阵由 IAM 契约任务落表。 - [国内货柜履约需求确认表](国内货柜履约需求确认表.md):需要核对已确认的业务口径时使用。
- [国内货柜履约页面与原型清单](国内货柜履约页面与原型清单.md):需要核对页面范围或原型入口时使用。
P3-Q1~P3-Q13 均已确认;P3-Q4 采用 uni-app 开发并支持在线更新,Android 广播扫描已接入。P3-Q5 复用入库测量与计费实时库存、当前位置和可用量接口,不扩展完整 WMS。 ## 冻结记录(只用于追溯)
### PDA 当前确认口径(2026-08-10) 开发规划、进度、门禁、验收矩阵、审计、产品确认和旧任务卡已移入[国内货柜履约历史记录](归档/README.md)。这些文件不删除、不回写;若要调整当前流程,修改总览、对应阶段或报关专题,并同步实际接口/权限契约。
- Android 扫描广播方式已接入;PDA 采用 uni-app 开发并支持在线更新,按既定发布安排完成真机验收。
- 正式作业仅支持在线:进入任务即标记“拣货中”,扫描保存在绑定作业员+任务+柜次的设备持久化草稿,点击提交时批量写后端。
- 允许部分拣货或跳拣,但每个未完成项必须填写异常原因;存在未解决异常时不能完成或进入 `LOADED`。
- 重复提交返回原结果,版本冲突提示员工刷新重试。
- PDA 只能现场拍照,Admin 可人工上传;五类证据各至少 1 张有效照片,可同类型多张追加,错图只作废不硬删除。
- 单柜次只允许一名作业员作业,不做多人并行和任务接管;进入任务即标记“拣货中”,扫描草稿按作业员+任务+柜次隔离,点击提交时批量写入后端。
- 后台操作员、理货员可按权限人工上传证据;拣货员只负责 PDA 现场拍照,不开放后台人工上传。照片无限期保留,客户不可见照片和锁码。
### 发布与真实验收状态(2026-08-10)
- Admin 已部署 `b593d72`:智能装柜、预装清单、装柜清单均可访问真实接口;预装/装柜清单不再要求选择仓库,详情仍使用列表行返回的真实仓库归属。
- Firstleg 已部署 `3bfc11a`:修复 PDA 拣货时库位分配状态提前变更的问题;真实复跑仍发现 PDA `pick` 第二处 `S0500`,当前仍阻断 PDA 复核、装柜完成、报关 LOADED 关联和最终门禁,不能标记国内货柜履约闭环完成。
- 验收 fixture 顺序已核实为 `orders → inbound-measurement → phase3-container-loading → phase3-loading → phase3-customs → phase3-port-schedules → phase3-loading-finalize`;脚本保留真实失败,不以 mock、历史资源或 coverage gap 伪装通过。
- PDA“点击提交时批量写入后端”的原子 batch 契约尚未实现;当前页面仍不能证明整批事务、批次幂等、服务端库存快照和失败整批回滚已具备。
- ZIM hCaptcha、COSCO 动态页继续按产品确认的人工兜底保留为 `MANUAL_REQUIRED`,不作为自动查询 PASS。
@@ -8,7 +8,7 @@
- 状态统一使用:待确认、确认中、已确认、已取消。 - 状态统一使用:待确认、确认中、已确认、已取消。
- 阻断级别统一使用:开工阻断、模块阻断、非阻断。 - 阻断级别统一使用:开工阻断、模块阻断、非阻断。
- 结论确认后同步更新 `国内货柜履约开发规划.md`、`国内货柜履约开发进度表.md` 和受影响的页面原型。 - 结论确认后同步更新 `归档/国内货柜履约开发规划.md`、`归档/国内货柜履约开发进度表.md` 和受影响的页面原型。
- 未确认事项只能作为候选方案,不能直接写成固定开发或验收承诺。 - 未确认事项只能作为候选方案,不能直接写成固定开发或验收承诺。
## 二、确认事项 ## 二、确认事项
@@ -22,13 +22,16 @@
| P3-Q5 | 拣货是否依赖实时库存和库位可用量? | 默认使用入库测量与计费处理单元和当前位置;如需完整库存,单独评估 WMS 范围 | 开工阻断 | 已确认 | 产品/业务 | 2026-08-10 | PDA 拣货必须依赖实时库存和库位可用量;首版复用入库测量与计费处理单元、当前位置和可用量接口,超量、库存不足和库位不可用由服务端拒绝;不扩展完整 WMS | 入库测量与计费及国内货柜履约契约、拣货、库存边界 | | P3-Q5 | 拣货是否依赖实时库存和库位可用量? | 默认使用入库测量与计费处理单元和当前位置;如需完整库存,单独评估 WMS 范围 | 开工阻断 | 已确认 | 产品/业务 | 2026-08-10 | PDA 拣货必须依赖实时库存和库位可用量;首版复用入库测量与计费处理单元、当前位置和可用量接口,超量、库存不足和库位不可用由服务端拒绝;不扩展完整 WMS | 入库测量与计费及国内货柜履约契约、拣货、库存边界 |
| P3-Q6 | 柜封照片有哪些必传类型、数量、采集方式、处理规则和留存期限? | 五类证据、角色和留存按确认版直接进入契约 | 模块阻断 | 已确认 | 产品/业务 | 2026-08-10 | 空仓、半仓、满仓、锁仓、带锁码照五类各至少 1 张有效照片,同类型可无限追加;PDA 只能现场拍照;后台操作员和理货员可人工上传;拣货员只负责 PDA 现场采集,不开放后台人工上传;错图不硬删除,按原因、操作人、时间作废;带锁码照必须填写锁码文本;照片无限期保留,客户不可见照片和锁码 | 装柜、PDA 拍照、Admin 上传、文件存储、订单后程门禁 | | P3-Q6 | 柜封照片有哪些必传类型、数量、采集方式、处理规则和留存期限? | 五类证据、角色和留存按确认版直接进入契约 | 模块阻断 | 已确认 | 产品/业务 | 2026-08-10 | 空仓、半仓、满仓、锁仓、带锁码照五类各至少 1 张有效照片,同类型可无限追加;PDA 只能现场拍照;后台操作员和理货员可人工上传;拣货员只负责 PDA 现场采集,不开放后台人工上传;错图不硬删除,按原因、操作人、时间作废;带锁码照必须填写锁码文本;照片无限期保留,客户不可见照片和锁码 | 装柜、PDA 拍照、Admin 上传、文件存储、订单后程门禁 |
| P3-Q7 | 报关资料清单是否按国家、渠道和货物类型变化? | 清单配置化,并保存业务使用的清单版本 | 模块阻断 | 已确认 | 产品/业务 | 2026-08-10 | 首版不对接海关或代理系统;按人工维护资料清单、收集/补件并保存版本,具体清单可配置 | 客户资料、报关审核、文件版本 | | P3-Q7 | 报关资料清单是否按国家、渠道和货物类型变化? | 清单配置化,并保存业务使用的清单版本 | 模块阻断 | 已确认 | 产品/业务 | 2026-08-10 | 首版不对接海关或代理系统;按人工维护资料清单、收集/补件并保存版本,具体清单可配置 | 客户资料、报关审核、文件版本 |
| P3-Q8 | 报关代理如何接收资料并返回回执? | 首版系统内整理、线下提交,正式接口后续评估 | 模块阻断 | 已确认 | 产品/业务 | 2026-08-10 | 全部人工处理:平台整理资料后线下交代理,授权人员人工上传代理回执;系统记录提交批次、回执版本和时间,不建设自动对接 | 报关协同、回执上传 | | P3-Q8 | 报关代理如何接收资料并返回回执? | 首版系统内整理、线下提交,正式接口后续评估 | 模块阻断 | 已确认 | 产品/业务 | 2026-08-10;2026-09-24 更正 | `LOADED` 后平台按客户/入仓码收集资料并线下发给报关行;授权人员上传每轮报关行回执,发给对应客户确认。客户打回后重新上传、重新发报关行并生成新回执,直到该客户确认;记录资料版本、回执版本、roundNo、发送时间和确认/打回审计 | 报关协同、客户确认、回执上传 |
| P3-Q9 | “港务信息”指船期、港口作业状态还是两者,包含哪些字段,由谁维护? | 国内货柜履约只维护订舱与出仓前船期资料 | 已重新归期 | 已确认 | 产品/业务 | 2026-08-19 | 柜子确认离开国内仓库后的船公司/货物跟踪查询、每 3 天最多 3 次、来源、更新时间和过期标识整体归海外仓业务;国内货柜履约不建设或验收该查询 | 国内货柜履约订舱资料、海外仓业务船节点查询 | | P3-Q9 | “港务信息”指船期、港口作业状态还是两者,包含哪些字段,由谁维护? | 国内货柜履约只维护订舱与出仓前船期资料 | 已重新归期 | 已确认 | 产品/业务 | 2026-08-19 | 柜子确认离开国内仓库后的船公司/货物跟踪查询、每 3 天最多 3 次、来源、更新时间和过期标识整体归海外仓业务;国内货柜履约不建设或验收该查询 | 国内货柜履约订舱资料、海外仓业务船节点查询 |
| P3-Q10 | 订单进入“装柜完成”后发现错误如何处理? | 仅保留线下人工处理和审计,不建设在线冲正 | 模块阻断 | 已确认 | 产品/业务 | 2026-08-10 | `LOADED` 后不提供在线冲正/回退入口,统一线下人工处理;系统保留原状态和审计记录,不由国内 Admin/PDA 推进 `DELIVERED` | 装柜完成门禁、权限、审计 | | P3-Q10 | 订单进入“装柜完成”后发现错误如何处理? | 仅保留线下人工处理和审计,不建设在线冲正 | 模块阻断 | 已确认 | 产品/业务 | 2026-08-10 | `LOADED` 后不提供在线冲正/回退入口,统一线下人工处理;系统保留原状态和审计记录,不由国内 Admin/PDA 推进 `DELIVERED` | 装柜完成门禁、权限、审计 |
| P3-Q11 | 九个动作中哪些是强制前置,哪些允许并行? | 统一门禁按已确认前置执行;PDA 单柜次单人作业 | 开工阻断 | 已确认 | 产品/业务 | 2026-08-10 | 订舱完成、拖车完成、报关资料完成且有放行回执、PDA 拣货完成及五类证据完整均为进入 `LOADED` 的强制门禁;PDA 单柜次单人作业,不做多人并行;进入任务即拣货中,提交时批量写入 | 全流程、状态机、PDA、页面进度 | | P3-Q11 | 九个动作中哪些是强制前置,哪些允许并行? | 统一门禁按已确认前置执行;PDA 单柜次单人作业 | 开工阻断 | 已确认 | 产品/业务 | 2026-08-10;2026-09-24 更正 | 费用确认不阻断排柜、预装、PDA 或装柜。进入 `LOADED` 只校验物理装柜、PDA、数量、真实柜号和五类证据;`LOADED` 后先完成退税报关,报关完成后进入待发区,再推进送港和船期;甩柜/改配只改变船次,不重做已完成报关;PDA 单柜次单人作业 | 全流程、状态机、PDA、报关、送港、页面进度 |
| P3-Q12 | 报关回执包含哪些类型,海关放行是否为装柜完成硬门禁? | 有效放行回执作为硬门禁,首版人工上传 | 开工阻断 | 已确认 | 产品/业务 | 2026-08-10 | 首版回执由人工上传;必须存在有效放行回执才能通过 `LOADED` 门禁。回执类型和版本可追溯,具体字段按人工业务单据映射 | 报关状态、装柜完成门禁、客户回执 | | P3-Q12 | 报关回执包含哪些类型,客户确认和海关放行如何衔接? | 首版人工上传回执并保留版本 | 开工阻断 | 已确认 | 产品/业务 | 2026-08-10;2026-09-24 更正 | `LOADED` 后按客户/入仓码收集资料并发送报关行;报关行回执发对应客户确认,客户打回则重新上传、重新发送并生成新回执;所有客户确认后才向报关行提交整柜资料并正式申报;之后分别记录查验、不查验放行、补件/退回等海关结果。回执上传不等于客户确认,客户确认也不等于海关放行 | 报关状态、客户回执、整柜申报、海关结果 |
| P3-Q13 | 国内货柜履约终点以什么状态为准? | 国内系统以能掌控的最后环节为终点 | 开工阻断 | 已确认 | 用户当前对话确认 | 2026-08-08 | 国内货柜履约终点为 `LOADED`/装柜完成;`DELIVERED`/派送完成只能在到达海外仓后由海外仓可信回传推进,不属于国内国内货柜履约操作和验收范围 | 阶段边界、状态、里程碑、验收、海外仓回传 | | P3-Q13 | 国内货柜履约终点以什么状态为准? | 国内系统以能掌控的最后环节为终点 | 开工阻断 | 已确认 | 用户当前对话确认 | 2026-08-08 | 国内货柜履约终点为 `LOADED`/装柜完成;`DELIVERED`/派送完成只能在到达海外仓后由海外仓可信回传推进,不属于国内国内货柜履约操作和验收范围 | 阶段边界、状态、里程碑、验收、海外仓回传 |
| P3-Q14 | 订舱、渠道柜次、放舱与智能排柜的先后关系是什么? | 线下已订妥的订舱在创建时完整登记五项真实运输快照并直接确认;放舱不覆盖首次快照 | 开工阻断 | 已确认 | 用户当前对话确认 | 2026-08-12 | 订舱创建请求必须携带提单号、船名、航次、预计开船时间、预计到港时间五项真实运输数据,并直接进入 `CONFIRMED`;渠道、箱型和数量同时确定,系统按箱型需求数量生成绑定渠道的稳定内部柜次。未放舱不影响候选查询、智能推荐、人工调整和保存装柜计划;同一柜次只能装同渠道入库单,服务端禁止跨渠道混装。`RELEASED` 仅作为后续放舱/PDA 门禁,不补录、不覆盖首次五项运输快照;真实集装箱号可在放舱时或之后录入 | 订舱、柜次、智能排柜、预装、PDA、运输信息 | | P3-Q14 | 订舱、渠道柜次、放舱与智能排柜的先后关系是什么? | 线下已订妥的订舱在创建时完整登记五项真实运输快照并直接确认;放舱不覆盖首次快照 | 开工阻断 | 已确认 | 用户当前对话确认 | 2026-08-12 | 订舱创建请求必须携带提单号、船名、航次、预计开船时间、预计到港时间五项真实运输数据,并直接进入 `CONFIRMED`;渠道、箱型和数量同时确定,系统按箱型需求数量生成绑定渠道的稳定内部柜次。未放舱不影响候选查询、智能推荐、人工调整和保存装柜计划;同一柜次只能装同渠道入库单,服务端禁止跨渠道混装。`RELEASED` 仅作为后续放舱/PDA 门禁,不补录、不覆盖首次五项运输快照;真实集装箱号可在放舱时或之后录入 | 订舱、柜次、智能排柜、预装、PDA、运输信息 |
| P3-Q15 | 客户未确认费用是否阻断排柜、装柜?装柜完成后如何处理? | 费用作为并行事实,装柜完成时对当前有效版本做系统默认确认 | 模块阻断 | 已确认 | 用户当前对话确认 | 2026-09-24 | 客户费用确认不阻断排柜、预装、PDA 或装柜。装柜完成后,针对本次已装范围的当前有效且已发布费用版本,若客户未确认则记录“系统默认确认(装柜完成)”;保留客户确认与 `SYSTEM_AUTO_AT_LOADED` 来源、版本、柜次/入仓码、时间和幂等标识。没有有效费用版本不得伪造确认;部分装载不确认余量或整张未完成订单 | 费用版本、装柜完成、客户进度、审计、部分装载 |
| P3-Q16 | 报关资料何时收集、何时正式报送? | 装柜后通知报关,按客户确认轮次完成后正式提交 | 模块阻断 | 已确认 | 用户当前对话确认 | 2026-09-24 | `LOADED` 后以最终实装清单通知报关行,按客户/入仓码收集资料并发送报关行;回执发客户确认,打回则重新上传、重新发送并产生新回执,循环至所有客户通过;全部客户确认后再提交整柜资料给报关行确认,由报关行正式申报;海关查验/不查验放行等结果单独记录;报关完成后进入待发区 | 客户资料、回执轮次、客户确认、整柜申报、待发区 |
| P3-Q17 | 送港和报关是否互相等待?甩柜何时发生? | 报关完成后进入待发区,实际开船才进入海运 | 开工阻断 | 已确认 | 用户当前对话确认 | 2026-09-24 | `LOADED` 后先完成报关;报关完成后进入待发区,再安排拖车、送港和进港。船舱不足记录 `ROLLED_OVER`,保存原船次、改配船次、滚动次数和通知;甩柜/改配不影响已完成报关资料、回执和客户确认;只有承运船舶真实开航才写 `VESSEL_DEPARTED`/海运节点 | 送港、船次、甩柜、海运节点 |
### 2.1 PDA 已确认子决策 ### 2.1 PDA 已确认子决策
@@ -44,7 +47,7 @@
| P3-PDA-D08 | 2026-08-09 | 同类型证据允许多张并采用追加记录;错误/重复照片不硬删除,只作废 | 每条照片独立保存;作废记录原因、操作人和时间,历史可追溯 | | P3-PDA-D08 | 2026-08-09 | 同类型证据允许多张并采用追加记录;错误/重复照片不硬删除,只作废 | 每条照片独立保存;作废记录原因、操作人和时间,历史可追溯 |
| P3-PDA-D09 | 2026-08-09 | 空仓、半仓、满仓、锁仓、带锁码照五类证据各至少 1 张有效且未作废的照片,可多张;带锁码照同时要求锁码文本 | 服务端完整性门禁按“每类至少一张有效记录”校验,不能按单槽位替换模型实现 | | P3-PDA-D09 | 2026-08-09 | 空仓、半仓、满仓、锁仓、带锁码照五类证据各至少 1 张有效且未作废的照片,可多张;带锁码照同时要求锁码文本 | 服务端完整性门禁按“每类至少一张有效记录”校验,不能按单槽位替换模型实现 |
> 验收映射:当前自动化已真实覆盖五类证据上传、同类型多图追加、跨类型/伪造 `fileId` 拒绝、锁码文本门禁和错图作废审计;设备在线、持久化草稿批量提交仍按[验收任务拆分与待确认清单](国内货柜履约验收任务拆分与待确认清单.md)保留 coverageGap。 > 验收映射:当前自动化已真实覆盖五类证据上传、同类型多图追加、跨类型/伪造 `fileId` 拒绝、锁码文本门禁和错图作废审计;设备在线、持久化草稿批量提交仍按[验收任务拆分与待确认清单](归档/国内货柜履约验收任务拆分与待确认清单.md)保留 coverageGap。
## 三、已确认架构决策 ## 三、已确认架构决策
@@ -52,9 +55,10 @@
|---|---|---|---| |---|---|---|---|
| P3-D1 | 2026-08-08 | 国内货柜履约不新建独立出仓单,现有订单列表承载全部主状态;柜次、订舱、拖车、拣货、证据和报关作为订单关联子对象 | 取消出仓单页面和数据模型规划,改为增强现有订单列表/详情及服务端统一编排 | | P3-D1 | 2026-08-08 | 国内货柜履约不新建独立出仓单,现有订单列表承载全部主状态;柜次、订舱、拖车、拣货、证据和报关作为订单关联子对象 | 取消出仓单页面和数据模型规划,改为增强现有订单列表/详情及服务端统一编排 |
| P3-D2 | 2026-08-10 | 订单拆分采用“父订单→子订单→柜次”;已装载数量形成子订单,未装载数量自动生成后续子订单;支持一单多柜和多订单拼柜 | 后端必须保留父子订单、柜次、数量分摊和整体时间线;不得把未装载部分静默丢弃 | | P3-D2 | 2026-08-10 | 订单拆分采用“父订单→子订单→柜次”;已装载数量形成子订单,未装载数量自动生成后续子订单;支持一单多柜和多订单拼柜 | 后端必须保留父子订单、柜次、数量分摊和整体时间线;不得把未装载部分静默丢弃 |
| P3-D3 | 2026-08-10 | `LOADED` 的硬门禁包含订舱完成、拖车完成、报关放行回执、PDA 拣货完成和五类证据完整;`LOADED` 后错误线下人工处理 | 统一门禁服务负责校验,国内页面不提供在线冲正或 `DELIVERED` 操作 | | P3-D3 | 2026-08-10;2026-09-24 更正 | `LOADED` 只表示物理装柜完成,门禁包含真实柜号、PDA 拣货、数量守恒和五类证据;报关完成后进入待发区,再推进送港/进港;甩柜只影响船期,不影响已完成报关;`LOADED` 后错误线下人工处理 | 统一门禁服务分别维护物理装柜、报关案例、待发区、送港/进港、甩柜和实际开船事实;国内页面不提供在线冲正或 `DELIVERED` 操作 |
| P3-D4 | 2026-08-10;2026-08-19 更正归期 | 船公司官网查询:每 3 天一次、最多 3 次,保存来源、更新时间和过期标识 | 该能力及首批六家来源整体归海外仓业务,国内货柜履约只保留订舱与出仓前船期资料 | | P3-D4 | 2026-08-10;2026-08-19 更正归期 | 船公司官网查询:每 3 天一次、最多 3 次,保存来源、更新时间和过期标识 | 该能力及首批六家来源整体归海外仓业务,国内货柜履约只保留订舱与出仓前船期资料 |
| P3-D5 | 2026-08-10 | 初始化仓库常用角色:操作员、拣货员、理货员;按最小权限授予拣货、证据上传和查看能力 | 角色初始化由 IAM/统一 SQL 任务实现,具体权限矩阵在技术契约评审中落表 | | P3-D5 | 2026-08-10 | 初始化仓库常用角色:操作员、拣货员、理货员;按最小权限授予拣货、证据上传和查看能力 | 角色初始化由 IAM/统一 SQL 任务实现,具体权限矩阵在技术契约评审中落表 |
| P3-D6 | 2026-09-24 | 费用确认不阻断排柜和装柜;装柜完成后对已装范围的当前有效已发布版本执行系统默认确认,来源与客户主动确认分开审计;`LOADED` 后报关采用“报关行回执→客户确认/打回重做→所有客户通过→整柜正式申报→查验/放行”,报关完成后进入待发区,送港/船次单独记录甩柜和实际开船 | 同步费用版本、部分装载、客户报关案例、回执轮次、整柜申报、待发区、送港/船次和客户/后台节点 |
## 四、建议确认顺序 ## 四、建议确认顺序
@@ -73,8 +77,8 @@
### 5.2 会议输入 ### 5.2 会议输入
- 本确认表中的 P3-Q1~P3-Q13。 - 本确认表中的 P3-Q1~P3-Q17。
- `国内货柜履约开发规划.md` 的流程、状态、里程碑和任务骨架。 - `归档/国内货柜履约开发规划.md` 的流程、状态、里程碑和任务骨架。
- `国内货柜履约页面与原型清单.md` 中已有参考原型和待补页面。 - `国内货柜履约页面与原型清单.md` 中已有参考原型和待补页面。
- 入库测量与计费输出契约、目标 PDA 信息、文件存储能力及报关/港务协作现状。 - 入库测量与计费输出契约、目标 PDA 信息、文件存储能力及报关/港务协作现状。
@@ -93,3 +97,4 @@
- 国内货柜履约范围内/范围外清单及跨期依赖。 - 国内货柜履约范围内/范围外清单及跨期依赖。
- 仍有风险的事项、责任人和完成日期。 - 仍有风险的事项、责任人和完成日期。
- 已允许进入 T02 契约设计与任务拆分;未决技术项只阻断其对应实现,不反向阻断整期已确认范围。 - 已允许进入 T02 契约设计与任务拆分;未决技术项只阻断其对应实现,不反向阻断整期已确认范围。
+18
View File
@@ -0,0 +1,18 @@
# 国内货柜履约历史记录
本目录保存国内货柜履约的开发规划、进度、开工门禁、验收、审计和旧确认材料。内容不删除,也不作为当前流程入口;当前规则以[国内货柜履约 README](../README.md)、[头程到尾程流程节点梳理](../../头程到尾程流程节点梳理.md)和[报关资料与船期价格接入梳理](../报关资料与船期价格接入梳理.md)为准。
## 文件
- [开发规划](国内货柜履约开发规划.md)
- [开发进度表](国内货柜履约开发进度表.md)
- [开发进度表(Excel)](虫虫出海国内货柜履约开发进度表.xlsx)
- [需求确认表之外的开工门禁与验收记录](国内货柜履约开工门禁.md)
- [验收任务拆分与待确认清单](国内货柜履约验收任务拆分与待确认清单.md)
- [货柜管理全链验收矩阵](货柜管理全链验收矩阵-2026-08-13.md)
- [货柜履约原型字段验收矩阵](货柜履约原型字段验收矩阵-2026-08-17.md)
- [闭环审计报告](国内货柜履约闭环审计报告-2026-08-08.md)
- [装柜闭环产品确认表](国内货柜履约装柜闭环产品确认表-2026-08-08.md)
- [装柜闭环开发前确认单](国内货柜履约装柜闭环开发前确认单-2026-08-08.md)
- [Wave1 开发任务卡](国内货柜履约Wave1开发任务卡-2026-08-09.md)
@@ -1,5 +1,7 @@
# 国内货柜履约 Wave 1 开发任务卡 # 国内货柜履约 Wave 1 开发任务卡
> **历史版本声明(2026-09-24)**:本文是旧版低风险任务拆分,不能直接作为当前开发排期或门禁依据。当前流程改为“柜前资料预收集 → 物理装柜 `LOADED` → 按最终实装清单正式报关 → 有效放行回执后 `DEPARTED_WAREHOUSE`”,费用确认不阻断装柜,装柜完成时按已装范围对当前有效已发布费用版本执行系统默认确认。当前开发范围以 [头程到尾程流程节点梳理(重构版)](../../头程到尾程流程节点梳理.md)、[报关资料与船期价格接入梳理](../报关资料与船期价格接入梳理.md) 和最新需求确认表为准。
整理日期:2026-08-09 整理日期:2026-08-09
用途:产品确认后用于研发排期和任务分派。 用途:产品确认后用于研发排期和任务分派。
当前范围:只做低风险基础能力;不提前实现未确认的主状态机规则。 当前范围:只做低风险基础能力;不提前实现未确认的主状态机规则。
@@ -53,3 +55,4 @@
- 允许无拣货、缺照片或缺锁码进入 `LOADED`。 - 允许无拣货、缺照片或缺锁码进入 `LOADED`。
- 国内 Admin/PDA 手工推进 `DELIVERED`。 - 国内 Admin/PDA 手工推进 `DELIVERED`。
- 在产品未确认前固化部分拣货拆单和一单多柜聚合规则。 - 在产品未确认前固化部分拣货拆单和一单多柜聚合规则。
@@ -2,12 +2,12 @@
> 创建日期:2026-07-28 > 创建日期:2026-07-28
> 状态:已进入分模块开发规划 > 状态:已进入分模块开发规划
> 流程依据:[出仓流程](参考资料/出仓流程.png)中的头程物流“03 出仓”;用户已于 2026-08-08 确认国内国内货柜履约以 `LOADED`/装柜完成为阶段终点 > 流程依据:[出仓流程](../参考资料/出仓流程.png)中的头程物流“03 出仓”;当前以 `LOADED` 作为物理装柜节点,报关线和送港线在装柜后并行,实际开船后进入海运节点。
> 前置阶段:[订单与客户文档](../订单与客户/README.md) · [入库测量与计费文档](../入库测量与计费/README.md) > 前置阶段:[订单与客户文档](../../订单与客户/README.md) · [入库测量与计费文档](../../入库测量与计费/README.md)
> 2026-08-10 产品确认版:国内货柜履约不新建独立出仓单;支持一单多柜、一个柜拼多个订单,采用“父订单→子订单→柜次”关系,已装载数量形成子订单,未装载数量自动生成后续子订单。`LOADED` 硬门禁为订舱完成、拖车完成、报关放行回执、PDA 拣货完成和五类证据完整;`LOADED` 后错误线下人工处理。五类证据各至少 1 张有效照片,同类型多张追加,PDA 仅现场拍照,后台操作员和理货员可人工上传,照片无限期保留且客户不可见。 > 2026-08-10 产品确认版;2026-09-24 按最新流程更正:国内货柜履约不新建独立出仓单;支持一单多柜、一个柜拼多个订单,采用“父订单→子订单→柜次”关系,已装载数量形成子订单,未装载数量自动生成后续子订单。`LOADED` 仅校验真实柜号、PDA 拣货、数量守恒和五类证据;装柜后报关线按“客户资料→报关行回执→客户确认/打回重做→所有客户通过→整柜正式申报→查验/放行”推进,送港线独立记录离仓、进港、甩柜和改配,实际开船才进入海运。费用确认不阻断排柜和装柜;装柜完成后对已装范围的当前有效已发布费用版本执行系统默认确认,保留客户/系统来源。`LOADED` 后错误线下人工处理。五类证据各至少 1 张有效照片,同类型多张追加,PDA 仅现场拍照,后台操作员和理货员可人工上传,照片无限期保留且客户不可见。
> 当前范围更正:原 `P3-PORT-01`、六家船公司官网查询及 `CarrierScheduleQuery` 是柜子确认离开国内仓库后的业务,整体重新归入海外仓业务。国内货柜履约仅保存订舱与出仓前所需的船名航次、港口和 ETD/ETA 等资料,不建设或验收出仓后的定时节点查询。 > 当前范围更正:国内货柜履约保留 `DEPARTED_WAREHOUSE`、`PORT_RECEIVED`、`ROLLED_OVER` 和实际开船前的船次/港口事实;承运船舶真实 `VESSEL_DEPARTED` 后的六家船公司官网查询、`CarrierScheduleQuery` 和定时节点查询归入海外仓业务。国内侧不以预计 ETD 提前展示海运中。
> 主体模型与硬约束:国内货柜履约只实现“平台—客户”两级,业务 `tenant_id > 0` / `tenantId` 当前表示客户 ID;`tenant_id=0` 是平台身份、平台 RBAC 和平台公共仓储资源技术作用域,客户往来单位、订单、文件和费用归属客户 `tenant_id>0`。禁止新增租户主表、租户选择器、客户所属租户配置、租户切换、租户级 RBAC 或租户级配置,禁止把现有 `tenant_id` 改义为上级租户 ID;历史类名、路径和字段继续兼容。 > 主体模型与硬约束:国内货柜履约只实现“平台—客户”两级,业务 `tenant_id > 0` / `tenantId` 当前表示客户 ID;`tenant_id=0` 是平台身份、平台 RBAC 和平台公共仓储资源技术作用域,客户往来单位、订单、文件和费用归属客户 `tenant_id>0`。禁止新增租户主表、租户选择器、客户所属租户配置、租户切换、租户级 RBAC 或租户级配置,禁止把现有 `tenant_id` 改义为上级租户 ID;历史类名、路径和字段继续兼容。
@@ -20,16 +20,15 @@
```text ```text
智能排柜 → 订舱 → 预约拖车 智能排柜 → 订舱 → 预约拖车
↓ ↓
PDA 拣货 → 装柜并上传货柜/铅封照片 PDA 拣货 → 装柜并上传五类证据
↓ ↓
客户上传报关资料 → 平台整理提交报关代理 → 上传回执供客户下载 `LOADED`/装柜完成
↓ ├─ 报关:通知报关行 → 客户资料 → 报关行回执 → 客户确认/打回重做
维护订舱与出仓前所需的船名航次、港口和预计时间 │ → 所有客户通过 → 整柜正式申报 → 查验/放行
↓ └─ 送港:拖车 → 离仓 → 送港/进港 → 甩柜/改配(如发生)→ 实际开船
国内国内货柜履约完成:`LOADED`/装柜完成
``` ```
国内货柜履约完成标准是同一订单/柜次已完成排柜和 PDA 拣货,空仓、半仓、满仓、锁仓、带锁码照五类证据各至少 1 张有效照片已真实上传,锁码文本已保存,服务端门禁通过并将订单推进为 `LOADED`/装柜完成。`DELIVERED`/派送完成必须等货物到达海外仓后由海外仓可信回传推进,不是国内国内货柜履约人工操作。 国内货柜履约的装柜完成标准是同一订单/柜次已完成排柜和 PDA 拣货,空仓、半仓、满仓、锁仓、带锁码照五类证据各至少 1 张有效照片已真实上传,锁码文本已保存,数量守恒且服务端门禁通过后推进为 `LOADED`/装柜完成。`LOADED` 后报关线和送港线同时启动;客户确认不阻断送港,进港不代表报关完成,容量不足记录甩柜;只有承运船舶实际开航后才进入海运节点。`DELIVERED`/派送完成必须等货物到达海外仓后由海外仓可信回传推进,不是国内国内货柜履约人工操作。
### 原型动作覆盖 ### 原型动作覆盖
@@ -42,8 +41,8 @@ PDA 拣货 → 装柜并上传货柜/铅封照片
| 5. 拍货柜及铅封照上传 | 装柜及柜封证据 | P3-LOAD-01、P3-LOAD-02 | 已确认五类证据各至少 1 张有效照片、同类型可多张,锁码文本必填 | | 5. 拍货柜及铅封照上传 | 装柜及柜封证据 | P3-LOAD-01、P3-LOAD-02 | 已确认五类证据各至少 1 张有效照片、同类型可多张,锁码文本必填 |
| 6. 客户上传报关资料 | 报关资料协同 | P3-CUS-01 | 已覆盖 | | 6. 客户上传报关资料 | 报关资料协同 | P3-CUS-01 | 已覆盖 |
| 7. 整理给到报关代理报关 | 报关资料协同 | P3-CLEAR-01 | 已覆盖 | | 7. 整理给到报关代理报关 | 报关资料协同 | P3-CLEAR-01 | 已覆盖 |
| 8. 回执上传到系统供客户下载 | 报关回执与客户下载 | P3-CLEAR-01、P3-CUS-02 | 已覆盖,首版由授权人员人工上传放行回执 | | 8. 回执上传并由客户确认 | 报关行回执与客户确认 | P3-CLEAR-01、P3-CUS-02 | 待补齐多轮回执、客户确认/打回和整柜正式提交 |
| 9. 出仓后查询港务/船节点 | 海外仓业务船节点定时查询 | 原 P3-PORT-01、P3-CUS-02 对应查询部分 | 已重新归入海外仓业务,不是国内货柜履约动作或验收项 | | 9. 送港、甩柜与实际开船 | 送港/船次事实 | P3-TRUCK-01、P3-CUS-02 | 装柜后与报关线并行;实际开船后进入海运节点 |
## 二、阶段边界 ## 二、阶段边界
@@ -54,8 +53,9 @@ PDA 拣货 → 装柜并上传货柜/铅封照片
- 预约拖车、车辆司机、到仓装柜和离仓记录。 - 预约拖车、车辆司机、到仓装柜和离仓记录。
- PDA 任务领取、扫码拣货、部分拣货、异常、复核和幂等提交。 - PDA 任务领取、扫码拣货、部分拣货、异常、复核和幂等提交。
- 装柜、柜号、铅封号及货柜/铅封照片证据。 - 装柜、柜号、铅封号及货柜/铅封照片证据。
- 客户上传报关资料、平台审核补件、整理并提交报关代理。 - `LOADED` 后通知报关行,客户上传报关资料、平台审核补件、线下发送报关行。
- 报关回执上传、版本、客户可见范围和授权下载。 - 报关行回执上传、版本、客户确认/打回重做、客户可见范围和授权下载;所有客户确认后才提交整柜资料正式申报。
- 装柜后送港、进港、甩柜/改配和实际开船事实。
- 装柜完成门禁、确认、时间线和站内通知;`LOADED` 后纠错走线下人工流程。 - 装柜完成门禁、确认、时间线和站内通知;`LOADED` 后纠错走线下人工流程。
### 明确不纳入国内货柜履约 ### 明确不纳入国内货柜履约
@@ -65,7 +65,7 @@ PDA 拣货 → 装柜并上传货柜/铅封照片
- GPS 实时跟车、电子铅封、称重设备、摄像头 OCR 和 IoT 自动采集。 - GPS 实时跟车、电子铅封、称重设备、摄像头 OCR 和 IoT 自动采集。
- 自动报关、关税计算、退税、完整清关业务和自动单证识别。 - 自动报关、关税计算、退税、完整清关业务和自动单证识别。
- 海上运输、海外清关、目的港提柜、海外仓入库和末端派送。 - 海上运输、海外清关、目的港提柜、海外仓入库和末端派送。
- 柜子确认离开国内仓库后的 `CarrierScheduleQuery`、船公司查询、定时船节点和到港跟踪;整体归海外仓业务。 - 承运船舶真实 `VESSEL_DEPARTED` 后的 `CarrierScheduleQuery`、船公司查询、定时船节点和海上到港跟踪;整体归海外仓业务。国内侧保留送港、进港和甩柜事实。
- 无人工确认的全自动排柜、自动订舱和不可逆业务操作。 - 无人工确认的全自动排柜、自动订舱和不可逆业务操作。
## 三、参与角色与数据边界 ## 三、参与角色与数据边界
@@ -87,7 +87,7 @@ PDA 拣货 → 装柜并上传货柜/铅封照片
## 四、流程与状态设计 ## 四、流程与状态设计
原型以 1 至 9 编号表达动作顺序。产品确认后,订舱、拖车、报关放行、PDA 拣货和证据完整是进入 `LOADED` 的强制前置;智能排柜、订舱、拖车和资料整理可按子流程并行,但服务端不得绕过门禁。PDA 单柜次单作业员,不实现多人并行或任务接管。 原图以 1 至 9 编号表达展示动作顺序。按本轮确认,费用确认不阻断排柜或装柜;`LOADED` 只校验物理装柜事实,装柜后报关线和送港线并行,客户确认不阻断送港,进港不代表报关完成,实际开船才进入海运。PDA 单柜次单作业员,不实现多人并行或任务接管。
### 1. 现有订单的国内货柜履约主状态 ### 1. 现有订单的国内货柜履约主状态
@@ -95,7 +95,7 @@ PDA 拣货 → 装柜并上传货柜/铅封照片
|---|---|---| |---|---|---|
| `WAIT_SPLIT` | 待分柜 | 入库测量与计费已完成,等待排柜/预装 | | `WAIT_SPLIT` | 待分柜 | 入库测量与计费已完成,等待排柜/预装 |
| `LOADING` | 装柜中 | 预装已确认,PDA 执行拣货和装柜证据上传 | | `LOADING` | 装柜中 | 预装已确认,PDA 执行拣货和装柜证据上传 |
| `LOADED` | 装柜完成 | 订舱、拖车、报关放行回执、PDA 拣货完成,且五类证据各至少 1 张有效照片和锁码文本已通过服务端门禁 | | `LOADED` | 装柜完成 | 真实柜号、PDA 拣货与数量守恒、五类证据各至少 1 张有效照片和锁码文本已通过服务端门禁;装柜后同时启动报关线和送港线 |
| `DELIVERED` | 派送完成 | 货物到达海外仓后由海外仓可信回传推进;属于国内货柜履约之后的只读状态 | | `DELIVERED` | 派送完成 | 货物到达海外仓后由海外仓可信回传推进;属于国内货柜履约之后的只读状态 |
### 2. 子流程状态 ### 2. 子流程状态
@@ -103,8 +103,8 @@ PDA 拣货 → 装柜并上传货柜/铅封照片
- 订舱:待订舱、订舱中、已订舱、订舱失败、已取消。 - 订舱:待订舱、订舱中、已订舱、订舱失败、已取消。
- 拖车:待预约、已预约、车辆已到仓、装柜中、已离仓、改约、已取消。 - 拖车:待预约、已预约、车辆已到仓、装柜中、已离仓、改约、已取消。
- 拣货:待分配、待拣货、拣货中、待复核、已完成、异常挂起、已取消。 - 拣货:待分配、待拣货、拣货中、待复核、已完成、异常挂起、已取消。
- 报关:资料待上传、资料待审核、待补件、待提交、已提交代理、回执待上传、回执已上传、已退回、已取消;有效放行回执是 `LOADED` 硬门禁,首版由授权人员人工上传。 - 报关:`LOADED` 后待通知报关、客户资料待上传/审核、已发报关行、回执待客户确认、客户已确认、客户打回待重做、所有客户已确认、整柜正式申报、查验、放行/退回;回执上传不等于客户确认,客户确认不等于海关放行。
- 出仓前船期资料:待维护、已确认、信息变更;出仓后节点和“已开船”等运输事实归海外仓业务。 - 送港/船期:待送港、已离仓、送港中、已进港、甩柜/改配、待开船;只有实际 `VESSEL_DEPARTED` 后进入海运节点。
主状态由服务端根据已确认的必要子流程推进。客户端不得通过传任意目标状态跳过拣货复核、装柜证据或已配置的装柜完成门禁。 主状态由服务端根据已确认的必要子流程推进。客户端不得通过传任意目标状态跳过拣货复核、装柜证据或已配置的装柜完成门禁。
@@ -127,10 +127,10 @@ PDA 拣货 → 装柜并上传货柜/铅封照片
### 3. 订舱与出仓前船期资料 ### 3. 订舱与出仓前船期资料
- 国内货柜履约只维护订舱和装柜/出仓交接所需的预计开船、到港等静态资料,不执行出仓后的船公司或船节点查询。 - 国内货柜履约维护订舱、送港、进港、甩柜/改配和实际开船前的状态;承运船舶实际开航后由海外仓业务执行船公司和船节点查询。
- 船公司/订舱代理、航线、订舱号、船名航次、起运港、目的港、截单、截关、截港、ETD 和 ETA 暂列为候选字段。 - 船公司/订舱代理、航线、订舱号、船名航次、起运港、目的港、截单、截关、截港、ETD 和 ETA 暂列为候选字段。
- 订舱失败、改船、甩柜、船期延误和取消暂列为候选异常场景,按业务确认结果实现。 - 订舱失败、改船、甩柜、船期延误和取消暂列为候选异常场景,按业务确认结果实现。
- 六家船公司来源、每 3 天/最多 3 次、最近有效结果和过期标识,以及对应适配层全部移至海外仓业务船节点查询维护。 - 六家船公司来源、每 3 天/最多 3 次、最近有效结果和过期标识,以及对应适配层在 `VESSEL_DEPARTED` 后由海外仓业务船节点查询维护。
- 国内货柜履约页面展示的 ETD/ETA 必须明确为订舱或人工确认快照,不得伪装成出仓后的实时查询结果。 - 国内货柜履约页面展示的 ETD/ETA 必须明确为订舱或人工确认快照,不得伪装成出仓后的实时查询结果。
- 建议关键信息变更保留旧值、新值、原因,并向授权用户发送站内提醒。 - 建议关键信息变更保留旧值、新值、原因,并向授权用户发送站内提醒。
@@ -165,18 +165,20 @@ PDA 拣货 → 装柜并上传货柜/铅封照片
### 7. 报关资料协同 ### 7. 报关资料协同
- 客户按资料清单上传发票、箱单、合同、委托书和申报要素等文件。 - `LOADED` 后按最终实装清单建立每个客户/入仓码的报关案例;客户按资料清单上传发票、箱单、合同、委托书和申报要素等文件。
- 资料清单可按国家/地区、渠道和货物类型配置,并保存订单使用的清单版本。 - 资料清单可按国家/地区、渠道和货物类型配置,并保存订单使用的清单版本。
- 平台报关专员审核完整性,可退回具体文件并记录补件原因和时限。 - 平台报关专员审核完整性,可退回具体文件并记录补件原因和时限。
- 提交报关代理时生成提交批次,冻结该批次关联的文件版本。 - 资料发送报关行时记录 roundNo 和发送时间,报关行回执上传后发对应客户确认;客户打回则重新上传、重新发送并生成新回执版本。
- 柜内所有客户确认后才生成整柜正式提交批次,冻结该批次关联的文件版本并交报关行正式申报。
- 首版采用系统内整理加线下提交,不直接对接海关单一窗口。 - 首版采用系统内整理加线下提交,不直接对接海关单一窗口。
### 8. 报关回执与客户下载 ### 8. 报关回执与客户下载
- 授权人员人工上传代理回传的报关回执并关联提交批次;有效放行回执是装柜完成硬门禁,回执类型、版本和操作者可追溯。 - 授权人员人工上传报关行回传的每轮回执并关联客户报关案例;回执类型、版本、roundNo、操作者和客户确认/打回结果可追溯。
- 替换文件产生新版本,不覆盖原记录;退单或补件形成明确任务。 - 替换文件产生新版本,不覆盖原记录;退单或补件形成明确任务。
- 客户只能下载本企业且标记为客户可见的回执。 - 客户只能下载本企业且标记为客户可见的回执。
- 文件下载使用授权地址并记录审计,不暴露内部存储路径。 - 文件下载使用授权地址并记录审计,不暴露内部存储路径。
- 所有客户确认后,平台向报关行提交整柜资料;报关行正式申报后另行记录查验、不查验放行、补件/退回等海关结果。
### 9. 装柜完成确认与海外回传边界 ### 9. 装柜完成确认与海外回传边界
@@ -246,8 +248,8 @@ PDA 拣货 → 装柜并上传货柜/铅封照片
| P3-M2 订舱与拖车 | 订舱、出仓前船期资料、拖车预约和异常处理可用 | 服务商与权限可用 | | P3-M2 订舱与拖车 | 订舱、出仓前船期资料、拖车预约和异常处理可用 | 服务商与权限可用 |
| P3-M3 PDA 拣货 | 在线任务、持久化草稿、批量提交、差异、复核和幂等可用 | 服务端任务与库存契约可用 | | P3-M3 PDA 拣货 | 在线任务、持久化草稿、批量提交、差异、复核和幂等可用 | 服务端任务与库存契约可用 |
| P3-M4 装柜封柜 | 柜号、铅封和照片证据完整,门禁生效 | 文件能力与必传清单确认 | | P3-M4 装柜封柜 | 柜号、铅封和照片证据完整,门禁生效 | 文件能力与必传清单确认 |
| P3-M5 报关协同 | 客户上传、平台审核、补件、提交和回执下载闭环 | 报关资料清单确认 | | P3-M5 报关协同 | `LOADED` 后客户资料、报关行回执、客户确认/打回重做、所有客户通过、整柜正式申报和查验/放行闭环 | 报关资料清单确认 |
| P3-M6 装柜完成 | 订舱、拖车、放行回执、PDA 拣货、五类证据和锁码文本满足门禁后进入 `LOADED`/装柜完成 | 装柜完成硬门禁已确认 | | P3-M6 装柜完成及并行送港 | 真实柜号、PDA 拣货、数量守恒、五类证据和锁码文本满足门禁后进入 `LOADED`;随后并行推进送港/进港/甩柜和报关线,实际开船才进入海运 | 装柜完成、报关线和送港线分开 |
| P3-M7 联调验收 | 跨端、设备、安全、弱网、性能、迁移和发布完成 | P3-M1 至 P3-M6 验收通过 | | P3-M7 联调验收 | 跨端、设备、安全、弱网、性能、迁移和发布完成 | P3-M1 至 P3-M6 验收通过 |
## 九、建议开发任务 ## 九、建议开发任务
@@ -259,18 +261,18 @@ PDA 拣货 → 装柜并上传货柜/铅封照片
| P3-DSP-01 | 后台 | 订单国内货柜履约编排 | 在现有订单列表/详情中接入柜次、子流程、异常、时间线和门禁操作 | P0 | P3-BASE-02 | | P3-DSP-01 | 后台 | 订单国内货柜履约编排 | 在现有订单列表/详情中接入柜次、子流程、异常、时间线和门禁操作 | P0 | P3-BASE-02 |
| P3-PLAN-01 | 公共 | 排柜规则 | 按已确认规则实现输入、约束、偏好和冲突判断 | P0 | P3-BASE-02、P3-Q1 | | P3-PLAN-01 | 公共 | 排柜规则 | 按已确认规则实现输入、约束、偏好和冲突判断 | P0 | P3-BASE-02、P3-Q1 |
| P3-PLAN-02 | 后台 | 智能排柜 | 按已确认范围实现建议、人工确认和追溯 | P0 | P3-PLAN-01 | | P3-PLAN-02 | 后台 | 智能排柜 | 按已确认范围实现建议、人工确认和追溯 | P0 | P3-PLAN-01 |
| P3-BOOK-01 | 后台 | 订舱 | 订舱和经确认的船名航次、港口、变更及异常;订舱完成是 `LOADED` 门禁 | P0 | P3-DSP-01 | | P3-BOOK-01 | 后台 | 订舱 | 订舱和经确认的船名航次、港口、变更及异常;订舱/拖车服务送港线,不作为 `LOADED` 的报关前置 | P0 | P3-DSP-01 |
| 原 P3-PORT-01 | 后台/服务端 | 出仓后船节点查询 | 已重新归入海外仓业务,不作为国内货柜履约交付或验收项;沿用现有 `CarrierScheduleQuery`,不得重复实现 | 海外仓业务 | P3-BOOK-01、确认国内出仓 | | P3-PORT-01 | 后台/服务端 | 送港、进港与甩柜 | 记录 `DEPARTED_WAREHOUSE`、`PORT_RECEIVED`、`ROLLED_OVER`、改配船次和客户通知;不以预计 ETD 推进海运 | P0 | P3-BOOK-01、P3-TRUCK-01 |
| P3-TRUCK-01 | 后台 | 拖车预约 | 服务商、车辆司机、时间窗、到离仓和异常 | P0 | P3-DSP-01 | | P3-TRUCK-01 | 后台 | 拖车预约 | 服务商、车辆司机、时间窗、到离仓、进港和异常 | P0 | P3-DSP-01 |
| P3-PICK-01 | 公共 | 拣货任务 | 按排柜方案生成任务、明细、差异和复核规则 | P0 | P3-PLAN-02 | | P3-PICK-01 | 公共 | 拣货任务 | 按排柜方案生成任务、明细、差异和复核规则 | P0 | P3-PLAN-02 |
| P3-PDA-01 | PDA | 在线扫码拣货 | 进入任务标记拣货中、扫描草稿、部分/跳拣异常原因和批量提交 | P0 | P3-PICK-01 | | P3-PDA-01 | PDA | 在线扫码拣货 | 进入任务标记拣货中、扫描草稿、部分/跳拣异常原因和批量提交 | P0 | P3-PICK-01 |
| P3-PDA-02 | PDA/服务端 | 草稿与提交安全 | 作业员+任务+柜次持久化草稿、幂等重试、版本冲突、成功/放弃清理 | P0 | P3-PDA-01 | | P3-PDA-02 | PDA/服务端 | 草稿与提交安全 | 作业员+任务+柜次持久化草稿、幂等重试、版本冲突、成功/放弃清理 | P0 | P3-PDA-01 |
| P3-LOAD-01 | 后台 | 装柜封柜 | 柜号、锁码文本、装柜节点、五类多图证据和门禁复核 | P0 | P3-PICK-01 | | P3-LOAD-01 | 后台 | 装柜封柜 | 柜号、锁码文本、装柜节点、五类多图证据和门禁复核 | P0 | P3-PICK-01 |
| P3-LOAD-02 | PDA/Admin/服务端 | 柜封拍照上传 | PDA 现场拍摄、Admin 人工上传、五类证据多图追加、真实文件上传、预览、失败重试、作废和提交 | P0 | P3-LOAD-01、文件能力可用 | | P3-LOAD-02 | PDA/Admin/服务端 | 柜封拍照上传 | PDA 现场拍摄、Admin 人工上传、五类证据多图追加、真实文件上传、预览、失败重试、作废和提交 | P0 | P3-LOAD-01、文件能力可用 |
| P3-CUS-01 | 客户端 | 报关资料 | 清单、上传、补件、版本和进度查看 | P0 | 文件能力可用 | | P3-CUS-01 | 客户端 | 报关资料与客户确认 | `LOADED` 后清单、上传、补件、回执查看、确认/打回和轮次进度 | P0 | 文件能力可用 |
| P3-CLEAR-01 | 后台 | 报关协同 | 人工审核、补件、线下提交代理、人工上传放行回执和版本审计 | P0 | P3-CUS-01 | | P3-CLEAR-01 | 后台 | 报关协同 | 通知报关行、人工审核、回执轮次、客户确认汇总、所有客户通过后整柜正式提交、查验/放行记录 | P0 | P3-CUS-01 |
| P3-CUS-02 | 客户端 | 回执及出仓前船期资料 | 回执下载、订舱预计开船/到港快照和变更时间线;出仓后查询展示归海外仓业务 | P0 | P3-BOOK-01、P3-CLEAR-01 | | P3-CUS-02 | 客户端 | 回执及送港/船期资料 | 回执确认、打回重做、送港/进港/甩柜和实际开船前状态展示 | P0 | P3-BOOK-01、P3-CLEAR-01 |
| P3-GATE-01 | 服务端 | 装柜完成门禁 | 校验订舱、拖车、报关放行回执、PDA 拣货、五类证据和锁码文本,幂等推进 `LOADED`;`LOADED` 后仅线下人工处理 | P0 | P3-PICK-01、P3-LOAD-01、P3-LOAD-02 | | P3-GATE-01 | 服务端 | 装柜完成与并行分支门禁 | 校验真实柜号、PDA 拣货、数量守恒、五类证据和锁码文本,幂等推进 `LOADED`;随后分别创建报关案例和送港任务,实际开船才推进海运 | P0 | P3-PICK-01、P3-LOAD-01、P3-LOAD-02 |
| P3-OVERSEAS-01 | 服务端 | 海外仓派送完成回传 | 只接受海外仓可信回传,校验身份、签名、时间窗、防重放和幂等,推进 `DELIVERED` | P1/后续阶段 | 海外仓契约 | | P3-OVERSEAS-01 | 服务端 | 海外仓派送完成回传 | 只接受海外仓可信回传,校验身份、签名、时间窗、防重放和幂等,推进 `DELIVERED` | P1/后续阶段 | 海外仓契约 |
| P3-NOTIFY-01 | 公共 | 通知异常 | 站内通知、阻塞、责任人、时限和失败补偿 | P1 | 核心流程完成 | | P3-NOTIFY-01 | 公共 | 通知异常 | 站内通知、阻塞、责任人、时限和失败补偿 | P1 | 核心流程完成 |
| P3-TEST-01 | 公共 | 自动化测试 | 权限、排柜、幂等、并发、文件、门禁和状态测试 | P0 | 所有 P0 模块 | | P3-TEST-01 | 公共 | 自动化测试 | 权限、排柜、幂等、并发、文件、门禁和状态测试 | P0 | 所有 P0 模块 |
@@ -305,11 +307,12 @@ PDA 拣货 → 装柜并上传货柜/铅封照片
| P3-Q5 | 拣货是否依赖实时库存和库位可用量? | 已确认依赖入库测量与计费实时库存、当前位置和可用量接口;不扩展完整 WMS | | P3-Q5 | 拣货是否依赖实时库存和库位可用量? | 已确认依赖入库测量与计费实时库存、当前位置和可用量接口;不扩展完整 WMS |
| P3-Q6 | 柜封照片有哪些必传角度和留存期限? | 已确认:五类各至少 1 张、同类型可多张追加、后台操作员/理货员可上传、拣货员仅 PDA 现场采集、错图作废、无限期保留、客户不可见 | | P3-Q6 | 柜封照片有哪些必传角度和留存期限? | 已确认:五类各至少 1 张、同类型可多张追加、后台操作员/理货员可上传、拣货员仅 PDA 现场采集、错图作废、无限期保留、客户不可见 |
| P3-Q7 | 报关资料清单是否按国家、渠道和货物类型变化? | 已确认首版人工维护清单和版本,不接自动报关 | | P3-Q7 | 报关资料清单是否按国家、渠道和货物类型变化? | 已确认首版人工维护清单和版本,不接自动报关 |
| P3-Q8 | 报关代理如何接收资料和返回回执? | 已确认线下提交,授权人员人工上传回执 | | P3-Q8 | 报关代理如何接收资料和返回回执? | 已确认 `LOADED` 后线下提交;授权人员人工上传每轮回执,客户确认/打回,所有客户通过后再提交整柜资料 |
| P3-Q9 | 原型中的“港务信息”具体指船期、港口作业状态还是两者,包含哪些字段,由谁维护? | 当前更正:国内货柜履约只维护订舱与出仓前船期资料;六家船公司及出仓后节点查询整体归海外仓业务 | | P3-Q9 | 原型中的“港务信息”具体指船期、港口作业状态还是两者,包含哪些字段,由谁维护? | 当前更正:国内货柜履约维护送港、进港、甩柜/改配和实际开船前状态;只有实际开船后进入海运节点查询 |
| P3-Q10 | 进入装柜完成后发现错误如何处理? | 已确认线下人工处理,当前不提供在线冲正 | | P3-Q10 | 进入装柜完成后发现错误如何处理? | 已确认线下人工处理,当前不提供在线冲正 |
| P3-Q11 | 九个动作中哪些是强制前置,哪些允许并行? | 已确认订舱、拖车、报关放行、PDA 拣货和五类证据为 `LOADED` 硬门禁;单柜次单作业员 | | P3-Q11 | 九个动作中哪些是强制前置,哪些允许并行? | 费用确认不阻断排柜/装柜;`LOADED` 只校验物理装柜、PDA、数量和证据;报关线和送港线并行,客户确认不阻断送港,进港不代表报关完成;单柜次单作业员 |
| P3-Q12 | “报关回执”具体包含哪些类型,海关放行是否为国内出仓硬门禁? | 已确认有效放行回执为 `LOADED` 硬门禁,首版人工上传 | | P3-Q12 | “报关回执”具体包含哪些类型,海关放行如何与客户确认衔接? | 已确认:回执人工上传并发客户确认;客户打回则重做并生成新回执;所有客户通过后才整柜正式申报,查验/放行单独记录 |
| P3-Q17 | 送港和报关是否互相等待?甩柜何时发生? | 已确认:`LOADED` 后两条线同时启动;送港可先到港,报关可先完成客户确认;船舱不足记录甩柜/改配,实际开船才进入海运 |
| P3-Q13 | 国内货柜履约终点以什么状态为准? | 已确认为 `LOADED`/装柜完成;`DELIVERED`/派送完成由海外仓回传,不属于国内国内货柜履约 | | P3-Q13 | 国内货柜履约终点以什么状态为准? | 已确认为 `LOADED`/装柜完成;`DELIVERED`/派送完成由海外仓回传,不属于国内国内货柜履约 |
## 十二、建议实施顺序 ## 十二、建议实施顺序
@@ -320,3 +323,5 @@ PDA 拣货 → 装柜并上传货柜/铅封照片
4. 完成管理后台的出仓编排,再接 PDA 现场执行和客户资料协同。 4. 完成管理后台的出仓编排,再接 PDA 现场执行和客户资料协同。
5. 使用脱敏数据演练拼柜、一单多柜、未装数量生成子订单、错拣、补件和改船;`LOADED` 后不演练在线冲正。 5. 使用脱敏数据演练拼柜、一单多柜、未装数量生成子订单、错拣、补件和改船;`LOADED` 后不演练在线冲正。
6. 在真实 PDA 和代表性仓库网络环境中完成联调、验收和灰度发布。 6. 在真实 PDA 和代表性仓库网络环境中完成联调、验收和灰度发布。
@@ -8,7 +8,7 @@
## 一、国内货柜履约目标 ## 一、国内货柜履约目标
国内货柜履约承接入库测量与计费到仓、实测、差异处理、处理单元编码和当前位置记录,完成智能排柜、订舱、拖车预约、PDA 拣货、装柜拍照、报关协同、港务信息查询,并将现有订单推进到 `LOADED`/装柜完成。 国内货柜履约承接入库测量与计费到仓、实测、差异处理、处理单元编码和当前位置记录,完成智能排柜、订舱、拖车预约、PDA 拣货、装柜拍照,并在 `LOADED` 后分别推进报关客户确认闭环和送港/进港/甩柜;只有承运船舶实际开航才进入海运节点。
当前验收基线已确认为 `LOADED`/装柜完成。`DELIVERED`/派送完成只能在货物到达海外仓后由海外仓可信回传推进,不属于国内国内货柜履约操作和验收范围。 当前验收基线已确认为 `LOADED`/装柜完成。`DELIVERED`/派送完成只能在货物到达海外仓后由海外仓可信回传推进,不属于国内国内货柜履约操作和验收范围。
@@ -24,8 +24,8 @@
| T06 | 拖车预约 | 服务商、车辆司机、预约时间窗、到离仓节点和异常 | 联调中 | 80% | 2026-08-10 | 待排期 | Firstleg/Admin | 预约生命周期和服务中心串联已通过,最终 LOADED 门禁待 PDA | | T06 | 拖车预约 | 服务商、车辆司机、预约时间窗、到离仓节点和异常 | 联调中 | 80% | 2026-08-10 | 待排期 | Firstleg/Admin | 预约生命周期和服务中心串联已通过,最终 LOADED 门禁待 PDA |
| T07 | PDA 拣货与复核 | 在线进入任务、持久化扫描草稿、批量提交、部分拣货、异常、幂等和单人作业 | 已阻塞 | 45% | 2026-08-10 | 待排期 | Firstleg/PDA | `pick` 第二处真实 S0500 未收口;原子 batch、库存快照、失败整批回滚未实现 | | T07 | PDA 拣货与复核 | 在线进入任务、持久化扫描草稿、批量提交、部分拣货、异常、幂等和单人作业 | 已阻塞 | 45% | 2026-08-10 | 待排期 | Firstleg/PDA | `pick` 第二处真实 S0500 未收口;原子 batch、库存快照、失败整批回滚未实现 |
| T08 | 装柜及柜封证据 | 装柜节点、柜号、铅封号、PDA 现场拍照、后台角色上传、多图追加、作废和复核 | 联调中 | 80% | 2026-08-10 | 待排期 | Firstleg/Admin/PDA | 五类证据、多图追加、作废和硬门禁已通过;终态仍依赖 PDA | | T08 | 装柜及柜封证据 | 装柜节点、柜号、铅封号、PDA 现场拍照、后台角色上传、多图追加、作废和复核 | 联调中 | 80% | 2026-08-10 | 待排期 | Firstleg/Admin/PDA | 五类证据、多图追加、作废和硬门禁已通过;终态仍依赖 PDA |
| T09 | 报关资料与回执 | 人工资料清单、后台审核补件、线下提交代理、人工上传放行回执 | 联调中 | 70% | 2026-08-10 | 待排期 | Firstleg/Admin | 人工清单和资料版本已通过;LOADED 子订单关联受 PDA 失败级联阻断 | | T09 | 装柜后报关资料与客户确认 | `LOADED` 后通知报关行;客户资料→报关行回执→客户确认/打回重做→所有客户通过→整柜正式申报→查验/放行 | 联调中 | 70% | 2026-09-24 | 待排期 | Firstleg/Admin | 多轮回执、客户确认和整柜提交仍待实现 |
| T10 | 装柜完成门禁 | 校验订舱、拖车、报关放行、PDA 拣货、五类证据和锁码文本,推进 `LOADED` | 已阻塞 | 70% | 2026-08-10 | 待排期 | Firstleg | 门禁逐项读取和 fail-closed 已通过,真实推进 `LOADED` 等 PDA 修复 | | T10 | 装柜完成与送港/开船门禁 | `LOADED` 校验物理装柜;送港线独立校验订舱/拖车、离仓、进港和甩柜;实际开船才进入海运 | 已阻塞 | 70% | 2026-09-24 | 待排期 | Firstleg | 报关线和送港线并行口径已确认,真实推进与 PDA 修复仍待完成 |
| T11 | 客户端国内货柜履约协同 | 装柜进度、柜次、回执、预计开船/到港和变更时间线 | 待开始 | 0% | 待排期 | 待排期 | 待分配 | 客户不查看装柜照片和锁码;依赖 T05、T09、T10 | | T11 | 客户端国内货柜履约协同 | 装柜进度、柜次、回执、预计开船/到港和变更时间线 | 待开始 | 0% | 待排期 | 待排期 | 待分配 | 客户不查看装柜照片和锁码;依赖 T05、T09、T10 |
| T12 | 联调测试与发布 | 跨端联调、自动化测试、PDA 真机、安全、弱网、迁移、验收和发布 | 联调中 | 70% | 2026-08-10 | 待排期 | 总控/测试 | Admin、Firstleg 已分模块部署并持续真实 HTTP 验收;PDA S0500、batch 契约和真机验收未收口 | | T12 | 联调测试与发布 | 跨端联调、自动化测试、PDA 真机、安全、弱网、迁移、验收和发布 | 联调中 | 70% | 2026-08-10 | 待排期 | 总控/测试 | Admin、Firstleg 已分模块部署并持续真实 HTTP 验收;PDA S0500、batch 契约和真机验收未收口 |
@@ -43,8 +43,8 @@
| P3-T06-00 | T06 | 后台/服务端 | 拖车预约 | 服务商、车辆司机、时间窗、到离仓和异常;完成状态供门禁校验 | P0 | 联调中 | 80% | P3-T03-00 | Firstleg/Admin | 预约、附件、历史及服务中心链路已通过真实接口 | | P3-T06-00 | T06 | 后台/服务端 | 拖车预约 | 服务商、车辆司机、时间窗、到离仓和异常;完成状态供门禁校验 | P0 | 联调中 | 80% | P3-T03-00 | Firstleg/Admin | 预约、附件、历史及服务中心链路已通过真实接口 |
| P3-T07-00 | T07 | PDA/后台/服务端 | PDA 拣货与复核 | 按单柜次单作业员实现在线草稿、批量提交、异常、幂等和实时库存校验 | P0 | 已阻塞 | 45% | P3-T04-00 | Firstleg/PDA | 广播扫描已接入;真实 pick S0500 与原子 batch 契约仍待收口 | | P3-T07-00 | T07 | PDA/后台/服务端 | PDA 拣货与复核 | 按单柜次单作业员实现在线草稿、批量提交、异常、幂等和实时库存校验 | P0 | 已阻塞 | 45% | P3-T04-00 | Firstleg/PDA | 广播扫描已接入;真实 pick S0500 与原子 batch 契约仍待收口 |
| P3-T08-00 | T08 | PDA/后台/服务端 | 装柜及柜封证据 | 实现五类多图追加、角色上传、作废和无限期留存,客户不可见 | P0 | 联调中 | 80% | P3-T07-00 | Firstleg/Admin/PDA | 五类证据与安全边界已通过,真机拍照和终态待验收 | | P3-T08-00 | T08 | PDA/后台/服务端 | 装柜及柜封证据 | 实现五类多图追加、角色上传、作废和无限期留存,客户不可见 | P0 | 联调中 | 80% | P3-T07-00 | Firstleg/Admin/PDA | 五类证据与安全边界已通过,真机拍照和终态待验收 |
| P3-T09-00 | T09 | 客户端/后台/服务端 | 报关资料与回执 | 实现人工清单、补件、线下提交记录、人工放行回执上传 | P0 | 联调中 | 70% | P3-T02-00 | Firstleg/Admin | 人工协同接口已部署,最终子订单关联受 PDA 失败级联阻断 | | P3-T09-00 | T09 | 客户端/后台/服务端 | 报关资料与客户确认闭环 | 实现客户案例、报关行回执轮次、确认/打回重做、所有客户通过后整柜正式提交、查验/放行记录 | P0 | 联调中 | 70% | P3-T02-00 | Firstleg/Admin | 人工协同接口已部署,客户确认闭环仍待实现 |
| P3-T10-00 | T10 | 后台/服务端 | 装柜完成门禁 | 实现订舱/拖车/放行/PDA/证据硬门禁并推进 `LOADED` | P0 | 已阻塞 | 70% | P3-T07-00、P3-T08-00、P3-T09-00 | Firstleg | 门禁读取已通过;推进 LOADED 受 PDA 主链阻断 | | P3-T10-00 | T10 | 后台/服务端 | 装柜完成与送港/开船事实 | 实现物理 `LOADED`、送港/进港、甩柜/改配和实际开船分层事实,不以报关确认阻断送港 | P0 | 已阻塞 | 70% | P3-T07-00、P3-T08-00、P3-T09-00 | Firstleg | 门禁读取已通过;推进 LOADED 受 PDA 主链阻断 |
| P3-T11-00 | T11 | 客户端/服务端 | 客户端国内货柜履约协同 | 展示柜次、装柜进度、客户可见回执和船期;不返回照片与锁码 | P0 | 待开始 | 0% | P3-T05-00、P3-T09-00、P3-T10-00 | 待分配 | - | | P3-T11-00 | T11 | 客户端/服务端 | 客户端国内货柜履约协同 | 展示柜次、装柜进度、客户可见回执和船期;不返回照片与锁码 | P0 | 待开始 | 0% | P3-T05-00、P3-T09-00、P3-T10-00 | 待分配 | - |
| P3-T12-00 | T12 | 公共 | 联调测试与发布 | 维护定向/全量真实 HTTP、PDA 真机、安全和发布回归 | P0 | 联调中 | 70% | P3-T02-00~P3-T11-00 | 总控/测试 | 已进入分模块部署验收;不得用 mock、历史资源或 coverage gap 伪装通过 | | P3-T12-00 | T12 | 公共 | 联调测试与发布 | 维护定向/全量真实 HTTP、PDA 真机、安全和发布回归 | P0 | 联调中 | 70% | P3-T02-00~P3-T11-00 | 总控/测试 | 已进入分模块部署验收;不得用 mock、历史资源或 coverage gap 伪装通过 |
| P3-T01-PROTO-01 | T01 | 公共 | 原型盘点 | 盘点流程图、后台、企业客户端和 PDA 中与国内货柜履约相关的页面及交互 | P0 | 已完成 | 100% | - | 待分配 | 2026-07-28 已完成首次盘点,来源为 `docs/悦` | | P3-T01-PROTO-01 | T01 | 公共 | 原型盘点 | 盘点流程图、后台、企业客户端和 PDA 中与国内货柜履约相关的页面及交互 | P0 | 已完成 | 100% | - | 待分配 | 2026-07-28 已完成首次盘点,来源为 `docs/悦` |
@@ -97,12 +97,12 @@
| P3-M2 订单国内货柜履约编排 | 现有订单、柜次、排柜、订舱、港务和拖车可关联追溯 | 联调中 | 待排期 | | P3-M2 订单国内货柜履约编排 | 现有订单、柜次、排柜、订舱、港务和拖车可关联追溯 | 联调中 | 待排期 |
| P3-M3 仓内出仓 | PDA 拣货、复核、装柜和柜封证据闭环 | 已阻塞 | 待排期 | | P3-M3 仓内出仓 | PDA 拣货、复核、装柜和柜封证据闭环 | 已阻塞 | 待排期 |
| P3-M4 报关协同 | 客户资料、后台审核、提交代理、回执上传下载闭环 | 联调中 | 待排期 | | P3-M4 报关协同 | 客户资料、后台审核、提交代理、回执上传下载闭环 | 联调中 | 待排期 |
| P3-M5 装柜完成 | 订舱、拖车、放行回执、PDA 和证据门禁满足后进入 `LOADED`;后续错误线下处理 | 已阻塞 | 待排期 | | P3-M5 装柜完成及并行分支 | 真实柜号、PDA、数量守恒和五类证据门禁满足后进入 `LOADED`;随后并行推进报关客户确认闭环和送港/进港/甩柜,实际开船才进入海运 | 已阻塞 | 待排期 |
| P3-M6 国内货柜履约上线 | 联调、真机、安全、测试、验收和生产发布完成 | 进行中 | 待排期 | | P3-M6 国内货柜履约上线 | 联调、真机、安全、测试、验收和生产发布完成 | 进行中 | 待排期 |
## 七、未确认事项(需求确认进度) ## 七、未确认事项(需求确认进度)
当前 13 项主确认事项均已有产品最终结论;P3-Q4 已确认采用 uni-app、在线更新与 Android 广播扫描。完整结论统一维护在 [国内货柜履约需求确认表](国内货柜履约需求确认表.md)。 当前 13 项主确认事项均已有产品最终结论;P3-Q4 已确认采用 uni-app、在线更新与 Android 广播扫描。完整结论统一维护在 [国内货柜履约需求确认表](../国内货柜履约需求确认表.md)。
验收拆分已建立:PDA 进入任务、拣货幂等/版本冲突、五类证据真实上传、多图追加和锁码门禁进入自动化;真机在线、设备草稿批量提交、证据作废、设备与权限留存等仍保留 coverageGap,详见[国内货柜履约验收任务拆分与待确认清单](国内货柜履约验收任务拆分与待确认清单.md)。 验收拆分已建立:PDA 进入任务、拣货幂等/版本冲突、五类证据真实上传、多图追加和锁码门禁进入自动化;真机在线、设备草稿批量提交、证据作废、设备与权限留存等仍保留 coverageGap,详见[国内货柜履约验收任务拆分与待确认清单](国内货柜履约验收任务拆分与待确认清单.md)。
@@ -118,8 +118,8 @@
| P3-Q8 | 模块阻断 | 报关代理接收资料和返回回执的方式 | 已确认 | 线下提交、人工上传回执 | | P3-Q8 | 模块阻断 | 报关代理接收资料和返回回执的方式 | 已确认 | 线下提交、人工上传回执 |
| P3-Q9 | 开工阻断 | 港务信息的业务含义、字段和维护方 | 已确认 | 六家船公司查询、三日周期、三次上限、过期标识 | | P3-Q9 | 开工阻断 | 港务信息的业务含义、字段和维护方 | 已确认 | 六家船公司查询、三日周期、三次上限、过期标识 |
| P3-Q10 | 模块阻断 | 装柜完成后的错误处理和冲正方式 | 已确认 | 线下人工处理,不提供在线冲正 | | P3-Q10 | 模块阻断 | 装柜完成后的错误处理和冲正方式 | 已确认 | 线下人工处理,不提供在线冲正 |
| P3-Q11 | 开工阻断 | 九个动作的强制前置和并行关系 | 已确认 | 订舱/拖车/放行/PDA/证据为硬门禁;单柜次单人 | | P3-Q11 | 开工阻断 | 九个动作的强制前置和并行关系 | 已确认 | `LOADED` 后报关线和送港线并行;客户确认不阻断送港,进港不代表报关完成;单柜次单人 |
| P3-Q12 | 开工阻断 | 报关回执类型及海关放行是否为装柜完成硬门禁 | 已确认 | 有效放行回执为硬门禁,人工上传 | | P3-Q12 | 开工阻断 | 报关行回执、客户确认、正式申报和海关结果 | 已确认 | 回执必须发客户确认,打回则重做;所有客户通过后才整柜正式申报,查验/放行单独记录 |
| P3-Q13 | 开工阻断 | 国内货柜履约终点 | 已确认 | `LOADED`/装柜完成;`DELIVERED` 由海外仓回传,移出国内货柜履约验收 | | P3-Q13 | 开工阻断 | 国内货柜履约终点 | 已确认 | `LOADED`/装柜完成;`DELIVERED` 由海外仓回传,移出国内货柜履约验收 |
## 八、开工准入记录 ## 八、开工准入记录
@@ -128,7 +128,7 @@
| 准入编号 | 准入条件 | 当前状态 | 责任方 | 完成证据 | | 准入编号 | 准入条件 | 当前状态 | 责任方 | 完成证据 |
|---|---|---|---|---| |---|---|---|---|---|
| P3-GO-01 | P3-Q1~P3-Q13 均形成产品结论 | 已完成 | 产品、业务 | `国内货柜履约需求确认表.md` 已同步最终结论 | | P3-GO-01 | P3-Q1~P3-Q17 均形成产品结论 | 已完成 | 产品、业务 | `国内货柜履约需求确认表.md` 已同步最终结论 |
| P3-GO-02 | 确认结论已同步开发规划、进度表、页面清单和验收范围 | 已完成 | 产品、项目负责人 | README、进度表、页面清单和验收口径已按确认版同步 | | P3-GO-02 | 确认结论已同步开发规划、进度表、页面清单和验收范围 | 已完成 | 产品、项目负责人 | README、进度表、页面清单和验收口径已按确认版同步 |
| P3-GO-03 | 关键缺失原型已补齐并评审,包括订单装柜完成门禁、客户端国内货柜履约页面和 PDA 五类多图拍照 | 进行中 | 产品、设计、业务 | 页面清单中的关键页面达到已确认状态 | | P3-GO-03 | 关键缺失原型已补齐并评审,包括订单装柜完成门禁、客户端国内货柜履约页面和 PDA 五类多图拍照 | 进行中 | 产品、设计、业务 | 页面清单中的关键页面达到已确认状态 |
| P3-GO-04 | T02 公共契约完成,入库测量与计费输入、状态机、权限、数据模型、接口、错误码和审计口径稳定 | 进行中 | 前后端、架构/技术负责人 | 主体契约已部署;PDA 原子 batch 契约仍缺 | | P3-GO-04 | T02 公共契约完成,入库测量与计费输入、状态机、权限、数据模型、接口、错误码和审计口径稳定 | 进行中 | 前后端、架构/技术负责人 | 主体契约已部署;PDA 原子 batch 契约仍缺 |
@@ -152,3 +152,4 @@
3. 完成 PDA 真机广播扫码、在线草稿、五类证据拍照、多图追加和作废验收。 3. 完成 PDA 真机广播扫码、在线草稿、五类证据拍照、多图追加和作废验收。
4. 收口 T11 客户端国内货柜履约页面及客户可见性、安全边界。 4. 收口 T11 客户端国内货柜履约页面及客户可见性、安全边界。
5. 复跑国内货柜履约定向和默认全量真实 HTTP 验收,完成发布记录后再评估国内货柜履约完成状态。 5. 复跑国内货柜履约定向和默认全量真实 HTTP 验收,完成发布记录后再评估国内货柜履约完成状态。
@@ -6,14 +6,15 @@
- 已确认规则可进入契约、数据、接口、页面和测试拆分,不需要等待整期所有模块完成。 - 已确认规则可进入契约、数据、接口、页面和测试拆分,不需要等待整期所有模块完成。
- 订单继续承载国内货柜履约主状态,不新建独立出仓单;支持父订单、子订单与柜次关系,以及一单多柜和多订单拼柜。 - 订单继续承载国内货柜履约主状态,不新建独立出仓单;支持父订单、子订单与柜次关系,以及一单多柜和多订单拼柜。
- 智能排柜、订舱与船期、拖车预约、PDA 在线拣货、五类装柜证据、人工报关回执和 `LOADED` 服务端门禁按需求确认表执行。 - 智能排柜、订舱与船期、拖车预约、PDA 在线拣货、五类装柜证据、`LOADED` 后客户报关确认闭环、送港/甩柜和实际开船按本轮确认流程执行。
- 国内货柜履约的国内终点为 `LOADED`;`DELIVERED` 只由海外仓可信回传推进。 - 国内货柜履约的国内终点为 `LOADED`;`DELIVERED` 只由海外仓可信回传推进。
## 跨端硬边界 ## 跨端硬边界
- `LOADED` 前必须由服务端校验订舱完成、拖车完成、有效报关放行回执、PDA 拣货完成和五类有效证据完整;国内 Admin/PDA 不提供在线冲正或手工推进 `DELIVERED`。 - `LOADED` 前必须由服务端校验真实柜号、PDA 拣货与数量守恒、五类有效证据和未解决异常。`LOADED` 后报关线和送港线分别校验:报关线按客户资料、报关行回执、客户确认/打回、所有客户通过、整柜正式申报和海关结果推进;送港线按订舱/拖车、离仓、进港、甩柜和实际开船推进。客户确认不阻断送港,进港不代表报关完成。国内 Admin/PDA 不提供在线冲正或手工推进 `DELIVERED`。
- PDA 正式作业仅在线;单柜次只允许一名作业员,不支持多人并行、任务接管或换班释放。进入任务即由服务端标记拣货中,扫描草稿按作业员、任务和柜次隔离,提交时批量写入。 - PDA 正式作业仅在线;单柜次只允许一名作业员,不支持多人并行、任务接管或换班释放。进入任务即由服务端标记拣货中,扫描草稿按作业员、任务和柜次隔离,提交时批量写入。
- 每类证据至少一张有效照片,允许同类型追加;错误照片只能作废并保留审计。客户不可见照片与锁码。 - 每类证据至少一张有效照片,允许同类型追加;错误照片只能作废并保留审计。客户不可见照片与锁码。
- 报关在 `LOADED` 后正式启动:每个客户经历资料上传、报关行回执、客户确认或打回重做,所有客户通过后才提交整柜资料给报关行正式申报;送港线独立记录拖车、进港、甩柜和实际开船。费用确认不阻断排柜/装柜,装柜完成后对已装范围的当前有效已发布费用版本记录系统默认确认,来源和客户主动确认必须分开审计。
- 前端页面、菜单和路由只能在对应服务端契约、权限和数据模型稳定后发布;原型中的完整 WMS、海外仓及未确认能力不属于国内货柜履约默认范围。 - 前端页面、菜单和路由只能在对应服务端契约、权限和数据模型稳定后发布;原型中的完整 WMS、海外仓及未确认能力不属于国内货柜履约默认范围。
## 局部阻断项 ## 局部阻断项
@@ -27,3 +28,4 @@
1. 先读 `README.md`、`国内货柜履约需求确认表.md` 和本文件,确认任务属于已确认范围。 1. 先读 `README.md`、`国内货柜履约需求确认表.md` 和本文件,确认任务属于已确认范围。
2. 再进入目标应用或服务的 `AGENTS.md`,按本地模块入口实现。 2. 再进入目标应用或服务的 `AGENTS.md`,按本地模块入口实现。
3. 发现新的产品决策或门禁变化时,先更新确认表与本文,再更新受影响模块指引;不要将短期进度、联调故障或环境地址写回模块规则。 3. 发现新的产品决策或门禁变化时,先更新确认表与本文,再更新受影响模块指引;不要将短期进度、联调故障或环境地址写回模块规则。
@@ -1,5 +1,7 @@
# 国内货柜履约装柜闭环产品确认表 # 国内货柜履约装柜闭环产品确认表
> **历史版本声明(2026-09-24)**:本文仅保留 2026-08-08 的原始讨论记录,其中“装柜完成即结束”和报关/离仓关系等内容已被当前流程替代。当前规则以 [头程到尾程流程节点梳理(重构版)](../../头程到尾程流程节点梳理.md)、[报关资料与船期价格接入梳理](../报关资料与船期价格接入梳理.md) 和最新需求确认表为准:`LOADED` 只表示物理装柜完成;正式报关在装柜完成后按最终实装清单执行,放行回执参与 `DEPARTED_WAREHOUSE` 离仓门禁。
> 确认方式:产品只需在“产品确认”一列填写“同意”,或写明修改后的规则。 > 确认方式:产品只需在“产品确认”一列填写“同意”,或写明修改后的规则。
> 会议目标:本表确认后直接进入开发,不再补完整高保真原型。 > 会议目标:本表确认后直接进入开发,不再补完整高保真原型。
@@ -64,3 +66,4 @@
| 本次明确不做的内容 | | | 本次明确不做的内容 | |
| 产品确认人 | | | 产品确认人 | |
| 确认日期 | | | 确认日期 | |
@@ -1,5 +1,7 @@
# 国内货柜履约装柜闭环开发前确认单 # 国内货柜履约装柜闭环开发前确认单
> **历史版本声明(2026-09-24)**:本文是旧版“以 `LOADED` 作为国内履约终点”的开发前确认材料,旧规则已被本轮新流程替代。当前按三大业务块梳理;`LOADED` 只表示物理装柜完成,正式报关在装柜完成后按最终实装清单执行,放行回执、订舱、拖车和异常门禁用于推进 `DEPARTED_WAREHOUSE`。费用确认不阻断装柜,当前有效已发布费用版本在 `LOADED` 时按已装载范围默认确认。开发以 [头程到尾程流程节点梳理(重构版)](../../头程到尾程流程节点梳理.md)、[报关资料与船期价格接入梳理](../报关资料与船期价格接入梳理.md) 和当前确认记录为准。
> 整理日期:2026-08-08 > 整理日期:2026-08-08
> 用途:产品、业务、仓库、研发在直接开发前确认最小闭环细节 > 用途:产品、业务、仓库、研发在直接开发前确认最小闭环细节
> 当前建议:不补完整高保真原型,确认本清单后直接开发 > 当前建议:不补完整高保真原型,确认本清单后直接开发
@@ -144,3 +146,4 @@ DELIVERED / 海外仓已收货
2. 更新 `国内货柜履约需求确认表.md` 中对应的 P3-Q2/P3-Q4/P3-Q5/P3-Q6/P3-Q10/P3-Q11/P3-Q12。 2. 更新 `国内货柜履约需求确认表.md` 中对应的 P3-Q2/P3-Q4/P3-Q5/P3-Q6/P3-Q10/P3-Q11/P3-Q12。
3. 明确是否允许按“服务端门禁 -> PDA -> Admin -> 联调验收”的顺序直接开发。 3. 明确是否允许按“服务端门禁 -> PDA -> Admin -> 联调验收”的顺序直接开发。
4. 将本清单作为接口、页面和测试验收的共同依据。 4. 将本清单作为接口、页面和测试验收的共同依据。
@@ -1,5 +1,7 @@
# 虫虫出海国内货柜履约闭环审计报告 # 虫虫出海国内货柜履约闭环审计报告
> **历史记录声明(2026-09-24)**:本文记录的是 2026-08-08 的旧口径和旧审计结论,不再作为当前流程或开发门禁依据。当前统一采用三大业务块和“装柜完成后正式报关”的新流程:`LOADED` 只确认物理装柜完成;装柜完成后按最终实装清单正式报送,取得有效回执/放行结果后,结合订舱、拖车和异常门禁推进 `DEPARTED_WAREHOUSE`。费用确认不阻断装柜,装柜完成时对当前有效已发布版本按已装载范围默认确认。当前规则以 [头程到尾程流程节点梳理(重构版)](../../头程到尾程流程节点梳理.md)、[报关资料与船期价格接入梳理](../报关资料与船期价格接入梳理.md) 和本轮确认记录为准。
> 审计日期:2026-08-08 > 审计日期:2026-08-08
> 审计范围:入库测量与计费终点→智能排柜→订舱→拖车→PDA 拣货→装柜/柜封证据→`LOADED`/装柜完成 > 审计范围:入库测量与计费终点→智能排柜→订舱→拖车→PDA 拣货→装柜/柜封证据→`LOADED`/装柜完成
> 审计对象:Admin、Client、PDA、`baiyue-firstleg` 后端、OpenAPI/SQL、自动化测试与现有测试环境报告 > 审计对象:Admin、Client、PDA、`baiyue-firstleg` 后端、OpenAPI/SQL、自动化测试与现有测试环境报告
@@ -239,3 +241,4 @@ PDA 已有调用拣货/证据/装柜接口的适配代码,但当前仍存在
> **国内货柜履约已确认复用现有订单列表承载全部主状态,不新建出仓单,国内终点为 `LOADED`/装柜完成;已完成排柜/预装/PDA 拣货/装柜清单子链路,订舱和拖车 API 可用。但订单国内货柜履约统一编排、五张装柜照片与锁码文本硬门禁、报关协同、冲正、Client 协同和 PDA 真机仍未闭环,且国内手工推进 `DELIVERED` 的现有能力必须整改,当前不具备整期验收条件。** > **国内货柜履约已确认复用现有订单列表承载全部主状态,不新建出仓单,国内终点为 `LOADED`/装柜完成;已完成排柜/预装/PDA 拣货/装柜清单子链路,订舱和拖车 API 可用。但订单国内货柜履约统一编排、五张装柜照片与锁码文本硬门禁、报关协同、冲正、Client 协同和 PDA 真机仍未闭环,且国内手工推进 `DELIVERED` 的现有能力必须整改,当前不具备整期验收条件。**
因此,现阶段不应标记“国内货柜履约完成”,应标记为“**子能力已实现,闭环整改中**”。 因此,现阶段不应标记“国内货柜履约完成”,应标记为“**子能力已实现,闭环整改中**”。
@@ -12,9 +12,9 @@
| 五类装柜证据 | 空仓、半仓、满仓、锁仓、带锁码照均上传真实文件并按客户/柜次绑定 | `phase3-loading.mjs` | | 五类装柜证据 | 空仓、半仓、满仓、锁仓、带锁码照均上传真实文件并按客户/柜次绑定 | `phase3-loading.mjs` |
| 同类型多图 | 同一证据类型追加第二张真实图片,原记录与新增记录同时保持有效 | `phase3-loading.mjs` | | 同类型多图 | 同一证据类型追加第二张真实图片,原记录与新增记录同时保持有效 | `phase3-loading.mjs` |
| 锁码门禁 | 缺少锁码照片或锁码文本为空时,完成装柜请求被拒绝 | `phase3-loading.mjs` | | 锁码门禁 | 缺少锁码照片或锁码文本为空时,完成装柜请求被拒绝 | `phase3-loading.mjs` |
| 统一装柜门禁 | 订舱未完成、拖车未完成、报关无有效放行回执、PDA 未完成或五类证据不完整时,真实 `LOADED` 请求均被拒绝 | `service-center-flow.mjs` / `phase3-loading.mjs` | | 统一装柜门禁 | 真实柜号缺失、PDA 未完成、数量不守恒或五类证据不完整时,真实 `LOADED` 请求被拒绝;`LOADED` 后分别验收客户报关回执确认闭环和送港/进港/甩柜事实,任何一条线都不反向阻断物理装柜 | `service-center-flow.mjs` / `phase3-loading.mjs` |
| 订单/柜次聚合 | 一单多柜、一个柜多订单、父子订单数量分摊及未装数量自动生成子订单可追溯 | `phase3-order-aggregate.mjs`(待补) | | 订单/柜次聚合 | 一单多柜、一个柜多订单、父子订单数量分摊及未装数量自动生成子订单可追溯 | `phase3-order-aggregate.mjs`(待补) |
| 出仓后船节点查询 | 已重新归入海外仓业务,不属于国内货柜履约验收 | 海外仓业务沿用现有 `CarrierScheduleQuery` 设计验收入口,不再补 `phase3-vessel-tracking.mjs` | | 实际开船后船节点查询 | 只有承运船舶真实开航后才进入海运节点;送港、进港和甩柜属于国内货柜履约并行线 | 海外仓业务沿用现有 `CarrierScheduleQuery` 设计验收入口,不再用预计 ETD 或 `DEPARTED_WAREHOUSE` 提前推进海运 |
| 仓库角色 | 操作员、拣货员、理货员初始化、最小权限和跨客户隔离 | `phase3-role-contract.mjs`(待补) | | 仓库角色 | 操作员、拣货员、理货员初始化、最小权限和跨客户隔离 | `phase3-role-contract.mjs`(待补) |
| 伪造与交叉归属 | 不存在 `fileId`、其他证据类型的 `fileId` 不能绑定 | `phase3-loading.mjs` | | 伪造与交叉归属 | 不存在 `fileId`、其他证据类型的 `fileId` 不能绑定 | `phase3-loading.mjs` |
@@ -33,3 +33,4 @@
4. `P3-ACCEPT-PDA-RELEASE`:按既定 uni-app 在线更新安排完成发布与真机验收。 4. `P3-ACCEPT-PDA-RELEASE`:按既定 uni-app 在线更新安排完成发布与真机验收。
每个任务完成后,必须把真实请求、响应状态、业务码、`requestId/traceId` 写入报告,并删除对应 coverageGap;不得以 mock 或数据库直写替代接口验收。 每个任务完成后,必须把真实请求、响应状态、业务码、`requestId/traceId` 写入报告,并删除对应 coverageGap;不得以 mock 或数据库直写替代接口验收。
@@ -42,3 +42,4 @@
- `phase3-container-loading` 对 ACTIVE 货柜、预装清单和完成装柜清单执行字段断言。 - `phase3-container-loading` 对 ACTIVE 货柜、预装清单和完成装柜清单执行字段断言。
- `ocean-bookings`、`phase3-port-schedules`、`truck-appointments`、`phase3-customs`、`phase3-outbound-dispatch` 在既有本轮资源响应上执行字段断言,不增加历史查询或伪造回退。 - `ocean-bookings`、`phase3-port-schedules`、`truck-appointments`、`phase3-customs`、`phase3-outbound-dispatch` 在既有本轮资源响应上执行字段断言,不增加历史查询或伪造回退。
- 默认 Admin 全量入口已包含上述生产模块;真实 HTTP 仅在测试环境重新部署且当前对话明确授权后执行。 - 默认 Admin 全量入口已包含上述生产模块;真实 HTTP 仅在测试环境重新部署且当前对话明确授权后执行。
@@ -219,3 +219,4 @@
| 全量编排 | 默认入口先运行 `phase3-container-loading` 完成“模拟柜新增 -> 同仓同渠道排货 -> 首次 link -> PDA”,再由证据、finalize、出仓模块沿本轮 marker 的稳定 ID 继续;禁止历史数据和 mock 回退 | Node 入口合同已锁定,待默认全量 HTTP 验证 | | 全量编排 | 默认入口先运行 `phase3-container-loading` 完成“模拟柜新增 -> 同仓同渠道排货 -> 首次 link -> PDA”,再由证据、finalize、出仓模块沿本轮 marker 的稳定 ID 继续;禁止历史数据和 mock 回退 | Node 入口合同已锁定,待默认全量 HTTP 验证 |
离线合同:`container-simulation-association-contract.test.mjs` 锁定跨层契约及全量顺序;`phase3-producer-chain-contract.test.mjs`、`phase3-order-splitting-contract.test.mjs`、`ocean-booking-channel-contract.test.mjs` 锁定生产者只使用 DRAFT/RELEASED、需求关联且不在订舱阶段自动建柜。 离线合同:`container-simulation-association-contract.test.mjs` 锁定跨层契约及全量顺序;`phase3-producer-chain-contract.test.mjs`、`phase3-order-splitting-contract.test.mjs`、`ocean-booking-channel-contract.test.mjs` 锁定生产者只使用 DRAFT/RELEASED、需求关联且不在订舱阶段自动建柜。
@@ -0,0 +1,195 @@
# 报关资料与船期价格接入梳理
> **当前用途:报关与船期价格专题参考。** 报关流程已经确认,第一批代码和页面已经接入测试环境;开发交接看[报关代码开发交接清单](../头程到尾程/报关代码开发交接清单.md)。主流程和节点关系以[头程到尾程流程节点梳理](../头程到尾程流程节点梳理.md)为准;本文保留资料字段、回执轮次、价格口径和接口查找信息。
>
> 文中“目标、实施顺序、进入条件、待确认事项”等段落属于原评审记录。开发已经完成后,不再据此重新拆开发任务;若与当前确认不一致,以总览和最新业务确认修正对应专题段落。
本文是企业客户端“报关资料”“船期价格”入口的专题评审记录。当前使用时只取已确认的流程、资料和价格口径;“建议”和“待确认”保留为历史评审痕迹,不再自动生成开发任务或验收门禁。
**当前基线**:以最新用户确认和[头程到尾程流程节点梳理](../头程到尾程流程节点梳理.md)为准。旧版需求表、README、开发规划和本文件中的历史建议若发生冲突,先在当前入口记录收尾变更,再决定是否需要修改专题细节。
**当前实现快照(2026-09-29)**:两份文件链路已经落到平台、客户和 Firstleg 报关接口,客户端“报关资料”和“船期价格”也已经作为独立模块接入导航和路由。客户资料、报关行回执、客户整份回执确认/打回、平台发送报关行执行、真实报关完税文件分别保存并受版本门禁控制。回执发送给报关行后不可再替换;只有包含退税货物的柜才允许走发送执行接口;全买单柜仍走平台直接完成。`brokerSubmittedAt` 只表示发送执行时间,不表示报关完成。PDA 只负责产生 `LOADED` 前置事实,报关验收不创建或操作 PDA 任务;船期、甩柜和改配只修改原柜运输信息,不重置报关资料和确认结果。
## 当前差异与下一步
当前主流程和代码的关系已经收敛:F01-F24(国内头程、报关、待发区、送港、进港、甩柜和实际开航)有最新真实 HTTP 证据;F25-F40(目的港、海外入库、库存、出库、派送和最终回写)已有综合真实 HTTP 证据和页面实现。客户端两个独立模块、订单快捷入口、平台整柜报关工作台和船期价格查询均已接入,不需要再按“新增页面”拆任务。
2026-09-29 的最新综合 F01-F40 验收报告为 `baiyue-firstleg/reports/fba-full-current-20260929.json`。报告前段业务链大量通过,但尾程和海外 PDA 产生了环境型阻断:`test-api-overseas.buggoglobal.com` 当时 DNS 不可解析,后续请求均为 `fetch failed`,因此这份报告不能作为全流程全绿结论,也不能据此判断报关或船期代码失败。此前报关专项 `customs-current-20260928.json`(543/543)和运输专项 `transport-current-20260929.json`(1036/1036)仍是当前可复用的绿色证据。
当前状态分为三类任务:
1. **规则已简化并确认**:不维护资料类型清单,也不区分逐项责任人;客户或平台只要在资料包上传文件即可。查验、扣货、补资料均由平台人工标记异常,选择预设理由;选择“其他”时填写备注即可,不要求接入短信或自动海关系统。
2. **环境/外部验收**:恢复海外测试域名解析后重新跑 F25-F40;COSCO 官方接口凭据、COSCO 动态页面和 ZIM hCaptcha 仍是外部非阻断项;Android/HBuilderX 真机扫码、弱网和在线草稿仍需现场设备验收。
3. **后续增强**:报关行接收回执/回执轮次和下载凭证仍可增强,但不影响当前两份文件闭环、客户确认、正式申报和报关完成后进入待发区。
4. **费用默认确认**:业务规则已经确认,但代码仍主要完成费用发布/客户确认;`LOADED` 时按已装范围写入 `SYSTEM_AUTO_AT_LOADED`、费用版本、柜次/入仓码和幂等审计的落地实现,仍需单独补齐,不能把 `SENT` 直接当成默认确认。
你当前不需要先操作系统或确认代码。资料上传和异常人工处理规则已经足够继续开发;其余技术修复和重新验收由开发侧继续处理。
## 先锁定的范围
国内货柜履约的物理装柜节点为 `LOADED`。`LOADED` 后先完成退税客户的报关协同,报关完成后进入待发区,再推进船期运输:
1. **报关线**:仅对退税客户通知报关行,收集退税客户资料,发送报关行,接收报关行回执并发客户确认;客户认为不正确时打回、重新上传、重新发送并生成新回执,循环至柜内退税客户均确认;全部确认后,再将退税申报资料提交报关行确认,由报关行正式申报,记录查验、不查验放行或其他海关结果。买单货物不进入这条资料和回执流程。
2. **船期线**:报关完成并进入待发区后,安排拖车、从仓库发运、送港、进港;港口容量不足时记录甩柜和改配船次。甩柜/改配只改变运输船次,不重新处理已完成的报关资料、回执和客户确认;`PORT_RECEIVED` 不等于海运中,只有船舶真实开航后才进入海运节点。
报关完成是进入待发区的前置;进入待发区后才推进船期运输。首期不对接海关单一窗口或报关代理系统:报关行回执以文件上传为主,正式申报由授权人员人工提交,客户确认和海关结果由平台人工记录。
费用确认是并行事实,不阻断排柜、预装、PDA 或装柜。装柜完成后,对应已实装范围若客户仍未确认当前有效且已发布费用版本,系统记录“系统默认确认(装柜完成)”;不伪造客户点击,保留 `SYSTEM_AUTO_AT_LOADED` 来源、费用版本、柜次/入仓码、时间和幂等标识。没有有效费用版本时不得生成零额或伪造确认,须保留费用异常待办。
实际装船、提单、舱单、结关、退税正式资料和船公司节点查询仍属于跨服务或外部业务事实;当前国内货柜链已实现本柜船期编辑、送港、进港和实际开航节点,外部船公司自动查询以及更复杂的提单/舱单凭证继续按独立来源和只读快照接入。若国内页面需要展示,只能消费已确认的跨服务只读快照,并单独定义事件、来源、更新时间和责任边界。
## 入口与权威数据
| 入口 | 本期职责 | 权威数据 | 当前状态 |
|---|---|---|---|
| 客户端“报关资料” | `LOADED` 后查看本企业资料包,上传/替换/补件,查看报关行回执并确认或打回 | Firstleg 报关协同;文件由 File 服务保存 | **已实现:独立入口 + 订单快捷入口** |
| 订单中的“上传资料” | 带订单和入仓码上下文进入同一资料包 | 与独立入口共用 packageId 和接口 | **现有快捷入口** |
| 平台整柜报关工作台 | 按实际装柜清单通知报关行,管理客户资料、回执轮次、全部确认、整柜正式提交和海关结果 | Firstleg 柜级报关、提交批次和结果事实 | **已实现:四态 + 独立正式申报/海关结果投影** |
| 客户端“船期价格” | 查询当前企业可见的有效渠道、参考船期、最晚进仓、参考时效和估价 | 生效价格簿及服务端估价 | **已实现:独立入口** |
| 平台“船期价格表” | 上传、解析、核对、发布公共或客户专属价格簿 | Firstleg 价格簿版本 | **已有平台能力** |
平台端应写“按申报组整理并线下提交”。在跨客户合并规则确认前,默认禁止把不同客户放入同一正式报关单;不得在结论表中把待决规则写成既定能力。
## 当前实现事实
1. 客户端现在同时提供独立“报关资料”入口和订单快捷入口,二者共用同一资料包和版本历史;仅对 `LOADED` 后的退税订单开放,按客户/入仓码收集资料、接收报关行回执、提交客户确认并支持打回重做。资料可上传、替换、改关联、删除并保留版本;每轮发送和回执都留痕,客户确认后才进入该客户的 `CUSTOMER_CONFIRMED`。对应接口和权限见 [customs-v1.yaml](../../baiyue-firstleg/firstleg/src/main/resources/openapi/customs-v1.yaml#L48)。
2. 当前柜级状态为 WAITING_CUSTOMER_DOCUMENTS → READY_TO_START → DECLARING → COMPLETED;客户确认轮次、首次发送批次、整柜正式提交、查验/放行和送港子状态通过独立事实和只读投影承载。资料关联以 loadingPlanId、柜级聚合、客户报关案例和整票入仓码为根。
3. 当前 COMPLETED 会发布报关完成事件并参与待发区门禁。契约将“客户资料确认轮次”“整柜正式提交”“海关查验/放行”分开;报关完成后才允许进入待发区,船期事实独立维护。
4. 全买单柜已有独立的二次确认接口和导出契约;它不创建退税客户资料、回执和确认案例,运输节点仍按装柜、待发区、送港和开船事实推进。
5. 客户端现有价格接口为按起运仓查询渠道,以及按指定渠道估算参考费用。/estimate 只返回基础参考费用,不含复杂附加费和最终结算调整;pricingTaxMode 不等同于订单 taxMode。见 [fba-pricing-v1.yaml](../../baiyue-firstleg/firstleg/src/main/resources/openapi/fba-pricing-v1.yaml#L130)。
6. 原型文档仍有“待原型/部分参考”的历史表述,但当前页面已按现行契约接入;页面范围以客户端路由、平台报关工作台和当前 OpenAPI 为准,不再把原型中的待建入口当作开发缺口。
7. **费用默认确认目前是目标变更,不是现有实现。** 当前装柜完成逻辑只会自动发送/发布费用,不能把 `SENT` 直接当成客户确认;现有费用锁定也主要依赖客户确认时间。实现本轮目标时必须增加确认来源和幂等审计,并改为“客户确认或装柜默认确认 + 已装柜完成后才最终锁定”。部分装载只能确认本次已装范围,余量不能被顺手确认。
8. **本轮报关完成→待发区门禁和船期例外需要保持独立。** 报关完成后才允许进入待发区;`ROLLED_OVER` 只记录新旧船次和运输变更,不回退或重新评估已完成的报关资料、回执和客户确认。
## 报关资料模型
### 0. `LOADED` 后报关完成与待发区
| 线路 | 触发时点 | 顺序 | 结果 |
|---|---|---|---|
| 报关线 | `LOADED` 事件产生后 | 通知报关行 → 收集每个客户资料 → 发报关行 → 接收回执 → 发客户确认 → 打回则重传重发并生成新回执 → 所有客户确认 → 整柜资料交报关行确认 → 正式申报 → 查验/放行 | 客户确认轮次、整柜正式申报、海关结果 |
| 送港线 | 报关完成并进入待发区后 | 安排拖车 → 仓库离开 → 送港 → 进港 → 等待船次;装不下时在原柜船期上人工修改船信息并留痕 | `DEPARTED_WAREHOUSE`、`PORT_RECEIVED`、`ROLLED_OVER`、实际开船 |
报关资料未完成时不得进入待发区;完成报关并进入待发区后才推进送港。已进港也不代表已经进入海运;只有船舶真实开航后,才写入海运起点。
客户确认是每个客户报关案例的完成条件;海关放行是整柜正式申报后的外部结果,不能用上传回执或任意“完成文件”代替。
### 1. 客户报关案例与资料包
报关资料主流程在 `LOADED` 后启动。每个客户/入仓码在本柜建立一个 `customerCustomsCase`,再挂载稳定的 `packageId` 和文件版本。首期不定义文件类型清单和逐项责任人;资料包只需支持文件上传、替换、版本、报关行发送时间、回执文件版本、客户确认/打回人和时间、打回原因、当前 `roundNo`、客户可见范围和审计记录。
资料包不能只关联整票入仓码。已确认支持一单多柜、拆批和父订单—子订单关系,因此每个关联项保存客户、订单、入仓码和装柜明细引用;部分装柜只展示本柜实际箱数并标记线下处理,不在系统内自动做数量分摊。柜次一旦装柜完成不因甩柜改船而变化,受影响案例不能静默重置回执轮次。
### 2. 实际装柜绑定快照
资料包与 loadingPlanId、containerBookingId 的关系应通过绑定记录表达,而不是覆盖原资料包。绑定记录至少保存实际装柜明细引用、实装箱数、客户、订单、入仓码、柜次和绑定版本。`LOADED` 后开始本轮报关时冻结该范围;部分装柜只生成箱数展示和线下处理标记,甩柜改船不使资料绑定和回执轮次失效。
### 3. 申报组与柜级总览
申报组归属一次实际装柜和一次整柜正式提交,记录成员客户案例、合并关系、报关代理、每轮回执、客户确认结果、正式提交时间、正式业务编号、查验/放行结果和异常历史。跨客户合并在业务确认前默认拒绝;若未来开放,必须增加授权、客户可见投影、组成员冻结快照和取消/重组规则。
柜级总览仅供平台使用,汇总实际装柜行、退税/买单行、缺件、提交批次和门禁结果。客户端接口必须按当前企业裁剪返回,不返回同柜其他客户的名称、数量、资料包 ID、申报组 ID 或异常细节。
### 4. 买单、退税和混合柜完成条件
三类柜不能用一条“缺回执即阻断”的规则代替:
| 柜型 | `LOADED` 前 | `LOADED` 后报关线 | 完成条件与开船影响 |
|---|---|---|---|
| 全买单 | 装柜物理门禁独立判断 | 不进入本报关资料、报关行回执和客户确认流程;继续按买单装柜、导出和运输节点处理 | 不创建退税报关案例,不以报关资料或回执作为门禁 |
| 退税柜 | 装柜物理门禁独立判断 | 对每个参与入仓码收集/补件,发送报关行,逐份接收回执并让对应客户确认;打回则重做当前案例 | 所有退税客户案例确认后才允许整柜正式提交;正式申报后的查验/放行单独记录 |
| 混合柜 | 装柜物理门禁独立判断 | 仅退税行建立报关资料和回执确认案例;买单行不进入该流程,仍保留买单装柜和导出事实 | 仅退税客户案例全部确认后才允许提交退税申报批次;不得把买单明细冒充报关确认 |
同一客户多个入仓码可以共享其授权资料;跨客户物理拼柜不等于允许跨客户正式合报。跨客户合并仍默认禁止,必须有独立授权和客户可见隔离契约。
## 状态、事实与门禁
建议把状态拆成独立事实面,页面总状态只做投影:
| 事实面 | 建议状态 | 说明 |
|---|---|---|
| 客户报关案例 | WAITING_DOCUMENTS、SENT_TO_BROKER、RECEIPT_PENDING_CUSTOMER_CONFIRM、CUSTOMER_CONFIRMED、NEEDS_RESUBMIT、INVALIDATED | 每轮 `roundNo` 保存资料版本、发送时间、报关行回执、客户确认/打回原因;回执上传不等于客户确认 |
| 整柜申报批次 | WAITING_ALL_CUSTOMER_CONFIRM、ALL_CUSTOMERS_CONFIRMED、FORMAL_SUBMITTED_TO_BROKER、DECLARED、INSPECTION、NO_INSPECTION、RELEASED、REJECTED | 所有客户案例确认后才允许整柜正式提交;首期由授权人员人工记录报关行确认和海关结果 |
| 送港/船期事实 | PORT_DELIVERY_PENDING、DEPARTED_WAREHOUSE、IN_TRANSIT_TO_PORT、PORT_RECEIVED、ROLLED_OVER、VESSEL_DEPARTED | 与报关案例独立;进港和甩柜不等于海运中,只有真实开船才进入海运节点 |
| 装柜门禁 | PASS/BLOCKED | 只判断是否满足 LOADED 的已确认前置 |
上述是首期状态投影。回执首期以文件为主、客户确认整份回执;正式申报由平台授权人员人工提交并回填结果;查验、扣货、补资料和其他情况均由平台人工点击标记异常、选择理由,选择“其他”时填写备注;异常解除也由平台人工点击处理。实际开航首期人工录入,甩柜/改配人工修改原柜船信息并保留原报关事实,不重新评估申报批次。当前四态不能直接承担新流程;收敛时应明确旧状态的映射和删除时点,不保留双协议。
物理 `LOADED` 门禁必须明确校验以下事实:
1. 真实柜号、预装计划和数量版本完整;
2. PDA 拣货和复核完成,整批提交成功;
3. 空仓、半仓、满仓、锁仓、带锁码照五类证据各有至少一张有效照片,锁码文本已保存;
4. 数量守恒、无未解决 PDA 异常。
`LOADED` 后创建报关案例;报关案例完成整柜正式申报并达到报关完成条件后,才允许进入待发区并创建/推进送港任务。送港任务继续校验装柜完成、真实柜号、订舱/拖车等运输条件。到港后如船舱不足记录 `ROLLED_OVER`;只有实际 `VESSEL_DEPARTED` 才进入海运节点。报关放行、送港和甩柜不能反向作为 `LOADED` 的前置,甩柜也不改变已完成的报关事实。
每个写动作都需要 Idempotency-Key、expectedVersion、规范化请求哈希、乐观锁冲突码、审计事件和结果回放。上传、替换、改关联、补件、审核、提交批次、回执上传和门禁确认不得仅靠前端推进。
## 权限、文件与接口边界
现有报关接口使用 merchant:order:view/edit 和 platform:firstleg:customs:list/manage。新增独立入口前必须确认是复用还是拆分为报关专用权限,并落到客户端路由、导航、Controller、OpenAPI x-permission、IAM 初始化 SQL 和服务端对象级校验:
- 客户查看、上传/替换、补件确认和下载分别校验当前企业、订单/子订单、入仓明细和客户可见标记;不能信任请求中的 tenantId、订单 ID 或入仓码。
- 平台查看、审核/退回、生成提交批次、上传回执和发布结果分别授权;列表权限只包含详情只读,写权限独立。
- File 文件类型、业务 ID、客户归属、版本、冻结和下载审计必须定义。现有 `LOADING_LIST_CUSTOMS_SOURCE`、`LOADING_LIST_CUSTOMS_RECEIPT`、`LOADING_LIST_CUSTOMS_RESULT` 只负责不可变文件对象,不能替代客户案例、提交批次和海关结果对象;正式申报与海关结果的独立接入见[专题设计](../头程到尾程/正式申报与海关结果接入设计.md)。
- File 上传成功但业务写入失败、业务写入成功但 File 失败、替换/作废和重试都要有补偿或可重放规则;不能产生越权文件或孤儿记录。
独立客户列表、详情、待办计数和平台筛选必须补充明确的路径、分页、稳定排序、筛选参数、空态/无权限响应和错误码。不能只写“新增列表”或继续复用单订单查询接口。
## 船期价格接入
### 展示边界
客户页只展示当前企业可见的有效价格簿快照:渠道、起运仓、目的地、pricingTaxMode、计费单位、单价、币种、参考船期、最晚进仓、参考时效、附加费说明、价格簿版本和更新时间。价格簿中的预计船期是参考文本,不是已订舱 ETD、实际开船或到港节点;时区、有效期、来源和过期展示必须明确。
客户专属与公共价格按版本作用域选择:先选择当前企业专属 ACTIVE 版本;只有不存在专属 ACTIVE 版本时才选择公共 ACTIVE 版本,不能按单条费率缺行再逐行回退。页面展示业务版本号或生效时间,不直接把内部 priceBookVersionId 当作用户可见编号。
### 批量估价契约
若要跨渠道列表展示,服务端新增批量估价契约,至少定义:起运仓、目的类型/目的地、渠道候选、重量、体积、pricingTaxMode、版本快照、批量上限、超时、无命中错误、计费量、单位、币种、基础金额、未包含附加费、舍入规则和排序规则。不得由浏览器自行计算或逐渠道扇出。
“价格优选”只有在币种、目的地、税模式、计费口径和附加费范围可比时才允许启用;否则只展示参考结果。订单创建时必须重新校验渠道资格和生效版本,明确旧报价失效、金额变化和重新报价的用户提示,不把客户端显示金额当成最终结算金额。
价格导出如需上线,应另定义客户可见字段、公共/专属价格隔离、导出审计、快照版本、文件保留期限和下载权限;在这些规则确认前不纳入本期上线。
## 实施顺序与进入条件
1. **冻结业务规则**:确认文件可上传即可、回执轮次、打回重做、所有客户确认、整柜正式申报、异常理由/备注、甩柜/改配和跨客户合并;已确认规则以[需求确认表](国内货柜履约需求确认表.md#L24)为准。
2. **先做服务端契约**:完成 customerCustomsCase、资料版本、报关行回执轮次、客户确认、整柜申报批次、送港/进港/甩柜/开船事实、状态投影、权限、幂等、审计、File 类别和初始化 SQL;同步更新 OpenAPI、Gateway、IAM 和相关消费者。
3. **接入客户入口**:独立列表/详情与订单快捷入口共用 packageId;仅在 `LOADED` 后进入本柜报关案例,覆盖资料上传、报关行回执查看、确认、打回、重新上传和新回执版本。
4. **接入平台协同**:`LOADED` 后按最终实装快照通知报关行,逐客户处理资料和回执,全部客户确认后提交整柜资料;平台人工记录正式申报,并通过异常节点选择查验、扣货、补资料或其他理由,必要时填写备注和处理结果。送港线独立接入拖车、进港、甩柜和实际开船。
5. **接入船期价格**:先复用有效价格簿和单渠道参考估价,再实现批量估价;批量列表、排序和导出必须先通过接口和价格可比性评审。
## 已确认的简化规则
| 问题 | 阻断范围 | 需要形成的结论 |
|---|---|---|
| 报关资料上传 | 客户案例、整柜提交 | 不区分文件类型;有文件即可上传、替换和保留版本 |
| 客户确认/打回原因和回执轮次 | 客户案例、整柜提交 | 回执版本、roundNo、确认人、打回重做规则 |
| 海关查验、扣货、补资料和其他异常 | 整柜申报批次、客户展示 | 平台人工标记异常并选择理由;选择“其他”时填写备注,不接短信或自动海关系统 |
| 送港、进港、甩柜、改配船次和实际开船事件 | 待发区、送港线、海运节点 | 事实字段、重试规则、客户通知和船次历史;首期人工录入实际开航,改配人工修改原柜船信息但不改变已完成报关事实 |
| 价格比较、导出、报价有效期和金额变化提示 | 客户报价页、下单 | 统一币种/税模式/附加费和失效处理 |
## 最低验收矩阵
- 客户 A 无法查询、上传、替换或下载客户 B 的资料、回执、价格和导出文件。
- 独立入口与订单快捷入口返回同一 packageId、版本历史和待办结果,不产生双历史。
- 同一幂等键同请求只产生一次记录;同键不同请求、版本冲突、并发换柜和重复回执均返回明确业务错误。
- `LOADED` 后每个客户案例都能经历“资料上传→报关行回执→客户确认”;打回后只重开对应案例,重新上传、重新发送并产生新回执轮次,其他客户历史不被覆盖。
- 所有客户案例均 `CUSTOMER_CONFIRMED` 后,平台才允许生成整柜正式提交;正式提交后分别验收查验、不查验放行和其他海关结果。
- 缺 PDA 结果、缺五类证据、真实柜号或数量不守恒时,`LOADED` 门禁失败;报关完成后才进入待发区,再验收离仓、进港和甩柜;只有真实开船才进入海运节点,甩柜不重做已完成报关。
- 全买单柜、退税柜和混合柜分别验证状态、权限、导出、回执和门禁结果。
- 价格无命中、失效版本、跨渠道批量估价、不同币种/税模式、附加费说明和订单创建重验均有可验证结果。
- 页面覆盖加载、空态、失败、无权限、过期和数据冲突;客户端按 1920×1080、100% 缩放人工验收。
## 接入核对入口
- 客户端订单与现有报关:apps/client-web/src/modules/first-leg/routes.ts、views/FirstLegOrdersView.vue、components/CustomsDocumentsDialog.vue、api/customs.ts。
- 客户端导航和新页面:apps/client-web/src/navigation/clientNavigation.ts 及对应页面注册、权限和 release 配置。
- 平台整柜报关:apps/admin-web/src/modules/container-loading/components/ContainerCustomsPanel.vue、api/platformContainerCustoms.ts。
- 后端报关:`../baiyue-firstleg/firstleg/src/main/java/com/baiyue/firstleg/customs/container/`、[customs-v1.yaml](../../baiyue-firstleg/firstleg/src/main/resources/openapi/customs-v1.yaml#L1)、`phase3-container-customs-schema.sql`。
- 报价:`../apps/client-web/src/modules/first-leg/api/firstLeg.ts`、`../apps/admin-web/src/modules/fba-pricing/carrier-rates/`、[fba-pricing-v1.yaml](../../baiyue-firstleg/firstleg/src/main/resources/openapi/fba-pricing-v1.yaml#L130)。
- 国内边界、状态和门禁:[国内货柜履约 README](README.md:3)、[国内货柜履约开发规划(归档)](归档/国内货柜履约开发规划.md:166)、[国内货柜履约需求确认表](国内货柜履约需求确认表.md:24)。
@@ -0,0 +1,671 @@
# 船期日历功能规划
> 文档状态:首版开发规划;2026-09-27 复核补充了数据闭环规则。本文是开发依据,不是代码完成或上线验收证明。
> 规划对象:Admin「国内头程 → 船期管理」独立船期日历。
> 目标:支持人工维护渠道和船期规律,按周或单次生成具体船期,并按渠道/船期查看收货体积。
> **当前展示版范围已重新冻结:只做船期维护和只读展示,不做自动归班、不消费预报、不改写收货审核、不自动改绑,也不改变现有智能排柜流程。** 首版只需要让管理人员看到每个航次的已收/预计货量、可用容量、按柜型初算的建议柜数、已订柜和待补柜,并据此人工判断是否合并到其他船。后续若要增加货物归班,再单独立项评审。第 15.8 节覆盖本文此前关于自动归班和异常改配的旧口径。
> **展示版统计口径**:每个船期按“收货仓 + 渠道 + 起运港 + 目的港”展示;已收使用现有收货/测量结果,预计量使用现有入仓和智能排柜可读数据;不创建或变更船期归班事实。收货截止时间只用于标记“截止前参考量/截止后风险”,不触发自动分配。订柜数只做只读初算,最终以现有智能排柜和人工确认结果为准。
## 1. 输入来源与现状边界
本规划以当前需求描述为业务输入,以用户提供的截图作为页面布局参考。截图中的红框、日期、船名、航次、数量和示例数据均不构成额外指令,也不代表需要沿用的真实业务数据。
仓库当前已有 `apps/admin-web/src/modules/port-schedules/` 和 Firstleg 的 `portschedule` 服务。现有“港务船期”记录绑定客户、订舱或柜次,主要保存船公司/码头/API 的船期观测、过期时间和海运节点查询结果;对应表为 `fl_port_schedule`。它服务于已存在的订舱和货柜履约链路,不直接承载本规划的排班模板、周循环生成或收货量统计。现有 `port-schedules/routes.ts` 也不是本规划新页面的正式入口;新日历应作为独立 Admin 页面、路由和权限接入,不能把现有隐藏/嵌入式船期组件直接改成排班管理页。
本功能建议新增“船期计划”域,与现有港务船期并列:
- 船期计划是运营人员提前安排“哪个渠道哪天开哪班船”,可以没有订舱和真实柜次;价格簿中的参考船期、最晚进仓和参考时效也不能直接当作该计划的实际开船事实。
- 港务船期是某个订舱/柜次的外部船期事实或人工观测,继续按现有接口和状态机运行。
- V1 先建立“计划实例 ↔ RELEASED 订舱”的最小关联用于订柜统计;真实柜次、港务船期和海运节点的完整关联后置,不能用计划数据覆盖已产生的运输事实。
本规划默认这是平台内部运营日历:渠道主数据平台级维护,模板和实例至少按收货仓隔离,实收汇总按“收货仓 + 渠道 + 收货日期”聚合并对平台运营人员可见。V1 不按客户拆分船期计划;如果实际业务存在客户专属船期或价格承诺,必须在开发前把客户作为模板、实例、查询和权限的正式维度,不能在上线后再用名称筛选补救。
## 2. 要解决的问题
运营人员需要在一个页面完成以下工作:
1. 维护当前可售或可安排的运输渠道,例如“MATSON / 美森”。
2. 配置固定每周哪几天有船,也可以只添加一班临时船期。
3. 根据开船时间和渠道的提前收货天数,自动算出收货截止时间。
4. 在月历上看到每天有几班船,以及每个渠道已收多少立方米、预计有多少货、容量还剩多少和建议订几个柜。
5. 对已生成的具体船期进行编辑、取消、复制和查看关联货量,并保留变更历史。
## 3. 建议的 V1 范围
### 3.1 本轮纳入
- 船期渠道的新增、编辑、启用/停用。
- 一次性船期的手工添加。
- 每周模板的配置,按指定周几生成未来具体船期。
- 每条模板/实例必填收货仓;首版不使用“全部仓”这种模糊范围。
- 开船时间、预计到港时间、收货截止时间和容量的维护与计算。
- 月历视图、月份切换、按收货仓/起运港/渠道/船名航次筛选。
- 选中日期的船期详情和渠道体积汇总。
- 船期实例的人工编辑、取消、复制下一班和变更历史。
- 货量按收货仓与渠道只读展示已收实测体积、预计体积、截止前参考量、截止后风险量、已订柜和待补柜;不产生归班事实、不提供货量改绑。
- 按现有柜型目录计算只读的“建议订柜数”,不直接创建正式订舱或货柜。
### 3.2 暂不纳入
- 船公司官网或第三方 API 自动抓取船期。
- 自动订舱、舱位分配、放舱、拖车、报关和实际出仓状态推进。
- 自动归班、预报消费、实收批次绑定、取消后自动改配和异常重新安排。
- 在收货审核、测量审核或智能排柜流程中增加回调、写入或阻断。
- 复杂的价格计算、客户报价和财务结算。
- 以计划日历替代现有订舱/柜次船期事实。
- 在没有业务确认前自动修改历史入仓数据或批量回溯全部历史货量。
- 复杂节假日规则、跨时区排班和通知中心;这些作为后续扩展点保留。
- 容量预占、超容强制处理、正常货量的批量改绑和跨客户拆分;异常货的最小重新安排按第 6.10 节纳入 V1。
## 4. 核心概念与生命周期
| 对象 | 作用 | 关键生命周期 |
| --- | --- | --- |
| 渠道 Channel | 表示一类运输服务,如 MATSON / 美森 | `ACTIVE`、`INACTIVE` |
| 船期模板 Schedule Template | 描述每周固定规律;固定添加一班直接创建实例,不再套一层单次模板 | `DRAFT`、`ACTIVE`、`INACTIVE` |
| 船期实例 Sailing | 某一具体日期的某一班船,是日历和货量统计的主体 | `DRAFT`、`OPEN`、`CLOSED`、`DEPARTED`、`CANCELLED`、`COMPLETED` |
| 归班事实 Sailing Assignment | 保存预计量/收货批次与船期的自动归班结果及历史 | `FORECAST_MATCHED`、`RECEIVED`、`LATE`、`UNMATCHED`、`SUPERSEDED` |
| 订舱关联 Sailing Booking Link | 将已放舱订舱的柜型需求关联到计划船期,用于订柜建议 | `ACTIVE`、`REVOKED` |
模板生成实例后,实例保存自己的船名、航次、港口、截仓时间和容量快照。以后修改模板不回写已经生成、已编辑或已关联货量的实例;需要调整时由运营人员编辑实例或重新生成未落地的未来实例。
## 5. 页面信息架构
### 5.1 顶部筛选和操作区
- 月份:默认当前月,提供上月、下月和“今天”。
- 收货仓:按仓库筛选;船期计划至少要绑定一个收货仓,不能只靠渠道和起运港推断。
- 出发港:按港口代码和名称筛选。
- 船期渠道:按启用渠道筛选,停用渠道仍可用于查询历史。
- 船名/航次:模糊搜索。
- 状态:全部、可收货、已截止、已取消、已开船、已完成。
- 归班状态:全部、预计可赶船、已收、晚到、未安排;用于把“漏排或赶不上”的货量变成运营待办。
- 操作:`新增船期`、`渠道与模板管理`。
另设“待安排/异常货量”入口,集中展示当前权限和仓库/渠道范围内仍待处理的货物,显示实际收货日或预计到仓日、等待天数及异常原因。未安排记录没有开船日期,不强行放进某个开船月,也不混入月历主合计;切换月份不使这些待办消失。
筛选条件应由服务端参与查询,不能先拉取整月全部记录后在浏览器本地拼装统计。
### 5.2 月历区
- 周一至周日为列,显示跨月日期但以浅色区分。
- 每个日期格显示当天船期数量和航线摘要。
- 摘要优先显示渠道名和收货体积,例如“美森 120 m³ / 200 m³”;渠道较多时显示前几项并提供“更多”。
- 当前日期、选中日期、已截止日期、容量超限日期分别使用清晰但不依赖颜色的标签/图标表达。
- 点击日期后,右侧详情区同步刷新;点击船期卡片可直接进入实例详情。
### 5.3 选中日期详情区
每个船期卡片至少展示:
- 渠道、船名、航次和船期业务编号。
- 起运港 → 目的港。
- 预计开船、预计到港、最终收货截止时间。
- 已收总量、本船可赶实收、预计可赶、晚到量、已订柜数、建议订柜数和待补柜数;各指标按第 6.6 节计算,已收总量不能直接当作可赶量。班次容量上限和剩余体积仅在已配置班次容量时展示,V1 不因容量不足自动改绑或强制拦截。
- 当前状态和风险提示:已过截止、接近满舱、超过容量、已取消。
- `编辑`、`复制为下一班`、`取消船期`、`查看货量明细`。
删除仅适用于未开船、未关联任何货量的草稿/实例;有货量或已产生履约事实的实例只能取消,不能物理删除。
### 5.4 新增/编辑弹窗
弹窗提供两个明确入口:
**按周添加**
- 选择渠道、起运港、目的港。
- 选择收货仓;同一渠道可按不同收货仓配置不同截止规则。
- 选择一个或多个周几。
- 选择开船时间、航程天数或预计到港时间。
- 设置提前收货天数、有效起止日期和默认容量。
- 设置船名固定值或船名规则;设置航次生成规则。
- 选择未来生成范围(建议 4 / 8 / 12 周)。
- 先预览将生成的实例,再确认批量生成。
**固定添加一个**
- 直接填写开船日期时间、船名、航次、起运港、目的港。
- 填写或确认收货截止时间、预计到港时间、容量。
- 保存为一条独立实例,可选关联一个模板作为来源。
周模板中的船名是生成实例的默认值;船司确认后可逐班编辑船名、航次和截止时间。当前展示版编辑实例时保留已保存的绝对截止时间,切换到“按开船前 N 天”后才重新计算;规则快照和覆盖原因待后端契约补齐后再做完整留痕。
### 5.5 区间汇总
月历上方建议提供当前筛选范围的渠道汇总卡:已收实测 CBM、预计可赶 CBM、风险/未安排 CBM、已订柜数、建议订柜数、待补柜数、晚到批次数和船期数量。V1 卡片固定标明“按开船月”,收货月仅在详情和后续报表中使用;多班同渠道同日时仍按船期实例分开,不能只显示一个渠道总数。
## 6. 业务规则
### 6.1 收货截止时间
首版把“收货截止时间”正式命名为**最晚到仓时间 `warehouseCutoffAt`**,表示货物最晚什么时候到达我司收货仓,和船公司的截单、截关、截港时间分开保存。默认公式:
```text
最晚到仓日期 = 预计开船本地日期 - 提前收货天数
最晚到仓时间 = 收货仓截收时刻
```
- 计算使用仓库业务时区,V1 默认 `Asia/Shanghai`;接口统一传 ISO 8601 时间。
- 计划截止计算只基于实例保存的计划 `etdAt`;后续实际开船时间属于订舱/船节点事实,不反向改写已经产生的收货归班。
- “提前 N 天”首版固定按自然日计算;工作日和节假日规则放到后续工作日历阶段。
- 若收货仓暂未配置截收时刻,首版按 18:00 默认并记录规则来源,不能由前端使用浏览器本地时刻隐式补齐。
- 首版默认使用 `3` 个自然日和 `18:00`;这个默认值不是从截图推断的,而是初始运营参数,后续按试运行数据校准。
- 单班页面允许选择提前 2/3/4 个自然日或自定义本班截止时间;当前展示版保存计算后的最终 `warehouseCutoffAt`,规则快照与覆盖原因审计字段待后端契约补齐后再启用,页面不宣称已完成服务端留痕。
- 最终截止时间必须严格早于开船时间;开船时间、截止时间和容量的校验由服务端最终执行。
- 时间边界统一到毫秒:实际/预计到仓时间等于截止时间视为准时;当前时间大于截止时间才停止新归班,不能由不同页面采用不同的 `<`、`<=` 判断。建议值由服务端计算并返回,前端只展示。
- 是否跳过周末/节假日、节假日向前顺延几天,需要在产品确认后接入工作日历,不能由前端自行猜测。
### 6.2 每周模板生成
- 按模板有效期和周几生成具体日期,跨月日期仍属于实例,查询某月时按开船时间落入月份返回。
- V1 采用“预览后手工确认生成”,不做后台滚动生成;页面默认未来 8 周,并提供未来 4/8/12 周快捷范围,生成范围由操作人确认后提交。
- 生成请求必须幂等;同一模板、日期、航次规则只能生成一条有效实例。
- 已编辑、已关联货量、已关闭、已开船或已完成的实例不被重新生成覆盖。
- 发现相同日期/航次冲突时返回冲突清单,让用户选择跳过或进入实例处理,不能静默覆盖。
- 模板停用只阻止未来生成,不删除历史实例。
- V1 如遇某周停航或临时改船,允许在生成预览中跳过日期或生成后取消实例;节假日批量例外规则放到后续阶段。
- 去重和冲突检查必须跨模板执行,至少按“收货仓 + 渠道代码 + ETD 本地日期时间 + 航次”判断,不能只用 `template_id + date` 作为唯一键。
- 同一收货仓、渠道、起运港和目的港下,若多班船的 ETD 相同,V1 按不可变的 `sailing_no` 升序确定唯一归班;复杂的运营优先级后置。
### 6.3 航次号和船名
V1 支持固定值和“前缀 + ETD 本地日期”两种航次生成规则;每个生成实例允许人工覆盖航次。顺序号和按船名递增规则后置,避免首版因船公司编号规则不同而误生成正式航次。
业务唯一性首版约束“收货仓 + 渠道代码 + 起运港 + 目的港 + ETD 本地日期时间 + 航次”;同一航次跨不同起运港可以存在,但不能在同一组合内重复。`sailing_no` 在实例创建时生成后保持不变,用于同一 ETD 的确定性排序;展示给用户的业务编号应为船期编号、船名和航次,不能回退显示数据库 ID。
### 6.4 可赶船判断和人工改绑
默认推荐某一入仓记录时,只允许候选实例同时满足:
- 渠道、起运港和目的港匹配。
- 状态为 `OPEN`,且当前时间未超过最终收货截止时间。
- 后续启用容量控制时再校验未超过容量;V1 只展示已配置容量和超量提示,不因容量字段缺失阻断归班。无上限实例可明确标记为“不限舱位”。
- 按“最早可开船”或产品确认的优先规则排序。
超过截止时间时不能自动分配到该船期;容量不足在 V1 只显示明确预警,不阻断自动归班,也不能把预警状态伪装成已锁定舱位。任何已关闭、已取消或已开船的船期都不能作为新的自动归班候选。人工改绑必须记录操作者、原船期、新船期、时间和原因。
建议把“预计归班”和“实际收货统计”分成两条事实:
- 预计归班可使用入仓单的 `expectedArrivalAt`,只有预计到仓时间早于或等于最终截止时间,才标记为“预计可赶船”。没有预计到仓时间的记录进入“待确认”,不能凭渠道名称或创建时间猜测。
- 实际统计使用已确认的实际收货时间和审核后的实测体积。已有计划归班的货实际到仓晚于截止时,保留原计划并标记“晚到风险”,不能自动塞到下一班。首次形成实收事实且从未归班的货,若仓库、正式渠道和航线明确,可首次自动选择仍开放且未过截止的最早匹配船期,同时校验实际到仓时间不晚于该船截止;无候选或资料不全则写入“未安排”。因取消、晚到而进入未安排的货不属于“从未归班”,须走第 6.10 节。
- 同一收货批次只能有一个有效计划归班。自动匹配以收货仓、渠道、港口和最早可赶上的有效实例为条件;同一时间存在多班时,必须有固定排序规则。
- 归班在入仓计划审核、预计到仓时间/渠道/仓库变化或实际收货确认时重新计算;船期取消时只新增一条 `UNMATCHED` 变更记录并标记待人工处理,不自动塞入下一班。船期仍为 `OPEN` 且尚未达到最终收货截止时间、没有锁班/订舱事实时允许动态重算。船期达到截止时间后冻结当前归班,即使实例仍显示为 `OPEN` 也不再自动换到下一班;截止前尚未匹配的对象才继续寻找后续可赶船。运营确认订舱、船期进入 `CLOSED` 或船期取消后的改配必须产生新的人工或明确改配记录。
建议的状态落库规则是:预计匹配但尚未收货为 `FORECAST_MATCHED`;实际收货时间不晚于截止且有审核实测体积为 `RECEIVED`;实际收货晚于截止仍沿用原计划为 `LATE`;没有可解释的计划归班为 `UNMATCHED`;重新计算后被新结果替代的旧记录为 `SUPERSEDED`。这些状态首版必须持久化,详情中追溯匹配规则、时间、来源和被替代关系。
首版自动归班采用“写入事实 + 版本化重算”:
- 预计匹配、实际收货、晚到和未安排都写入归班事实,不能只在查询时临时计算。
- 船期仍为 `OPEN` 且未锁班时,重新计算不覆盖旧记录,而是将旧记录标记 `SUPERSEDED` 并写入新版本。
- 船期进入 `CLOSED` 或已确认订舱后,原归班结果保留;取消、甩柜或改配只新增变更记录,不静默改写历史。
- V1 仅开放第 6.10 节的异常重新安排,来源记录为 `MANUAL`;正常货量的批量改绑、拆分分配和强制赶船后置。
- 冻结的是船期归属,不是收货事实的数值。冻结后最终审核、复测、冲正仍更新事实版本及其统计值;原归属保留,不因数值变化自动换船。
### 6.5 货量统计
V1 建议至少将“已收体积”和“预计体积”分开;“预占体积”只有在确认需要锁定容量后再启用:
- **已收体积**:入仓事实已达到产品确认的可计入状态,并有有效体积。
- **预计体积**:按预计归班的未收货量单独展示,不直接计入“已收体积”,也不自动扣减容量,除非产品确认要按预计量锁舱。
- **预占体积**:已明确锁定该船期但尚未形成收货事实的货量;V1 若不做预占则固定为 0。
- **剩余体积**:配置容量上限时按 `容量上限 - 已收体积 - 预占体积` 计算;V1 未启用预占时预占值为 0,预计体积不扣减剩余容量;结果不得小于 0,无上限显示“—”。
体积字段必须统一单位为 m³,并保存统计快照时间。V1 只统计明确达到“已收货”状态、且有正数 `actualVolumeCbm` 的收货批次;实测体积是后续作业的权威输入,申报体积仅作对比,计费体积不能冒充“已收体积”。当前 `inboundedAt` 会在多个入库流程节点写入,不能单独视为最终收货事实;V1 必须新增或正式暴露稳定的收货批次事实,不能把 `inboundedAt` 作为替代。取消、草稿、作废或不符合统计口径的记录不计入已收体积。拆批、复测和冲正均按收货批次版本守恒。
### 6.5.1 V1 数据来源契约(必须一并实现)
当前入仓模型已经有 `warehouseId`、`channelCode`、`expectedArrivalAt`、`actualVolumeCbm` 和测量审核状态,但没有稳定的收货批次 ID、实际收货时间和可靠的未收预计 CBM;现有 `originalVolumeCbm` 是客户申报值,不能作为预计可赶体积。首版必须补齐下面两类事实,不能在页面层临时拼接:
| 事实 | V1 必须提供的字段 | 统计和归班规则 |
| --- | --- | --- |
| 收货批次事实 `ReceiptBatchFact` | `receiptBatchId`、`inboundId`、`receivingWarehouseId`、`channelCode`、起运港/目的港快照、`receivedAt`、`actualVolumeCbm`、最终测量批次 ID、审核状态、冲正/作废状态 | 仅 `RECEIVED/APPROVED` 且实测 CBM 大于 0 的批次计入已收;复测替换同一批次最新有效值,冲正/作废不重复计入 |
| 未收货量预报 `InboundVolumeForecast` | `forecastId`、`inboundId` 或可收货批次键、收货仓/渠道/起运港/目的港、`expectedArrivalAt`、`forecastVolumeCbm`、来源、有效状态、版本和更新时间 | 只有有效状态、预计体积大于 0 且有 ETA 的预报可计入预计可赶量;不得使用 `originalVolumeCbm`、申报箱数或计费体积代替 |
补充规则:
- 当前系统没有上述稳定事实的部分,V1 必须由 Firstleg 提供正式的收货批次和货量预报服务事实;页面不直接读取入仓单分页拼装。没有可靠预报时允许只显示已收和风险,但应显示“未提供有效预报”及缺资料票数,不能把未知量写成“预计无货”。数据生产入口按第 6.5.2 节落地。
- 预报和实收按明确的预报批次关联,不以同一 `inboundId` 就认定整票预报已收完。实收只替换其明确对应的预计批次;未到货部分保留独立有效预报,禁止用实测 CBM 直接减整票预计 CBM。具体拆批与复测规则见第 6.5.2 节。
- 航线匹配优先使用入仓/预报事实中的起运港和目的港;事实缺失时,仅当启用渠道存在唯一的默认起运港/目的港映射,才使用该映射并保存 `route_source=CHANNEL_DEFAULT`。渠道没有唯一默认航线时进入 `UNMATCHED`/风险,不按目的仓名称或自由文本猜测。
- 一票分批到仓时按批次统计;复测、冲正和作废必须以版本或状态替换旧值,并保留审计历史。
- 收货仓、渠道或航线缺失时,批次/预报进入 `UNMATCHED` 或风险清单,不得按渠道名称、订单创建时间或目的地名称猜测。
日历汇总应与右侧详情使用同一服务端统计口径,避免页面格子和详情卡片出现不同数字。建议由服务端按收货仓、渠道、船期、收货日聚合后一次返回;前端不得跨分页拉取入仓单再自行求和。超过容量时返回明确的 `overCapacity=true`,前端只负责展示。月历按开船日期展示班次,详情中应能展开实际收货日期和未安排/晚到记录,避免把“收货发生日”和“船期开船日”混为一个日期。
日期维度固定为两种:月历落格使用 `etdAt` 的本地日期;已收体积明细保留收货批次的 `receivedAt` 日期。V1 月历默认按“开船月”汇总,并将归属该船期的已收实测体积展示在对应开船日;收货月只用于详情展开和后续报表,不参与首版月历主合计。没有稳定 `receivedAt` 的批次只能进入风险/未安排,不能回退使用 `inboundedAt`。月历主合计排除已取消实例;取消实例仍可查历史快照,当前货量进入独立异常待办,重新安排后只计入目标实例,不能在两班重复相加。
### 6.5.2 事实产生、分批收货与预报替换
- **实际收货来源**:仓库完成一批到货确认时生成稳定收货批次业务键,记录真实 `receivedAt`、仓库和对应箱/件范围;最终测量审核通过后,该批次的实测体积才能计入已收。到货确认和最终审核是两个独立条件,审核操作时间不能冒充实际到仓时间。到货待审核单列票数;体积未知显示“待测量”,不补成 0 m³。
- **未收预报来源**:V1 推荐由运营在入仓详情的“货量预报”区域维护预计批次、预计到仓时间、预计 CBM 和航线,Firstleg 保存来源、录入人及版本;更新/作废预报沿用入仓写权限,服务端核验仓库范围。日历消费这些正式事实。客户申报值可作录入参考,但不得未经运营确认直接成为有效预报。
- **分批规则**:一条有效预报表示一批可对应收货的货物;部分到仓前或确认到仓时,将其拆成“本次到货预报部分”和“剩余未到货部分”,子批次保留父预报键、各自预计 CBM 和预计到仓时间。拆分必须显式确认且预计量合计等于拆分前预计量;修订预计总量则另存一个有原因的新版本。
- **替换规则**:本次到货批次一经确认,就停止把该部分计为未收预报;尚未测量审核时归入“已到待审核”,审核通过后用该批的实际体积替换。剩余批次继续按自己的预计体积统计。复测只更新对应实收批次,不能改变其他未到货批次的预计量。
- **无法对应**:实收与预报无法确认对应关系时,相关预计量暂列“待核对”,不与可能重复的实收量一起计入可赶总量;展示缺口原因,运营补齐关系后再恢复。不得凭实测体积相近自动抵消。
- **首版批次关联入口**:审核事件若能携带 `SAILING_FORECAST:<forecastKey>`,服务端只消费该预报批次;多条有效预报且事件没有明确批次键时,实收保持 `UNMATCHED`/待核对,不自动按相近体积抵销。运营可通过预报维护接口显式绑定实收批次、修订预报或作废预报,所有动作均追加版本并保留原记录。
- **事件与版本**:到货、审核、预报修订/拆分、冲正和作废均带稳定业务键及版本;同一事件重复到达不重复记量。来源版本更新与归班更新必须具备重试及对账机制,返回事实版本、归班版本和计算时间,不能只声明建了四张表就认为数据链路完成。
示例:整票预计 100 m³,先拆成本批预计 40、后批预计 60。本批实际到货审核后为 45,则“已收 45 + 未收预计 60 = 可赶 105”;复测为 43 后变成 103。不能用 `100 - 45` 把后批预计改成 55。
### 6.6 订柜数量建议
订柜数量是只读的运营建议,不是正式订舱或货柜创建。首版按以下口径展示:
```text
本船可赶实收 CBM = 当前有效归班为 RECEIVED 的审核实测 CBM
可赶总 CBM = 本船可赶实收 CBM + 有效未收预计可赶 CBM
已收口径建议柜数 = 向上取整(本船可赶实收 CBM / 规划装载容量)
建议订柜数 = 向上取整(可赶总 CBM / 规划装载容量)
已订规划容量 = 求和(每个有效订舱需求的柜数 × 该柜型规划装载容量)
待补 CBM = max(0, 可赶总 CBM - 已订规划容量)
待补柜数(某柜型方案) = 向上取整(待补 CBM / 该方案柜型规划装载容量)
```
- “有效预计 CBM”只取有明确预计到仓时间、渠道/仓库/航线匹配且不晚于最晚到仓时间的有效入仓计划;没有 ETA 的货列为风险,不直接导致多订柜。
- `LATE` 仍保留在该船历史和已收总量中,但不计入本船可赶实收或订柜建议。已收总量与可赶量是不同指标,不要求相等。
- 超过截止但尚无到货确认的原预报,保留原归属并标为“到仓待核实”,退出有效预计可赶量;实际到货事实到达后依据真实到仓时间判为准时或晚到。不得仅凭“当前时间已过截止”把所有未审核批次判成晚到。
- `规划装载容量`、柜型、重量和装载约束复用现有统一柜型目录和智能排柜规则,不在船期日历中另写一套容量或利用率。未选择柜型时,按 40GP/40HQ/45HQ 分别展示方案,不能给出无条件的单一柜数。
- 已订柜型混合时,展示各柜型数量及合计柜数,先按各自规划容量折算已订容量再计算待补量;不能拿“已订 1 个小柜”直接抵掉“建议 1 个大柜”。柜型容量缺失时待补数显示“待核实”,不默认为 0。
- 班次容量上限只触发超量预警,不用它截断可赶总量。例如可赶 150 m³、班次上限 100 m³,建议仍按 150 m³ 计算,并标明超出 50 m³;不能少显示所需柜数。
- 各柜型方案表示“如果待补量全部采用该柜型”的体积初算,未执行重量、混装及实际摆放优化;页面不用“必须订柜数”表示已经确认的订舱指令。
- 页面必须标注“按体积初算,最终以智能排柜/人工确认结果为准”;重量、箱数、货物混装限制或数据缺失会使结果进入风险提示。
- 已订柜数只读取 V1 计划船期-订舱关联下的有效 `RELEASED` 订舱需求;日历只保存建议计算的输入、规则版本、计算时间和结果快照,不直接生成正式柜次。
### 6.7 容量提示
- 0%~80%:正常。
- 80%~100%:接近满舱提示。
- 大于 100%:超容量提示;V1 不自动阻断只读汇总,也不提供绕过容量的强制关联。异常重新安排仍须满足目标船期状态、截止时间和履约锁定校验。
- 无容量上限:展示“—”或“不限”,不参与百分比计算。
### 6.8 船期实例状态转换
建议只允许以下状态转换:
```text
DRAFT → OPEN → CLOSED → DEPARTED → COMPLETED
└──────────────→ CANCELLED
OPEN → CANCELLED
CLOSED → CANCELLED(尚未开船;必须确认影响)
```
`CLOSED` 表示停止收货,`DEPARTED`/`COMPLETED` 表示计划记录的运营状态,不得代替现有订舱、装柜或实际船节点事实。实例一旦有有效收货或预占记录,不能回到 `DRAFT`,取消后仍保留货量关联和审计历史。
建议 `OPEN → CLOSED` 由服务端根据最终截止时间自动生效,页面只展示结果;`CLOSED` 不因刷新或修改筛选重新打开。`DEPARTED`、`COMPLETED` 在 V1 仅允许明确的运营动作或后续已确认事实推进,不能由“预计开船时间已到”直接推断。
### 6.9 停用、取消和甩柜
- 渠道停用只阻止新模板和新实例生成;已经生成且仍为 `OPEN` 的实例默认继续有效,是否批量关闭必须由运营人员明确操作。
- 取消实例前必须展示影响范围:预计归班量、已收量、预占量和已关联订舱/柜次。已有已收量的实例只能取消或进入改配流程,不能删除。
- 取消后,将原有效归班标记 `SUPERSEDED`,新增 `UNMATCHED` 版本并保存原船期及 `reason=CANCELLED`,展示为“未安排/待人工处理”;不自动把货量塞进下一班。新版本保留事实引用,原版本可追溯,不原地覆盖历史。
- 同一取消操作将有效订舱关联改为 `REVOKED`,保留历史快照;不自动作废、重开或修改正式订舱。关联解除后当前订柜统计重新计算,正式订舱是否改船由已有订舱流程处理。
- 甩柜/改配时保留原实例、原归班和实际收货事实,新增目标实例关联;不能回写或覆盖现有港务船期、订舱资料或报关事实。
### 6.10 V1 受限的异常重新安排
这是本轮推荐的范围补充,解决“异常已展示,但首版没有办法处理”的缺口。只允许处理未安排、晚到或因船期取消而待处理的货,正常批次批量改绑仍后置。
1. 运营在异常待办选择货物,查看原船期、当前事实版本、原因及匹配候选;选择目标并填写原因后确认,保存前先显示两班的货量变化。
2. 目标须仓库、正式渠道、港口相符,状态 `OPEN` 且当前未过截止;预报另核验预计到仓时间,实收另核验真实到仓时间。V1 不提供绕过截止、强行修改实收时间或跨仓挪量的入口。
3. 服务端核验独立异常安排权限、当前归班版本及目标船期版本;原有效版本转 `SUPERSEDED`,新版本写 `MANUAL`,保留原/新船期、操作者、时间和原因。并发重复确认只能成功一次。
4. 货物如已绑定真实柜次、预装或装柜履约,先阻止在日历直接改配,并指向既有履约流程;不得通过改日历归班绕过实物锁定。无符合条件的目标时继续待安排,可先新增临时船期。
5. 归班重新安排不自动转移订舱关联;目标班的已订柜仍只来自重新校验后建立的有效订舱关联。
## 7. 建议数据模型
以下为规划字段,具体命名应在接口和 SQL 评审时统一。
### 7.1 `fl_sailing_channel`
| 字段 | 说明 |
| --- | --- |
| `id` | 渠道业务主键 |
| `channel_code` | 稳定渠道代码;固定渠道可映射现有渠道目录,自定义渠道也必须先建立稳定代码。现有装柜的九类渠道分组只作为兼容映射,不能把枚举写死为日历渠道全集 |
| `channel_name` | 渠道名称,如 MATSON / 美森 |
| `source_type` | `CATALOG`(复用现有物流渠道)或 `SCHEDULE_ONLY`(仅用于排班,尚未映射为可订舱渠道) |
| `mapped_channel_code` | 自定义排班渠道对应的正式物流渠道代码,可为空;为空时不能被订舱/价格接口当作正式渠道 |
| `default_departure_port_code` | 默认起运港,可被模板覆盖 |
| `default_destination_port_code` | 默认目的港,可被模板覆盖 |
| `default_cutoff_days` | 默认提前收货天数 |
| `status` | `ACTIVE` / `INACTIVE` |
| `remark` | 备注 |
| `created_at` / `updated_at` | 审计时间 |
标准渠道优先复用现有仓库范围内的 ACTIVE 物流渠道和稳定 `channelCode`,不能只保存一个自由文本名称。自定义排班渠道必须通过 `SCHEDULE_ONLY` 明确标记,后续若要用于订舱或报价,先完成正式渠道映射。渠道停用不影响历史实例和历史统计;停用后不能新建模板或自动生成未来实例。
### 7.2 `fl_sailing_template`
| 字段 | 说明 |
| --- | --- |
| `template_no` | 模板业务编号 |
| `channel_id` | 所属渠道 |
| `receiving_warehouse_id` | 收货仓;截止规则和可赶船判断的范围键 |
| `template_type` | V1 固定为 `WEEKLY` |
| `weekdays` | 周一至周日的选中集合 |
| `effective_from` / `effective_to` | 规则有效期 |
| `departure_time` | 开船本地时间 |
| `voyage_rule` | 船名/航次生成规则快照 |
| `transit_days` 或 `eta_time` | 预计到港计算依据 |
| `cutoff_days` | 模板级提前收货天数 |
| `cutoff_local_time` | 收货仓默认截收时刻,可被实例覆盖 |
| `default_capacity_cbm` | 可选的班次计划容量;不替代统一柜型目录的柜容 |
| `status` | `DRAFT` / `ACTIVE` / `INACTIVE` |
### 7.3 `fl_sailing`
| 字段 | 说明 |
| --- | --- |
| `sailing_no` | 船期实例业务编号 |
| `template_id` | 来源模板,可为空(独立单次船期) |
| `channel_id` | 渠道快照引用 |
| `channel_code_snapshot` / `channel_name_snapshot` | 生成时的渠道编码和名称快照 |
| `receiving_warehouse_id` | 收货仓 |
| `departure_port_code` / `destination_port_code` | 港口快照 |
| `vessel_name` / `voyage_no` | 船名和航次 |
| `etd_at` / `eta_at` | 预计开船、预计到港 |
| `suggested_cutoff_at` | 计算出的建议截止时间 |
| `cutoff_at` | 最终收货截止时间 |
| `cutoff_override` / `cutoff_override_reason` | 是否人工覆盖及原因 |
| `cutoff_rule_version` | 计算时使用的时区、自然日/工作日和截收时刻规则版本 |
| `capacity_cbm` | 可选的班次计划容量上限;空值表示不做班次容量提示,不替代统一柜型目录的柜容 |
| `container_type_code` | 默认柜型;为空时按可用柜型分别给出建议 |
| `status` | 实例生命周期状态 |
| `generated_key` | 模板生成幂等键 |
| `version` | 乐观锁版本 |
| `created_at` / `updated_at` | 审计时间 |
不建议把已收体积、剩余体积作为可直接修改的主表字段;它们应由关联事实聚合,必要时做带统计时间的服务端快照。
### 7.4 `fl_sailing_assignment`(V1 自动归班;V1 受限异常重新安排)
V1 必须由服务端持久化自动归班结果;常规人工改绑、拆分分配和预占仍放到 Phase 2,第 6.10 节的异常重新安排除外。归班对象以收货批次或货量预报为最小粒度,不以整张订单或整张入仓单代替。`sailing_id` 可以为空,表示已记录但尚未找到可解释班次的 `UNMATCHED` 结果。
| 字段 | 说明 |
| --- | --- |
| `id` | 归班事实 ID |
| `sailing_id` | 船期实例;`UNMATCHED` 时为空 |
| `inbound_id` / `receipt_batch_id` / `forecast_id` | 归班对象;至少有一个稳定业务键 |
| `assignment_source` | V1 为 `AUTO`;预留 `MANUAL`、`ROLLOVER` |
| `assignment_version` | 同一归班对象的版本号,重算递增 |
| `match_status` | `FORECAST_MATCHED` / `RECEIVED` / `LATE` / `UNMATCHED` / `SUPERSEDED` |
| `volume_cbm` | 本次归属的已收实测体积;V1 固定来自审核后的 `actualVolumeCbm` |
| `forecast_volume_cbm` | 本次归属的未收有效预计体积,与已收体积分开 |
| `forecast_source` | 预计体积来源;没有可靠预计体积时为空,不得用申报值冒充已收体积 |
| `route_source` | 航线来自入仓/预报事实或 `CHANNEL_DEFAULT`,用于追溯匹配依据 |
| `volume_source` | 已收状态固定为 `MEASURED_ACTUAL`;仅预计状态为空,计费/申报仅作对比或后续扩展 |
| `rule_version` | 自动归班规则版本 |
| `matched_at` / `superseded_at` | 归班和被替代时间 |
| `locked_at` / `lock_reason` | 达到船期截止、确认订舱或船期关闭后冻结归班的时间和原因 |
| `operator_id` / `reason` | 自动任务/后续人工操作审计 |
同一批次或预报在同一时刻只能有一个 `AUTO` 有效归班版本;重新计算采用旧版本 `SUPERSEDED` + 新建版本,不能静默覆盖旧历史。
“同一业务对象”在这里指收货批次,不是整票订单或整张入仓单;一票分批到仓、复测或冲正时,必须按批次守恒,不能用单据级唯一键把后续批次锁死。
### 7.5 `fl_sailing_booking_advice_snapshot`
这是订柜建议的可追溯快照,不是正式订舱记录。每次刷新或人工确认建议时保存:
| 字段 | 说明 |
| --- | --- |
| `sailing_id` / `container_type_code` | 船期和柜型 |
| `received_cbm` / `forecast_catchable_cbm` / `risk_cbm` | 已收、可赶预计和风险体积 |
| `planning_capacity_cbm` | 从统一柜型目录读取的规划容量快照 |
| `recommended_container_count` | 按体积初算的建议柜数 |
| `booked_container_count` / `shortage_count` | 已订柜数和待补柜数 |
| `rule_version` / `calculated_at` | 计算规则版本和计算时间 |
| `risk_codes` | ETA 缺失、重量缺失、箱数缺失、混装限制等风险 |
### 7.6 `fl_sailing_booking_link`(V1 最小订舱关联)
首版要显示“已订柜数”和“待补柜数”,因此必须在 V1 建立计划船期与订舱的最小关系;复杂的实际柜次、甩柜和海运节点关联仍放到后续阶段。
| 字段 | 说明 |
| --- | --- |
| `sailing_id` | 计划船期实例 |
| `ocean_booking_id` | 海运订舱 |
| `link_status` | `ACTIVE` / `REVOKED`;解除关系保留历史 |
| `booking_status_snapshot` | 关联时的订舱状态快照;当前只有订舱状态为 `RELEASED` 才允许计数 |
| `warehouse_id` / `channel_code` / 起运港 / 目的港 | 关联时的业务匹配快照 |
| `linked_at` / `operator_id` / `reason` | 关联审计 |
V1 采用以下计数契约:
- 只有当前订舱状态为 `RELEASED` 且关联记录为 `ACTIVE` 的订舱才计入已订柜;`DRAFT`、已作废或已解除关联的不计入。`RELEASED` 是订舱状态,不是关联记录状态。
- 已订柜数按该订舱的柜型需求 `quantity` 汇总,不按已生成真实柜次数量、不按装柜完成数量替代。
- 一个 `RELEASED` 订舱首版只能关联一个计划船期;如果未来需要一个订舱拆到多班,再升级到按柜型需求行分摊的关系。
- 关联时必须校验收货仓、渠道代码、起运港、目的港和计划船期一致;不一致进入冲突,不允许仅凭船名/航次文字关联。
- 订舱解除、作废或计划取消后,已订柜数应在服务端重新计算,并保留原关联历史;不得把已订柜数当作人工可编辑字段。
## 8. 接口草案
接口路径和 DTO 以最终服务端归属为准,以下只作为拆分和评审入口:
| 能力 | 建议接口 | 说明 |
| --- | --- | --- |
| 月历查询 | `GET /platform/v1/sailings/calendar` | 按月份、收货仓、港口、渠道、关键词、状态返回实例和服务端汇总;同时返回未安排/晚到摘要 |
| 实例详情 | `GET /platform/v1/sailings/{sailingId}` | 返回实例、统计、关联货量和操作权限 |
| 新增单次实例 | `POST /platform/v1/sailings` | 幂等创建,支持无模板来源 |
| 编辑/取消实例 | `PUT/PATCH /platform/v1/sailings/{sailingId}` | 乐观锁;取消保留历史 |
| 渠道管理 | `GET/POST/PUT /platform/v1/sailing-channels` | 启用、停用和主数据维护 |
| 模板管理 | `GET/POST/PUT /platform/v1/sailing-templates` | 周模板和启停;固定单次船期直接走实例接口 |
| 生成预览 | `POST /platform/v1/sailing-templates/{id}/generation-preview` | Phase 1 必须支持;返回日期、航次、冲突和截止时间预览 |
| 批量生成 | `POST /platform/v1/sailing-templates/{id}/generate` | 使用幂等键,返回成功、跳过和冲突清单 |
| 货量明细 | `GET /platform/v1/sailings/{id}/volume-summary` | V1 返回自动归班结果、服务端汇总和收货批次明细,不要求已经存在人工改绑 |
| 收货批次事实 | Firstleg 服务正式事实查询(路径以 Controller 归属评审为准) | 提供 `receiptBatchId`、`receivedAt`、最终实测 CBM、审核/冲正状态及仓库/渠道/航线快照;船期页面不得从入仓单分页自行拼装 |
| 货量预报事实 | Firstleg 服务正式事实查询(路径以 Controller 归属评审为准) | 提供 `forecastId`、`expectedArrivalAt`、`forecastVolumeCbm`、有效状态、版本和来源;没有可靠预报时只返回风险/未安排 |
| 订柜建议 | `GET /platform/v1/sailings/{id}/booking-advice` | 按柜型返回已收、可赶预计、风险、已订柜、建议柜数和待补柜数;只读 |
| 订舱关联 | `POST /platform/v1/sailings/{id}/booking-links` | V1 关联一个 `RELEASED` 订舱并校验仓库、渠道、港口和船期;只建立最小关系,不创建柜次 |
| 手工关联/改绑 | `POST /platform/v1/sailings/{id}/volume-allocations` | Phase 2+;校验截止、容量、收货仓归属和幂等键 |
| 变更历史 | `GET /platform/v1/sailings/{id}/history` | 实例、模板和手工改绑审计 |
所有写接口建议使用 `Idempotency-Key`、`expectedVersion` 和服务端权限校验;错误响应应能区分重复生成、容量不足、已截止、状态冲突和归属不一致。
## 9. 权限建议
权限按“看”和“改”拆分,至少包括:
- `platform:firstleg:sailing-calendar:list`:查看月历、详情、货量汇总和只读历史。
- `platform:firstleg:sailing-calendar:create`:新增单次船期。
- `platform:firstleg:sailing-calendar:edit`:编辑、复制和取消。
- `platform:firstleg:sailing-volume:exception-reassign`:V1 受限异常重新安排;只能处理取消、晚到和未安排货量,不能绕过截止、容量或真实履约锁定。
- `platform:firstleg:sailing-volume:bind`:常规人工改绑、拆分和预占,Phase 2+ 才启用。
- `platform:firstleg:sailing-booking:link`:建立或解除计划船期与订舱的最小关联。
- `platform:firstleg:sailing-template:manage`:渠道、模板、批量生成和停用。
- `platform:firstleg:sailing-volume:bind`(Phase 2+):关联/改绑货量。
- 审计导出或跨业务检索如确有需要,再单独增加权限;普通详情历史不另造重复的只读权限。
权限只由服务端决定,前端按钮隐藏不能替代后端校验。
## 10. 分期建议
### Phase 1:可用的日历排班
- 渠道主数据、单次船期、周模板。
- 截止时间计算和实例生成。
- 生成预览、冲突清单和确认后批量生成。
- 月历、日期详情、渠道维度的预计/已收体积汇总。
- 服务端自动归班的只读结果:预计可赶船、已收、晚到风险、未安排。
- 按现有柜型目录计算只读订柜建议:可赶总 CBM、建议柜数、已订柜数、待补柜数和风险提示。
- 保存自动归班事实和版本历史;建立计划船期与 `RELEASED` 订舱的最小关联,用于计算已订柜数;为取消、晚到和未安排货提供受限异常重新安排。
- 实例编辑、取消和基础历史。
Phase 1 不提供正常货量的批量改绑、强制赶截止和容量预占;只提供第 6.10 节的受限异常重新安排。若没有明确归班事实,只展示“未安排”,不能把按渠道汇总的体积伪装成某一班船已收。
### Phase 2:排班辅助和容量控制
- 模板复制和批量调整。
- 在 V1 已实现的收货仓、渠道、港口、截止时间和确定性排序基础上,Phase 2 再增加复杂优先级、容量约束和多班冲突处理。
- 容量阈值、超容拦截和有权限的强制处理。
- 手工关联、改绑、预占和货量明细。
### Phase 3:运营增强
- 工作日/节假日日历。
- 月度/渠道汇总导出和报表。
- 截止提醒、异常通知和更完整的审计检索。
- 与真实柜次、港务船期、甩柜/改配和实际海运节点的完整可追溯关联,但不覆盖已有运输事实;V1 的最小订舱关联已经前置。
## 11. 验收标准
1. 新建“美森每周周四”模板,预览并生成指定月份的所有周四实例;再次生成不产生重复实例。
2. 新增一条固定船期,能够编辑开船时间、船名、航次、截止时间和容量;已有归班或已收货事实后只能取消,不能物理删除。
3. 日历格和日期详情显示同一套渠道统计口径;至少能区分预计体积、已收体积、未安排/晚到和剩余容量。
4. 根据收货仓、起运港、渠道、船名/航次和月份筛选后,月历数量、日期详情和统计合计一致;跨月日期不会重复或漏显示。
5. 截止时间按服务端规则计算,人工覆盖有明确标识;超过截止或已取消的船期不能被自动推荐。
6. 接近容量上限和超容量有明确状态;V1 只读提示,不能因为体积初算直接生成正式柜次。
7. 停用渠道的历史实例可查询,停用后不能创建新的模板实例;渠道改名不改变历史实例的名称快照。
8. 写接口具备幂等和乐观锁;重复提交、并发编辑、重复生成均返回可理解的冲突信息。
9. 列表/详情只读、实例编辑/取消、模板管理、货量改绑分别受权限控制;操作历史可追溯到操作者和原因。
10. 页面展示业务编号、船名、航次、港口和渠道,不以内部数据库 ID 作为用户可见回退。
11. 对一班固定船和一班临时船,系统能分别展示已收 CBM、截止前预计 CBM、风险 CBM、已订柜数、建议订柜数和待补柜数;建议结果标注计算时间、柜型和规则版本,并明确最终以智能排柜/人工确认结果为准。
12. 同一收货批次先产生预计归班,之后实际收货并复测;系统保留旧归班版本、只计最新有效实测体积,且不把预计体积与实测体积重复相加。
13. 同一时刻建立两班船,自动归班结果稳定选择 `sailing_no` 较小者;船期截止后刷新页面,原归班仍显示为 `LATE` 或 `RECEIVED`,不会变成无历史的未安排。
14. 一个 `RELEASED` 订舱关联一条计划船期,柜型需求数量计入已订柜;`DRAFT` 订舱、未关联订舱和真实柜次数量不会被错误计入。
15. 自动归班在截止前可以重算;达到截止后原归班被冻结,后续实际收货标记为 `LATE` 时仍保留原船期。没有稳定收货批次或预报事实时只显示风险/未安排,不得用 `inboundedAt`、`originalVolumeCbm` 或入仓单分页合计补出数字。
## 12. 首版已冻结与后续校准
本轮已先采用以下口径,开发按此实现:
1. 船期模板/实例必须绑定收货仓、渠道、起运港和目的港;不使用“全部仓”作为模糊范围。
2. 已收只统计 V1 收货批次事实中明确完成收货、最终测量审核通过且 `actualVolumeCbm > 0` 的批次;申报体积和计费体积不计入已收。
3. V1 新增或正式暴露稳定的 `receiptBatchId + receivedAt` 收货批次事实;不能用现有会被多个流程节点更新的 `inboundedAt` 单独代替。
4. V1 新增或正式暴露 `forecastVolumeCbm + expectedArrivalAt` 货量预报事实;`originalVolumeCbm`、申报箱数和计费体积不得作为预计可赶量。
5. 预计可赶量只纳入有明确 ETA、预计体积、渠道/仓库/航线匹配且不晚于 `warehouseCutoffAt` 的有效预报;没有 ETA 或航线的货列为风险/未安排。
6. 自动归班选择最早可赶的 `OPEN` 船期,并在 V1 持久化 `FORECAST_MATCHED`、`RECEIVED`、`LATE`、`UNMATCHED` 和 `SUPERSEDED` 历史;截止前且未锁班时可以版本化重算,达到截止、`CLOSED` 或已确认订舱后冻结当前归班;船期取消只转为风险/待人工处理,不自动换班;晚到不自动改班。
7. 同一收货仓、渠道、起运港和目的港下,ETD 相同的多班船按 `sailing_no` 升序确定唯一归班;同一归班对象同一时刻只能有一个有效版本。
8. `warehouseCutoffAt` 暂定为开船本地日期前 3 个自然日、收货仓 18:00,时区为 `Asia/Shanghai`;它与官方截单/截关/截港分开。
9. V1 建立计划船期与 `RELEASED` 订舱的最小关联;已订柜数按关联订舱的柜型需求 `quantity` 统计,`DRAFT` 不计入,不按真实柜次数量替代。
10. 订柜建议复用现有柜型目录、容量和已订柜事实,只读展示建议柜数和待补柜数,不直接创建正式柜次;结果标注“按体积初算,最终以智能排柜/人工确认结果为准”。
11. V1 航次规则只支持固定值或“前缀 + ETD 本地日期”,生成实例允许人工覆盖;不做顺序号自动递增。
12. V1 采用人工预览后生成固定周模板实例;停航或临时变更先手工跳过/取消,暂不做节假日自动日历。
以下事项不阻断首版,但需要在试运行或进入后续阶段前校准:
1. 多个收货仓是否能共同供货给同一班船;如果可以,建立明确的收货仓组,再做线路级合计,不能直接跨仓混算。
2. 提前天数是否从自然日升级为工作日,周末/节假日是否接入工作日历。
3. 渠道是否需要客户专属范围;若需要,客户必须进入模板、实例、查询和权限维度。
4. 同一渠道同一天多班船的复杂运营优先级、航次生成规则和模板覆盖策略。
5. 订柜建议是否支持多柜型混合、重量约束和装载率优化;首版按体积初算,最终以智能排柜/人工确认结果为准。
6. 计划实例与真实柜次、港务船期的完整关联时机,以及甩柜、改配后的运输事实展示。
## 13. 工程接入门禁
进入实现阶段后,页面与接口需要同步维护以下入口:
- Admin 页面放在 `apps/admin-web/src/modules/` 的独立业务模块内,包含 `pages/`、`routes.ts`、`api/` 和 `types.ts`;不能把模板和实例逻辑塞入现有 `CarrierScheduleQueryPanel.vue`。
- 正式接入时同步 `src/app/router/index.ts`、`src/core/navigation/adminNavigation.ts` 和平台 IAM 权限初始化;菜单归属应在“国内仓”与“货柜管理”中选定后固定。
- Firstleg 若承载服务端能力,需同步 Controller、OpenAPI、数据库基线、Gateway 路由和权限契约;月历统计由服务端返回,前端不以 `InboundOrderSummary` 分页结果自行拼装。
- 需要优先复用现有仓库范围内的正式 `channelCode`/渠道目录,再为确有需要的排班专用渠道建立明确映射;同时校验入库实测字段、订舱/货柜船期和价格簿的引用边界。新计划不能回写港务船期观测或订舱快照。
- V1 开发前必须先落地 `ReceiptBatchFact`、`InboundVolumeForecast`、`fl_sailing_assignment` 和 `fl_sailing_booking_link` 的服务端事实与索引;Firstleg 的当前基线对应 `phase4-sailing-facts-schema.sql`、`sailingcalendar/fact/entity` 和 `SailingFactsRepository`,部署统一增量也必须包含这四张表。如果这些事实没有来源,接口只能返回风险/未安排,不能伪造已收或已订柜数字。
- 订柜建议必须读取统一柜型目录和 `RELEASED` 订舱需求;不得另建 40GP/40HQ/45HQ 容量常量,也不得用真实柜次数量替代订舱需求数量。
- 页面验收覆盖正常、空数据、加载、失败、无权限、并发冲突、已截止、超容量和已取消状态,并按 Admin 当前 1920×1080、100% 缩放基线执行。
## 14. 建议实施顺序
1. 按第 12 节首版冻结口径建立统一的术语、体积、归班、截止时间和订柜建议规则。
2. 画出模板、实例、货量关联和现有港务船期之间的关系,并评审权限与审计边界。
3. 先落地服务端查询模型和月历返回结构,再实现 Admin 月历页面,避免前端自行拼装统计。
4. 用“美森每周周四 + 一条临时船期 + 一批预计到仓数据 + 一批已收实测数据 + 一批晚到数据”做端到端造数和验收。
5. 完成 Phase 1 后再决定手工改绑、容量预占、工作日历、导出和外部船期接入,避免首期把订舱和船公司接口一起带入。
## 15. 本轮复核结论与验收算例
本轮复核后的结论是:**基础排班可以进入开发;完整的收货统计、订柜建议和异常处理必须按本节算例验收后,才能认为首版可用。** 下面的数字是验收用例,不是初始化数据,也不是对截图示例的默认值。
### 15.1 分批收货不能用整票相减
- 一票有效预报拆为 A 批 40 m³、B 批 60 m³。
- A 批实际到货并审核为 45 m³时,结果为“已收 45 m³ + 未收预计 60 m³”;不能把整票 100 m³ 直接减去 45 m³后把 B 批改成 55 m³。
- A 批复测为 43 m³时,只更新 A 批实收版本;B 批仍为 60 m³。任一版本重复消费都不得重复计量。
- 如果实收不能明确对应 A 或 B,相关预报暂列“待核对”,不把实收和预报同时计入可赶总量。
### 15.2 无预报直接收货与晚到的区别
- 没有预报但首次形成 20 m³审核实收,且仓库、渠道、航线明确、实际到仓时间不晚于某个 `OPEN` 船期截止:自动归入该船,状态为 `RECEIVED`。
- 已经归属于周四船的批次,实际到仓晚于周四截止:保留周四历史,状态为 `LATE`;已收总量增加,但周四的“本船可赶实收”和订柜建议不增加。
- 没有归班、资料缺失或已过截止才首次到仓的批次进入异常待办,不能仅因体积或渠道相似自动塞进下一班。
### 15.3 订柜建议要排除晚到并抵扣真实柜型容量
- 40HQ 规划容量按统一柜型目录读取,不能在日历模块复制常量。
- 一班船有本船可赶实收 40 m³、有效未收预报 28 m³、晚到 35 m³;建议计算量为 68 m³,晚到 35 m³只在已收总量/风险中展示。
- 若已有一个 40GP 和一个 40HQ 的 `RELEASED` 订舱关联,已订规划容量按两个柜型各自容量折算;不能只按“已订 2 柜”抵扣,也不能把 `DRAFT` 订舱计入。
- 班次规划容量小于可赶总量时只显示超容量和超出体积,不能静默截断可赶量或降低建议柜数。
### 15.4 取消后的异常重新安排
- `CLOSED` 且尚未开船的船期可以取消;取消会保留原归班和订舱关联历史,将当前货量转为异常待办,不自动改到下一班。
- 运营有异常重新安排权限时,选择目标 `OPEN` 船期、填写原因,系统同时校验仓库、渠道、港口、截止时间、目标版本和履约锁定状态。
- 成功后旧归班为 `SUPERSEDED`,新归班为 `MANUAL`,目标班只计一次;目标班订柜关联必须另行建立或确认,不随货量改配自动转移。
- 已有真实柜次、预装或装柜履约锁定的货不能从日历直接改配,必须回到对应履约流程处理。
### 15.5 开发完成判定
满足以下条件才通过首版业务验收:事实来源可追溯、预报和实收不重复、晚到不增加原班可赶量、取消后有异常处理入口、订柜按柜型需求折算且仅统计有效 `RELEASED` 关联、月历与详情使用同一服务端快照。仅完成页面、接口返回空数组或通过类型/编译检查,均不能作为通过依据。
### 15.6 成熟货代系统的排船期做法
成熟系统把“排船期”视为一条可执行的运输计划,而不是日历上的一个标记,通常分为四层:
1. **服务/周班模板**:维护渠道、收货仓、起运港、目的港、固定星期、开船时间、时区、默认航程和默认截止规则。固定周班按滚动窗口生成未来 8~12 周的具体航次;模板停用只影响未来生成,不回写历史实例。Oracle OTM 也支持按固定星期时间或相对开船时间的偏移配置航次截点:[Oracle Cutoff Recovery Time](https://docs.oracle.com/en/cloud/saas/transportation/26c/otmol/planning/power_data/rates_and_codes/cutoff_recovery_time_details.htm)。
2. **具体航次实例**:每班保存自己的船名、航次、计划 ETD/ETA、内部收货截止、船司确认的各类截止、状态和容量。模板只提供默认值;船司确认或运营人工覆盖后,只更新实例并保留变更历史。
3. **货物归班事实**:预计到仓、审核后的实收批次、体积版本和当前归属独立保存,能追溯自动归班、晚到、取消和人工改配的前后航次。
4. **订舱执行**:预报量、已收量、已订柜量、待补柜量分开统计。只有已确认/已放舱的订舱关联计入已订柜,草稿和取消订舱不计入。
一个航次不应只有一个“截止时间”。至少区分:我司仓库最晚收货时间、订舱接受截止、截单/SI、截关/CY、VGM,以及危险品/冷柜等特殊货类截止。DCSA 将这些作为不同的业务节点,并指出其会随船期、码头和货类变化:[DCSA Cut-off Times](https://dcsa.org/newsroom/cut-off-times-in-shipping)。VGM 还必须在装船前提前提交,才能满足装载条件:[IMO VGM](https://www.imo.org/en/ourwork/safety/pages/verification-of-the-gross-mass.aspx)。因此,本系统的“开船前 3 个自然日、收货仓 18:00”只能作为我司内部 `warehouseCutoffAt` 默认值,不能当作船司截关时间。
自动归班采用以下顺序:先按收货仓、渠道、起运港、目的港筛选 `OPEN` 且尚未超过 `warehouseCutoffAt` 的候选,再按 ETD 最早排序。实际到仓时间等于截止时间仍算准时;超过截止时间后,未锁班、未订舱的货物自动寻找下一班,下一班不存在时进入 `UNMATCHED/待人工`。已经锁班或已确认订舱的货物即使晚到,也保留原 `sailingId`,标记 `LATE/MISSED_CUTOFF`,由运营确认是否转下一班,不能静默改写原归属。
例如美森固定周四 10:00 开船,义乌仓内部收货截止为周二 18:00:周二 17:59 和 18:00 到仓的货物可赶本周四;周二 18:01 首次到仓的货物只能进入下一周四;已经确认归属本周四的晚到货物则保留本周四并进入晚到异常。
建议状态补充 `NEAR_CUTOFF` 和 `BOOKING_CONFIRMED/LOCKED`。`NEAR_CUTOFF` 只用于预警,仍允许收货;超过内部截止后由服务端禁止新的自动归班。船司延误、甩柜或取消时,保留原实例和归班历史,生成异常待办并要求明确改配,不直接把货物静默塞入下一班。
### 15.7 从当前版本到可运营版本的改造顺序
结论是保留现有“模板 → 航次实例 → 收货归班 → 货量汇总 → 订柜建议”主模型,不重做日历页面,先补齐以下规则和闭环。
**P0:上线前必须完成**
1. 服务端统一执行收货截止门禁。候选航次必须同时满足 `status=OPEN` 和 `arrivalAt <= warehouseCutoffAt`;首次晚到不能继续挂当前航次,已存在归班的晚到只能保留原航次并标记 `LATE`。
2. 建立锁班和字段冻结。已有确认订舱、人工锁班或履约事实后,禁止直接修改收货仓、渠道、港口、ETD、截止时间等关键字段;需要调整时走复制、取消或异常改配。
3. 完善预报与实收的批次关联。同一收货批次只能消费一个有效预报;多个预报、错误的预报键、预报作废和拆分必须进入待核对,不能同时计入预报量和实收量。
4. 取消/甩柜只产生异常待办,不自动把货物静默塞进下一班;人工改配必须记录原航次、目标航次、操作者、时间、原因和目标版本。
5. 收货仓、渠道、起运港和目的港使用主数据选择并由服务端校验,不能长期依赖前端自由填写名称或 ID。
6. 月历和详情只统计同一服务端口径:已收使用审核实测 CBM,晚到不计入原班可赶量,取消航次不计入主汇总,已订柜只统计有效的 `RELEASED/CONFIRMED` 关联。
**P1:首版稳定运行后完成**
1. 增加预报维护、异常待办、人工改配、订舱关联/撤销等 Admin 操作入口。
2. 模板支持完整有效期、停班例外、跨月生成和生成前冲突预览;默认滚动生成未来 8~12 周。
3. 增加 `NEAR_CUTOFF`、待补柜、超容量、未安排等风险提示,并提供按渠道的 CBM 和柜量分组汇总。
4. 所有写操作接入统一幂等和版本校验,避免重复点击、重复生成和并发覆盖。
**P2:运营增强**
再接入船司/码头实际截点、节假日工作日历、容量预占、自动提醒、外部船期同步和更复杂的混合柜型优化。它们不应阻塞首版排船和收货统计上线。
### 15.8 当前展示版范围修正(以本节覆盖前文自动归班口径)
本轮需求已明确:船期日历先作为**展示和决策辅助页面**,不接管现有收货、预报、智能排柜或订舱流程。前文关于 `Sailing Assignment` 自动写入、自动下一班、晚到改配、取消后异常重排和收货审核回调的内容,全部降为后续规划,不纳入当前开发验收。
当前版本允许运营人员维护渠道、周模板和具体船期;货量相关能力全部只读:
- **已收 CBM**:读取现有收货/测量流程已经产生的有效实测结果,不在船期页面重新生成收货事实。
- **预计 CBM**:读取现有入仓预报或智能排柜可读数据;没有可靠来源时显示“暂无数据”,不凭渠道名称或订单分页猜测。
- **截止前参考量**:按船期的收货仓、渠道、起运港、目的港和 `warehouseCutoffAt` 做查询口径,只用于显示“理论上可供管理人员参考的货量池”,不表示货物已经归入该船。
- **已明确本船量**:只读取现有系统已经明确关联到该船名/航次或现有订舱/柜次事实的数据;日历不新增关联。
- **建议订柜数**:按可展示货量和统一柜型容量做初算,显示计算时间、柜型和“最终以智能排柜/人工确认结果为准”;不创建订舱、不锁舱位、不改柜次。
- **合船判断**:页面只提供“本船未满、建议关注相邻船期”的提示,并展示相邻船的可用容量和货量对比;不自动合并、不自动改绑。
展示版的数据实现口径再明确一层:已收实测只统计测量审核为 `APPROVED` 且有 `actual_volume_cbm` 的有效入库单,按上一班截止时间到当前班截止时间的窗口汇总;主单只在未拆分时统计,拆分后的有效余量子单单独统计,避免父子单重复。当前没有可核验的预计体积来源时,预计量按 0 展示并在页面提示“暂无可核验数据”,不得把申报体积、原始体积或分页列表合计冒充预计量。已订柜读取已放舱订舱的柜型需求,优先识别已有船期关联,同时允许用仓库、渠道、港口、船名、航次和开船日期做确定性只读匹配;日历页面不创建关联。建议柜数只按统一柜型容量计算,待补柜只做提示。
当前版本明确不做以下写操作:
1. 收货审核通过时,不调用船期日历服务,不写入 `fl_sailing_assignment`、预报消费或船期实收事实。
2. 创建或修订预报不自动生成船期归班;预报维护接口不作为本轮页面入口。
3. 取消船期不自动把任何货物转到下一班;货物归属仍由原智能排柜和订舱流程维护。
4. 页面不提供货量异常改配、手工绑定实收、订舱关联/解除等操作;这些操作留在现有业务流程。
因此,本轮验收重点从“自动归班正确”改为:船期维护正确、展示口径透明、已收/预计/已订柜/建议柜数不重复、取消或截止只影响展示标签、不会改变原收货和智能排柜数据。后续如果需要让管理人员在页面上确认“合并到哪一班”,再单独增加人工确认动作和正式归属模型。
+32
View File
@@ -0,0 +1,32 @@
# 头程到尾程当前维护入口
这里集中列出 F01-F40 全流程变更需要查找和修改的文档。报关协同代码已接入并通过真实 HTTP 验收,当前进入全流程状态与页面证据收尾;日常只从本目录进入,历史开发材料统一放在[文档归档](../归档/README.md)。
## 当前流程文档
| 用途 | 文档 | 修改什么 |
|---|---|---|
| 总览与节点 | [头程到尾程流程节点梳理](../头程到尾程流程节点梳理.md) | 三大业务块、客户进度、后台节点、真实明细和 F01-F40 关系 |
| 分段流程 | [头程到尾程分阶段流程](../头程到尾程分阶段流程/README.md) | 六个阶段的字段、页面操作、权限、状态和异常 |
| 货柜入口 | [国内货柜履约 README](../国内货柜履约/README.md) | 分柜、装柜、报关协同、送港和进港的货柜范围 |
| 报关与船期专题 | [报关资料与船期价格接入梳理](../国内货柜履约/报关资料与船期价格接入梳理.md) | 客户资料、报关行回执、客户确认/打回、正式申报、海关结果和船期价格 |
| 报关开发交接 | [报关代码开发交接清单](报关代码开发交接清单.md) | 报关代码完成条件、已验收范围和后续增强项 |
| 头程与报关交互矩阵 | [头程节点与报关清关交互矩阵](头程节点与报关清关交互矩阵.md) | F01-F24 各节点的客户、平台、PDA、报关行和船期交互 |
| 全流程实现对照 | [全流程节点矩阵与缺口清单](头程至实际开船节点冻结矩阵与缺口清单.md) | F01-F40 节点、现行规则、实现差异和验证边界;保留原文件路径 |
| 正式申报与海关结果 | [正式申报与海关结果接入设计](正式申报与海关结果接入设计.md) | F22.7 正式申报批次、报关单号、F22.8 查验/补资料/放行/扣货/其他结果及三端边界 |
| 甩柜改配接入设计 | [甩柜改配接入设计](甩柜改配接入设计.md) | F23.3 原柜人工修改船信息并保留修改历史 |
## 变更查找
- **改客户看到的主节点或三大块关系**:先改总览,再检查对应阶段文档。
- **改头程下单**:查阶段一、阶段二;费用确认仍是并行事项,不阻断排柜和装柜。
- **改海运(货柜)**:查阶段三、阶段四和报关专题;报关完成后进入待发区,甩柜只影响船期,实际开船后才进入海运节点。
- **安排报关开发**:只看[报关代码开发交接清单](报关代码开发交接清单.md),流程规则回看报关专题,不再从归档的开发规划开始。
- **改尾程入库和派送**:查阶段五、阶段六。
- **改页面范围或已确认需求**:查[页面与原型清单](../国内货柜履约/国内货柜履约页面与原型清单.md)和[需求确认表](../国内货柜履约/国内货柜履约需求确认表.md)。
## 归档位置
- [头程到尾程历史文档](../归档/头程到尾程/README.md):全流程手册、旧现状全景、AI 上下文、易用性方案。
- [国内货柜履约历史记录](../国内货柜履约/归档/README.md):开发规划、进度、门禁、验收、审计和旧确认材料。
- 跨区域认证、权限、统一订单状态、船节点、部署和数据库等正式契约继续留在原业务目录,不归入流程历史归档。
@@ -0,0 +1,217 @@
# 全流程节点矩阵与缺口清单
本文按当前确认结果冻结 F01-F40 全流程范围:从头程下单开始,完成国内履约、报关协同、送港运输、实际开航、海外入库、出库和最终回写。F01-F24 是国内头程至实际开航的前段,F25-F40 是海运目的港及尾程履约。流程基线同时采用《报关代码开发交接清单》和《头程到尾程流程节点梳理》;原型只用于页面字段和承载方式参考。
## 一、阶段边界
```text
头程下单
F01-F13:下单、审核、到仓、测量、计费、费用确认、国内扣货/解除、组托、待分柜
国内货柜履约
F14-F21:分柜、订舱、拖车、拣货、装柜、LOADED
报关完成后进入待发区
F22:报关协同
F23:待发区、送港、进港、甩柜、改配
海运起点
F24:承运船舶实际开航
目的港与海外入库
F25-F30:目的港处理、尾程订单、入仓计划、接柜、收货、库存入账
海外库存与出库
F31-F37:库内操作、暂扣、库内服务、排车、生成出库/派送单、拣货发车、出库
派送与完成
F38-F40:签收、异常退回、回访和完成回写
```
国内前段 F01-F24 的终点是实际开航,全流程继续至 F40;其中 F37 为海外出库。`LOADED` 只表示物理装柜完成;报关完成是进入待发区的前置条件,待发区和船期节点分别保存,不能把其中一条线的结果写成另一条线的结果。
### 实现与验证口径
“已有实现”不等于最新版本已完成验收。下表的既有 HTTP 证据只证明对应报告范围与版本;历史通过不能替代当前完整链路、页面或 PDA 现场验证。报关和运输专项的通过也不能外推为 F01-F40 全部通过。后续增强项不作为首期主流程缺失处理。
2026-09-29 修复后的默认全量真实 HTTP 回归已通过:Admin 11,627 项检查、120 个模块、7,429 次请求,0 失败、0 跳过模块;Client 195 项检查全部通过。F31 换托同库位比较、A0 共享溢出位移库、F33 无贴标转仓查询及跨服务错误处理已修复并部署测试环境;验收脚本补齐直接贴标审核、返工重新领取及禁止回移虚拟收货位的边界。离线合同 128 个文件、773 项断言全部通过。
同票普通 FBA 主链证据为入仓码 `NYEXX2609290171`、柜次 `D1063`、柜号 `TSTU3425326`、排车单 `DS-WH-20260929-067073`、出库单 `OB-WH-20260929-158402`;两张目的仓派送单签收后,已核对来源入仓单 `DELIVERED` 和来源订单 `COMPLETED`。随后故意执行的退回异常测试会改变留存单据状态,不能把最终留存状态误读成未曾完成。退税报关分支另由同一全量报告中的混合柜检查覆盖,不冒充同一票退税至签收证据。
对应证据:`baiyue-firstleg/reports/admin-full-current-20260929-r7.json`、`reports/client-full-current-20260929-r3/client-test-env-20260929063613-e54d44dd.json`、`reports/fba-main-chain-evidence-20260929.json`(后两个路径同属后端仓库)。Admin/Client 报关详情已按 1920×1080 页面核对;船期日历网络恢复后重载正常。未离仓测试柜 `TSTU7897110` 已实际验证首次发送、普通文本回执上传、客户确认后的平台执行、正式申报、其他理由必填备注、异常保存与人工处理;客户确认通过该客户自己的 HTTP 接口完成。异常处理后回执确认保留,未上传完税文件仍保持报关中并阻断离仓。
页面复验发现并修复异常发生时间早 8 小时的问题:国内 `LocalDateTime` 接口改为接收上海业务时间。Admin 提交 `4ead51a5feedf65be9443ddfe3dd45da7ca49e64` 已通过测试环境 Jenkins #482 部署;262 个测试文件、2,121 项测试和构建通过。部署后真实页面新增查验记录的发生时间与服务器记录时间相差 0.879 秒。详见后端仓库 `reports/customs-time-postdeploy-20260929.json` 和 `reports/customs-other-resolved-1920-20260929.jpg`。Android 真机、弱网和外部船司正式凭据仍属于单列验证边界,不纳入本次内置浏览器与 HTTP 通过结论。
## 二、F01-F40 节点冻结矩阵
| 节点 | 客户可见进度 | 后台业务对象 | 必须形成的真实事实 | 当前状态 | 本阶段缺口 |
|---|---|---|---|---|---|
| F01-F07 | 待下单、审核中、已审核 | 企业、订单、审核任务 | 提交、补件、审核、入仓单生成 | 已有主链 | 按现有订单契约回归,不在本轮重做 |
| F08-F10 | 待到仓、测量中、待确认 | 入仓单、测量记录 | 收货、扫码、称重、测量、审核 | 已有主链 | 只核对是否能稳定产出排柜事实 |
| F11 | 费用待确认 | 费用版本、客户确认记录 | 计费推送、客户主动确认、版本留痕 | 已有实现;旧总览的默认确认表述与阶段二及服务指引冲突 | 按现行规则,装柜可自动发布费用,但不能代替客户确认;不将缺少 `SYSTEM_AUTO_AT_LOADED` 列为必修代码缺陷 |
| F12 | 国内扣货中、已解除 | 国内入仓单 HOLD 记录 | 扣货、解除、原因和后续作业门禁 | 已实现;最新全量 inbound-hold 模块通过 | 与报关海关异常、海外库存暂扣分别维护,不能混为同一节点 |
| F13 | 待组托、待分柜 | 一件代发清点、托盘和封托记录 | 逐箱清点、归托、封托 | 已有主链 | 结合一件代发路径验证;不要求普通散货重复执行一件代发清点流程 |
| F14-F20 | 待分柜、订舱中、装柜中 | 柜次、装柜计划、拖车、PDA 任务 | 分柜、订舱、排车、拣货、照片、铅封、数量核对 | 主链已有 | 核对真实柜号、订舱和装柜快照能否冻结 |
| F21 | 国内已装柜 | 装柜计划、物理货柜、装柜证据 | 实际柜号、实装箱数、装柜证据、`LOADED` | 已有 | 报关案例按最终实装范围建立;部分装柜只显示已装箱数并标记线下处理,不在系统内自动分摊 |
| F22.1 | 报关确认中 | 柜级报关聚合内的客户资料范围 | 每客户范围、入仓码范围、混合柜隔离、实装范围回显 | 已实现并通过真实 HTTP 验收 | 独立“案例”对象仍可在正式批次设计时补充;部分装柜仍线下处理 |
| F22.2 | 待提交资料、待补资料 | 客户资料包 | 上传、替换、关联范围、版本、冻结 | 已实现并通过真实 HTTP 验收 | 首期不维护资料类型清单;有文件即可上传,补件通过人工异常理由和备注说明 |
| F22.3 | 已发送报关行 | 独立首次发送批次 `brokerSubmission` | 业务批次号、发送人、发送时间、冻结版本、资料快照、幂等历史 | 已实现并通过定向测试与测试环境部署 | 报关行接收确认和回执轮次对象待补 |
| F22.4 | 待客户确认 | 回执/完成文件版本 | 文件版本、关联客户范围、客户可下载 | 已实现;回执历史和确认动作历史均只读投影 | 独立回执返回时间/下载凭证仍待补 |
| F22.5 | 客户确认中、已打回 | 客户确认记录与动作历史 | 确认/打回、回执版本、操作人、时间、原因 | 已实现并通过定向测试与测试环境部署 | 通知聚合和报关行回执轮次待补 |
| F22.6 | 等待整柜确认 | 完税文件齐全门禁 | 所有退税客户确认、发送执行、真实完税文件齐全 | 已实现并通过专项真实 HTTP 验收 | 查验、扣货、补资料作为平台人工异常节点处理,不新增自动凭证门禁 |
| F22.7 | 已提交正式申报 | 正式申报批次 | 报关行确认、正式申报时间、操作人、批次、报关单号 | 已实现并通过真实 HTTP 7 步联调 | 后续可补报关行接收时间和下载凭证 |
| F22.8 | 查验中、待补资料、已放行、扣货/其他 | 海关结果事实 | 报关单号、结果类型、时间、人工理由、备注和处理结果 | 已实现;真实 HTTP 与人工异常页面保存/处理通过,发生时间偏差已修复并部署复验 | 不接短信或自动海关系统;真机及外部系统不在页面验证范围 |
| F23.1 | 待发区、送港中、已离仓 | 待发区与送港/出仓任务 | 报关完成时间、待发区门禁、离仓时间、车辆/任务、操作人、证据 | 已实现并通过真实 HTTP 验收 | 继续补待发区客户/平台投影展示 |
| F23.2 | 已送港、已进港 | 运输和港口事实 | 送港时间、进港时间、来源和凭证 | 已实现;已有真实 HTTP 证据 | 继续补充最新页面证据,并保持与订舱、拖车和船次事实统一读写 |
| F23.3 | 已甩柜、等待改船后承运 | 船期记录修改历史 | 甩柜原因、发生时间、修改前后船名/航次/船期、处理人 | 已实现并通过测试环境真实 HTTP;平台与客户端最新船期投影一致 | 继续补页面截图和更复杂异常分支;柜次、订舱关联和报关事实不变 |
| F24 | 海运中 | 船次实际节点 | 承运船舶、航次、实际开航时间、来源/凭证 | 已实现;实际节点与查询任务已有真实 HTTP 证据 | 继续补充最新一轮页面证据;只允许实际开航事实推进海运节点 |
| F25 | 目的港处理中、待海外接柜 | 船节点、目的港清关/提柜、尾程订单 | 到港、卸船、清关、提柜和可接柜事实 | 已实现并有综合真实 HTTP 证据 | 外部码头/车队差异继续按异常分支补充 |
| F26 | 尾程订单待建计划 | 跨区事件、尾程订单 | 装柜完成、船节点和来源入仓单快照可靠投递与消费 | 已实现并有综合真实 HTTP 证据 | 继续观察跨区事件延迟和补偿告警 |
| F27 | 待建立海外入仓计划 | 入仓计划、计划托盘和资源锁 | 按柜内每票生成计划、预计到仓和托盘资源冻结 | 已实现并有综合真实 HTTP 证据 | 继续补齐异常重试页面证据 |
| F28 | 待接柜、接柜中 | 海外 PDA 接柜会话 | 柜号认领、三类签收照片和签收确认 | 已实现并有综合真实 HTTP 证据 | Android 真机验收仍是独立非阻塞项 |
| F29 | 入库中 | 海外 PDA 收货任务 | FBA 散货、海外仓逐箱、一件代发整托等实收事实 | 已实现并有综合真实 HTTP 证据 | 继续补充现场设备和弱网证据 |
| F30 | 入库完成 | 入库任务、库存和跨区回写事件 | 全柜核平、库存同事务入账、卸柜完成事件 | 已实现并有综合真实 HTTP 证据 | 保持事件幂等和库存数量守恒 |
| F31 | 库存可用、库内服务中 | 库存、库位、托盘、盘点 | 上架、移库、合托/拆托、盘点和库存流水 | 已实现并有综合真实 HTTP 证据 | 继续补充大批量库存性能验收 |
| F32 | 暂扣中、已解除 | 暂扣记录和库存锁 | 暂扣原因、解除原因、操作人和库存可用性变化 | 已实现并有综合真实 HTTP 证据 | 暂扣与出库并发场景继续补充 |
| F33 | 换标/转运/废弃处理中 | 换标、转运、废弃子单 | 客户确认、箱唛/托盘变更、库存锁和实际扣减事实 | 已实现并有综合真实 HTTP 证据 | 继续补充复杂返工和跨仓异常 |
| F34 | 待派送、排车中 | 智能预排、排车单 | 候选、草稿锁、正式排车和目的仓分配 | 已实现并有综合真实 HTTP 证据 | 继续补充多车多目的仓页面证据 |
| F35 | 待转派送、待出库 | 排车转派送、出库单、派送单 | 出库/派送单生成、目的仓拆分、费用只发布一次 | 已实现并有综合真实 HTTP 证据 | 保持转派送前不可发车 |
| F36 | 拣货中、待发车 | 海外 PDA 排车任务 | 托盘扫描、数量核平、车辆资料和发车门禁 | 已实现并有综合真实 HTTP 证据 | Android 真机和弱网恢复仍需专项验证 |
| F37 | 已出库、派送中 | 出库单、派送单 | 出库完成、库存扣减和派送任务关联 | 已实现并有综合真实 HTTP 证据 | 继续补跨目的仓汇总展示 |
| F38 | 派送中、已签收 | 派送单、签收凭证 | 签收文件、签收时间和每个目的仓派送完成 | 已实现并有综合真实 HTTP 证据 | 继续补异常签收凭证类型 |
| F39 | 异常退回处理中 | 异常单、退回入仓和库存恢复 | 拒收/部分拒收、退回、库存恢复和原因历史 | 已实现并有综合真实 HTTP 证据 | 继续补多次退回和部分恢复组合场景 |
| F40 | 已完成、待回访 | 客户回访、跨区完成事件、订单回写 | 回访记录、`DELIVERED` 回写及订单 `COMPLETED` 收口 | 已实现并有综合真实 HTTP 证据 | 继续补跨区延迟时的客服投影 |
## 三、当前实现与目标的主要断点
### 1. 客户范围和首次发送批次已落地,回执轮次属于后续增强
当前 `fl_customs_container` 仍是柜级状态聚合,但客户资料通过客户和入仓码范围隔离,真实验收已覆盖同柜多客户和混合柜。正式申报批次、海关结果事实、首次发送报关行批次和客户确认动作历史已经独立落地;尚未独立建模的是报关行接收回执、回执轮次和更细的客户案例聚合。
### 1.1 费用自动发布与客户确认必须区分
阶段二“费用计费与确认”和 `baiyue-firstleg/firstleg/AGENTS.md` 明确规定:费用不阻断排柜和装柜,装柜完成不得代替客户自动确认,客户确认与本票装柜完成共同构成最终冻结条件。`FbaPricingService.autoSendAfterLoadingCompleted` 执行平台费用确认与发送,`confirmByCustomer` 才记录客户确认人和时间;`SENT` 不等于客户确认。旧总览要求 `SYSTEM_AUTO_AT_LOADED` 的表述与现行规则冲突,不能据此直接新增自动代客确认。若未来明确改变该规则,再同步费用版本、确认来源和冻结边界。
### 1.2 海关异常按人工节点处理
海关短信由平台人员人工查看和操作,系统不接短信、不自动判断查验或扣货。平台在正式申报批次上人工标记异常,选择“查验”“扣货”“补资料”或“其他”等理由;选择“其他”时填写备注,后续由平台人员人工解除或录入处理结果。异常是申报批次上的附加事实,不改变已上传资料、回执和客户确认历史。
目标至少需要以下关系:
```text
物理货柜
├─ 最终实装快照
├─ 客户报关案例 × N
│ ├─ 客户资料包与版本
│ ├─ 报关行回执轮次 × N
│ └─ 客户确认/打回记录与动作历史 × N
├─ 整柜正式申报批次
└─ 海关结果事实 × N
```
### 2. 当前“报关完成”仍需与正式申报、海关结果区分
现有完成动作是平台上传每份完成文件,或对全买单柜直接确认;客户确认和完成文件链路已有真实验收。正式申报批次、报关单号和海关结果已经分别记录,仍不能把其中任何一个状态直接当成海关放行或所有运输事实。
### 3. 报关完成与待发区的门禁关系
当前 `CustomsDispatchGateContributor` 要求 `fl_customs_container.status=COMPLETED` 才通过国内出仓门禁,`CustomsAutoDispatchCoordinator` 也在报关完成后自动尝试确认出仓。按最新口径,这不是冲突:报关完成后货柜进入待发区,待发区是送港运输真正开始前的状态门槛;甩柜只在船期运输层处理,不触碰报关事实。
需要重新定义:
- 待发区门禁先检查报关 `COMPLETED`,再叠加装柜、PDA、订舱、证据等运输条件;通过后只推进到 `WAITING_FOR_LOADING`。
- 报关线单独保存客户确认、整柜申报和海关结果;这些事实不会被船期修改覆盖。
- 报关完成事件只能推进待发区,不得自动伪造送港、进港或开船事实。
- 实际开航只能由船次实际节点推进。
### 4. 客户端基础报关协同闭环已完成
当前客户端 `CustomsDocumentsView.vue` 提供独立报关资料列表和待办入口,`CustomsDocumentsDialog.vue` 已支持上传、替换、调整关联入仓码、查看和下载报关行回执/真实报关完税文件、确认整份回执和填写原因打回,并展示回执历次上传版本及确认/打回动作历史;仍缺少:
- 客户案例的进度和通知。
### 5. 平台端基础整柜协同闭环已完成
当前 `ContainerCustomsPanel.vue` 已展示退税资料、首次发送报关行批次、回执/完成文件、客户范围、确认状态、回执历次上传版本和确认/打回动作历史,并支持正式申报批次和海关结果基础操作;仍缺少:
- 按客户查看案例和实际装柜覆盖;
- 报关行接收回执和回执轮次管理;
- 报关行接收回执时间和下载凭证等更细历史。
## 四、接口、权限、审计和测试缺口
### 接口与数据库
- OpenAPI 不能继续只暴露旧的四态 `ContainerView`。
- 需要继续补充报关行接收回执、回执轮次和下载凭证的查询/命令契约;资料包、首次发送批次、回执版本和确认动作只读历史、整柜申报和海关结果基础契约已落地。
- 文件仍由 File 服务保存,但每个文件必须绑定业务类型、客户案例/申报批次、版本和覆盖范围。
- 每个写命令都要带版本和幂等键;重放同参数返回原结果,不同参数返回冲突。
- 换柜时需要保留新旧柜关联;部分装柜只记录已装箱数和线下处理标记,不在系统内自动做数量分摊或覆盖旧资料。
### 权限
至少区分:
- 客户上传、替换、补件、确认、打回;
- 平台客服接收、核对、退回补件;
- 平台报关操作员发送报关行、上传回执、提交正式申报;
- 平台人员录入查验、放行、扣货及其他海关结果;
- 客户和平台各自的只读下载权限。
### 审计
需要保留客户范围、资料版本、回执轮次、确认人、打回原因、提交批次、报关单号、异常理由、备注和操作时间。客户 A 的动作不能出现在客户 B 的案例中;柜级汇总可以看到客户名和业务编号,但客户端只能看到自身范围。
### 测试
最小验收矩阵至少覆盖:
1. 单客户和多客户同柜。
2. 一客户打回时其他客户继续保持已确认。
3. 同一请求重放、同幂等键换参数、版本冲突。
4. 未全部客户确认时正式提交被拒绝。
5. 正式申报、查验、不查验放行、扣货和其他结果分别显示。
6. 报关完成后货柜进入待发区,等待船舶承运。
7. 甩柜改配在原柜上人工修改船信息并留痕,柜子和报关事实不变。
8. 只有实际开航事实推进 F24。
9. 客户越权读取同柜其他客户资料被拒绝。
10. 部分装柜能显示实际箱数并留下线下处理标记;换柜不能直接覆盖原案例和历史回执。
## 五、后续增强(无需当前业务确认)
以下内容不阻断当前开发:回执接收时间、回执轮次和下载凭证可以后续增强;海关短信、查验、扣货、补资料和其他异常按平台人工标记、选择理由和填写备注处理。
### 已冻结的业务规则
| 规则 | 冻结口径 | 依据 |
|---|---|---|
| 资料提交时点 | `LOADED` 后按最终实装快照建立客户案例并进入本轮报关 | 交接清单“一、必须实现的报关流程”;总流程 F21/F22 |
| 同柜客户边界 | 一个客户案例只属于一个客户;同一客户多个入仓码可以共享资料,但跨客户正式合报默认禁止 | 报关专题“申报组与柜级总览”“买单、退税和混合柜完成条件” |
| 回执与客户确认 | 首期以报关行回执文件为主,客户对整份回执确认;回执上传不等于客户确认 | 本轮业务确认 |
| 资料与部分装柜 | 报关资料、报关行回执都按文件保存;部分装柜只展示箱数,线下人员处理后续,不做系统内数量分摊 | 本轮业务确认 |
| 首期正式申报 | 由平台授权人员人工提交并回填报关行确认和海关结果 | 本轮业务确认;报关专题状态约定 |
| 报关与待发区关系 | 报关完成后货柜才能进入待发区;待发区是等待船舶承运的运输状态,报关和船期事实分开保存 | 本轮业务确认 |
| 海运起点与改配 | 首期人工录入实际开航;甩柜/改配只变更船期/航次,不重新处理已完成报关资料;只有实际开航事实推进 F24 | 本轮业务确认;交接清单第二条;总流程 F23/F24 |
### 本轮补充确认的甩柜/改配口径
| 项目 | 已确认口径 |
|---|---|
| 发起与确认 | 平台人员直接编辑原柜船期,记录操作人、时间、原因和修改前后船信息。 |
| 资料继承 | 报关完成后资料、平台回执和客户确认与船期独立;甩柜/改配不触发重新上传或重新确认。 |
| 航次任务 | 平台人工修改原柜船信息,继续使用原任务;保留修改历史和已有节点。 |
### 已确认的字段和操作规则
1. (已确认)首期不维护资料类型清单和逐项责任人;资料包只要有文件即可上传、替换和留版本。
2. (已确认)查验、扣货、补资料和其他结果由平台人员人工标记异常、选择理由;选择“其他”时填写备注,异常解除也由平台人工点击。
3. (已确认)第一版由平台人员直接修改原柜船名、航次和船期,填写原因并保留修改历史。
4. (已确认)平台人工修改原柜船名、航次和船期;柜子与原任务不变。
5. (已确认)原航次退税资料、回执和客户确认与船期独立,甩柜/改配不触发重新确认。
6. (已确认)修改船信息不生成实际开航事实;只有本柜实际随船开航后才记录 `DEPARTED_ORIGIN_PORT`。
### 代码接入前置缺口
最新确认取消新增航次对象和重建任务的方案。复用现有船期编辑及修改历史,柜次、订舱关联和查询任务保持不变。测试环境已核验平台与客户端都会投影修改后的最新船期,报关资料、回执、完成文件和客户确认保持不变;证据见 `baiyue-firstleg/reports/platform-and-client-transport-projection-20260927.json`。
## 六、冻结结论
- 全流程基线覆盖 F01-F40;F01-F24 终点为实际开航,F25-F40 继续完成目的港、海外入库、出库、派送和最终回写。
- F22 报关完成后货柜进入 F23 待发区;甩柜/改配只改变运输航次,不改变报关事实。
- 客户确认、报关行回执、整柜正式申报、海关放行、离仓、进港、甩柜和实际开航都是独立事实。
- 节点清单覆盖完整范围;各节点实现与验证程度以表内状态为准,不将整张矩阵标为全部验收完成。
- F25-F40 已有实现,最新默认全量 HTTP 回归已通过,并核对同票签收后的国内完成回写;本轮报关可写异常页面操作已完成,设备和外部船司边界继续单列,不能用 HTTP 全绿替代这些证据。
@@ -0,0 +1,78 @@
# 头程节点与报关清关交互矩阵
> 本文把 F01-F40 全流程中的头程、海运与报关清关交互放在同一张图里;其中 F01-F24 是国内头程到实际开航,F25-F40 由阶段四至阶段六继续承接。报关资料只适用于包含退税货物的柜,买单货物不创建客户资料协同。
## 一、总链路
```text
客户下单/入仓
→ 收货、测量、计费、费用确认
→ 分柜、订舱、拖车、PDA 装柜
→ LOADED(物理事实)
→ 客户上传报关资料
→ 平台冻结资料并首次发送报关行(生成独立批次)
→ 报关行回执
→ 客户确认整份回执/打回
→ 平台把客户确认后的回执发送报关行执行
→ 报关行完成
→ 平台上传真实报关完税文件
→ 报关完成
→ 待发区、送港、进港
→ 甩柜/改配只修改原柜船期
→ 实际开航
```
`LOADED` 是 PDA 产生的装柜事实,也是当前客户报关详情的准入条件;PDA 不参与资料、回执、确认或完税文件接口。报关完成是待发区的门禁,实际开航只由船次实际事实推进。
## 二、F01-F21:报关前的头程节点
| 节点 | 客户动作 | 平台动作 | PDA/运输动作 | 报关影响 |
|---|---|---|---|---|
| F01-F07 下单、审核、补件 | 提交订单、补充订单信息 | 审核订单、生成入仓单 | 无 | 仅确定客户、订单和退税/买单属性;不创建报关资料 |
| F08-F10 到仓、收货、测量 | 查看入仓进度 | 收货、扫码、称重、测量并审核 | 仓内作业 | 形成后续实装范围的来源数据 |
| F11-F13 计费、费用确认、组托、待分柜 | 查看/确认费用 | 发布费用版本、记录确认、组托封托 | 无 | 费用确认不能代替报关资料确认 |
| F14-F20 分柜、订舱、拖车、拣货、装柜中 | 查看柜次和船期 | 建立柜次、订舱、拖车和装柜计划 | PDA 领取、拣货、复核、装柜 | 仍不能启动客户报关资料入口 |
| F21 `LOADED` | 查看实际装箱数 | 固化实际柜号、实装箱数和装柜证据 | PDA 提交并产生 `LOADED` | 按最终实装范围建立退税客户报关资料范围 |
部分装柜只回显实际箱数并留下线下处理标记,系统不自动分摊数量,也不覆盖原始资料范围。
## 三、F22:报关平台与客户交互
| 子节点 | 平台页面/接口 | 客户页面/接口 | 关键状态与门禁 |
|---|---|---|---|
| F22.1 建立资料范围 | Admin 查看柜级退税客户、入仓码和实装范围 | Client 只能看到自身订单范围 | 退税客户按租户和入仓码隔离;买单客户不建资料 |
| F22.2 客户上传资料 | `GET /api/platform/v1/customs/loading-plans/{planId}` 查看汇总 | `GET /api/merchant/v1/customs/orders/{orderId}`;`POST .../documents/upload`;可替换、调整入仓码范围 | 当前要求 `LOADED`;资料版本和幂等键受门禁控制 |
| F22.3 首次发送报关行 | Admin `POST .../{planId}/send-to-broker` | 只读看到批次和发送时间 | 资料全部冻结后生成独立 `brokerSubmission` 批次;未首次发送不能上传回执;只适用于含退税货物的柜 |
| F22.4 上传回执 | Admin `POST .../documents/{documentId}/receipt/upload` | `GET .../receipt/download` | 回执进入 `PENDING`;回执不是报关完成文件 |
| F22.5 客户确认/打回 | Admin 查看每客户回执状态 | `POST .../receipt/confirm` 或 `.../receipt/reject` | 确认整份回执;打回必须填写原因;版本冲突拒绝 |
| F22.6 回执冻结与执行 | Admin `POST .../{planId}/submit-to-broker` 再次发送客户确认后的回执 | Client 只能查看确认结果和动作历史 | 发送执行后回执不能替换;`brokerSubmittedAt` 仅表示发送执行时间 |
| F22.7 正式申报与报关行完成 | Admin 创建/提交正式申报批次、回填报关单号,并上传真实报关完税文件:`POST .../final/upload` | `GET .../final/download`;只读批次投影 | 完税文件齐全后整柜状态才可 `COMPLETED`;正式申报批次和完税文件是两件事,不能把回执或客户确认当成正式申报 |
| F22.8 清关结果 | 平台人工补录查验、补资料、放行、扣货等独立事实;可处理未决结果 | 客户只读查看自身可见结果和凭证 | 已落地 `customs_declaration_batch`、`customs_clearance_result`;结果不推进待发区、船期或 PDA |
当前客户端状态映射:`WAITING_UPLOAD` → `DOCUMENT_UPLOADED` → `DECLARING` → `CUSTOMS_COMPLETED`。平台柜级状态映射:`WAITING_CUSTOMER_DOCUMENTS` → `READY_TO_START` → `DECLARING` → `COMPLETED`。`COMPLETED` 仍需继续与正式申报、海关放行和运输节点拆开。
## 四、F23-F24:报关完成后的运输交互
| 节点 | 平台动作 | 客户可见内容 | 报关资料处理 |
|---|---|---|---|
| F23.1 待发区、送港、离仓 | 报关完成后通过待发区门禁,记录送港/离仓事实 | 查看待发、送港状态和当前船期 | 资料、回执、完税文件只读保留 |
| F23.2 进港 | 记录进港时间、来源和凭证 | 查看进港节点 | 不改变报关状态 |
| F23.3 甩柜/改配 | 平台人员编辑原柜船名、航次、预计时间并记录前后值、原因、操作人 | 查看修改后的当前船期和历史 | 柜号、订舱关联、资料、回执、客户确认和完税文件不变,不重新确认 |
| F24 实际开航 | 人工录入承运船舶实际开航事实 | 查看海运已开航 | 只记录关联关系,不重做报关 |
甩柜只改变运输信息,不生成新柜、不重建报关任务、不把预计船期修改误写成实际开航。
## 五、当前接口覆盖与待补项
已落地并部署的基础闭环:客户资料上传/替换/范围调整、平台查看、冻结资料首次发送报关行并生成独立批次、回执上传及历次版本只读投影、客户整份回执确认/打回及动作历史、平台发送报关行执行、真实完税文件上传/下载、退税与买单分流、版本和幂等门禁;当前平台与客户页面均读取最新预计船期字段,实际开航字段单独保留。
仍需补齐:
1. 报关行接收确认、回执轮次和回执下载凭证的独立对象及更细历史投影。
2. 待发区客户/平台投影的更细页面展示和截图证据;`LOADED → 报关 → 待发区` 已在混合柜报告中通过,平台与客户改船后的当前船期双端回读已验收。F25-F40 的海运目的港、海外入库、库存、出库、派送和最终回写由阶段四至阶段六维护,综合证据见 `baiyue-firstleg/reports/admin-overseas-chain-final-fixture-20260924.json`。
正式申报批次和海关结果已在本轮实现并通过真实 HTTP:平台创建/提交批次、录入查验、查询并处理结果,客户按自身订单查询结果;证据见 `baiyue-firstleg/reports/formal-customs-declaration-and-clearance-result-20260927.json`。
报关专项真实 HTTP 证据、构建号和当前 PDA 边界见[报关代码开发交接清单](报关代码开发交接清单.md)、`baiyue-firstleg/reports/focused-customs-flow-without-pda-20260927.json`、`baiyue-firstleg/reports/customs-mixed-20260927i.json` 及 `baiyue-firstleg/reports/customs-prep-container-20260926.json`。专项证据验证客户确认回执、发送报关行、上传完税文件和客户回读 `COMPLETED`,没有调用 PDA;新建混合柜全链路报告已通过 532/532。
F22.7/F22.8 的独立批次、报关单号和海关结果设计见[正式申报与海关结果接入设计](正式申报与海关结果接入设计.md);该设计不改变现有两份文件闭环,也不把结果事实写入船期或 PDA 状态。
@@ -0,0 +1,110 @@
# 报关代码开发交接清单
> **当前状态:报关协同已接入测试环境。** 客户资料、首次发送报关行批次、回执、客户确认历史和真实完税文件已形成独立链路;海关查验、扣货、补资料和其他结果由平台人员人工标记异常、选择理由并填写备注,不接短信或自动海关系统。报关行接收回执和下载凭证仍可后续增强。头程至尾程的全流程范围和缺口以[头程至实际开船节点冻结矩阵与缺口清单](头程至实际开船节点冻结矩阵与缺口清单.md)为准;流程规则以[报关资料与船期价格接入梳理](../国内货柜履约/报关资料与船期价格接入梳理.md)为准,节点关系以[头程到尾程流程节点梳理](../头程到尾程流程节点梳理.md)为准。
> **本轮补充确认:** 首期报关行回执以文件为主,客户确认整份回执;正式申报由平台授权人员人工提交并回填结果;报关完成后货柜进入待发区;实际开航首期人工录入,甩柜/改配只变更船期,不重新处理已完成报关资料。
> **验收证据:** 既有全链路报告保留旧版 526/526、混合柜 532/532 记录;本轮新增代码、数据库和三端已部署,已用现有完成柜做接口烟测并核对首次发送门禁。完整造数到报关回归已补齐测试环境专用国内 PDA 作业员并通过;当前报关主链报告为 543/543,运输节点报告为 1036/1036。
## 一、必须实现的报关流程
从装柜完成(`LOADED`)开始,按柜内客户分别处理:
1. 按最终实装清单建立客户报关案例和资料包。
2. 收集客户上传、替换或补充的资料,冻结后由平台生成独立批次首次发送给报关行。
3. 接收报关行回执并发给对应客户确认。
4. 客户打回时,只重开对应客户当前轮次,重新上传、重新发送并生成新回执;保留每轮资料、回执、确认人、时间、动作历史和打回原因。
5. 柜内所有客户确认后,平台发送客户确认后的回执给报关行执行。
6. 报关行执行完成后,平台上传真实报关完税文件;全部退税资料对应的完税文件齐全后,整柜报关完成。
7. 分别记录海关查验、不查验放行、扣货或其他正式结果。
报关行回执、客户确认、整柜正式申报和海关放行是不同节点。客户确认不能自动完成,平台费用确认与发布也不能代替报关资料确认。
## 二、报关完成与待发区关系
- `LOADED` 只表示物理装柜完成;报关资料、回执、客户确认和正式申报仍需独立完成。
- 报关完成后,货柜才能进入待发区;待发区表示等待船舶承运,不表示已经开船。
- 送港、进港、甩柜和改配是运输事实;甩柜只在原柜船期记录上人工修改船信息,不回退或重新处理已完成报关资料。
- 只有承运船舶实际开航后,才推进 `DEPARTED_ORIGIN_PORT` 海运节点。
## 三、当前代码交接重点
### 已落地的第一批能力
- 平台端和客户端都能展示当前视角的实际装箱数;部分装柜只展示箱数,后续由线下人员处理,系统不做数量分摊。
- 报关资料和报关行回执继续按文件上传、覆盖、版本和下载处理;页面文案已区分“回执”和“完成”,避免把上传回执误认为客户确认或正式申报。
- 首次发送报关行单独记录 `brokerSubmission`(业务批次号、冻结资料版本、快照、操作人和时间);未完成首次发送时不能上传回执,也不能发送客户确认结果给报关行执行。
- 报关资料链路仅适用于退税货物;买单货物不创建客户报关资料、回执和客户确认流程。
- 回执上传后进入待确认状态;客户端已提供整份回执确认和打回入口,平台与客户端都展示每个回执版本的确认/打回历史,打回原因回传后再由平台重新上传回执。
- 后端 OpenAPI、平台/客户端模型和基础测试已同步实际箱数字段;管理员端、客户端类型检查及相关组件测试已通过。
旧版资料与回执基础链路已通过测试环境真实 HTTP 验收;两份文件新流程已通过本地单测、契约测试和测试环境部署。报关闭环不依赖 PDA;真实 HTTP 验收应使用已经处于待发区的柜作为前置,不能因为装柜/PDA 前置失败而把报关结论判为失败。
### 报关与 PDA、船期的边界
- PDA 只负责装柜现场作业,产出 `LOADED` 事实;本报关模块不创建、领取、认领或提交 PDA 任务。
- 报关模块只消费已完成装柜且可进入待发区的柜。装柜链路可以作为系统级前置验收,但不属于报关两份文件闭环的验收内容。
- 船期、价格、甩柜和改配属于运输模块。甩柜时只人工修改原柜的船名、航次和时间,柜号、报关资料、回执、客户确认和完税文件不变,也不重新创建报关任务。
### 本轮对 PDA 关系的落地说明(2026-09-26)
- PDA 没有参与本轮代码修改,也没有被报关接口调用;客户资料、报关行回执、客户确认和真实报关完税文件仍由平台与客户/报关行接口独立处理。
- 当前客户报关详情接口只对已完成装柜的订单开放,未达到 `LOADED` 时返回“订单尚未完成装柜”。因此 PDA 只是报关入口的上游准入事实,不是报关协同动作的一部分。
- 若后续业务确认“装柜前就允许客户上传报关资料”,应单独调整 `LOADED` 准入门禁;不能通过在报关模块里偷偷创建或操作 PDA 任务解决。
- 本轮测试已用真实 HTTP 建立退税柜、订舱和船期关联,并确认装柜计划仍为 `EDITING`、`readyForPda=false` 时不启动报关;证据见 `baiyue-firstleg/reports/customs-prep-container-20260926.json`。
### 本轮报关专项真实 HTTP 证据(2026-09-27)
- 使用测试库中已完成装柜的退税计划 `loadingPlanId=2103494180160507905`,没有调用任何 PDA 接口。
- 客户确认回执:HTTP 200、业务码 `200`,报关状态仍为 `DECLARING`。
- 平台发送客户确认结果给报关行:HTTP 200、业务码 `200`,产生 `brokerSubmittedAt`,状态仍为 `DECLARING`。
- 平台上传真实报关完税文件:HTTP 200、业务码 `200`;随后平台和客户查询均返回 `COMPLETED`,并可见完成文件。
- 完整证据:`baiyue-firstleg/reports/focused-customs-flow-without-pda-20260927.json`。该证据证明两份文件报关协同闭环本身不依赖 PDA。
- 早期全量验收报告 `customs-full-20260926h.json` 的失败项集中在 PDA 任务被分配给其他作业员,导致装柜链未进入 `LOADED`;修正验收作业员绑定并补齐 File 服务回执类型后,新的全链路报告 `customs-mixed-20260927i.json` 已通过 532/532,报关模块 223+47+23 项全部通过。
### 本轮部署证据
- 本轮 Firstleg 后端 `backend-java #652`、下游 `baiyue-firstleg-firstleg #455`、平台管理端 `admin-web-test #473`、客户端 `client-web-test #355` 均已成功部署到测试环境,健康检查为 `UP`。
- 客户端报关资料定向测试 61/61 通过;报关服务单测、OpenAPI 契约测试和平台报关组件测试结果记录在本轮交接记录及对应构建产物中。
- 正式申报/海关结果接入提交:Firstleg `ed692ee3`、路由合同修正 `95da66c7`、执行顺序修正 `4bec639a`,`backend-java #639/#640/#641` 成功;Admin `29cb0bd`、顺序修正 `855d8c0`,`admin-web-test #461/#462` 成功;Client `8c8fdbc`、`client-web-test #350` 成功。正式申报和结果真实 HTTP 7 步全部通过,证据见 `baiyue-firstleg/reports/formal-customs-declaration-and-clearance-result-20260927.json`。
- 甩柜改配投影提交 `ac3acfce`、`f1218cef`,平台容器读模型修复提交 `2c4f1ea3`;当前分支的船期展示修复已由 `backend-java #649`、`baiyue-firstleg-firstleg #452` 和 `client-web-test #351` 成功部署。真实验证确认改船只更新原柜船期,平台与客户端同步最新船期,柜号和报关资料/回执/完成文件保持不变,证据见 `baiyue-firstleg/reports/platform-and-client-transport-projection-20260927.json`。
- 回执历史投影提交 Firstleg `f6e70ea5`、Admin `ffe91a1`、Client `3e28478` 已成功部署:`backend-java #650`、`baiyue-firstleg-firstleg #453`、`admin-web-test #471`、`client-web-test #353`。健康检查为 `UP`,平台和客户真实接口均返回 `receiptHistory`;证据见 `baiyue-firstleg/reports/customs-receipt-history-20260928.json`。
- 本轮首次发送批次与确认动作历史提交为 Firstleg `e63cb2b2`、Admin `730defa`、Client `8fd4063`;数据库已核对 `fl_customs_broker_submission` 与 `fl_customs_completion_action_history`。现有完成柜烟测返回 `A0409 当前柜不在报关中`,确认新首次发送接口的状态门禁;证据见 `baiyue-firstleg/reports/customs-send-batch-confirmation-history-20260928.json`。
- 本轮页面回归又修复了一个实际问题:Client 订单列表契约此前没有保留 `taxMode`,导致真实退税订单在“报关资料”页被过滤为 0 个资料包;Client `214fe4f` 已补齐退税字段映射,测试部署 `client-web-test #357` 成功。随后发现船期价格页首次加载重复请求渠道列表,`32c5241` 已收敛初始化监听,`client-web-test #358` 成功。
- 后续回归又修复两个页面事实问题:未知海外仓不再把内部仓库 ID当作客户可见名称;报关完成详情改为明确提示“真实报关完税文件已齐全”。同时同步了现有实现对应的离线合同断言,客户端全量 `npm test` 已通过 `398/398`,生产构建通过,提交 `ffbe348`,测试部署 `client-web-test #359` 成功。
- 测试环境内置浏览器已按 1920×1080 复验 Admin 与 Client:最新 Admin 柜次详情展示 `LOADED`、8 条仓内节点、PDA 作业摘要 100%、报关“已完成”、国内离仓“已自动离仓”和 7/7 门禁通过;最新 Client 报关资料页展示退税资料包“报关完成”,详情可见回执版本、客户确认状态、真实完税文件和下载入口。Client 船期价格查询以 100 KG/1.2 CBM 真实调用 15 个估价接口并返回 4 个匹配渠道;同一页面初始化只保留 1 次渠道列表请求。
- 页面请求量抽样:Admin 货柜详情 13 个 API 请求且无重复;Client 报关资料列表 10 个不同 API 请求,打开两个资料详情各刷新一次资料接口;Client 船期价格初始化 1 次渠道请求,查询阶段 15 次并行估价请求,符合当前“每渠道估价”契约。完整新造数 HTTP 链已解除 PDA 前置阻塞并通过;报告 `baiyue-firstleg/reports/customs-current-20260928.json` 共 543/543 项通过,包含订单、测量、PDA 装柜、混合柜报关资料、回执、客户确认、报关行执行、完税文件、自动离仓和客户端下载。
- 2026-09-28 再次复核:测试 API 健康检查、Admin 货柜列表/详情和 Client 报关资料页均返回 HTTP 200;Admin 与 Client 均在 1920×1080 下重新打开验证。已完成柜调用首次发送接口并携带确认参数,服务端返回 `A0409 当前柜不在报关中`,证明已完成柜不会重复创建报关批次;当前无新增数据库记录。客户端全量测试保持 `398/398` 通过,`client-web-test #359` 成功。
当前仍需继续补齐的不是客户资料协同、正式申报和海关结果基础链路,而是:
- 报关行回执的外部确认/接收回执、下载凭证和回执轮次的更细对象;首次发送批次与客户确认动作历史已经落地;
- 更细的报关行接收回执和下载凭证;海关异常继续按人工理由和备注处理,不新增自动结果凭证门禁;
- 将正式申报/海关结果继续扩展到待发区、送港、进港和实际开航的只读投影,保持运输线独立;F23.3 的船期投影已完成真实 HTTP 核验。
开发时不要只增加页面节点文案,也不要把旧的 `COMPLETED` 直接当成客户确认、正式申报或海关放行。
## 四、开发入口
先核对当前代码和 OpenAPI,再决定复用或调整现有接口:
- 客户端报关资料:`apps/client-web/src/modules/first-leg/`,重点查看 `routes.ts`、`CustomsDocumentsDialog.vue` 和 `api/customs.ts`。
- 平台整柜报关:`apps/admin-web/src/modules/container-loading/`,重点查看 `ContainerCustomsPanel.vue` 和 `api/platformContainerCustoms.ts`。
- 后端报关:`baiyue-firstleg/firstleg/src/main/java/com/baiyue/firstleg/customs/container/`。
- 接口与数据:`baiyue-firstleg/firstleg/src/main/resources/openapi/customs-v1.yaml`、报关相关数据库脚本和 IAM 权限初始化。
具体类名、接口路径、状态编码和数据库字段以当前代码核对结果为准;本清单只定义业务完成条件,不预先替换技术实现。
## 五、完成条件
- 客户 A 与客户 B 的资料、回执和确认严格隔离。
- 每个客户都能完成“资料上传 → 报关行回执 → 客户确认/打回”,资料和完成文件保留版本,客户范围严格隔离。
- 首次发送报关行必须生成独立业务批次;客户每次确认或打回都保留对应回执版本、操作人、时间和原因。
- 未全部客户确认时不能完成整柜报关;正式申报批次、海关回填结果和报关单号已独立建模,不能把客户确认或完税文件上传直接当作海关放行事实。
- 海关查验、不查验放行、扣货、补资料和其他结果已落地为批次下独立事实;平台人员人工选择理由,选择“其他”时填写备注并人工处理异常。
- 报关完成后才能进入待发区;进入待发区后才推进送港/进港。甩柜/改配只修改原柜船名、航次和船期并保留历史,不能伪造或覆盖报关资料、回执和客户确认。
- 重复请求、版本冲突、换柜、部分装柜箱数展示和权限越界都有明确结果和审计记录;部分装柜的后续处理在线下完成。
- F22 和阶段三的实现状态已按当前代码和真实 HTTP 结果回写;后续继续按 `COMPLETED`、海关放行和运输节点分别验收,不把报关完成合并成海运或尾程完成。
- 2026-09-29:补齐测试环境专用 `CN_FIRSTLEG_PDA_OPERATOR` 账号并验证登录,重新执行 `phase3-container-customs` 正式 HTTP 造数链;订单、测量、PDA 领取/扫码/提交、`LOADED` 硬门禁、混合柜 BUY/TAX 隔离、首次发送批次、回执幂等、客户确认、报关行执行、完税文件、`COMPLETED`、自动离仓和 Client 完税文件下载共 543/543 通过,348 个唯一 HTTP 请求,0 个 coverage gap。报告:`baiyue-firstleg/reports/customs-current-20260928.json`。
- 2026-09-29:继续执行头程运输节点造数链;订舱、港务船期、甩柜改船、拖车预约、报关完成后的待发区、国内离仓门禁和船司查询策略共 1036/1036 通过,641 个唯一 HTTP 请求,0 个阻塞缺口。甩柜只更新原柜船期,柜次及报关事实不变。报告:`baiyue-firstleg/reports/transport-current-20260929.json`;剩余 4 个缺口均为非阻塞的 COSCO/ZIM 外部接入或 Android 真机验收。
@@ -0,0 +1,128 @@
# 正式申报与海关结果接入设计
本文只补 F22.7、F22.8 的业务对象和交互边界,不改变已经验收的退税报关基础闭环:客户上传退税资料 → 平台发送报关行 → 报关行回执 → 客户确认或打回 → 平台发送确认结果给报关行 → 平台上传真实报关完税文件。
## 一、先冻结现有边界
```text
LOADED
↓
客户退税资料齐全
↓ 平台开始报关,冻结资料范围和版本
DECLARING
↓ 报关行回执
客户确认整份回执 / 打回
↓ 平台发送客户确认结果给报关行
等待真实报关完税文件
↓ 每个退税客户均有完成文件
COMPLETED(平台已收到本轮完税文件)
↓
WAITING_FOR_LOADING(进入待发区)
```
`COMPLETED` 只表示平台收到本轮真实完税文件,不能解释为海关放行、正式申报成功或船舶已开航。正式申报批次可以在报关行执行后、完税文件回传前建立;PDA 只在上游产出 `LOADED`;待发区、送港、甩柜、改配和船舶实际开航属于运输线,不能由正式申报对象反向改写。
## 二、F22.7 正式申报批次
正式申报批次是平台授权人员人工提交后形成的独立事实,粒度为整柜一次申报批次。它引用当前柜级报关聚合和已冻结的客户资料/回执快照,不复制文件内容。
建议对象:`customs_declaration_batch`
| 字段 | 说明 |
|---|---|
| `id` | 平台长 ID,前端按字符串传输 |
| `customsContainerId` / `loadingPlanId` | 绑定整柜报关聚合和装柜计划,创建后不可换柜 |
| `batchNo` | 平台生成的批次号,人工提交前为空或草稿号 |
| `status` | `READY`、`SUBMITTED`、`ACKNOWLEDGED`、`RESULT_PENDING`、`CLOSED`、`CANCELLED` |
| `sourceVersion` | 提交时整柜报关聚合版本,防止提交后资料范围漂移 |
| `receiptSnapshot` | 提交时客户资料、回执、确认结果的客户范围和文件版本快照 |
| `customsEntryNo` | 报关单号,平台人工回填;同一有效批次唯一 |
| `submittedBy/submittedAt` | 平台提交人和时间 |
| `acknowledgedBy/acknowledgedAt` | 报关行或平台确认受理人和时间 |
| `remark` | 提交说明,长度受服务端限制 |
创建或提交门禁:
1. 柜级报关已进入 `DECLARING`,且整柜退税资料已覆盖实际装柜退税票;批次也允许在完税文件上传后的 `COMPLETED` 阶段补建。
2. 所有退税客户的当前回执均为 `CONFIRMED`。
3. 已执行发送动作,`brokerSubmittedAt` 已存在。
4. 提交使用版本号和幂等键;相同请求重放返回同一批次,不同载荷返回冲突。
5. 提交后禁止修改客户资料范围、回执和确认结果;补资料必须通过新批次或明确的退回重提动作产生新版本,不能覆盖历史批次。
建议平台接口:
- `GET /api/platform/v1/customs/loading-plans/{planId}/declaration-batches`
- `POST /api/platform/v1/customs/loading-plans/{planId}/declaration-batches`
- `POST /api/platform/v1/customs/loading-plans/declaration-batches/{batchId}/submit`
- 提交时在请求体回填 `customsEntryNo`,不另设独立改单接口。
客户端只读当前批次的可见投影,不提供提交和修改入口;客户只能看到自己资料覆盖的结果。
## 三、F22.8 海关结果事实
海关结果不是柜级状态字段,而是批次下的不可变事实记录。一次正式申报可以先产生“待结果”,之后根据实际回执追加查验、补资料、放行、扣货或其他结果;修正不能覆盖历史记录。
建议对象:`customs_clearance_result`
| 字段 | 说明 |
|---|---|
| `id` | 结果事实长 ID |
| `declarationBatchId` | 所属正式申报批次 |
| `resultType` | `INSPECTION`、`SUPPLEMENT_REQUIRED`、`RELEASED`、`DETAINED`、`OTHER` |
| `resultStatus` | `OPEN`、`RESOLVED`、`CANCELLED` |
| `customsEntryNo` | 报关单号快照,必须与批次一致 |
| `occurredAt` | 海关事实发生时间 |
| `recordedAt/recordedBy` | 平台录入时间和操作人 |
| `resolution` | 处理结果、补资料说明或扣货原因 |
| `evidenceFileId` | 可选结果凭证,文件由 File 保存,归属由 Firstleg 校验 |
| `previousResultId` | 更正或追加结果的前序事实,不能原地覆盖 |
结果门禁:
- `INSPECTION` 和 `SUPPLEMENT_REQUIRED` 未解决时,客户看到处理中/待补资料,平台不能显示放行。
- `RELEASED` 只表示海关放行事实,不自动写入送港、进港或实际开航。
- `DETAINED` 进入扣货/异常处理,保留原因和凭证,不自动删除报关文件。
- `OTHER` 必须有说明,不能用空状态吞掉未知海关结果。
- 只有平台授权人员可以新增或更正结果;客户只能读取自身可见的结果和凭证。
建议平台接口:
- `GET /api/platform/v1/customs/loading-plans/declaration-batches/{batchId}/results`
- `POST /api/platform/v1/customs/loading-plans/declaration-batches/{batchId}/results`
- `POST /api/platform/v1/customs/loading-plans/clearance-results/{resultId}/resolve`
- `GET /api/merchant/v1/customs/orders/{orderId}/clearance-results`
## 四、三端交互
| 参与方 | 可以做什么 | 不可以做什么 |
|---|---|---|
| 客户 | 上传/替换自身退税资料;查看并确认或打回整份回执;查看自身批次、报关单号、海关结果和凭证 | 不能查看同柜其他客户;不能提交正式申报;不能录入放行/扣货 |
| 平台报关人员 | 核对资料和回执;发送报关行;创建/提交正式申报批次;回填报关单号;录入和解决海关结果 | 不能用客户确认代替正式申报;不能用完税文件代替放行结果 |
| 报关行 | 线下处理申报并返回回执、报关单号和海关结果文件 | 不直接调用客户接口;所有回执和结果由平台留痕上传 |
| PDA/运输 | PDA 产出 `LOADED`;运输处理待发区、送港、进港、甩柜、改配和实际开航 | 不创建报关批次,不修改报关结果,不因甩柜重置资料或确认 |
## 五、状态投影
平台柜级状态继续保留当前四态,用新增投影补充信息:
| 现有状态 | 新增投影 | 客户文案 |
|---|---|---|
| `WAITING_CUSTOMER_DOCUMENTS` | 无有效批次 | 待上传退税报关资料 |
| `READY_TO_START` | 可开始报关 | 资料已齐,等待平台发送报关行 |
| `DECLARING` | 回执确认中/已发送报关行/正式申报中 | 报关处理中 |
| `COMPLETED` | 完税文件齐全,正式申报或结果可能仍未关闭 | 报关文件已完成,等待海关结果(如有) |
运输投影单独读取待发区和船期对象;甩柜只更新原柜船名、航次和时间历史,不变更批次、资料、回执、结果或客户确认。
## 六、最小验收矩阵
1. 未全部客户确认时创建/提交正式批次返回业务冲突,数据零漂移。
2. 同一幂等键重放返回同一批次;换参数返回冲突。
3. 提交后资料范围、回执和客户确认不可修改。
4. 同一批次可追加查验、补资料、放行、扣货和其他结果,历史顺序稳定。
5. 查验/补资料未解决时不显示放行;扣货保留原因和凭证。
6. 客户 A 不能读取客户 B 的批次、结果和文件。
7. 报关结果不推进送港、进港或实际开航;甩柜只改变原柜船期。
8. 正式申报和结果事实可以在报关 `COMPLETED` 后继续存在,不能把 `COMPLETED` 直接当成 `RELEASED`。
本设计已完成代码接入:Firstleg 建立正式申报批次和海关结果表、版本/幂等/审计门禁及平台/客户接口;Admin 页面提供创建、提交、录入和处理入口,Client 页面展示本订单可见结果。真实 HTTP 证据见 `baiyue-firstleg/reports/formal-customs-declaration-and-clearance-result-20260927.json`。当前仍保持 `COMPLETED`、海关放行、待发区和实际开航的状态边界,PDA 与船期不参与结果对象。
@@ -0,0 +1,109 @@
# 测试环境真实联调记录(2026-09-25)
本记录只登记已经在测试环境真实调用得到的结果,不把本地单测或设计文档当作真实验收证据。环境配置来自本机受控配置目录,不在文档中记录密码、Token 或 Jenkins 凭据。
## 一、本批部署
| 部署单元 | 测试构建 | 结果 | 说明 |
|---|---:|---|---|
| `backend-java` | 618 | 成功 | `firstleg` 选择构建;第 617 次因测试仍引用已删除旧方法失败,修正后第 618 次成功 |
| `admin-web-test` | 454 | 成功 | 平台回执上传不再携带 `finalConfirmation`,上传后等待客户确认 |
| `client-web-test` | 331 | 成功 | 客户端新增整份回执确认、打回和原因展示 |
路由合同检查通过;后端报关服务定向测试和 Controller 合同测试通过,Admin 类型检查及报关组件测试通过,Client 类型检查通过。
## 二、真实接口证据
测试客户属于退税客户,使用已完成装柜的测试订单和柜次进行验证。测试库已补齐 `fl_customs_completion_document` 的客户确认字段,现有记录仅用于本次测试。
### 1. 客户查看退税报关资料
调用:
```text
GET /api/merchant/v1/customs/orders/{orderId}
```
结果:`200`。客户只能看到自身资料,返回实际箱数 `40`、退税资料 `1` 份;部分装柜的系统展示只读箱数,不做数量拆分。
### 2. 平台查看柜级报关状态
调用:
```text
GET /api/platform/v1/customs/loading-plans/{loadingPlanId}
```
结果:`200`。平台视角返回同一柜次实际箱数 `40`、退税资料覆盖数和回执状态;客户视角没有返回同柜其他客户资料。
### 3. 平台上传报关行回执
调用:
```text
POST /api/platform/v1/customs/loading-plans/documents/{documentId}/completion/upload?expectedVersion=1
```
结果:`200`,回执状态为 `PENDING`,文件版本变为 `2`。上传回执没有自动把柜次标记为报关完成。
### 4. 客户打回整份回执
调用:
```text
POST /api/merchant/v1/customs/documents/{documentId}/receipt/reject
```
结果:`200`,回执状态为 `REJECTED`,打回原因被保存,柜次仍为 `DECLARING`。
### 5. 客户确认整份回执
调用:
```text
POST /api/merchant/v1/customs/documents/{documentId}/receipt/confirm
```
结果:`200`,回执状态为 `CONFIRMED`;该柜唯一退税客户确认后,柜次变为 `COMPLETED`。相同幂等键重放仍返回同一完成结果。
### 6. 头程到报关真实 HTTP 回归
在补齐国内 PDA 测试作业员凭据后,使用 `scripts/admin-test-env-acceptance.mjs --modules phase3-container-customs` 重新执行依赖闭环,覆盖客户下单、审核、入库测量、分柜/订舱、预装、PDA 装柜、`LOADED`、退税资料上传、平台回执上传、客户回执确认、自动离仓及船期查询任务。
结果:报告 `baiyue-firstleg/reports/e2e-phase3-container-customs-20260925d.json`,`526/526` 断言通过,`0` 失败;其中混合柜验证确认回执后才进入 `COMPLETED`,自动离仓 `SYSTEM` 历史为 `1` 条,`OUTBOUND_CONFIRM` 船期查询任务为 `1` 条。验收脚本同步提交为 `8940c4bc`。
### 7. 送港、船期与实际开航真实 HTTP 回归
使用 `phase3-port-schedules,phase3-carrier-schedule-queries,phase3-outbound-dispatch` 执行送港和出仓链路,报告 `baiyue-firstleg/reports/e2e-phase3-transport-20260925.json`,`1024/1024` 通过;验证报关完成后国内离仓门禁、拖车自动完成、`OUTBOUND_CONFIRM` 任务唯一性及 `DEPARTED_WAREHOUSE` 事实。
随后使用 `phase4-carrier-pickup-ready` 执行船节点人工回填,报告 `baiyue-firstleg/reports/e2e-phase4-carrier-pickup-ready-20260925.json`,`1093/1093` 通过;节点按顺序推进到 `AT_ORIGIN_PORT`、`LOADED_ON_VESSEL`、`DEPARTED_ORIGIN_PORT`,并覆盖幂等重放、旧版本冲突、旧节点回写禁止和至 `PICKUP_READY` 的连续事实。
## 三、当前已确认的业务边界
- 报关资料、报关行回执和客户确认流程只适用于退税货物。
- 买单货物不创建客户报关资料、回执和客户确认流程;买单装柜、导出和运输节点独立处理。
- 报关资料和回执均为文件;回执状态单独保存,文件版本覆盖会重新进入待确认。
- 部分装柜只展示实际箱数,后续由线下人员处理,系统不自动分摊数量。
- `LOADED` 后先完成报关协同;报关完成后货柜进入待发区,等待船期承运。甩柜/改配只影响运输航次,不回退或重做报关资料、回执和客户确认。
## 四、F01-F24 验证状态
| 范围 | 当前证据 | 状态 |
|---|---|---|
| F01-F13 下单、审核、到仓、测量、计费、费用确认、组托 | 本批依赖闭环已通过真实 HTTP;仍需拆分逐节点证据和异常分支 | 主链路已验收 |
| F14-F21 分柜、订舱、拖车、拣货、装柜、`LOADED` | 本批依赖闭环已通过真实 HTTP,包含 PDA 领取、提交、审核和 `LOADED` 冻结 | 主链路已验收 |
| F22 退税报关资料、回执、客户确认 | 已完成真实平台/客户端闭环 | 本批已验收 |
| F23 送港、进港、甩柜、改配 | 送港/进港/出仓和船期查询主链路已通过真实 HTTP;已用测试环境真实柜次验证平台人工修改原柜船名/航次/预计时间,柜次、订舱关联和船期记录 ID 不变,修改历史新增 `UPDATE`;报关事实保持不变 | 主链路和原柜人工改船已验收;完整装柜依赖链仍需补 PDA 凭据后复跑 |
| F24 实际开航 | 已通过人工船节点回填验证 `DEPARTED_ORIGIN_PORT`,顺序、版本和旧节点冲突均通过 | 本批已验收 |
| F25 以后目的港清关、海外入仓、尾程 | 已有综合真实 HTTP 证据覆盖目的港节点、海外 PDA 收货、库存、排车、出库、派送和跨区回写;`admin-full-postdeploy-66c2651b.json` 相关模块失败数为 0 | 已有主链证据;仍需按具体柜次补最终业务签字和页面截图 |
## 五、下一批开发入口
下一批聚焦 F23 的人工改船页面回读、客户侧船期投影和异常分支;当前已确认只变更原柜船期,柜次、订舱关联和报关事实均不被覆盖。尾程节点再按 F25 以后阶段推进。每批完成后继续追加真实 HTTP 证据。
## 六、2026-09-27 追加验证:F23.3 客户船期投影
- 后端提交 `f1218cef` 已由 `backend-java #643` 完整测试并部署,Firstleg 独立任务 `baiyue-firstleg-firstleg #446` 成功;随后提交 `2c4f1ea3` 由 `backend-java #645` 完整测试并部署,Firstleg 独立任务 `baiyue-firstleg-firstleg #448` 成功;当前分支追加船期展示修复后,`backend-java #647` 与 `baiyue-firstleg-firstleg #450` 也已成功。
- 修复统一订单运输摘要仍读取订舱初始船名/航次的问题:现在按客户、订舱和柜次读取最新 `fl_port_schedule` 记录,采用窗口函数选取最新观测,保留柜次与报关对象独立性。
- 对退税柜 `TSTU0152125` 实际执行“创建原柜改配船期 → 平台容器详情与客户订单同时查询 → 版本更新恢复原船信息”。平台和客户端均读到新船名、航次及预计时间;柜号不变,恢复后两端再次一致。本轮不涉及 PDA,PDA 仍只作为 `LOADED` 上游事实。
- 详细请求结果和断言见 `baiyue-firstleg/reports/platform-and-client-transport-projection-20260927.json`;此前客户侧单独投影证据仍保留在 `transport-projection-after-schedule-update-20260927.json`。
@@ -0,0 +1,35 @@
# 甩柜与改配接入设计(F23.3)
## 最新确认
柜子不会变。平台人员在原柜子的船期信息上人工修改船名、航次和预计时间即可;保留修改前后内容、修改人和时间。报关资料、回执、完成文件和客户确认保持不变。
## 操作流程
1. 退税报关完成后进入待发区,等待船舶承运。
2. 原船装满导致甩柜时,平台编辑该柜当前船期,填写实际安排的船名、航次和预计开船/到港时间。
3. 保存后继续使用原柜次和原船期查询任务;保留已经发生的离仓、进港事实。
4. 货柜实际随船开航后,再记录实际开航节点。修改预计船期本身不表示已经开船。
不新建柜子、订舱关联或航次变更审批对象,不重建船期任务,也不重新上传或确认报关资料。此前建议的 voyage-changes 接口和批次评估状态已取消。
## 现有接入入口与待验收项
现有平台船期页面 `PortSchedulesView.vue` 提供编辑船名、航次、预计开船和到港时间的入口;后端 `PortScheduleService.update` 保持客户、订舱和柜次归属不变,并保存版本和修改前后历史。优先复用该能力。
当前船期展示已改为读取同一客户、订舱和柜次下最新船期记录,不再固定读取订舱初始快照。平台人工改船后,客户端会同步显示最新船名、航次和预计时间。
## 验收要求
- 修改后柜次、柜号、装柜清单、订舱关联和船期查询任务不变。
- 船名、航次和预计时间正确更新,平台与客户可见的当前船期一致。
- 修改前后历史、操作人和时间可追溯,重复请求和版本冲突有明确结果。
- 报关状态、资料、回执、完成文件、客户确认与修改前一致。
- 已发生的物理节点不重置,预计时间调整不推进实际开航。
## 真实联调证据(2026-09-27)
测试柜 `TSTU0152125`(`containerBookingId=2104006600809353218`)的退税报关计划
`2104006600830324737` 已完成资料、回执确认和完税文件闭环。平台创建一次原柜船期改配记录后,客户端同一订单立即读到新船名、航次和预计时间;柜号、柜次不变,报关状态、退税客户数量、资料/回执/完成文件 ID 与版本均未变化。随后已用版本更新恢复原船信息,恢复后的客户端投影再次一致。完整证据见
`baiyue-firstleg/reports/platform-and-client-transport-projection-20260927.json`(平台与客户端同时回读)以及
`baiyue-firstleg/reports/transport-projection-after-schedule-update-20260927.json`。
+24 -28
View File
@@ -1,36 +1,32 @@
# 头程到尾程分阶段流程文档 # 头程到尾程分阶段流程
本目录把“头程下单 → 尾程出库”拆成六个可独立评审、以后也可独立优化的阶段。各阶段统一描述现状操作和数据流,不在流程确认前直接决定改版方案。 本目录是端到端流程的分段查找入口。F01-F40 流程基线已确认,当前用于全流程收尾变更;阶段三报关协同代码已接入并通过真实 HTTP 验收。总览和节点关系看[《头程到尾程流程节点梳理》](../头程到尾程流程节点梳理.md),字段、页面操作、权限和异常细节在对应阶段文件维护。
当前六个阶段的现状基线均已完成。下一步按阶段组织业务、产品、运营、国内仓、海外仓和技术评审;每阶段确认后,再将评审结论转入易用性和数据流转优化方案。 ## 三大业务块与六个分段
## 分阶段计划 | 业务块 | 分段 | 节点范围 | 详细文档 |
| 阶段 | 范围 | 对应全景流程 | 文档 |
|---|---|---|---| |---|---|---|---|
| 阶段一 | 客户准入、基础资料、单票/批量下单、提交、审核、订单交接 | F01~F07 | [阶段一:客户准入与头程下单](阶段一-客户准入与头程下单.md) | | **头程下单** | 阶段一:客户准入与头程下单 | F01-F07 | [打开阶段一](阶段一-客户准入与头程下单.md) |
| 阶段二 | 国内到仓、箱码、测量、称重、费用、扣货、一件代发组托 | F08~F13 | [阶段二:国内到仓、测量计费与组托](阶段二-国内到仓测量计费与组托.md) | | **头程下单** | 阶段二:国内到仓、测量计费与组托 | F08-F13 | [打开阶段二](阶段二-国内到仓测量计费与组托.md) |
| 阶段三 | 模拟柜、排柜、订舱、拖车、预装、国内 PDA、报关、出仓 | F14~F23 | [阶段三:国内货柜履约与出仓](阶段三-国内货柜履约与出仓.md) | | **海运(货柜)** | 阶段三:国内货柜履约与出仓 | F14-F23 | [打开阶段三](阶段三-国内货柜履约与出仓.md) |
| 阶段四 | 海运节点、目的港、跨区尾程建单、尾程入仓计划 | F24~F27 | [阶段四:海运、目的港与尾程入仓计划](阶段四-海运目的港与尾程计划.md) | | **海运(货柜)** | 阶段四:海运、目的港与尾程计划 | F24-F27 | [打开阶段四](阶段四-海运目的港与尾程计划.md) |
| 阶段五 | 海外接柜、实收、库存、暂扣和库内服务 | F28~F33 | [阶段五:海外接柜、库存与库内服务](阶段五-海外接柜库存与库内服务.md) | | **尾程入库和派送** | 阶段五:海外接柜、库存与库内服务 | F28-F33 | [打开阶段五](阶段五-海外接柜库存与库内服务.md) |
| 阶段六 | 海外排车、转派送、PDA 出库、派送、异常和最终回写 | F34~F40 | [阶段六:海外排车、出库、派送与最终回写](阶段六-海外排车出库派送与回写.md) | | **尾程入库和派送** | 阶段六:海外排车、出库、派送与最终回写 | F34-F40 | [打开阶段六](阶段六-海外排车出库派送与回写.md) |
## 每阶段统一模板 ## 修改时只看这三层
1. 阶段目标、起点和终点; 1. **总览层**:三大块、客户进度和节点关系变化,改总览节点梳理。
2. 角色、终端和权限边界; 2. **分段层**:某一段的页面操作、字段、权限、状态或异常,改对应阶段文件。
3. 前置主数据和检查项; 3. **专题层**:报关资料、报关行回执、客户确认、送港/甩柜和船期价格,改[报关资料与船期价格接入梳理](../国内货柜履约/报关资料与船期价格接入梳理.md),并回看总览中的 F22/F23。
4. 页面逐步操作;
5. 字段与条件必填规则;
6. 状态机、可用动作和不可逆节点;
7. 单据、编号、快照和数据归属;
8. 同步/异步调用和上下游交接;
9. 正常流、条件分支和异常恢复;
10. 阶段完成判定与评审清单。
总览入口: ## 跨段交接
- [现状流程全景清单](../头程下单到尾程出库现状流程全景清单.md) - 阶段二完成后进入阶段三的分柜;费用确认是并行事项,不阻断排柜、拣货和装柜。
- [一票主链操作手册](../头程下单到尾程出库全流程操作手册.md) - 阶段三的装柜完成(`LOADED`)后先完成退税报关;报关完成后货柜进入待发区,再推进送港运输。甩柜/改配只影响船期,不改变已完成报关事实。
- [易用性与数据流转优化草案](../头程下单到尾程出库流程易用性与数据流转优化方案.md) - 报关协同必须经过“客户资料 → 报关行回执 → 客户确认/打回重做”,柜内所有客户确认后才提交整柜资料并正式申报。
- [AI 流程优化上下文包](../头程到尾程AI流程优化上下文包.md) - 送港完成、进港或甩柜都不等于海运中;承运船舶实际开航后才进入阶段四的海运节点。
- 阶段四形成海外接柜输入后,阶段五负责实收、入库和库存,阶段六负责出库、派送、签收和异常回写。F01-F37 以海外出库为阶段性业务终点,F38-F40 继续完成派送、签收和国内最终回写。
## 旧文档的使用范围
全流程操作手册、现状全景清单、AI 优化上下文、开发规划、进度表、开工门禁和验收任务继续保留,用于追溯历史决策和实现记录;它们不是当前节点维护入口。新增规则只写入总览、对应阶段或专题文件,避免同一流程在多份历史文档中重复修改。
@@ -2,8 +2,8 @@
> 对应全景流程:F14~F23。 > 对应全景流程:F14~F23。
> 阶段起点:入库单主状态为 `WAIT_SPLIT`,不存在有效 HOLD。 > 阶段起点:入库单主状态为 `WAIT_SPLIT`,不存在有效 HOLD。
> 阶段终点:整柜满足国内出仓门禁,产生唯一实际 `DEPARTED_WAREHOUSE` 节点并开始出仓后的船节点查询。 > 阶段终点:装柜后完成退税报关并进入待发区,再完成送港线的仓库离开/进港事实;实际开船 `VESSEL_DEPARTED` 由阶段四承接。
> 本阶段复用订单、入库单、柜次和装柜计划,不新建独立“出仓单”。 > 本阶段复用订单、入库单、柜次和装柜计划,不新建独立“出仓单”。`LOADED` 后先推进报关协同,报关完成后进入待发区,再推进送港;费用确认是并行事实,装柜完成后对已装范围的当前有效费用版本执行系统默认确认。
## 1. 阶段目标和边界 ## 1. 阶段目标和边界
@@ -15,12 +15,12 @@
4. 模拟柜与订舱柜型需求、真实集装箱号关联; 4. 模拟柜与订舱柜型需求、真实集装箱号关联;
5. 预装确认、动态增减和普通散货托盘标签; 5. 预装确认、动态增减和普通散货托盘标签;
6. 国内 PDA 拣货、整托装柜和异常闭环; 6. 国内 PDA 拣货、整托装柜和异常闭环;
7. 四步装柜照片、铅封照片与铅封号; 7. 空仓、半仓、满仓、锁仓、带锁码照五类装柜证据与锁码文本;
8. 装柜完成、部分装载分片和跨区交接快照; 8. 装柜完成、部分装载分片和跨区交接快照;
9. 客户资料、整柜出口报关与放行; 9. `LOADED` 后通知报关行、客户资料收集、回执确认、整柜正式申报和海关结果;
10. 国内出仓门禁、离仓确认和拖车费用归集。 10. 送港、进港、甩柜/改配、实际离仓和拖车费用归集。
`LOADED` 表示货物已经完成实际装柜,不等于柜子已经离开国内仓。报关放行等条件在国内出仓环节统一校验;国内 Admin/PDA 不得把订单推进到海外派送完成 `DELIVERED`。 `LOADED` 表示货物已经完成实际装柜。此时先触发报关线:收集退税客户资料、发送报关行、处理回执和客户确认;报关完成后进入待发区,才允许推进拖车、离仓和进港。已进港不代表报关完成,容量不足时记录甩柜和改配船次;甩柜不影响已完成报关资料、回执和客户确认。只有实际开船后才进入海运节点。国内 Admin/PDA 不得把订单推进到海外派送完成 `DELIVERED`。
## 2. 角色、终端和对象 ## 2. 角色、终端和对象
@@ -55,7 +55,7 @@
- 柜型规格、国内中转仓、有效渠道和供应商主档可用; - 柜型规格、国内中转仓、有效渠道和供应商主档可用;
- 操作员理解模拟柜、真实柜号、订舱和拖车是不同对象; - 操作员理解模拟柜、真实柜号、订舱和拖车是不同对象;
- 同柜不可拆组、已占用数量和版本冲突均以服务端返回为准; - 同柜不可拆组、已占用数量和版本冲突均以服务端返回为准;
- 费用仍可并行维护,但已经确认/发送或客户已确认版本不得被静默改写。 - 费用仍可并行维护,客户未确认不阻断排柜、预装、PDA 或装柜;装柜完成后对已装范围的当前有效已发布版本记录系统默认确认。客户确认和系统默认确认来源分开审计;缺少有效费用版本不伪造确认,部分装载不得把余量一起确认。
## 4. F14 模拟柜与智能排柜 ## 4. F14 模拟柜与智能排柜
@@ -225,13 +225,13 @@ PDA 装柜完成不推进拖车状态。只有订舱要求的全部柜型数量
## 10. F20 装柜证据与铅封 ## 10. F20 装柜证据与铅封
PDA 按现场顺序拍摄: PDA 按现场要求采集五类证据:
1. `PHOTO_STEP_1`:装柜初始/空柜; 1. `EMPTY`:空仓照片;
2. `PHOTO_STEP_2`:装载过程; 2. `HALF`:半仓照片;
3. `PHOTO_STEP_3`:接近完成; 3. `FULL`:满仓照片;
4. `PHOTO_STEP_4`:满柜/关门前; 4. `LOCKED`:锁仓照片;
5. `SEAL`:带有效铅封号的封柜照片。 5. `SEAL`:带有效铅封号的带锁码照片。
每类至少一张有效照片,同类允许追加。PDA 仅允许现场相机拍摄;有权限的 Admin 操作员/理货员可人工补充,普通拣货员不开放后台上传。 每类至少一张有效照片,同类允许追加。PDA 仅允许现场相机拍摄;有权限的 Admin 操作员/理货员可人工补充,普通拣货员不开放后台上传。
@@ -245,7 +245,7 @@ PDA 点击“完成装柜”时,服务端重新校验:
- 真实集装箱号存在; - 真实集装箱号存在;
- 所有普通箱码或一件代发整托均核平; - 所有普通箱码或一件代发整托均核平;
- 没有未解决异常; - 没有未解决异常;
- 四步照片和带铅封号的 `SEAL` 完整; - 空仓、半仓、满仓、锁仓、带锁码照五类证据和锁码文本完整;
- 计划明细、已拣数量和最终实装数量守恒。 - 计划明细、已拣数量和最终实装数量守恒。
校验通过后: 校验通过后:
@@ -260,45 +260,53 @@ PDA 点击“完成装柜”时,服务端重新校验:
## 12. F22 客户资料与整柜出口报关 ## 12. F22 客户资料与整柜出口报关
### 12.1 客户上传资料 ### 12.1 F22-A `LOADED` 后通知报关并建立客户案例
入口:Client → 头程订单 → 报关资料。 入口:`LOADED` 事件 → Admin/Client → 报关资料。
客户只可对本企业订单上传退税/报关资料,选择资料类型并填写说明。文件归属、订单归属和客户身份由服务端校验,文件名不能代替合法文件 ID。 1. 装柜完成后按最终实装清单通知报关行,建立本柜报关批次和每个客户/入仓码的 `customerCustomsCase`;
2. 客户上传本企业资料,平台校验客户、订单、入仓码、实际装载数量和文件归属;
3. 平台将资料发送给报关行,记录发送时间、资料版本和 `roundNo`;
4. 报关行返回本轮回执,平台保存文件和回执字段,并向对应客户展示确认任务。
### 12.2 平台整柜报关 柜前可以存在资料准备或历史附件,但不创建本柜正式客户确认轮次,也不能显示“已通知报关”。客户资料缺失形成报关补件待办,未完成报关不得进入待发区或推进送港。
入口:Admin → 柜次详情 → 出口报关。 ### 12.2 F22-B 报关行回执与客户确认循环
1. 查看柜内所有入仓码及其资料覆盖情况; 客户查看报关行回执后有两个结果:
2. 对退税资料逐项核对,缺件时联系对应客户补充;
3. 开始报关时冻结当前参与资料和版本;
4. 线下向报关代理提交;首版不做外部系统直连;
5. 完成后为每份退税资料上传一一对应的完成文件;
6. 全买单柜由平台确认买单,并从导出中心获取最终实装买单明细;
7. 点击完成整柜报关,写入放行结果和历史。
报关完成后系统立即尝试国内出仓;若其他门禁尚未齐全,保留明确阻断项并由受控补偿重试,不能伪装为已离仓。 1. **确认**:当前客户案例进入 `CUSTOMER_CONFIRMED`,保存确认人、确认时间、回执版本和幂等键;
2. **打回**:当前案例进入 `NEEDS_RESUBMIT`,保存打回原因;客户重新上传/替换资料,平台重新发送报关行,报关行生成新回执,`roundNo` 加一后再次发客户确认。
## 13. F23 国内出仓 客户打回只重开对应客户案例,不重置其他客户已经确认的轮次。直到柜内所有客户案例都为 `CUSTOMER_CONFIRMED`,才允许进入整柜正式提交。
### 12.3 F22-C 所有客户通过后的整柜正式申报
1. 平台检查所有客户案例均已确认,冻结本柜最终实装和资料版本,生成整柜正式申报批次;
2. 将整柜资料提交报关行确认,报关行完成正式申报;首版不做外部系统直连,保留人工提交和审计记录;
3. 海关结果独立记录为查验、免查验放行、补件/退回、扣货等,不把客户确认回执直接当成海关放行;
4. 报关完成后进入待发区;报关事实不覆盖送港线的离仓、进港、甩柜事实。甩柜只改变运输船期,不回退报关资料、回执或客户确认。
## 13. F23 送港、进港与甩柜
### 13.1 出仓硬门禁 ### 13.1 出仓硬门禁
整柜所有关联入库单逐项检查: 送港线的离仓/进港门禁逐项检查:
- 无有效 HOLD; - 无有效 HOLD;
- 入库单为 `LOADED`; - 入库单为 `LOADED`;
- 装柜计划为 `COMPLETED`; - 装柜计划为 `COMPLETED`;
- PDA 柜次任务为 `COMPLETED`; - PDA 柜次任务为 `COMPLETED`;
- 订舱已 `RELEASED` 且分配当前柜次; - 订舱已 `RELEASED` 且分配当前柜次;
- 四步照片与有效铅封完整; - 五类证据与有效锁码文本完整;
- 整柜报关已完成并放行。 - 送港任务和当前船次分配完整;
- 报关完成是进入待发区以及后续仓库离开、送港和进港的前置。
独立拖车状态和独立船期字段提供调度参考,但不是当前确认离仓的硬门禁。拖车在全部订舱柜次离仓后自动完成。 订舱、拖车、仓库离开和港口进场属于待发区之后的送港线事实。容量不足时记录 `ROLLED_OVER`,保存原船次、滚动次数、新船次、预计开船时间和客户通知;不重新生成报关批次或客户确认任务。
### 13.2 自动与人工确认离仓 ### 13.2 自动与人工确认离仓
报关完成或其他门禁变化时系统自动尝试收敛。未自动完成时,平台在柜次/国内出仓页面: 送港状态变化或其他送港门禁满足时系统自动尝试收敛。未自动完成时,平台在柜次/送港页面:
1. 打开门禁清单; 1. 打开门禁清单;
2. 逐项处理未通过原因; 2. 逐项处理未通过原因;
@@ -309,13 +317,13 @@ PDA 点击“完成装柜”时,服务端重新校验:
成功后系统: 成功后系统:
- 写入整柜唯一国内离仓事实; - 写入整柜唯一国内离仓事实;
- 创建 `CarrierScheduleQuery`;
- 写入实际 `DEPARTED_WAREHOUSE` 节点; - 写入实际 `DEPARTED_WAREHOUSE` 节点;
- 触发出仓后船节点查询; - 写入 `PORT_RECEIVED` 或 `ROLLED_OVER`;
- 维护船次和开船前等待,不把预计 ETD 记成海运在途;
- 检查并尝试完成订舱级拖车; - 检查并尝试完成订舱级拖车;
- 保持跨区交接事件可重试且不重复建单。 - 保持跨区交接事件可重试且不重复建单。
实际离仓节点产生后禁止撤销。发现错误转入线下和后续阶段异常处理,不提供修改历史伪装未离仓的能力。 实际离仓和进港节点产生后禁止撤销。发现错误转入线下和后续阶段异常处理,不提供修改历史伪装未离仓或未进港的能力。报关线的客户打回、重新发送和海关查验单独记录,不回滚送港事实。
## 14. 状态和动作总表 ## 14. 状态和动作总表
@@ -325,8 +333,9 @@ PDA 点击“完成装柜”时,服务端重新校验:
| 装柜计划 | `EDITING → LOADING → COMPLETED` | 预装调整/PDA 作业/最终完成 | | 装柜计划 | `EDITING → LOADING → COMPLETED` | 预装调整/PDA 作业/最终完成 |
| 订舱 | `DRAFT → RELEASED` | 补齐资料并放舱 | | 订舱 | `DRAFT → RELEASED` | 补齐资料并放舱 |
| 拖车 | 非终态 → `COMPLETED` | 所有要求柜次实际离仓后自动完成 | | 拖车 | 非终态 → `COMPLETED` | 所有要求柜次实际离仓后自动完成 |
| 报关 | 资料收集 → 已冻结办理中 → 已完成/放行 | 客户上传、平台开始、上传回执并完成 | | 报关 | `WAITING_DOCUMENTS → SENT_TO_BROKER → RECEIPT_PENDING_CUSTOMER_CONFIRM → CUSTOMER_CONFIRMED / NEEDS_RESUBMIT → ALL_CUSTOMERS_CONFIRMED → FORMAL_SUBMITTED → INSPECTION/RELEASED` | 装柜后通知报关行;回执必须经对应客户确认,打回则新资料/新回执轮次 |
| 国内出仓 | 等待门禁 → 可出仓 → 已离仓 | 自动尝试或平台确认 | | 送港 | `WAITING_FOR_LOADING → PORT_DELIVERY_PENDING → DEPARTED_WAREHOUSE → IN_TRANSIT_TO_PORT → PORT_RECEIVED / ROLLED_OVER` | 报关完成后进入待发区,再安排拖车和进港;容量不足时在原柜船期上人工修改船信息并留痕 |
| 海运 | `WAITING_SAILING → VESSEL_DEPARTED → IN_TRANSIT` | 只有承运船舶真实开航才进入海运节点 |
主状态只表达阶段结果。订舱、拖车、PDA、证据和报关保持关联子状态,页面应汇聚展示,但不能互相覆盖。 主状态只表达阶段结果。订舱、拖车、PDA、证据和报关保持关联子状态,页面应汇聚展示,但不能互相覆盖。
@@ -358,8 +367,11 @@ WAIT_SPLIT 入库单/已封托托盘
→ 预装确认/动态调整 → 预装确认/动态调整
→ PDA 实装 + 五类证据 → PDA 实装 + 五类证据
→ COMPLETED / LOADED + 数量分片 + 跨区快照 → COMPLETED / LOADED + 数量分片 + 跨区快照
→ 整柜报关放行 ├─ 报关线:通知报关 → 客户资料 → 报关行回执 → 客户确认/打回重做
→ 国内离仓 + DEPARTED_WAREHOUSE + 船节点查询任务 │ → 所有客户通过 → 整柜正式申报 → 查验/放行
└─ 送港线:拖车 → DEPARTED_WAREHOUSE → PORT_RECEIVED
→ 甩柜/改配(如发生)→ 等待实际开船
→ VESSEL_DEPARTED → 海运节点查询
``` ```
阶段完成必须同时满足: 阶段完成必须同时满足:
@@ -367,14 +379,14 @@ WAIT_SPLIT 入库单/已封托托盘
- [ ] 最终柜次、装柜计划、订舱、真实柜号关联可追溯 - [ ] 最终柜次、装柜计划、订舱、真实柜号关联可追溯
- [ ] 全部实装箱/托盘/SKU 与入库单数量守恒 - [ ] 全部实装箱/托盘/SKU 与入库单数量守恒
- [ ] PDA 任务完成且无未解决异常 - [ ] PDA 任务完成且无未解决异常
- [ ] 四步照片、铅封照片和铅封号完整有效 - [ ] 五类证据和锁码文本完整有效
- [ ] 装柜计划 `COMPLETED`,实装入库单 `LOADED` - [ ] 装柜计划 `COMPLETED`,实装入库单 `LOADED`
- [ ] 部分装载时已装子单和余量子单正确 - [ ] 部分装载时已装子单和余量子单正确
- [ ] 整柜报关已完成并放行 - [ ] 报关线已为每个客户建立案例,回执、确认/打回和每轮资料版本可追溯
- [ ] 所有入库单无 HOLD - [ ] 送港线已记录唯一国内离仓历史;如已进港,存在 `PORT_RECEIVED`,如甩柜,存在原船次/改配船次历史
- [ ] 唯一国内离仓历史存在 - [ ] 客户全部确认后才允许整柜正式提交;正式申报后的查验/放行结果单独记录
- [ ] 第一条实际 `DEPARTED_WAREHOUSE` 存在 - [ ] 船舶实际开航后才写入 `VESSEL_DEPARTED` 并启动海运节点查询
- [ ] 船节点查询任务和跨区事件可幂等重试 - [ ] 跨区事件可幂等重试;甩柜/改配只新增船期事实,不覆盖报关资料、回执和客户确认
## 17. 易用性与数据流评审问题 ## 17. 易用性与数据流评审问题
@@ -408,7 +420,7 @@ WAIT_SPLIT 入库单/已封托托盘
- `docs/国内货柜履约/README.md` - `docs/国内货柜履约/README.md`
- `docs/国内货柜履约/国内货柜履约页面与原型清单.md` - `docs/国内货柜履约/国内货柜履约页面与原型清单.md`
- `docs/头程下单到尾程出库现状流程全景清单.md` - `docs/归档/头程到尾程/头程下单到尾程出库现状流程全景清单.md`
- `docs/统一订单主状态与操作契约.md` - `docs/统一订单主状态与操作契约.md`
- `apps/admin-web/src/modules/container-loading/` - `apps/admin-web/src/modules/container-loading/`
- `apps/admin-web/src/modules/loading-lists/` - `apps/admin-web/src/modules/loading-lists/`
@@ -422,3 +434,4 @@ WAIT_SPLIT 入库单/已封托托盘
- `baiyue-firstleg/firstleg/src/main/java/com/baiyue/firstleg/service/SmartLoadingService.java` - `baiyue-firstleg/firstleg/src/main/java/com/baiyue/firstleg/service/SmartLoadingService.java`
- `baiyue-firstleg/firstleg/src/main/java/com/baiyue/firstleg/service/LoadingPickService.java` - `baiyue-firstleg/firstleg/src/main/java/com/baiyue/firstleg/service/LoadingPickService.java`
- `baiyue-firstleg/firstleg/src/main/java/com/baiyue/firstleg/outbound/dispatch/service/OutboundDispatchService.java` - `baiyue-firstleg/firstleg/src/main/java/com/baiyue/firstleg/outbound/dispatch/service/OutboundDispatchService.java`
@@ -574,7 +574,7 @@ Firstleg 正式入库单 + 稳定箱码
## 16. 事实来源 ## 16. 事实来源
- `docs/头程下单到尾程出库现状流程全景清单.md` - `docs/归档/头程到尾程/头程下单到尾程出库现状流程全景清单.md`
- `docs/入库测量与计费/README.md` - `docs/入库测量与计费/README.md`
- `docs/入库测量与计费/入库测量与计费需求优化版-v2-测量计费入库主流程.md` - `docs/入库测量与计费/入库测量与计费需求优化版-v2-测量计费入库主流程.md`
- `docs/统一订单主状态与操作契约.md` - `docs/统一订单主状态与操作契约.md`
@@ -590,3 +590,4 @@ Firstleg 正式入库单 + 稳定箱码
- `baiyue-firstleg/firstleg/src/main/java/com/baiyue/firstleg/service/InitialInboundPricingService.java` - `baiyue-firstleg/firstleg/src/main/java/com/baiyue/firstleg/service/InitialInboundPricingService.java`
- `baiyue-firstleg/firstleg/src/main/java/com/baiyue/firstleg/service/DropshipPalletizationService.java` - `baiyue-firstleg/firstleg/src/main/java/com/baiyue/firstleg/service/DropshipPalletizationService.java`
- `baiyue-firstleg/firstleg/src/main/resources/openapi/dropship-palletization-v1.yaml` - `baiyue-firstleg/firstleg/src/main/resources/openapi/dropship-palletization-v1.yaml`
@@ -345,6 +345,8 @@ PDA 扫描托盘后按服务端返回的 `palletVersion`、`positionVersion` 执
## 12. 阶段完成判定 ## 12. 阶段完成判定
测试环境综合证据 `baiyue-firstleg/reports/admin-full-postdeploy-66c2651b.json` 已覆盖海外 PDA、收货、库存、库内服务和 `phase5-overseas-fulfillment`;上述模块失败数均为 0。这里的清单继续保留为逐票验收条件,不能用综合报告替代具体柜次的业务核对。
主链完成必须满足: 主链完成必须满足:
- [ ] 柜号由正确仓库操作员认领 - [ ] 柜号由正确仓库操作员认领
@@ -264,6 +264,8 @@ INBOUND_COMPLETED + 可用库存
## 13. 全流程最终完成判定 ## 13. 全流程最终完成判定
测试环境综合证据 `baiyue-firstleg/reports/admin-full-postdeploy-66c2651b.json` 已覆盖 `phase4-overseas-dispatch`、`phase5-terminal-drayage`、`phase5-overseas-fulfillment`、客户服务和跨区回写模块,相关模块失败数均为 0。清单仍按具体派送单保留,最终上线前需要用业务柜次逐项复核。
- [ ] 排车候选来自真实、可用且未被其他业务占用的库存 - [ ] 排车候选来自真实、可用且未被其他业务占用的库存
- [ ] 草稿锁、正式锁和取消/完成释放均可追溯 - [ ] 草稿锁、正式锁和取消/完成释放均可追溯
- [ ] 排车路线由实际目的地生成 - [ ] 排车路线由实际目的地生成
@@ -1,7 +1,7 @@
# 阶段四:海运、目的港与尾程入仓计划 # 阶段四:海运、目的港与尾程入仓计划
> 对应全景流程:F24~F27。 > 对应全景流程:F24~F27。
> 阶段起点:柜次已确认国内离仓,存在实际 `DEPARTED_WAREHOUSE` 节点和可查询的真实订舱/柜次。 > 阶段起点:柜次已完成送港/进港或甩柜处理,并产生承运船舶实际 `VESSEL_DEPARTED`/`DEPARTED_ORIGIN_PORT` 节点;真实 `DEPARTED_WAREHOUSE` 和 `PORT_RECEIVED` 属于阶段三送港线事实。
> 阶段终点:跨区尾程订单完整生成,整柜每票入仓计划及托盘/库位资源已生成或有明确资源失败待办,订单进入 `INBOUND_PLANNED`。 > 阶段终点:跨区尾程订单完整生成,整柜每票入仓计划及托盘/库位资源已生成或有明确资源失败待办,订单进入 `INBOUND_PLANNED`。
> 本阶段同时维护船舶/货柜轨迹和尾程业务准备,但两类状态不得互相冒充。 > 本阶段同时维护船舶/货柜轨迹和尾程业务准备,但两类状态不得互相冒充。
@@ -9,7 +9,7 @@
本阶段完成四条相互关联但独立的链路: 本阶段完成四条相互关联但独立的链路:
1. 从国内离仓开始查询并保存十个标准船节点; 1. 从承运船舶实际开航开始查询并保存十个标准船节点;
2. 管理目的港清关、海外码头车队、提柜、预计到仓和还空; 2. 管理目的港清关、海外码头车队、提柜、预计到仓和还空;
3. 将国内最终实装快照可靠投递到海外区域并创建尾程订单; 3. 将国内最终实装快照可靠投递到海外区域并创建尾程订单;
4. 按整柜维护每票计划并转换为可执行的海外入仓计划和资源。 4. 按整柜维护每票计划并转换为可执行的海外入仓计划和资源。
@@ -35,9 +35,9 @@
## 3. 阶段前置检查 ## 3. 阶段前置检查
- 柜次存在真实集装箱号、订舱、提单号和国内离仓事实; - 柜次存在真实集装箱号、订舱、提单号、送港/进港事实和实际开船节点;
- 装柜完成事件包含最终实装订单、入仓单、目的类型、箱数及必要托盘/SKU/箱唛快照; - 装柜完成事件包含最终实装订单、入仓单、目的类型、箱数及必要托盘/SKU/箱唛快照;
- 国内四步照片和铅封证据已经冻结; - 国内五类装柜证据和锁码文本已经冻结;
- 接柜海外仓是 Warehouse 中 `ACTIVE + OVERSEAS + RECEIVING` 的平台共享物理仓; - 接柜海外仓是 Warehouse 中 `ACTIVE + OVERSEAS + RECEIVING` 的平台共享物理仓;
- FBA 目的仓是 Warehouse 有效公共主档,不能用接柜仓或国内仓代替; - FBA 目的仓是 Warehouse 有效公共主档,不能用接柜仓或国内仓代替;
- 船司/轨迹查询标识足以唯一指向目标订舱和柜次; - 船司/轨迹查询标识足以唯一指向目标订舱和柜次;
@@ -47,9 +47,11 @@
### 4.1 查询任务创建 ### 4.1 查询任务创建
国内出仓确认事务幂等创建 `CarrierScheduleQuery`。任务必须绑定真实订舱、柜次以及可用的船司、船名航次、提单号或柜号,不创建脱离业务单据的孤立轮询任务。 承运船舶实际开航事务幂等创建 `CarrierScheduleQuery`。任务必须绑定真实订舱、柜次以及可用的船司、船名航次、提单号或柜号,不创建脱离业务单据的孤立轮询任务。送港、进港、甩柜和客户报关确认在阶段三分别记录,不能用预计 ETD 提前创建“海运中”展示。
首个实际节点由国内出仓写入: 标准节点保留国内送港事实,但海运查询的起点是实际开船:
`DEPARTED_WAREHOUSE`、`AT_ORIGIN_PORT` 和 `LOADED_ON_VESSEL` 可以作为送港/装船历史补录;客户的“海运中”节点和定时船节点查询以真实 `DEPARTED_ORIGIN_PORT`/`VESSEL_DEPARTED` 为起点。
```text ```text
10 DEPARTED_WAREHOUSE 已离开国内仓 10 DEPARTED_WAREHOUSE 已离开国内仓
@@ -327,6 +329,8 @@ Lastleg 消费步骤:
## 10. 阶段完成判定 ## 10. 阶段完成判定
现有测试环境综合证据 `baiyue-firstleg/reports/admin-full-postdeploy-66c2651b.json` 中,`phase4-carrier-nodes`、`phase4-overseas-pda`、`phase4-overseas-pda-operations`、`phase4-overseas-inbound-operations`、`phase4-overseas-dispatch`、`phase4-tail-order-controls` 和 `phase5-overseas-fulfillment` 均为通过;每个模块的失败数为 0。F23.3 的最新船期客户端投影另见 `baiyue-firstleg/reports/transport-projection-after-schedule-update-20260927.json`。
- [ ] 国内离仓产生的船节点任务绑定真实订舱和柜次 - [ ] 国内离仓产生的船节点任务绑定真实订舱和柜次
- [ ] 节点预计/实际/观测时间没有混用 - [ ] 节点预计/实际/观测时间没有混用
- [ ] 异常事实与正常节点分开保存 - [ ] 异常事实与正常节点分开保存
+91
View File
@@ -0,0 +1,91 @@
# 头程到尾程流程节点梳理
> **当前用途:全流程收尾变更的流程入口。** F01-F40 的业务基线已经确认,报关协同代码已接入并通过测试环境验收;本文件只保留三大业务块、关键节点和节点之间的关系,便于查找和修改。报关实现细节请看[报关代码开发交接清单](头程到尾程/报关代码开发交接清单.md),历史开发规划、进度、门禁和评审不在这里继续维护。
>
> **维护原则:** 客户看到的是进度投影,后台看到的是业务对象节点,明细节点记录真实操作和结果。三者使用同一组业务事实,不另建一套客户状态。
## 一、三大业务块
| 业务块 | 覆盖范围 | 对外主要进度 | 后台主要对象 | 分段详情 |
|---|---|---|---|---|
| **头程下单** | 客户下单、审核、国内到仓、测量、计费、确认、组托 | 待下单 → 审核中 → 待到仓/测量 → 待分柜 | 订单、入仓单、测量记录、费用记录、托盘 | [阶段一](头程到尾程分阶段流程/阶段一-客户准入与头程下单.md)、[阶段二](头程到尾程分阶段流程/阶段二-国内到仓测量计费与组托.md) |
| **海运(货柜)** | 分柜、订舱、拖车、拣货、装柜、报关协同、待发区、送港、进港、甩柜、实际开船、目的港和尾程计划 | 待分柜 → 装柜中 → 报关中 → 待发区 → 送港/待开船 → 海运中 → 待入仓 | 柜次、装柜任务、报关批次、待发区、送港任务、船次、尾程入仓计划 | [阶段三](头程到尾程分阶段流程/阶段三-国内货柜履约与出仓.md)、[阶段四](头程到尾程分阶段流程/阶段四-海运目的港与尾程计划.md)、[报关专题](国内货柜履约/报关资料与船期价格接入梳理.md) |
| **尾程入库和派送** | 海外接柜、拆柜实收、入库、库存服务、排车、出库、派送、签收、异常回写 | 待接柜 → 入库中 → 待派送 → 出库/派送中 → 已签收/异常 | 接柜任务、入库单、库存、出库单、派送单、异常单 | [阶段五](头程到尾程分阶段流程/阶段五-海外接柜库存与库内服务.md)、[阶段六](头程到尾程分阶段流程/阶段六-海外排车出库派送与回写.md) |
三大块是客户和产品的展示分组;F01~F40 是后台查找和验收用的内部编号,不代表客户必须看到 40 个节点,也不代表所有动作严格串行。
## 二、主流程
```text
头程下单
客户下单 → 订单审核 → 国内到仓 → 测量/计费 → 费用确认(不阻断)→ 组托/待分柜
↓
海运(货柜)
分柜/订舱/拖车 → 拣货 → 装柜完成(LOADED)
└─ 报关协同:客户资料 → 报关行回执 → 客户确认/打回重做 → 全部客户通过
→ 整柜资料交报关行 → 正式申报 → 查验或不查验放行
↓ 报关完成
进入待发区
送港运输:待发区 → 离仓 → 送港 → 进港 → (容量不足时)甩柜/改配
↓
船舶实际开航后进入海运节点
↓
目的港清关/提柜 → 尾程入仓计划
↓
尾程入库和派送
海外接柜 → 拆柜实收 → 入库/库存 → 排车 → 出库 → 派送 → 签收/异常回写
```
## 三、关键节点总表
| 编号 | 业务块 | 客户进度节点 | 后台管理节点 | 真实明细节点 | 完成结果或分支 |
|---|---|---|---|---|---|
| F01-F07 | 头程下单 | 待下单、审核中、已审核 | 企业、订单、审核任务 | 填写、提交、补件、审核、生成入仓单 | 审核通过后进入国内履约 |
| F08-F10 | 头程下单 | 待到仓、测量中、待确认 | 入仓单、测量记录 | 到仓收货、扫码、称重、测量、审核 | 形成可排柜的实测数据 |
| F11-F13 | 头程下单 | 费用待确认、国内扣货/解除、待组托、待分柜 | 费用版本、确认记录、HOLD 记录、托盘 | 计费、推送、客户确认、国内扣货/解除、组托/封托 | 费用确认不阻断主链;国内扣货单独控制作业门禁;装柜不能代替客户确认费用 |
| F14-F20 | 海运(货柜) | 待分柜、订舱中、装柜准备/进行中 | 柜次、装柜计划、拖车任务、拣货任务 | 分柜、订舱、排车、拣货、拍照、铅封、数量核对 | 通过装柜门禁后才能完成装柜 |
| F21 | 海运(货柜) | 国内已装柜 | 装柜任务已完成 | 实际柜号、实装数量、装柜证据确认 | 产生 `LOADED`;完成报关后才进入待发区 |
| F22 | 海运(货柜) | 报关确认中、待补资料、已提交报关 | 客户报关案例、报关批次 | 收集资料、发报关行、接收回执、客户确认或打回、重新上传和重发 | **已实现并通过真实 HTTP 验收**;柜内所有客户确认后,才能提交整柜资料并正式申报;客户确认不等于海关放行 |
| F23 | 海运(货柜) | 待发区、送港中、已进港、待开船、已甩柜 | 待发区、送港/拖车任务、港口和船次事实 | 报关完成后入待发区、离仓、送港、进港、甩柜、改配 | 报关完成是进入待发区的门槛;甩柜/改配只改变运输船期,不重做已完成报关 |
| F24 | 海运(货柜) | 海运中 | 船次实际状态 | 承运船舶实际开航、船期回写 | 只有实际开航后进入海运节点 |
| F25-F27 | 海运(货柜) | 目的港处理中、待海外接柜 | 目的港清关/提柜、尾程订单、入仓计划 | 清关、提柜、创建尾程计划 | 形成海外接柜输入,不等于已经入库 |
| F28-F33 | 尾程入库和派送 | 待接柜、入库中、库存可用 | 接柜任务、入库单、库存 | 接柜、拆柜、收货核对、上架、盘点及库内服务 | 实收核平并入账后形成可用库存 |
| F34-F37 | 尾程入库和派送 | 待派送、出库处理中、已出库 | 排车、出库单、派送单 | 生成出库/派送单、拣货、复核、发车 | 出库和签收分开记录 |
| F38-F40 | 尾程入库和派送 | 派送中、已签收、异常 | 派送单、签收和异常单 | 送达、签收、拒收/部分拒收、退回、最终回写 | 异常保留原事实和恢复结果;全部有效分片完成后订单收口 |
## 四、必须保持的流程关系
### 1. 报关完成后进入待发区,船期单独推进
`LOADED` 只表示货物已经实际装入集装箱并完成装柜记录。之后先完成报关协同,报关完成后货物进入待发区:
- **报关协同线**:通知报关行,按客户/入仓码收集资料;报关行生成回执后发客户确认。客户打回时,只重做对应客户的资料、发送和回执,直到柜内所有客户都确认。全部确认后,将整柜资料交报关行确认,再记录正式申报和海关结果。
- **待发区与船期线**:报关完成后进入待发区,再安排离仓、送港和进港;船舱不足时记录甩柜和改配。甩柜/改配只人工修改原柜的船名、航次和船期,不影响已完成的报关资料、回执和客户确认。
报关行回执、客户确认、正式申报、海关放行、进入待发区、进港、甩柜和实际开船是不同事实,不能合并成一个“报关完成”或“海运中”。
### 2. 费用确认不阻断装柜主链
费用确认是头程下单块中的并行事项。客户未确认时可以继续排柜、拣货和装柜。按阶段二及 Firstleg 当前服务指引,装柜完成可以触发平台费用确认与发布,但不能代替客户主动确认;客户已确认且本票装柜完成时才最终冻结。费用确认与报关资料的客户确认分别记录。
### 3. 异常附着在主节点上
查验、扣货、资料打回、甩柜、拒收和跨区回写失败都应保留发生在哪个主节点、责任人、处理结果和恢复时间。异常可以阻断对应分支,但不要用“异常”覆盖主流程已经发生的事实。
## 五、三层节点的使用口径
| 层级 | 解决的问题 | 示例 |
|---|---|---|
| 客户进度节点 | 客户现在处于哪一段、下一步做什么 | 报关确认中、送港中、海运中、入库中 |
| 后台管理节点 | 哪个业务对象正在处理、由谁处理 | 报关批次待客户确认、送港任务已进港、派送单已出库 |
| 真实明细节点 | 事实何时发生、凭什么证明 | 上传资料、回执版本、客户确认、离仓时间、进港记录、签收凭证 |
客户页面只展示与自身相关的进度和资料;后台详情保留完整明细;异常作为附加状态展示,不另建一条互相矛盾的主流程。
## 六、查找和修改规则
1. **改流程关系或客户节点**:先改本文件,再检查对应阶段文档的名称和链接。
2. **改单个阶段的字段、页面操作或权限**:只改对应的六份阶段文档和实际契约,不回写历史开发规划。
3. **改报关资料、回执确认或船期价格**:以[报关资料与船期价格接入梳理](国内货柜履约/报关资料与船期价格接入梳理.md)为专题入口,同时核对本文件中的 F22/F23 关系。
4. **开发规划、进度、开工门禁、验收任务、旧审计和优化方案**:保留原文作为追溯资料,标记为冻结,不作为当前流程入口。
5. **新增或调整节点时**:先判断它属于客户进度、后台对象还是明细事实;只有确实改变三大块关系时才改总表,避免在多份文档复制同一段流程。
+10
View File
@@ -0,0 +1,10 @@
# 文档归档
这里保存已经完成开发阶段、当前不作为日常流程入口的历史文档。归档只改变文件位置,不删除内容;需要追溯旧决策、旧验收或旧开发计划时再进入对应子目录。
## 归档目录
- [头程到尾程](头程到尾程/README.md):全流程操作手册、旧现状全景、AI 上下文和易用性方案。
- [国内货柜履约归档](../国内货柜履约/归档/README.md):开发规划、进度、门禁、验收矩阵、审计和旧确认材料。
当前流程只从 [头程到尾程流程节点梳理](../头程到尾程流程节点梳理.md) 开始查找。
+11
View File
@@ -0,0 +1,11 @@
# 头程到尾程历史文档
本目录只保留历史操作说明、旧版现状盘点和流程优化材料。它们不再作为当前流程或开发计划入口;当前节点关系以[头程到尾程流程节点梳理](../../头程到尾程流程节点梳理.md)为准,分段细节见[头程到尾程分阶段流程](../../头程到尾程分阶段流程/README.md)。
## 文件
- [全流程操作手册](头程下单到尾程出库全流程操作手册.md)
- [现状流程全景清单](头程下单到尾程出库现状流程全景清单.md)
- [AI 流程优化上下文包](头程到尾程AI流程优化上下文包.md)
- [易用性与数据流转优化方案](头程下单到尾程出库流程易用性与数据流转优化方案.md)
@@ -5,7 +5,7 @@
> 当前口径:以现行服务端模块指引、页面入口和代码状态机为准。历史设计与当前实现冲突的地方集中列在第 11 节,旧文档不能直接作为操作依据。 > 当前口径:以现行服务端模块指引、页面入口和代码状态机为准。历史设计与当前实现冲突的地方集中列在第 11 节,旧文档不能直接作为操作依据。
> 不在主链内展开:换标、仓储转运、货物废弃、退货换标、异常退回、客户回访、海外采购和本土散板;这些能力在第 9 节说明如何接入出库。 > 不在主链内展开:换标、仓储转运、货物废弃、退货换标、异常退回、客户回访、海外采购和本土散板;这些能力在第 9 节说明如何接入出库。
> 完整现状流程目录:见[《头程下单到尾程出库现状流程全景清单》](头程下单到尾程出库现状流程全景清单.md)。该清单以 F01~F40 覆盖主链、并行流程、条件分支和异常流;本文侧重一票主链如何实际操作。 > 当前流程基线:见[《头程到尾程流程节点梳理(重构版)》](../../头程到尾程流程节点梳理.md)。[《头程下单到尾程出库现状流程全景清单》](头程下单到尾程出库现状流程全景清单.md)仅保留旧版 AS-IS 证据;本文侧重一票主链如何按最新报关/送港并行流程实际操作。
## 1. 一张图看完整主链 ## 1. 一张图看完整主链
@@ -23,10 +23,11 @@
创建模拟柜/订舱 → 智能或人工排柜 → 预装确认 创建模拟柜/订舱 → 智能或人工排柜 → 预装确认
↓ ↓
国内 PDA 拣货装柜 → 五类证据和铅封 → 装柜完成 LOADED 国内 PDA 拣货装柜 → 五类证据和铅封 → 装柜完成 LOADED
├─ 报关线:通知报关行 → 客户资料 → 报关行回执 → 客户确认/打回重做
│ → 所有客户通过 → 整柜正式申报 → 查验/放行
└─ 送港线:拖车 → 离仓 → 送港/进港 → 甩柜/改配(如发生)→ 实际开船
↓ ↓
整柜出口报关完成 → 系统自动收敛或平台确认国内出仓 实际开船后进入海运节点:装船/离港 → 在途 → 到目的港 → 卸船 → 可提柜
↓
船节点:离开国内仓 → 起运港 → 装船 → 在途 → 到目的港 → 卸船 → 可提柜
↓ ↓
装柜完成事件跨区 → 海外生成 PENDING_ASSIGNMENT 尾程订单 装柜完成事件跨区 → 海外生成 PENDING_ASSIGNMENT 尾程订单
↓ ↓
@@ -43,9 +44,10 @@
主链有三个不能混淆的“出库/出仓”: 主链有三个不能混淆的“出库/出仓”:
1. 国内装柜完成:入库单为 `LOADED`,表示货已经装入国内出口柜,不等于柜已离开国内仓。 1. 国内装柜完成:入库单为 `LOADED`,表示货已经装入国内出口柜;同时启动报关线和送港线。
2. 国内出仓:整柜通过报关等门禁并确认离仓,系统开始船节点跟踪。 2. 国内送港:送港线记录拖车、仓库离开、进港和甩柜;客户报关确认不阻断送港,进港不等于报关完成。
3. 海外尾程出库:海外仓库存经排车/PDA 作业离仓,出库单为 `OUTBOUNDED`。 3. 海运起点:承运船舶真实开航后才进入海运节点,预计 ETD 不推进海运中。
4. 海外尾程出库:海外仓库存经排车/PDA 作业离仓,出库单为 `OUTBOUNDED`。
### 1.1 操作与交接总表 ### 1.1 操作与交接总表
@@ -63,10 +65,10 @@
| 8 | 国内履约运营 / Admin | 创建模拟柜,选择候选,人工/智能排柜 | 生成稳定柜次、预装计划、分配明细和容量占用 | 订舱/柜务运营 | | 8 | 国内履约运营 / Admin | 创建模拟柜,选择候选,人工/智能排柜 | 生成稳定柜次、预装计划、分配明细和容量占用 | 订舱/柜务运营 |
| 9 | 订舱/柜务运营 / Admin | 建订舱草稿、补资料、放舱,关联柜次并录入真实柜号 | 冻结订舱和运输快照,建立订舱需求与柜次分配关系 | 国内履约运营 | | 9 | 订舱/柜务运营 / Admin | 建订舱草稿、补资料、放舱,关联柜次并录入真实柜号 | 冻结订舱和运输快照,建立订舱需求与柜次分配关系 | 国内履约运营 |
| 10 | 国内履约运营 / Admin | 核对预装清单并确认 | 固化预装快照,生成或开放国内 PDA 任务 | 国内 PDA | | 10 | 国内履约运营 / Admin | 核对预装清单并确认 | 固化预装快照,生成或开放国内 PDA 任务 | 国内 PDA |
| 11 | 国内 PDA | 扫箱/整托拣货,批量提交,拍四步照片和铅封,完成装柜 | 计划 `COMPLETED`、入库单 `LOADED`,发布最终实装事件 | 报关/出仓运营 | | 11 | 国内 PDA | 扫箱/整托拣货,批量提交,拍五类证据和锁码,完成装柜 | 计划 `COMPLETED`、入库单 `LOADED`,发布最终实装事件并启动报关/送港两条线 | 报关/送港运营 |
| 12 | 报关运营 / Admin | 上传出口报关资料并完成报关 | 报关状态完成;系统自动尝试收敛国内出仓门禁 | 出仓运营/系统 | | 12 | 报关运营 / Admin、Client | `LOADED` 后收集客户资料、发报关行、上传回执、发客户确认;打回则重做,所有客户通过后提交整柜正式申报 | 每客户确认轮次可追溯;整柜正式申报后记录查验/放行,不把回执上传当成客户确认 | 报关运营/客户 |
| 13 | 出仓运营 / Admin | 自动未收敛时,在柜次门禁面板点击“确认离仓” | 整柜进入已离仓事实,自动建船节点任务和 `DEPARTED_WAREHOUSE` | 船务/海外运营 | | 13 | 送港运营 / Admin | 独立安排拖车、离仓、送港和进港;容量不足记录甩柜/改配 | 写入 `DEPARTED_WAREHOUSE`、`PORT_RECEIVED` 或 `ROLLED_OVER`,不等待报关客户确认 | 船务/海外运营 |
| 14 | 船务 / Admin、第三方 | 查看自动轨迹,缺失时按权限补录真实节点 | 实际节点单调推进;到 `PICKUP_READY` 后开放海外 PDA 候选 | 海外计划运营、海外 PDA | | 14 | 船务 / Admin、第三方 | 只在承运船舶真实开航后查看/补录船节点 | 写入 `VESSEL_DEPARTED` 并进入海运节点;到 `PICKUP_READY` 后开放海外 PDA 候选 | 海外计划运营、海外 PDA |
| 15 | 海外计划运营 / Admin | 在尾程订单按柜预览阻断项并确认转换入仓计划 | `PENDING_ASSIGNMENT → INBOUND_PLANNED`;逐票建计划并生成/绑定托盘资源 | 海外 PDA | | 15 | 海外计划运营 / Admin | 在尾程订单按柜预览阻断项并确认转换入仓计划 | `PENDING_ASSIGNMENT → INBOUND_PLANNED`;逐票建计划并生成/绑定托盘资源 | 海外 PDA |
| 16 | 海外 PDA | 选柜锁定,拍车牌/封签/开柜照片,确认签收 | 建立柜级收货会话,冻结实际接柜仓和操作员 | 海外 PDA | | 16 | 海外 PDA | 选柜锁定,拍车牌/封签/开柜照片,确认签收 | 建立柜级收货会话,冻结实际接柜仓和操作员 | 海外 PDA |
| 17 | 海外 PDA | FBA 按 SKU+箱数收货,OVERSEAS 按箱唛逐箱收货,完成整柜 | 尾程进入 `INBOUND_COMPLETED`;生成库存余额、仓位、托盘、流水并回写国内 | 海外排车运营 | | 17 | 海外 PDA | FBA 按 SKU+箱数收货,OVERSEAS 按箱唛逐箱收货,完成整柜 | 尾程进入 `INBOUND_COMPLETED`;生成库存余额、仓位、托盘、流水并回写国内 | 海外排车运营 |
@@ -239,43 +241,37 @@
装柜证据: 装柜证据:
- 空仓、半仓、满仓、锁仓四步照片; - 空仓、半仓、满仓、锁仓、带锁码照五类证据和锁码文本;
- 带有效铅封号的铅封证据;
- 同类可追加,错误证据作废并保留审计,不硬删除历史。 - 同类可追加,错误证据作废并保留审计,不硬删除历史。
最终完成门禁:全部计划明细核平、五类有效证据齐全、铅封号存在且真实柜号已就绪。完成后装柜计划为 `COMPLETED`,来源入库单为 `LOADED`。 最终完成门禁:全部计划明细核平、五类有效证据齐全、铅封号存在且真实柜号已就绪。完成后装柜计划为 `COMPLETED`,来源入库单为 `LOADED`。
### 6.3 出口报关与国内出仓 ### 6.3 报关线与送港线
入口:Admin → 货柜管理 → 柜次详情/国内出仓。 入口:Admin → 货柜管理 → 柜次详情;客户确认入口为 Client → 头程订单 → 报关资料。
当前整柜出仓门禁: **报关线**按客户案例推进:
| 门禁 | 要求 | 1. `LOADED` 后通知报关行,按客户/入仓码收集资料并发送;
|---|---| 2. 授权人员上传报关行本轮回执,客户查看并确认;
| 扣货 | 柜内入库单均未被扣货 | 3. 客户打回时保存原因,重新上传/替换资料,重新发送报关行并生成新回执轮次;
| 入库单 | 所有绑定入库单为 `LOADED` | 4. 柜内所有客户均确认后,冻结整柜资料并提交报关行正式申报;
| 装柜计划 | `COMPLETED` | 5. 记录查验、不查验放行、补件/退回等海关结果。
| 国内 PDA | 拣货任务 `COMPLETED` |
| 订舱 | 已放舱并分配当前柜次,状态 `RELEASED` |
| 装柜证据 | 四步照片和有效铅封齐全 |
| 出口报关 | 整柜报关 `COMPLETED` |
拖车状态和独立船期当前只作为参考,不属于服务端硬门禁。出口报关完成后,系统会在全部门禁满足时自动尝试确认离仓;若未自动收敛,平台可在“国内出仓门禁”面板点击“确认离仓”。 **送港线**独立推进:
成功结果: 1. 校验 `LOADED`、真实柜号、订舱和拖车条件,安排车辆离仓、送港和进港;
2. 写入唯一 `DEPARTED_WAREHOUSE` 和 `PORT_RECEIVED` 事实;
3. 船舱不足时写入 `ROLLED_OVER`,保存原船次、改配船次、滚动次数和客户通知;
4. 送港线不等待客户报关确认,报关线也不等待送港完成。
- 整柜出仓状态进入 `WAITING_FOR_LOADING`(现有内部编码,业务含义是已确认离开国内仓); 只有承运船舶真实开航才写入 `VESSEL_DEPARTED` 并进入海运节点。预计 ETD、已离仓或已进港不能显示为海运中。
- 只写一次整柜离仓历史;
- 自动创建唯一船节点查询任务和第一条实际 `DEPARTED_WAREHOUSE`;
- 尝试完成同订舱关联的国内拖车单;
- 已产生实际离仓节点后不得撤销。
## 7. 阶段四:海运节点、跨区尾程建单和海外入仓 ## 7. 阶段四:海运节点、跨区尾程建单和海外入仓
### 7.1 船节点推进 ### 7.1 船节点推进
船节点任务由国内出仓自动创建,不能由操作员另造一套。标准实际节点按以下顺序单调推进: 船节点任务在承运船舶真实开航后幂等创建,不能由操作员另造一套。标准实际节点按以下顺序单调推进:
`DEPARTED_WAREHOUSE → AT_ORIGIN_PORT → LOADED_ON_VESSEL → DEPARTED_ORIGIN_PORT → IN_TRANSIT → ARRIVED_DESTINATION_PORT → DISCHARGED_FROM_VESSEL → PICKUP_READY → PICKED_UP → EMPTY_RETURNED` `DEPARTED_WAREHOUSE → AT_ORIGIN_PORT → LOADED_ON_VESSEL → DEPARTED_ORIGIN_PORT → IN_TRANSIT → ARRIVED_DESTINATION_PORT → DISCHARGED_FROM_VESSEL → PICKUP_READY → PICKED_UP → EMPTY_RETURNED`
@@ -481,8 +477,8 @@ OVERSEAS:
1. 费用不再阻断待分柜。旧测量文档把“发送费用给客户”写成入库成功节点;当前 Firstleg 口径是测量审核通过后直接进入 `WAIT_SPLIT`,费用独立版本化。 1. 费用不再阻断待分柜。旧测量文档把“发送费用给客户”写成入库成功节点;当前 Firstleg 口径是测量审核通过后直接进入 `WAIT_SPLIT`,费用独立版本化。
2. 跨区事件不自动建海外入仓计划。旧海外验收手册曾写“装柜完成事件直接生成入仓计划”;当前只生成 `PENDING_ASSIGNMENT` 尾程订单,平台必须按柜预览并确认转换。 2. 跨区事件不自动建海外入仓计划。旧海外验收手册曾写“装柜完成事件直接生成入仓计划”;当前只生成 `PENDING_ASSIGNMENT` 尾程订单,平台必须按柜预览并确认转换。
3. 国内出仓硬门禁不含拖车和独立船期。当前服务端硬门禁是未扣货、入库单 `LOADED`、装柜计划/PDA完成、订舱 `RELEASED`、装柜证据与出口报关完成;拖车和独立船期仅展示参考。 3. `LOADED` 只校验物理装柜。报关线按客户回执确认、整柜正式申报和海关结果推进;送港线按拖车、离仓、进港和甩柜推进,两条线互不替代。
4. 国内出仓既有自动收敛也保留人工入口。出口报关完成后系统会自动尝试确认;未收敛时平台可在柜次或国内出仓页手工确认,二者共享同一服务端门禁与幂等结果。 4. 只有实际开船才进入海运节点。`DEPARTED_WAREHOUSE` 和 `PORT_RECEIVED` 是送港事实,`ROLLED_OVER` 是船次异常,预计 ETD 不推进海运中。
5. 真实柜号最迟时点存在历史指引差异。当前代码允许在 `EDITING/LOADING` 补录,但最终 PDA 完成前必须存在;为避免页面入口差异,正式操作统一要求预装确认前补齐。 5. 真实柜号最迟时点存在历史指引差异。当前代码允许在 `EDITING/LOADING` 补录,但最终 PDA 完成前必须存在;为避免页面入口差异,正式操作统一要求预装确认前补齐。
6. 尾程主状态与子单状态分开。入仓后主流程固定在 `INBOUND_COMPLETED`,排车、出库、派送、换标和转运的精确状态保存在子单,不得互相覆盖。 6. 尾程主状态与子单状态分开。入仓后主流程固定在 `INBOUND_COMPLETED`,排车、出库、派送、换标和转运的精确状态保存在子单,不得互相覆盖。
@@ -510,7 +506,10 @@ OVERSEAS:
- [ ] 模拟柜、订舱、真实柜号、预装计划和订单分配关系一致 - [ ] 模拟柜、订舱、真实柜号、预装计划和订单分配关系一致
- [ ] 国内 PDA 全部拣货,五类证据和铅封齐全 - [ ] 国内 PDA 全部拣货,五类证据和铅封齐全
- [ ] 装柜计划 `COMPLETED`,来源入库单 `LOADED` - [ ] 装柜计划 `COMPLETED`,来源入库单 `LOADED`
- [ ] 整柜出口报关完成,国内出仓成功并生成船节点任务 - [ ] 每个客户完成“资料→报关行回执→客户确认”,打回客户已重新上传、重新发送并生成新回执
- [ ] 所有客户确认后,整柜资料已提交报关行正式申报,并记录查验/放行结果
- [ ] 送港线已记录 `DEPARTED_WAREHOUSE`、`PORT_RECEIVED` 或 `ROLLED_OVER`
- [ ] 承运船舶实际开航后才生成 `VESSEL_DEPARTED` 和船节点任务
- [ ] 实际船节点到 `PICKUP_READY` 后海外 PDA 才看到柜号 - [ ] 实际船节点到 `PICKUP_READY` 后海外 PDA 才看到柜号
- [ ] 海外只先生成 `PENDING_ASSIGNMENT` 尾程订单,平台按柜转换计划成功 - [ ] 海外只先生成 `PENDING_ASSIGNMENT` 尾程订单,平台按柜转换计划成功
- [ ] 海外 PDA 三类签收照片齐全,FBA/OVERSEAS 按正确模式实收 - [ ] 海外 PDA 三类签收照片齐全,FBA/OVERSEAS 按正确模式实收
@@ -526,7 +525,7 @@ OVERSEAS:
- `docs/业务快速索引.md` - `docs/业务快速索引.md`
- `docs/订单与客户/订单与客户头程订单闭环设计.md` - `docs/订单与客户/订单与客户头程订单闭环设计.md`
- `docs/入库测量与计费/入库测量与计费需求优化版-v2-测量计费入库主流程.md` - `docs/入库测量与计费/入库测量与计费需求优化版-v2-测量计费入库主流程.md`
- `docs/国内货柜履约/货柜管理全链验收矩阵-2026-08-13.md` - `docs/国内货柜履约/归档/货柜管理全链验收矩阵-2026-08-13.md`
- `docs/海外仓业务/README.md` - `docs/海外仓业务/README.md`
- `docs/海外仓业务/虫虫出海全流程人工验收手册.md` - `docs/海外仓业务/虫虫出海全流程人工验收手册.md`
- `baiyue-firstleg/order/AGENTS.md` - `baiyue-firstleg/order/AGENTS.md`
@@ -536,3 +535,4 @@ OVERSEAS:
- `apps/pda-overseas-uniapp/AGENTS.md` - `apps/pda-overseas-uniapp/AGENTS.md`
本文用于统一业务操作和评审口径;接口字段、权限码、并发版本和错误码仍以对应 Controller、DTO、OpenAPI 与服务端状态机为最终依据。 本文用于统一业务操作和评审口径;接口字段、权限码、并发版本和错误码仍以对应 Controller、DTO、OpenAPI 与服务端状态机为最终依据。
@@ -461,3 +461,4 @@ P0 不改变核心状态机,主要是聚合查询、反馈和导航,风险
5. 国内/海外 PDA 接入稳定错误原因、恢复动作和操作回执。 5. 国内/海外 PDA 接入稳定错误原因、恢复动作和操作回执。
6. 完成 P0 人工验收和埋点基线后,再做表单向导、自动带出和批量体验。 6. 完成 P0 人工验收和埋点基线后,再做表单向导、自动带出和批量体验。
7. 最后基于真实操作数据决定 P2 的智能推荐和 SLA 预警,不凭主观增加自动化。 7. 最后基于真实操作数据决定 P2 的智能推荐和 SLA 预警,不凭主观增加自动化。
@@ -1,5 +1,7 @@
# 头程下单到尾程出库现状流程全景清单 # 头程下单到尾程出库现状流程全景清单
> **历史现状声明(2026-09-24)**:本文记录旧版 AS-IS 盘点,报关/送港的单线门禁、柜前资料和“四步证据”等内容不再作为当前业务依据。当前流程以 [头程到尾程流程节点梳理(重构版)](../../头程到尾程流程节点梳理.md)、[报关资料与船期价格接入梳理](../../国内货柜履约/报关资料与船期价格接入梳理.md) 和最新需求确认表为准:`LOADED` 后报关线与送港线并行,客户回执确认完成后整柜正式申报,甩柜独立记录,实际开船才进入海运节点。
> 文档性质:现状流程盘点(AS-IS),先描述现在业务怎么走,不在本文讨论页面改版或技术优化。 > 文档性质:现状流程盘点(AS-IS),先描述现在业务怎么走,不在本文讨论页面改版或技术优化。
> 覆盖起点:企业具备下单资格。 > 覆盖起点:企业具备下单资格。
> 主链终点:海外仓完成尾程出库;为保证交接完整,附带记录派送、异常退回和国内最终完成回写。 > 主链终点:海外仓完成尾程出库;为保证交接完整,附带记录派送、异常退回和国内最终完成回写。
@@ -568,7 +570,7 @@ INBOUND_COMPLETED
- `docs/入库测量与计费/README.md` - `docs/入库测量与计费/README.md`
- `docs/入库测量与计费/入库测量与计费需求优化版-v2-测量计费入库主流程.md` - `docs/入库测量与计费/入库测量与计费需求优化版-v2-测量计费入库主流程.md`
- `docs/国内货柜履约/README.md` - `docs/国内货柜履约/README.md`
- `docs/国内货柜履约/货柜管理全链验收矩阵-2026-08-13.md` - `docs/国内货柜履约/归档/货柜管理全链验收矩阵-2026-08-13.md`
- `docs/海外仓业务/README.md` - `docs/海外仓业务/README.md`
- `docs/海外仓业务/虫虫出海全流程人工验收手册.md` - `docs/海外仓业务/虫虫出海全流程人工验收手册.md`
- `baiyue-firstleg/order/AGENTS.md` - `baiyue-firstleg/order/AGENTS.md`
@@ -579,3 +581,4 @@ INBOUND_COMPLETED
- `apps/client-web/AGENTS.md` - `apps/client-web/AGENTS.md`
- `apps/pda-uniapp/AGENTS.md` - `apps/pda-uniapp/AGENTS.md`
- `apps/pda-overseas-uniapp/AGENTS.md` - `apps/pda-overseas-uniapp/AGENTS.md`
@@ -1,5 +1,7 @@
# 头程到尾程 AI 流程优化上下文包 # 头程到尾程 AI 流程优化上下文包
> **规则基线声明(2026-09-24)**:本文中的旧状态表和阶段合同可能保留历史口径,不能覆盖当前流程。当前分析必须先采用 [头程到尾程流程节点梳理(重构版)](../../头程到尾程流程节点梳理.md) 和 [报关资料与船期价格接入梳理](../../国内货柜履约/报关资料与船期价格接入梳理.md):`LOADED` 后报关线、送港线并行,客户逐轮确认后整柜正式申报,送港可甩柜,实际开船后才进入海运节点。
> 用途:给 AI、产品、业务和技术提供同一份优化输入规范。本文不替代六阶段现状文档,也不直接改变状态机;它定义分析顺序、术语、证据、指标、输出格式和实施门禁,防止 AI 只根据局部页面提出脱离业务事实的建议。 > 用途:给 AI、产品、业务和技术提供同一份优化输入规范。本文不替代六阶段现状文档,也不直接改变状态机;它定义分析顺序、术语、证据、指标、输出格式和实施门禁,防止 AI 只根据局部页面提出脱离业务事实的建议。
## 1. 第二轮完整性审计结论 ## 1. 第二轮完整性审计结论
@@ -34,7 +36,7 @@
优化分析的默认入口: 优化分析的默认入口:
- 总览:[分阶段流程目录](头程到尾程分阶段流程/README.md) - 总览:[分阶段流程目录](../../头程到尾程分阶段流程/README.md)
- 操作:[全流程操作手册](头程下单到尾程出库全流程操作手册.md) - 操作:[全流程操作手册](头程下单到尾程出库全流程操作手册.md)
- 现状:[现状流程全景清单](头程下单到尾程出库现状流程全景清单.md) - 现状:[现状流程全景清单](头程下单到尾程出库现状流程全景清单.md)
- 方案:[易用性与数据流转优化方案](头程下单到尾程出库流程易用性与数据流转优化方案.md) - 方案:[易用性与数据流转优化方案](头程下单到尾程出库流程易用性与数据流转优化方案.md)
@@ -294,3 +296,4 @@ AI 应优先:复用服务端权威动作与门禁、减少重复输入、显
10. 国内离仓、海外入仓、海外出库和最终签收的客户可见进度语义。 10. 国内离仓、海外入仓、海外出库和最终签收的客户可见进度语义。
每项决定应记录:结论、负责人、确认日期、影响阶段、是否改变接口/状态/权限,以及需要更新的文档。未决定项保持“待确认”,不能由 AI 默认选择。 每项决定应记录:结论、负责人、确认日期、影响阶段、是否改变接口/状态/权限,以及需要更新的文档。未决定项保持“待确认”,不能由 AI 默认选择。
@@ -182,7 +182,7 @@ baiyue-firstleg/
## 6. 自动编号和文件命名 ## 6. 自动编号和文件命名
SQL 迁移使用每个 schema 内递增的整数序号,由创建工具生成。业务版本、Git commit 和 Jenkins 构建号只用于发布追踪,不参与 SQL 序号计算。无需开发人工决定“这次是 0.0.10 还是 0.0.11”。 2026-09-22 确认:SQL 迁移保持 `V1、V2、V3、V4、V5……`,每个 schema 独立递增,由创建工具生成,不采用时间戳编号。序号随变更自然增长,不因位数增加而重置、归零或重新编号。生产发布版本、Git commit 和 Jenkins 构建号只用于发布追踪,不参与 SQL 序号计算。
```text ```text
migrations/cn/baiyue_order/V1__add_order_reference.sql migrations/cn/baiyue_order/V1__add_order_reference.sql
@@ -225,6 +225,24 @@ migrations/cn/baiyue_auth/V1__create_login_audit_table.sql
- 同一库内按完整版本链推进,不按某个服务或某个文件跳过中间版本。该库随包包含的其他待执行变更必须一并评审;尚不具备发布条件时阻断本候选,不通过删文件、临时降低目标或开启乱序绕过。 - 同一库内按完整版本链推进,不按某个服务或某个文件跳过中间版本。该库随包包含的其他待执行变更必须一并评审;尚不具备发布条件时阻断本候选,不通过删文件、临时降低目标或开启乱序绕过。
- 例如只发布 Auth,且与 Firstleg 无依赖,则只核验并迁移 Auth 的必要库。同一提交中 Firstleg 的待执行 SQL 不被带入;若 Auth 确实依赖 Firstleg 的新结构,则先补齐发布范围和测试证据再发布。 - 例如只发布 Auth,且与 Firstleg 无依赖,则只核验并迁移 Auth 的必要库。同一提交中 Firstleg 的待执行 SQL 不被带入;若 Auth 确实依赖 Firstleg 的新结构,则先补齐发布范围和测试证据再发布。
### 6.3 功能分支与生产发布编号
以下为确认的发布工作流;跨分支检查和发布编号自动分配尚待流水线实现,不代表当前工具已经提供这些门禁。
| 记录 | 示例 | 增长规则 |
|---|---|---|
| 单库 SQL 迁移编号 | Auth 的 `V1`、`V2`;Order 的 `V1`、`V2` | 该库新增数据库逻辑变更时自动生成;普通提交、重复构建和重复部署不增加 |
| 生产发布版本 | `release-1`、`release-2` | Jenkins 为新的生产发布候选自动分配,不要求开发手工维护版本文件;只有发布成功才更新当前生产版本 |
生产发布版本与 SQL 编号不绑定。例如 `release-12` 可以对应 Auth `V3`、Order `V7`;纯代码发布仍有新发布版本,但数据库目标不变。发布编号须在受保护记录中唯一分配,失败编号不回收;同一制品重试沿用原发布编号,修改代码、SQL 或其他制品内容后分配新编号并重新验证。`release-13` 失败时保留失败记录,当前生产版本仍为最近成功版本;各库和服务的实际状态另行记录,不能据此假定没有发生部分更新。
1. 功能分支从最新 `main` 创建,代码与 SQL 在同一分支维护;这里约定后续团队流程,不自动创建或切换本次工作区分支。
2. 进入共享测试前,拉取并合并最新 `main`,检查同库重复编号和执行顺序。冲突只调整尚未冻结、未在保留历史环境执行的草稿;成功文件不改内容、不改编号,修复使用新增迁移。冻结失败候选只能按第 13.2.1 节处理。
3. 两人可以并行开发;共享测试同一时间只验收一个待合并功能。前一功能测试通过、合并并完成发布或处理失败后,下一功能同步最新 `main` 再进入测试,避免未合并 SQL 污染其他功能的验证起点。
4. 测试结果绑定提交和 SQL 哈希;合并前重新检查 `main` 是否变化,变化时同步并重新验证,不能仅凭“以前拉取过 main”放行。
5. 合并后的 `main` 构建正式候选并再次自动验证;生产使用该正式候选原制品。功能分支测试证据不自动等同于合并后候选证据;已成功的 SQL 保持原编号及内容,由数据库历史决定跳过或执行。
6. 发布记录绑定 `release-N`、`main` 的完整提交、镜像 digest、SQL 清单及各库版本,并保存成功发布的 Git 标签。`main` 表示已合并代码,实际生产版本以成功发布记录为准,不通过分支名称推断数据库历史。
## 7. 迁移类型 ## 7. 迁移类型
### 7.1 版本迁移 ### 7.1 版本迁移
@@ -581,7 +599,7 @@ MySQL DDL 可能已隐式提交,不能假定整个文件自动回滚。按以
- Jenkins 构建号。 - Jenkins 构建号。
- Git commit 和镜像标签。 - Git commit 和镜像标签。
- 发布身份、清单/SQL 包 SHA-256、各镜像 digest、审批及发布锁状态。 - 发布身份、清单/SQL 包 SHA-256、各镜像 digest、审批及发布锁状态。
- 候选制品身份、可选的业务发布标签,以及对应测试通过记录;不维护独立手工 SQL 发布版本。 - 候选制品身份、生产发布版本 `release-N`、发布状态及对应测试通过记录;不维护独立手工 SQL 发布版本,编号规则见第 6.3 节。
- 环境与区域。 - 环境与区域。
- schema 名称。 - schema 名称。
- Flyway 镜像版本。 - Flyway 镜像版本。
@@ -651,6 +669,7 @@ MySQL DDL 可能已隐式提交,不能假定整个文件自动回滚。按以
- 实现 `plan/run` 及分阶段校验配置,在获授权的隔离数据库验证原始 SQL、首次执行、重复执行、结构断言与失败恢复;验证单服务范围隔离,并用应用预期结构及实际读写测试发现漏写迁移。 - 实现 `plan/run` 及分阶段校验配置,在获授权的隔离数据库验证原始 SQL、首次执行、重复执行、结构断言与失败恢复;验证单服务范围隔离,并用应用预期结构及实际读写测试发现漏写迁移。
- 单服务 Job 先支持构建与部署解耦;总控固定为“全部目标镜像就绪 -> SQL 阶段 -> 同批镜像部署”,此能力必须先于共享测试接入完成。 - 单服务 Job 先支持构建与部署解耦;总控固定为“全部目标镜像就绪 -> SQL 阶段 -> 同批镜像部署”,此能力必须先于共享测试接入完成。
- 全部独立部署入口纳入环境锁和候选资格校验,补齐归档保护、镜像保留、未决状态及撤销记录;禁止旧 Job 绕过新的 SQL 门禁。 - 全部独立部署入口纳入环境锁和候选资格校验,补齐归档保护、镜像保留、未决状态及撤销记录;禁止旧 Job 绕过新的 SQL 门禁。
- 接入第 6.3 节的 main 同步检查、分支编号冲突检查和合并后候选验证;自动分配并保护 `release-N`,同一候选重试不换号,成功后更新生产版本和发布标签。
- 对从未成功、未进入生产的失败候选验证第 13.2.1 节修订链;对已成功或生产尝试过的文件验证例外被拒绝。 - 对从未成功、未进入生产的失败候选验证第 13.2.1 节修订链;对已成功或生产尝试过的文件验证例外被拒绝。
### 阶段 D:共享测试完整演练 ### 阶段 D:共享测试完整演练
+38 -150
View File
@@ -1,159 +1,47 @@
# 开发/测试环境 Jenkins API 自动部署指南 # TEST 环境 Jenkins 部署指南
> 最后核对:2026-08-25 更新日期:2026-09-29。本指南描述唯一 TEST 单机目标;仓库配置已收敛不表示实际服务器已部署。统一架构切换与验收以[测试环境单机部署与配置契约](测试环境单机部署与配置契约.md)为准。
>
> 只适用于当前开发、测试阶段。生产环境启用后必须重新收紧权限、轮换并移除开发 Token。
## 1. 使用场景 ## 授权与边界
本指南用于长时间全量测试或夜间任务。用户在当前对话明确要求“持续修复并部署”“自动部署并测试”或等价表述后,工具可以在本次授权范围内循环执行: 默认只做本地修改与离线检查。实际Jenkins构建发布、Nacos发布、SQL和清理分别落实本轮授权范围;本指南不授予持续部署权限。不得读取或覆盖其他任务维护的真实生产/测试凭据。运行事实与本目标不一致时先核对,不自行改名或删除运行环境。
`定位失败 → 修改代码 → 本地门禁 → 提交并推送 → API 部署 → 等待终态 → 健康/业务验收 → 继续修复` ## 唯一发布入口
同一轮任务不需要每次提交或重试都重新询问。以下情况仍必须停下确认: | 对象 | 入口 |
- 涉及预发布或生产环境。
- 需要执行 SQL、初始化数据库、修改真实数据或清理容器/数据。
- 需要跳过测试、停止他人构建或扩大到未授权服务。
- 缺少环境凭据,或连续三次遇到同一个外部阻断。
## 2. 本机一次性配置
Jenkins API 信息固定保存在以下未提交文件:
`C:/Users/BY-OY/.codex/jenkins-api.env`
文件格式:
```dotenv
JENKINS_URL=https://jenkins.example.com
JENKINS_USER=admin
JENKINS_API_TOKEN=replace-with-current-development-token
DEV_GATEWAY_URL=https://dev-api.example.com
TEST_GATEWAY_URL=https://test-api.example.com
```
工具直接读取该文件,不把 Token 输出到 commentary、最终回复、命令日志或仓库。使用 API Token 的 Jenkins 请求不需要 CSRF Crumb。
连通性检查:
```bash
curl -fsS --user "$JENKINS_USER:$JENKINS_API_TOKEN" \
"${JENKINS_URL%/}/api/json?tree=nodeName,mode"
```
## 3. Job 对照
| 环境 | 后端总控 | Admin | Client | 后端分支 | 下游前缀 |
|---|---|---|---|---|---|
| 开发 | `backend-java-dev` | `admin-web-dev` | `client-web-dev` | `dev` | `baiyue-firstleg-dev-` |
| 测试 | `backend-java` | `admin-web-test` | `client-web-test` | `test` | `baiyue-firstleg-` |
后端可部署服务:
`gateway`、`gateway-overseas`、`auth`、`iam`、`firstleg`、`finance`、`order`、`warehouse`、`file`、`print`、`integration-service`、`lastleg-service`、`warehouse-overseas-service`、`event-bridge-service`、`audit-service`。海外安全投影随 `lastleg-service` 部署,不再有独立 Job。
正常从总控 Job 发起。只有重跑同一提交的单个失败服务时,才直接触发下游 Job。
## 4. API 触发
### 4.1 前端
```bash
curl -fsS -X POST \
--user "$JENKINS_USER:$JENKINS_API_TOKEN" \
-D build.headers -o /dev/null \
"${JENKINS_URL%/}/job/admin-web-dev/build"
```
按目标环境和应用替换 Job 名称。
### 4.2 后端
开发环境选择两个服务的示例:
```bash
curl -fsS -X POST \
--user "$JENKINS_USER:$JENKINS_API_TOKEN" \
-D build.headers -o /dev/null \
--data-urlencode 'BUILD_MODE=SELECT' \
--data-urlencode 'SERVICE_GATEWAY_OVERSEAS=true' \
--data-urlencode 'SERVICE_LASTLEG=true' \
--data-urlencode 'ENVIRONMENT=development' \
--data-urlencode 'DEPLOY=true' \
--data-urlencode 'SKIP_TESTS=false' \
--data-urlencode 'EVENT_BRIDGE_REGION=BOTH' \
--data-urlencode 'DOWNSTREAM_JOB_PREFIX=baiyue-firstleg-dev-' \
"${JENKINS_URL%/}/job/backend-java-dev/buildWithParameters"
```
规则:
- 日常优先 `AUTO`;明确修复单个或少量服务时使用 `SELECT`。
- `SELECT` 只把目标 `SERVICE_*` 设为 `true`,其余保持 `false`。
- `ALL` 只用于用户明确授权的全量部署。
- 开发环境固定 `ENVIRONMENT=development`;测试固定 `ENVIRONMENT=test`。
- 开发/测试默认 `DEPLOY=true`、`SKIP_TESTS=false`。
- 事件桥默认 `BOTH`;单区故障重跑才使用 `CN` 或 `OVERSEAS`。
- 不在 API 参数中传密码、数据库凭据或服务 Token。
## 5. 自动等待终态
触发响应的 `Location` 是队列地址:
```bash
QUEUE_URL="$(awk 'BEGIN{IGNORECASE=1} /^Location:/{gsub("\r",""); print $2}' build.headers)"
curl -fsS --user "$JENKINS_USER:$JENKINS_API_TOKEN" \
"${QUEUE_URL%/}/api/json?tree=id,why,cancelled,executable[number,url]"
```
出现 `executable.url` 后,将其作为 `BUILD_URL`:
```bash
curl -fsS --user "$JENKINS_USER:$JENKINS_API_TOKEN" \
"${BUILD_URL%/}/api/json?tree=number,building,result,url,duration,estimatedDuration"
```
每 5–10 秒轮询一次。只有 `building=false` 且 `result=SUCCESS` 才成功;进入队列、拿到构建号或 HTTP POST 成功都不算完成。后端总控还必须确认每个下游 Job 都是 `SUCCESS`。
失败时读取:
```bash
curl -fsS --user "$JENKINS_USER:$JENKINS_API_TOKEN" \
"${BUILD_URL%/}/consoleText"
```
删除本次产生的临时 `*.headers` 文件,不提交。
## 6. 夜间自动闭环
1. 记录目标环境、服务和远端 commit。
2. 运行直接受影响的本地测试;签名变化必须编译测试源码。
3. 只提交当前修复文件并推送目标分支。
4. 用 API 触发对应 Job,保存队列 URL、构建 URL 和构建号。
5. 等待总控及全部下游进入终态。
6. 失败时读取第一个有效错误,修改后使用新 commit 再部署。
7. 网络抖动、镜像拉取等瞬时基础设施错误允许同一提交重试,最多两次。
8. 部署成功后检查 Gateway `/actuator/health`,再执行本轮真实 API/全量测试。
9. 全部通过后汇总 commit、构建号、服务结果和验收结果。
不要因为某个服务失败就盲目重跑全量;优先修复并只重跑失败服务。部署脚本会在新容器不健康时自动回滚,任务仍视为失败。
## 7. 快速故障判断
| 现象 | 处理 |
|---|---| |---|---|
| `401` | 检查本机 API Token 和反向代理 `Authorization` 头 | | 后端总控 | `backend-java`,仓库 `baiyue-firstleg/Jenkinsfile` |
| `403` | 检查 Job Read/Build 权限;不要关闭 CSRF | | 后端单服务 | `baiyue-firstleg-<module>`,`Jenkinsfile.service` |
| `400` | 参数名或 Choice 值与当前 Job 不一致 | | 构建/部署节点 | `java-builder` / 同机 `java-test` |
| 队列长期等待 | 查询队列 `why`,检查节点、执行器和部署锁 | | 环境凭据 | Jenkins Secret File `firstleg-test-env`,真实值不入库 |
| Maven/测试失败 | 修复代码并产生新 commit,不跳过测试 | | 服务与镜像列表 | [service-map.yml](../baiyue-firstleg/deploy/service-map.yml) |
| 容器不健康 | 读取 Job 自动采集的容器日志和回滚结果 | | Compose | [docker-compose.yml](../baiyue-firstleg/deploy/docker-compose.yml),项目 `firstleg-test` |
| 镜像被其他任务覆盖 | 核对同服务部署锁和实际运行镜像标签 | | 环境模板 | [.env.test.example](../baiyue-firstleg/deploy/env/.env.test.example) |
| 总控成功但下游失败 | 整体仍按失败处理,只重跑失败服务 | | Nacos | [config/nacos/test](../baiyue-firstleg/config/nacos/test/README.md),14个Data ID、一个实际Namespace ID |
| 执行顺序与恢复 | [TEST单机部署执行清单](../baiyue-firstleg/deploy/TEST单机部署执行清单.md) |
## 8. 完成记录 保留13个服务:gateway、auth、iam、order、firstleg、finance、warehouse、warehouse-overseas-service、lastleg-service、file、print、audit-service、integration-service。Gateway Overseas、两区Event Bridge不在新发布清单。停旧服务必须等统一认证、直接投递、撤销和四端切换验证完成;源码退役不等于获准停止当前服务。
最终只需记录:环境、Job、服务、分支、commit、Jenkins 构建号、最终结果、健康检查、业务验收及剩余阻断。不得输出 Token、Cookie、Jenkins Credential 或环境文件内容。 旧开发/生产Job不再匹配当前流水线,不能借环境参数使本版本执行生产部署。已有其他环境应由其独立明确授权任务处理,不在本次TEST发布中操作。
参考:[Jenkins Remote Access API](https://www.jenkins.io/doc/book/using/remote-access-api/)、[Jenkins CSRF Protection](https://www.jenkins.io/doc/book/security/csrf-protection/)。 ## 参数与门禁
总控支持AUTO、SELECT、ALL。AUTO保留失败服务重试与直接依赖识别;架构首次切换使用审核后的完整匹配发布清单,不以AUTO遗漏服务。ENVIRONMENT仅test,下游前缀仅baiyue-firstleg-。DEPLOY默认false;IMAGE_REPOSITORY必须替换为已核镜像仓库,DOCKER_BASE_IMAGE由构建节点可访问的Java17镜像提供。不得将凭据拼入参数、URL或日志。
默认执行Maven测试;仅明确选择SKIP_TESTS时跳过执行,仍编译测试源码。总控先统一测试,再向固定commit的单服务任务传递跳过重复执行。发布前还须完成网关路由、部署拓扑、失败回滚和受影响前端合同。离线检查不能证明镜像健康或HTTP闭环。
单服务任务在取目标节点执行器前锁定对应服务,目标节点通过同一env文件拉镜像并更新容器。没有HEALTHCHECK、启动失败、不健康、退出或超时均判失败。只有同协议同Schema版本才可显式启用ALLOW_SAME_CONTRACT_ROLLBACK;架构切换保持false,恢复原则见执行清单。
## 配置与端侧
容器共用firstleg-test-network;同网络Web Nginx使用http://gateway:9000。Gateway宿主机发布仅127.0.0.1,业务服务只内部expose。Auth使用http://auth:9100,不能把Nacos应用名当Docker DNS。宿主机中间件通过host.docker.internal访问,不能使用容器localhost。
所有服务使用同一Nacos Namespace ID/Group、Redis DB与会话前缀。Auth独占签名私钥;JWKS和内部会话验证共用Auth。EVENT_OPERATIONS_TOKEN独立于内部业务令牌,留空禁用运维操作。现有文件卷和非桥业务MQ保留,topic/group使用test-前缀。
Admin与Client各自Compose项目共接后端网络,发布必须给出CLIENT_WEB_URL/VITE_ADMIN_WEB_ORIGIN;两个PDA保留独立产物及仓绑定。域名、Namespace ID、MQ范围、数据卷和主机容量必须据实际清单核实,不能用模板默认值充当验收。
## 发布与验收
按执行清单记录镜像、配置、SQL与四端版本,在停写窗口发布完整匹配版本。SQL不由Compose/Jenkins自动运行,初始化脚本仅接受两份显式审核的空库基线并受授权开关保护。禁止整机清空Redis/MQ/文件。
启动就绪后先验证统一登录/撤销/隔离/仓绑定、资源查询和文件,再用新造数据验证装柜至尾程、资金指令结果回传及故障恢复。真实API通过后还需页面/PDA验收。未部署、未验证项目必须明确标记;不能以Job成功替代整条业务链完成。
+100
View File
@@ -0,0 +1,100 @@
# 测试环境单机部署与配置契约
更新日期:2026-09-29。当前只有 test,没有开发/生产环境。本文定义目标部署、切换与验收;具体路由、认证、投递契约唯一见[统一认证与服务通信契约](统一认证与服务通信契约.md)。
状态:目标已确认,统一 Gateway/Token、可靠直接投递、单 TEST Compose/Nacos 与四端统一入口已进入源码并完成分批本地验证,后端全量 Maven 回归已通过(4149项,12项跳过,0失败/错误)。尚未发布到测试环境;运行服务器、Nacos 发布值、主机资源和真实 MySQL 故障恢复尚未验证。
## 结论与范围
按“头程和海外仓不再分区域部署、所有服务同机运行、取消独立事件接收服务与海外网关”设计。这里将“事件接收”对应为当前 `event-bridge-service`,不推定要删除业务通知、异步任务或消息队列。
建议目标:一个 Gateway、一套 Auth/IAM 登录与权限体系、一个测试 Nacos 命名空间和一套测试内部容器网络。保留 Firstleg、Lastleg、Warehouse、Warehouse Overseas 等业务服务,各自拥有数据表与业务规则。同机可以共用 MySQL 实例,继续按服务分 Schema;不要求合并为一个数据库或一个 Java 进程。
最终移除 `gateway-overseas` 与 `event-bridge-service` 部署单元及其区域分支。服务名称中的海外业务含义可以保留;仓库类型、仓管角色、仓绑定和客户数据隔离仍有业务用途。
## 测试环境目标部署清单
| 类别 | 目标 |
|---|---|
| 环境 | 仅 test,所有服务同一台宿主机 |
| 用户端 | Admin、Client、国内 PDA、海外 PDA 共用一个业务 API 入口;页面和作业职责保留 |
| 入口 | Nginx/反向代理接统一 Gateway,业务内部端口不作为客户端访问入口 |
| 认证 | Auth、IAM、统一 JWT 与 Redis 会话,按平台/客户/PDA 校验权限 |
| 业务 | Order、Firstleg、Lastleg、Warehouse、Warehouse Overseas、Finance |
| 公共能力 | File、Print、Audit、Integration 按现有职责保留 |
| 配置与发现 | 一套 Nacos,使用实际 Namespace ID 的单一测试命名空间,不再分 test-cn/test-overseas |
| 数据与缓存 | 一套测试 MySQL 实例,按服务分 Schema;统一可访问的测试 Redis,保留必要键隔离 |
| 消息 | 保留现有 RocketMQ 用于导出、通知和审计等已发现用途 |
| 服务协同 | 同机内部调用;需要可靠交付的业务采用本地事务记录加直接投递和消费幂等 |
| 退出部署 | gateway-overseas、CN/OVERSEAS 两个 Event Bridge 实例及专用配置 |
服务名、Schema、端口、数据卷和实际中间件配置在改造前做一次清单核对;当前表是目标部署结构,不是对服务器现状的确认。旧 development/production 配置不再作为本次发布入口,也不要求新建对应环境。
## 分批实施与交付门槛
| 批次 | 工作 | 完成依据 |
|---|---|---|
| 0:文档与基线 | 确认仅 test 的目标、唯一接口路径、统一认证、直接投递职责;列出当前配置与服务清单 | 新目标、当前实现、待办三者明确区分 |
| 0A:资金消费前置修复 | 区分临时执行失败与最终业务拒绝;补齐并发 Inbox 抢占后的摘要校验和一致结果处理 | 临时故障原事件重试、并发同 hash/异 hash、执行成功后结果保存失败的恢复验证通过;修复规则见统一认证与服务通信契约;本地已通过,实库待验证 |
| 1:入口与认证 | Gateway 接入全部业务;Auth/common-security/海外服务统一认证;各端共用入口;解决仓库路由冲突 | 本地编译、认证测试、路由合同及受影响前端测试通过 |
| 2:业务通信 | 替换装柜、船节点、卸柜、暂扣、派送、费用和资金链;补齐直接投递重试及失败处置 | 各链路有直接消费者,成功确认、重复投递和故障恢复测试通过 |
| 3:部署收敛 | 单套 test Compose/Nacos/Jenkins;清理两个废弃服务和专用配置、SQL 初始化引用、安全投影依赖 | 构建与配置合同通过;形成唯一测试发布清单及启动依赖 |
| 4:测试环境验证 | 发布一致的新版本,以新造数据执行 API 全链路和各端实际操作 | 下表业务验收全部通过,保留报告及未通过项 |
改造批次可以分别完成代码检查;仅入口批次完成时,不把测试环境视为已跑通。正式测试部署须使用接口、认证、通信与配置相互匹配的一组版本,避免先停 Bridge 导致现有业务失联。
本地编译和离线检查只是开发工具使用,不代表存在独立“开发环境”。最低检查包括相关 Maven 测试编译/测试、网关路由与拓扑合同、前端类型检查及受影响测试;不以构建成功代替测试环境闭环通过。
## 测试环境跑通的验收标准
下表是测试环境验收标准;本地实现与离线测试不代表环境验收,当前所有环境验收项均待验证。
| 验收项 | 操作与预期 |
|---|---|
| 部署与发现 | 所有保留服务启动健康,统一命名空间中可发现;客户端无需访问海外 Gateway 或 Bridge |
| 登录与权限 | Admin、Client、两类 PDA 使用统一认证;刷新有效、退出后失效;停用账号/客户和越权访问被拒绝 |
| PDA 仓绑定 | 未绑定拒绝作业,绑定仓限制正确,换仓后旧会话失效 |
| 仓库路由 | 仓库主档、库位、托盘访问正确服务,原重复前缀不再造成路由歧义 |
| 订单到装柜 | 新造客户与订单走审核、入仓、测量、分柜和装柜;完成后正确生成尾程数据 |
| 海外履约 | 船节点同步、接柜、卸柜、入仓、库存、排车、出库、派送形成闭环;签收按来源回写 Firstleg/Order |
| 状态协同 | 暂扣/解除、卸柜事实、分单签收作用于正确单据,不误推进同柜或同车其他订单 |
| 费用与资金 | 费用准确入 Finance;资金指令与结果对应;重复请求不重复入账、冻结或扣款 |
| 可靠性 | 消费服务短时停止、重启、响应超时、重复和乱序投递后可恢复,失败可查且可重试,无永久丢单 |
| 公共能力 | 文件上传下载、标签打印、异步导出、消息通知、审计正常 |
| 客户与作业界面 | Admin/Client 和 PDA 实际操作完成核心流程;HTTP 通过不能替代页面/设备验证 |
每次验收记录版本、测试数据业务编号、覆盖场景、结果及错误诊断信息。修复失败项后执行受影响回归,再给出整体是否跑通的结论。
### D. 唯一测试环境的整体切换与失败恢复
本次采用测试停机窗口一次切换,允许测试数据按明确范围重建,不做新旧协议并行。实际部署、SQL、清理操作不在本文编写过程中执行。
| 顺序 | 操作 | 放行条件/记录 |
|---|---|---|
| D0 版本准备 | 记录各后端/前端/PDA 仓库提交、镜像 tag/digest、APK/WGT 版本、Nacos 配置版本与 SQL 基线 | 各端对应同一架构契约;本地检查通过 |
| D1 运行清单 | 列出当前容器、Compose 项目、网络、服务注册、Nacos Data ID/Group/Namespace、Redis DB/key、MQ topic/group、DB/文件卷引用 | 填实际标识,不输出凭据;确认主机容量和端口 |
| D2 停止写入 | 公告测试窗口、停止正在进行的验收/造数、阻断业务写入;停止旧业务容器、Relay 和相关消费任务 | 没有旧进程继续发消息、续写数据库或向旧 Nacos 注册 |
| D3 应用基线与配置 | 按逐项对象清单处理测试业务数据/旧投递、会话、必要 MQ 测试消息与文件引用;发布统一 test Nacos/Compose 配置 | 数据一致;不整机清空 Redis/MQ/文件,不触碰不在清单中的资源 |
| D4 启动新服务 | 中间件健康 → IAM/Auth 及公共能力 → 所有业务消费者与生产者 → Gateway → 前端;写入口保持关闭 | 健康检查通过且消费者就绪;无循环依赖导致的启动等待;旧网关/Bridge 不再启动 |
| D5 端侧切换 | 发布 Admin/Client 新构建,更新两类 PDA,清除旧登录态后重新登录 | 验收设备构建版本与配置正确;原生地址不再指向海外入口 |
| D6 冒烟 | 统一登录、主档/资源查询、越权拒绝、文件上传,加一条装柜→尾程链与一条资金指令→结果回传 | 无路由误投、认证失效或严重业务错误 |
| D7 完整验收 | 开放本轮验收写入,按前述矩阵新造数据执行完整 API、页面、PDA 及故障恢复 | 所有阻断项关闭才声明跑通 |
| D8 清理退役资源 | 核对旧容器、注册、配置及专用卷/库引用,形成明确清理清单 | 新链路通过、没有残余调用;删除动作单独按范围执行 |
启动顺序是依赖就绪原则,不允许写死为某服务必须业务调用另一未启动服务后才能健康。生产端 Outbox 可先记录并有限重试,不能在业务消费者启动前产生验收写入;冒烟前以实际健康状态确认。
停止条件:认证/客户隔离错误、资金重复执行、必需消费者不可达、投递无法恢复、数据库基线不匹配,任何一项即关闭测试写入并停止本轮验收,不用跳过场景换取整体通过。
失败恢复默认选择:保留故障证据,环境继续停写,修复新架构后用匹配版本重新部署并重建本轮失败测试数据。只有确需恢复原测试工作时,整体恢复旧镜像/前端/PDA、旧 Nacos/Compose 和匹配旧 Schema 基线,清理新旧会话及消息交叉引用;不恢复已经放弃的测试业务数据。单服务镜像回滚仅适用于确认契约和 Schema 未变的情况,不能代替本次架构整体恢复。
待部署准备时填写的运行值:测试窗口、发布清单、实际 Namespace ID、Data ID/Group、域名与端口、Redis DB/key 前缀、MQ 范围、SQL/卷操作清单、主机资源预算、验收数据编号。不得用猜测值替代运行检查;这些值未填写不进入 D2。
## 基线与范围
测试数据可以按明确对象重建,不设计存量迁移、双写、旧协议兼容或生产发布。本地编译不是独立开发环境。执行初始化、清理和部署前落实具体对象清单与适用授权,本契约不表示这些动作已执行。
配置收敛必须覆盖 Compose、Jenkins、deploy/service-map.yml、发布脚本、Nacos Data ID/Group/Namespace、前端代理与构建变量、PDA 地址、SQL 初始化引用、服务发现和健康检查。容器内不能用 localhost 代替其他服务名。保留文件数据卷及仍被导出/通知/审计使用的 RocketMQ。
不新增中间件,不合并业务服务、Schema、两类 PDA 或领域状态机;旧 development/production 退出当前发布入口,不顺手删除无关历史文件。模块旧指引中双区域部署、双 Token 或必须经海外 Gateway 的强制描述属于迁移前实现,后续实现以本契约和统一认证契约为准,并随对应批次更新模块说明。
验收记录保存各仓库提交、镜像/配置版本、业务编号、覆盖场景与失败项。本地检查、H2 事务测试与真实 MySQL/HTTP/页面/PDA 验收分别记录,不能互相代替。
+124
View File
@@ -0,0 +1,124 @@
# 统一认证与服务通信契约
更新日期:2026-09-29。本文是已确认目标的唯一主契约;当前仅有测试环境,所有服务同机部署。部署与切换见[测试环境单机部署与配置契约](测试环境单机部署与配置契约.md)。
状态:整体迁移尚未完成。统一 Token/JWKS/Redis 会话、八类业务事件直连与结构化 ACK、有限重试及人工原事件重试已进入源码并完成分批本地验证。构建与部署已收敛为单 TEST 的13个服务,两个旧模块已退出清单;旧模块源码批量清理被自动审批拒绝,尚未删除。撤销并发替代链已通过定向验证,旧安全投影链已移除,逐次投递审计与指标、协议去区域字段已实现,后端全量 Maven 回归已通过(4149项,12项跳过,0失败/错误),真实测试环境尚未部署验收。不得混合发布新旧协议或把本地测试视为环境验收。
下文路径、响应与时序为改造目标。实际业务服务、客户隔离、仓库类型、作业角色与状态机保持原职责;不能将“同机”解释为合并数据库表或绕过权限。
### A. 唯一路由与消费端映射
全部客户端共用 Gateway。下表写完整服务端路径;前端 HTTP Base 若已含 `/api`,业务调用不重复拼接该段。所有资源接口仍校验平台身份、客户范围及业务权限。
海外资源前缀记作 R=`/api/platform/v1/overseas-warehouse-resources`,权限前缀记作 P=`platform:overseas-warehouse:`。以下 R/P 仅用于文档缩写,不是配置变量。
| 方法与目标路径 | 目标服务 | 权限 | 主要调用方/改动 |
|---|---|---|---|
| GET `/api/platform/v1/warehouse-admin` 及现有主档 CRUD | Warehouse | 维持现有主档权限,GET 为 `platform:warehouse:list` | 主档页面与 IAM 的共享收货仓查询保留现有调用;写操作不改权限 |
| GET `/api/platform/v1/warehouse-admin/overseas-receiving-options` | Warehouse | P+`warehouse:list` | 新增限定用途查询;替代海外资源服务原根目录查询,返回平台公共、OVERSEAS、ACTIVE、RECEIVING 仓库,不因迁移给资源角色授予主档维护权限 |
| GET R+`/pallets`、R+`/pallets/summary` | Warehouse Overseas | P+`pallet:list` | Admin `overseas-warehouse/api/pallets.ts` 跨仓查询 |
| GET R+`/{warehouseId}/locations`、R+`/{warehouseId}/locations/{id}` | Warehouse Overseas | P+`location:list` | Admin `overseas-warehouse/api/locations.ts` |
| POST R+`/{warehouseId}/locations` | Warehouse Overseas | P+`location:create` | 同上 |
| PUT R+`/{warehouseId}/locations/{id}` | Warehouse Overseas | P+`location:edit` | 同上 |
| DELETE R+`/{warehouseId}/locations/{id}` | Warehouse Overseas | P+`location:delete` | 同上 |
| GET R+`/{warehouseId}/pallets`、`/pallets/summary`、`/pallets/{id}`、`/pallets/{id}/label`(后面三项同属 R+`/{warehouseId}`) | Warehouse Overseas | P+`pallet:list` | Admin `overseas-warehouse/api/pallets.ts`,标签二进制响应保持原格式 |
| POST R+`/{warehouseId}/pallets` | Warehouse Overseas | P+`pallet:create` | 同上 |
| PUT R+`/{warehouseId}/pallets/{id}` | Warehouse Overseas | P+`pallet:edit` | 同上 |
| DELETE R+`/{warehouseId}/pallets/{id}` | Warehouse Overseas | P+`pallet:delete` | 同上 |
| 现有方法 `/api/platform/v1/last-leg/**`、`/api/merchant/v1/last-leg/**`、`/api/pda/v1/last-leg/**` | Lastleg | 保留对应 Controller 权限与作业数据范围 | Admin、Client、海外 PDA 改用统一 HTTP/Token,业务路径保持 |
| 现有文件、打印、审计、集成公开接口 | 原对应服务 | 保留现有权限 | 从原双网关去重后接入唯一入口 |
| 任意 `/internal/**` | 仅服务间内部网络 | 内部服务身份 | Gateway 无公开路由;测试内部接口不能通过公网入口调用 |
新增收货仓选项查询沿用原海外目录的分页参数 `page/size`(size≤200)和 `WarehouseOption` 字段语义,由 Warehouse 直接查询权威主档,不能只通过客户端过滤实现范围限制。该用途查询需在 Warehouse Controller/OpenAPI/IAM 权限合同中明确登记。现有 IAM 查询与 Admin pallets 中 `listSharedReceivingOverseasWarehouseOptions` 已使用主档接口,保留其现有权限边界;仅原海外目录的直接调用者迁移到新用途接口,不批量改写无关主档消费者。
修改 `PlatformWarehouseResourceController` 和 `PlatformWarehouseDirectoryController` 的资源路径;移除海外服务中的重复目录代理和无独立必要性的公开健康路由。内部资源锁、托盘作业路径保持服务内使用。Gateway 对 `/warehouse-admin/**` 只指向 Warehouse,对 R 只指向 Warehouse Overseas,不按路由先后顺序或请求 warehouseId 猜测目标服务。
路由验收:逐条 method/path 唯一匹配;静态 `/overseas-receiving-options` 不误命中 `/{id}`;同名旧前缀下的国内接口仍有效;海外调用方全部迁移,不为其保留旧别名;客户端角色只能读取被授权目录,不能借新增用途查询修改主档。
### B. 逐事件直接投递与结果确认
以下内部路径复用当前消费者入口,统一为 POST,使用内部服务令牌、服务发现或容器服务名,不能经公开 Gateway。按 eventType 明确选择目标,不再根据 CN/OVERSEAS 选择目标;未知事件类型直接记录永久错误,不默认投某个业务服务。
| eventType | 当前生产与投递入口 | 直接目标 |
|---|---|---|
| `FirstLegLoadingPlanCompleted` | Firstleg `LoadingCompletedOutboxService` → `LoadingCompletedOutboxRelay` | Lastleg `/internal/lastleg/events` |
| `FirstLegContainerShippingNodeRecorded` | Firstleg `CarrierScheduleNodeOutboxService` → 同一 `LoadingCompletedOutboxRelay` | Lastleg `/internal/lastleg/events` |
| `OverseasContainerUnloaded` | Lastleg `InboundUnloadCompletedOutboxService` → `InboundUnloadCompletedOutboxRelay` | Firstleg `/internal/firstleg/v1/container-events` |
| `OverseasInboundOrderDetainedChanged` | Lastleg `InboundOrderDetainedOutboxService` → 同一卸柜 Relay | Firstleg `/internal/firstleg/v1/container-events` |
| `OverseasDeliveryCompleted` | Lastleg `DeliveryCompletedOutboxService` → 同一卸柜 Relay | Firstleg `/internal/firstleg/v1/container-events` |
| `BusinessFeeSourceChanged` | Lastleg `OverseasFeeOutboxService` → `OverseasFeeOutboxRelay` | Finance `/internal/finance/v1/business-fee-source-events` |
| `WalletCommandRequested` | Lastleg `WalletCommandOutboxService` → `InboundUnloadCompletedOutboxRelay` | Finance `/internal/finance/v1/wallet-command-events` |
| `WalletCommandCompleted` | Finance 资金指令处理的结果 Outbox → `WalletResultOutboxRelay` | Lastleg `/internal/lastleg/events` |
| `IamUserStatusChanged`、`IamTenantStatusChanged`、`IamPermissionVersionChanged` | IAM 安全事件专用生产/Relay | 不迁移业务投递;完成 C 的撤销替代验证后移除专用投影链 |
已核对:Lastleg 卸柜 Relay 的 Repository 还选择了资金指令,不能把它整体改成 Firstleg URL;费用 Relay 只选择费用来源事件。实现时使用明确的事件白名单分派,并测试资金请求不误投 Firstleg。Firstleg 现有直达 Finance 的其他费用链、Order 的既有投递和 RocketMQ 导出/通知不并入本次新路由表,保持现有行为并做受影响回归。
统一目标返回结构为 `ApiResponse<DeliveryAck>`,其中 `DeliveryAck={eventId,payloadHash,outcome}`。`outcome` 只允许 `APPLIED`(已完成消费)、`DUPLICATE`(已成功处理的同一事件)、`STALE`(该类事件明确允许忽略的旧版本)。四个内部消费路径同步修改为这个返回结构,Relay 与全部直接调用者同步更新;当前 Integer/Object/feeSourceId 等响应不作为最终成功判定依据,不引入双响应兼容。
成功必须同时满足:HTTP 2xx、body code 为字符串 `200`、ACK 中 eventId/payloadHash 与发送一致、outcome 为该类事件允许的值。消费端只在可靠提交后返回成功;不能刚入内存或仅保留待处理记录就返回 APPLIED。重复确认必须来自持久化幂等记录;同 eventId 不同 hash 为冲突,不允许覆盖。
消费处理的原子性按业务实现验证:普通消费者将业务变更与成功幂等记录同事务提交;第 0A 批已将资金执行、成功 Inbox 和结果 Outbox 收敛到同一事务,保存结果失败时资金一同回滚;事件身份独立持久化防止重试换内容。保留既有钱包业务幂等键和状态机,真实 MySQL 故障恢复仍需验证。
特别约定:资金指令的投递成功不等于冻结/扣款成功。Finance 必须可靠保存 SUCCEEDED 或 FAILED 业务结果及结果 Outbox 后确认该指令已消费,Lastleg 以 `WalletCommandCompleted` 更新业务状态。余额不足等已形成 FAILED 结果的指令不进行无意义的传输重试;成功扣款后结果发送失败,只重试原结果事件,不能再次生成扣款指令。
| 情况 | 生产端动作 | 消费端要求 |
|---|---|---|
| APPLIED / DUPLICATE | 标记完成 | 已提交、幂等记录可核验 |
| STALE | 仅显式允许旧版本忽略的事件标记完成 | 证明较新版本已覆盖且不丢独立业务事实;资金和独立费用动作不能泛用 STALE |
| 连接失败、超时、HTTP 5xx/429、临时数据库失败 | 原事件重试 | 超时后可能已提交,下次必须幂等 |
| 船节点等先于依赖单据到达 | 返回明确的可重试“依赖未就绪”业务错误,退避重试 | 不以不存在直接当成功,不靠查询顺序假设到达顺序 |
| 非法信封/版本、hash 冲突、未知类型、明确不可执行协议错误 | DEAD 并保留原因 | 不修改业务,不兜底成功 |
| 401/403 或内部令牌错误 | DEAD,标注配置/认证失败,修复后人工原样重试 | 失败关闭,不绕过鉴权 |
| 响应缺失、ACK 不匹配、未识别业务错误 | 不确认成功,有限重试后 DEAD | 保留诊断信息,不能仅按 HTTP 200 通过 |
统一逻辑状态为待投递、投递中、重试等待、完成、DEAD;可映射到现有表字段,不要求批量改名。初始测试参数:连接超时 3 秒、单次请求超时 15 秒、租约 60 秒、累计自动尝试 12 次、退避从 5 秒翻倍上限 30 分钟,加入小幅抖动;参数需可配置。租约失效后的恢复和最终状态更新必须校验持有者,避免旧任务覆盖新任务。消费超时不能被解释为事务一定回滚。
源码配置已统一为 `baiyue.event-delivery.connect-timeout-ms=3000`、`read-timeout-ms=15000`、`max-attempts=12`、`base-delay-seconds=5`、`max-delay-seconds=1800`、`jitter=0.1`、`lease-seconds=60`,供四个业务 Relay 使用。事件 Feign 客户端显式应用 EventDeliveryFeignConfiguration,禁止客户端内部自动重试及重定向,最终构建参数不被旧的全局 Feign 超时覆盖;连接与读取超时之和必须小于租约时长。`retry_count` 表示已失败或租约超时的投递次数;普通领取不递增,领取超时任务或恢复超时租约时计入一次,自动预算耗尽后保持 DEAD。实际投递失败从失败时刻计算下一次重试时间;每次领取使用独立租约 ID 和当前时间,最终写入必须匹配该 ID。DEAD 保留原始事件,不能通过定时扫描自行恢复。人工重试、逐次审计和指标已落地并通过本地事务回归,真实数据库/多服务故障恢复仍未验证,尚未达到停桥部署门槛。
每次尝试在本服务 event_delivery_attempt 表记录事件、目标、时间、耗时、结果、有限错误码和下一次重试;领取与STARTED审计同事务提交后才发HTTP,持有者CAS完成与审计完成同事务,失败一同回滚。过期租约审计为LEASE_EXPIRED并退避,本轮不立即重发。按服务/类型提供 pending/DEAD 数量及最老待处理时长;指标 baiyue.event.delivery.pending/dead/oldest.pending.seconds/sample.timestamp/sample.success 默认30秒采样,Prometheus只读缓存。采样失败保留旧值并标记失败,未知初值为NaN,不误报零积压。告警接入现有能力,不为本次新增独立监控平台。人工重试采用各生产服务的受保护内部操作与配套运维脚本,不新增公开后台页面:只允许 DEAD 原事件重试,记录操作人/原因,保留 eventId/hash/payload/业务幂等键,禁止修改载荷或伪造新 ID 后重发。
人工重试源码接口已冻结:GET `/internal/{firstleg|lastleg|finance}/event-operations/{entryId}` 查询状态,POST 同路径加 `/retry` 提交 `{requestId,operator,reason,expectedPayloadHash}`。使用独立 `X-Event-Operations-Token`,服务配置 `baiyue.event-delivery.operations-token` 对应 `EVENT_OPERATIONS_TOKEN`;缺失或不足32字节时仅关闭该运维能力,不影响业务启动。请求编号为稳定UUID,锁定本服务原Outbox行,DEAD→PENDING和 `event_delivery_retry_audit` 同事务提交;相同请求参数幂等,不同参数冲突,审计失败回滚状态。脚本 `baiyue-firstleg/scripts/event-outbox-operations.mjs` 只接受显式服务源地址与 `CHONGCHONG_ENV=test`,凭据仅从环境读取,不跟随重定向、不自动重试。不得通过公网Gateway或直接改表验收。
信封保留业务事件类型/版本、客户归属、聚合版本、因果/追踪标识及 payloadHash;删除 sourceRegion/targetRegion 及纯区域部署字段时同步 DTO、Validator、构造调用、SQL 基线和测试。语义事件版本及业务载荷不因去桥而随意改动。本轮不重写旧测试事件,不做旧信封兼容。
### C. 统一认证和会话撤销矩阵
Auth 是唯一签发者;Gateway 负责入口令牌与访问域校验,业务服务通过 common-security 校验同一会话及业务权限。统一使用 Auth 现有国内会话协议,不只调整海外 Audience。Auth、Gateway、Lastleg、Warehouse Overseas 必须使用一致 Redis DB、会话键前缀、序列化结构与有效期规则;业务缓存用独立前缀,不能混同会话键。
JWT 不携带角色或权限集合,只保留必要身份、客户/应用/仓绑定与版本声明;授权快照取服务端会话,平台/客户/PDA 访问域仍独立校验。客户端不能从 JWT 或外部伪造头获得绕过服务器权限检查的能力。
并发撤销以持久版本和权威快照指纹为准,不能只依赖删除Redis:Auth账号变更与签发读取使用行锁,Access会话另存状态指纹,Refresh签发前复核旧指纹;Gateway及common-security在Redis会话检查后调用Auth `/internal/auth/accounts/sessions/validate`。Auth重新核对账号版本及IAM当前授权快照,缺失状态或下游不可用拒绝访问。IAM用单条SELECT读取身份、客户、角色权限、两类仓绑定及subject/tenant版本,避免跨查询混合快照。Gateway采用非阻塞HTTP,校验调用不转发Bearer Token,内部服务令牌保护该端点且不递归调用会话验证。此依赖增加每次请求的权威校验成本,测试环境仍须测可用性与延迟。
| 触发行为 | 撤销范围与负责链 | 必须验证 |
|---|---|---|
| 当前会话退出 | Auth 撤销当前会话的 Access/Refresh 能力 | 原 Access 被拒绝,原 Refresh 不能恢复 |
| 密码重置、账号停用 | Auth 或 IAM 调 Auth,撤销该账号全部相关会话 | 多端旧 Token 均失效,停用后不可重新登录 |
| 客户停用 | IAM 确定该客户成员范围,Auth 撤销该客户作用域会话 | 该客户业务不可访问/刷新;其他客户与平台账号不被误撤销 |
| 成员移除、成员角色改变 | IAM → Auth 撤销对应成员/客户作用域会话 | 旧权限不可继续使用,重新登录/刷新不能恢复被移除身份 |
| 角色权限、角色分配变化 | IAM RBAC 确定所有受影响账号与作用域 → Auth 撤销 | 已登录用户不能继续使用旧权限快照,遗漏批量关联用户算失败 |
| 平台人员角色改变 | IAM 平台人员维护 → Auth 撤销相应账号会话 | 新旧角色与平台访问域正确 |
| PDA 仓绑定修改/清空 | IAM → Auth 撤销绑定账号全部相关会话 | 原仓 Token 拒绝;新登录只获得新仓;无绑定拒绝受限作业 |
| Refresh Token 轮转与重放 | Auth 维持现有会话轮转规则,各端共用刷新编排 | 失效 Refresh 不重复换取;并发刷新行为与当前契约一致 |
撤销职责优先复用现有 MemberService、RbacService、PlatformInternalUserService/PlatformUserManagementService 与 Auth revokeSessions 链。逐入口确认,不能只凭其中一处已有调用就删除全体安全投影。
安全变更不得在撤销失败后仍返回完整成功。实施必须核对调用与提交顺序,证明“新安全状态已生效、旧会话却残留”的异常路径不会继续授权;同进程 try/catch 或口头要求重试不构成保证。若当前实现无法保证,应在该批次补齐可靠撤销及失败关闭机制,并先验证再删投影,不能降级为等待 Token 自然过期。这里冻结的是安全结果,具体撤销代码调整依据逐入口核查限定范围。
必须覆盖 Redis 不可用、Auth 撤销调用超时、账号/客户停用后的刷新、跨客户 Token 混用、伪造身份头。业务服务不能仅信任浏览器提供的权限头;统一服务端认证后清除对原海外可信头及 Lastleg 安全投影的专用依赖。权限继续由服务器决定,客户端快照只用于显示。
## 业务归属与权限边界
平台和客户两级模型、服务端客户隔离、实际收货仓与 FBA 目的仓的区分继续有效。仓管绑定修改须撤销会话;无关平台角色不能通过客户端参数假冒仓绑定。统一认证后,不再用双区域安全投影作为权限来源。
资金指令当前实现补充:Finance 先单独提交 eventId/hash 身份记录,再在事务内锁定 Inbox 并复核 hash。资金变更、Inbox 最终结果及结果 Outbox 同事务提交;明确业务拒绝在原事务回滚后重新加锁记录,已有最终结果不得覆盖。可重试异常不产生最终 FAILED。内部消费响应已统一为 ApiResponse<DeliveryAck>,可靠提交后才确认成功。
最终业务拒绝白名单为 FIN-WALLET-INSUFFICIENT、FIN-WALLET-HOLD-409、FIN-IDEMPOTENCY-CONFLICT、FIN-REQ-400;处理中、乐观锁冲突、依赖冻结未到达及未分类异常继续向投递方抛出。基于 H2 的 JDBC 并发与回滚测试已经通过,不替代真实 MySQL 和测试环境全链路验证。
### 国内仓库目录同步读取
- 国内 `warehouse-service` 是 Warehouse ID、类型、状态、地址和能力的唯一权威。海外数据库不得复制仓库、地址或服务能力主表。
- `warehouse-overseas-service` 只保存库位、托盘、资源锁及其国内 `warehouseId` 引用;资源写入和 Lastleg PDA 仓绑定校验通过受内部服务令牌保护的国内只读目录完成。
- 只允许平台共享、`OVERSEAS`、`ACTIVE` 且启用 `RECEIVING` 的仓作为海外实际收货仓。低频正结果可缓存 30 分钟,空目录、不存在和停用结果不得长缓存。
- FBA 目的仓同样只以国内 `warehouse-service` 的平台公共主数据为权威,但语义与海外实际收货仓严格分离:Admin 候选使用 `warehouseType=FBA&status=ACTIVE` 的平台仓库分页;Lastleg 写入通过受内部服务令牌保护的 `/internal/warehouses/0/{warehouseId}/active` 读取当前事实,并继续校验 `warehouseType=FBA` 及 ID/编码/名称一致。`OVERSEAS`、`OVERSEAS_PARTNER` 或 `DOMESTIC` 均不得作为 FBA 目的仓。
- 按 FBA 仓拆分的海外派送单在签收完成时,由 Lastleg 在同一事务按关联来源入仓单分别写 `OverseasDeliveryCompleted` V1 Outbox;Lastleg Relay 直接投递 Firstleg 的 `/internal/firstleg/v1/container-events`。Firstleg 校验事件信封、客户、来源入仓单/订单、入仓码和 FBA 仓后,只将该来源入仓单从 `LOADED` 推进到 `DELIVERED`;同一 Order 的全部有效入仓单均为 `DELIVERED` 后,才以内部服务身份幂等推进该 Order 到 `COMPLETED`。同车其他 FBA 派送单必须各自签收,不得随整车一起完成。
+1
View File
@@ -63,6 +63,7 @@
详细设计材料: 详细设计材料:
- [海外仓费用统一接入财务评审方案](海外仓费用统一接入财务评审方案.md) - [海外仓费用统一接入财务评审方案](海外仓费用统一接入财务评审方案.md)
- [海外仓费用统一接入阶段0技术契约](海外仓费用统一接入阶段0技术契约.md)
- [财务业务操作流程图](财务全链路流程图.md) - [财务业务操作流程图](财务全链路流程图.md)
- [财务业务全流程总览图(PNG)](财务业务全流程总览图.png) - [财务业务全流程总览图(PNG)](财务业务全流程总览图.png)
- [财务来源接入现状](财务来源接入现状.md) - [财务来源接入现状](财务来源接入现状.md)
@@ -0,0 +1,229 @@
# 海外仓费用统一接入阶段 0 技术契约
> 文档状态:开发基线配套契约 V0.1
> 编制日期:2026-09-21
> 适用范围:阶段 0A—0E;配套需求基线为 [海外仓费用统一接入财务评审方案](海外仓费用统一接入财务评审方案.md)
本文把 V0.5 的阶段 0 规则转成可编码的跨服务边界、状态和唯一性约束。本文不是数据库字段逐项施工单;开发时可以调整表名和类名,但不得改变这里的业务语义、状态分离、幂等边界和跨区域结果规则。
## 一、阶段 0 目标与顺序
阶段 0 不是新增仓租算法,先修复已有海外费用链路的一致性:
| 子阶段 | 目标 | 依赖 |
|---|---|---|
| 0A | 统一收费身份、人工/自动去重、换标漏发、拆柜费用身份、派送收付方向 | 先冻结本文模型和唯一键 |
| 0B | 人工费用草稿/驳回修改、待审工作台、业务费用聚合、直付证据 | 0A 收费身份 |
| 0C | Finance 费用接受/拒绝结果回传、来源版本变更裁决 | 0A 的版本模型 |
| 0D | 资金计划 ID/版本、来源精确分配、冻结/结算/释放旧计划隔离 | 0C 的有效版本结果 |
| 0E | 商业减免、取消收费、待财务处理及自动重算门禁 | 0C、0D |
0A—0E 可以在前序数据结构稳定后并行实现,但不能在未冻结本契约前各模块自行新增状态或幂等字段。
## 二、当前代码事实与必须修正的断点
| 现状入口 | 当前行为 | 阶段 0 修正 |
|---|---|---|
| `lastleg-service/financefee/OverseasFeeSourceService` | `adjust` 先把旧版本设为 `SUPERSEDED`,`voidSource` 先设为 `VOIDED` | Finance 接受前旧有效版本继续保留;新候选/作废命令等待 Finance 结果 |
| `OverseasFeeOutboxService` / `BusinessFeeSourceChangedV1` | 只有海外向 Finance 的完整快照事件,没有业务可消费的接受/拒绝结果 | 增加版本化费用变更命令和 Finance 结果事件,双向 Outbox/Inbox 幂等 |
| `BusinessFeeSourceEventService` | Finance 直接入池并返回本地方法结果,无结果事件;资金关联按业务类型、业务单号和金额匹配 | 同事务记录命令结果;接受、拒绝、冲突、超时可回传;资金按计划版本和来源分配关联 |
| `WalletCommandRequestedV1` | 只带业务类型、业务单号、金额和聚合版本 | 资金计划 ID/版本、收费身份、计划金额快照和来源分配进入新目标协议 |
| `DestuffingPalletCostService` | 手工构造 `APPROVED/PUBLISHED` 来源,绕过通用审核和统一收费身份 | 复用计费身份、来源版本、审核策略和调整门禁;分摊组保持守恒 |
| 换标完成分支 | 仅部分 `COMPLETED` 路径发布换标费并发起资金结算 | 所有合法完成分支汇合到唯一发布/结算入口,重复完成幂等 |
| 派送转单 | 转派送时人工费用自动审核,且同一费用项目的应收/应付身份不完整 | 人工费用进入待审核;应收与应付按收费身份独立,实际供应商和直付证据必填 |
| `listForBusiness` | 主要按单一 `businessType + businessId` 查询 | 业务详情按稳定关系聚合来源,当前有效版本与待确认变更分开返回 |
## 三、收费身份模型
### 3.1 收费身份与来源版本分离
收费身份表示“同一业务应该收哪一笔钱”;来源版本表示“这一笔钱当前提交了哪个金额版本”。二者不得混用。
收费身份逻辑字段:
```text
identityKey
customerId
sourceSystem
businessType
businessId / businessNo
scenarioCode
feeItemCode
direction
priceRole CUSTOMER_SALE / SUPPLIER_COST
supplierId 成本侧必填;销售侧为空
periodScope 离散事实或计费期间范围
```
约束:
- 客户应收和供应商应付是两条身份;不能用方向字段在一行中来回切换。
- 成本侧实际供应商进入身份。多个供应商责任必须拆成多个身份。
- 自动任务、人工补录、重放、报价恢复和资金计划都引用同一身份。
- 明确免收也占用身份,不能因为没有 Finance 来源而再次收费。
- 退货按票身份按 `RETURN_ORDER + RETURN_HANDLING + CUSTOMER_SALE` 去重;退货操作费按实收累计组;仓租按原始分量、角色、供应商和日期范围占用。
### 3.2 来源候选版本状态
业务审核状态、Finance 同步状态、财务来源状态和结算状态分开保存:
| 状态轴 | 首版值 | 含义 |
|---|---|---|
| `reviewStatus` | `DRAFT`、`PENDING`、`APPROVED`、`REJECTED` | 业务是否允许向 Finance 提交 |
| `financeSyncStatus` | `NOT_SENT`、`PENDING_FINANCE`、`ACCEPTED`、`REJECTED` | 该候选命令的跨区结果 |
| `sourceStatus` | `ACTIVE`、`SUPERSEDED`、`VOIDED` | Finance 接受后的来源有效性;接受前不得覆盖旧有效版本 |
| `settlementStatus` | `AVAILABLE`、`PENDING_WALLET`、`SETTLED`、`BILLED`、`BLOCKED_FINANCE` | 出账或资金路径状态 |
同一收费身份最多一个待 Finance 确认的候选或变更。Finance 拒绝后,旧有效版本继续有效;修订必须以最后 Finance 接受的版本为前序生成新候选。
## 四、跨区域费用命令与结果
### 4.1 费用变更命令
现有 `BusinessFeeSourceChangedV1` 保留为被替换的旧目标,不新增双协议兼容。阶段 0 直接收敛到新版本事件,建议逻辑载荷名为 `BusinessFeeSourceCommandV2`,事件动作:
- `PUBLISH`:首次发布一个候选版本;
- `REPLACE`:申请替代当前有效版本;
- `VOID`:申请作废当前有效版本。
命令必须携带:
```text
commandId
identityKey
sourceFeeId
targetVersion
expectedActiveVersion 首次发布显式为空
action
sourceSnapshot
sourceHash
requestedAt
```
`sourceSnapshot` 继续沿用现有完整客户、业务、方向、供应商、付款、币种、数量、期间和审核快照。Finance 不跨区回查 Lastleg。
### 4.2 Finance 结果事件
Finance 在同一事务完成校验、来源写入/变更裁决和结果 Outbox,向海外发送 `BusinessFeeSourceResultV2`:
```text
commandId
identityKey
result ACCEPTED / REJECTED
acceptedSourceFeeId
acceptedSourceVersion
activeSourceVersion
errorCode
errorMessage
processedAt
```
规则:
- 同 `commandId + payloadHash` 重放返回原结果;同命令异载荷拒绝。
- `expectedActiveVersion` 不等于 Finance 当前有效版本时拒绝,不回退当前有效版本。
- `ACCEPTED` 才能让海外候选变为有效版本;`REJECTED` 只关闭该候选命令,不删除事实。
- 超时和网络失败保持 `PENDING_FINANCE`,不能标记成功或拒绝。
- 结果回传失败不改变 Finance 已接受状态;海外重试同一结果事件。
- Event Bridge 只负责路由和投递,不把“已转发”当作 Finance 已接受。
## 五、资金计划版本
费用来源与资金冻结不能再通过“业务类型 + 业务单号 + 金额”模糊关联。
### 5.1 计划模型
资金计划逻辑字段:
```text
planId
planVersion
identityKey
customerId
amountCny
status PENDING / FROZEN / SETTLE_PENDING / SETTLED / RELEASE_PENDING / RELEASED / FAILED
sourceAllocations[] sourceFeeId + sourceVersion + amountCny
```
一笔计划可以分配多笔来源,但所有分配金额之和必须等于计划金额;一份来源版本只能被该计划消费一次。计划金额、身份和版本一旦冻结,不允许先改费用再等待来源到达。
### 5.2 指令规则
资金命令至少携带 `planId + planVersion + operation + identityKey + amountSnapshot`。`SETTLE` 先到时,Finance 持久化等待;只有目标来源全部接受、分配完整且金额守恒后才扣款。`RELEASE` 结果未知时保持锁定,不允许同时建立新计划。
旧计划释放后收到迟到 `SETTLE`,只能访问旧计划并返回拒绝,不能按业务单号找到新计划执行扣款。计划 ID 不复用。
## 六、业务链路修复要求
### 6.1 换标
- 统一所有合法完成分支进入一个费用/资金编排入口。
- `RELABEL_SERVICE` 保持现有费用编码,不新增同义 `RELABEL_FEE`。
- 费用发布、资金结算和业务完成各自幂等;纯 SKU、需要出库和退货换标路径都必须覆盖。
- Finance 接受前允许业务保持原有效候选;资金结算必须绑定计划版本和已接受来源版本。
### 6.2 拆柜打托
- 保留全柜成本总额和客户分摊守恒;每客户分摊来源拥有稳定收费身份。
- 不再手工直接插入“已审核已发布”绕过通用服务;自动审核必须来自获批规则,调整和作废复用统一命令。
- 首版继续 `DESTUFF_PALLET` 与 `OVERSEAS_CONTAINER` 业务身份,但应在通用校验中明确允许该组合,避免项目编码与调整校验不一致。
- 当前仅自动客户应收;供应商成本属于后续阶段,不能伪造应付。
### 6.3 派送
- 同一派送业务允许一条客户应收和一条供应商应付,但两者身份、价格、供应商和结算方式独立。
- 人工金额默认进入 `PENDING`,不能在转派送动作中自动审核。
- 业务日期使用真实费用触发日期,不使用无关任务执行时刻作为历史补价日期。
- `DIRECT_PAID` 必须有付款时间、方式、流水号或凭证,并由 Finance 形成已确认成本;`ON_ACCOUNT` 进入应付。
### 6.4 业务费用查询
业务详情查询按稳定关系聚合订单、入仓、柜、派送、换标和退货来源;返回:
- 当前 Finance 接受的有效版本;
- 待 Finance 确认的候选/变更;
- 被拒绝、超时、待资金、已结算和已作废结果;
- 共享费用的分摊金额,不重复计入多个订单小计。
Finance 尚未接受的来源必须能从海外异常入口查询,不能以 Finance 费用池没有记录作为“未生成”的唯一判断。
## 七、ID、供应商和事件边界
- 跨端 DTO 和事件中的仓库、供应商、客户、业务 ID 使用十进制字符串;领域层严格解析,禁止使用名称或 FBA 目的仓代码替代主档 ID。
- Lastleg 报价仓、实际作业仓、库存仓引用同一国内 Warehouse 主档 ID;`providerName` 只能是快照,不能作为供应商身份。
- 供应商成本来源必须通过 Warehouse 校验启用状态和类别;Finance 再次失败关闭校验。
- 事件载荷不携带用户 JWT,不跨区域回查数据库;生产者、Event Bridge、Finance、结果消费者和测试必须同步升级。
## 八、开发与验证门禁
### 8.1 0A 开工前
开发先提交以下技术设计并在代码中一次性收敛:
1. 收费身份、候选版本、当前有效版本和唯一约束;
2. `BusinessFeeSourceCommandV2` / `BusinessFeeSourceResultV2` 事件 DTO、事件类型和双向路由;
3. 资金计划、分配表、计划版本和 V2 指令事件;
4. 仓库/供应商 ID 与业务场景枚举校验;
5. Lastleg、Finance、Event Bridge 的锁顺序、Outbox/Inbox 和拒绝重试分类。
### 8.2 阶段验证
- 0A:换标四类完成路径、拆柜分摊守恒、派送应收/应付和人工审核。
- 0B:草稿驳回修改、统一待审查询、业务聚合和直付证据。
- 0C:Finance 接受、拒绝、超时、乱序、重放、前序版本冲突和来源冻结。
- 0D:冻结/结算/释放乱序、计划版本隔离、来源分配守恒、旧指令拒绝。
- 0E:减免接受、减免拒绝、自动重算暂停、取消收费和待财务处理。
跨服务修改至少运行公共事件契约、Lastleg、Finance、Event Bridge 直接消费者测试,并执行 `node scripts/mapper-scan-contract.mjs`、`node --test scripts/gateway-route-contract.test.mjs`;未经明确环境授权不启动服务、不执行真实 HTTP、不部署。
## 九、代码入口
- 海外费用来源:`baiyue-firstleg/lastleg-service/src/main/java/com/baiyue/lastleg/financefee/`
- Finance 海外费用消费:`baiyue-firstleg/finance/src/main/java/com/baiyue/finance/service/BusinessFeeSourceEventService.java`
- 资金事件:`baiyue-firstleg/common-event-contract/src/main/java/com/baiyue/common/event/WalletCommandRequestedV1.java`、`WalletCommandCompletedV1.java`
- 资金生产/消费:`baiyue-firstleg/lastleg-service/src/main/java/com/baiyue/lastleg/wallet/`、`baiyue-firstleg/finance/src/main/java/com/baiyue/finance/service/WalletCommandEventService.java`
- 换标:`baiyue-firstleg/lastleg-service/src/main/java/com/baiyue/lastleg/relabel/service/RelabelApplicationService.java`
- 派送:`baiyue-firstleg/lastleg-service/src/main/java/com/baiyue/lastleg/delivery/service/DeliveryTransferService.java`
- 拆柜打托:`baiyue-firstleg/lastleg-service/src/main/java/com/baiyue/lastleg/inboundplan/service/DestuffingPalletCostService.java`
- 业务费用来源表:`lastleg-service/src/main/resources/db/lastleg.sql` 的 `ll_finance_fee_source`;Finance 表:`finance/src/main/resources/db/finance.sql` 的 `fin_fee_source`、`fin_wallet_hold`、`fin_wallet_command_inbox`
@@ -123,6 +123,16 @@ Finance 不以当前查询结果覆盖已保存快照。查询超时、5xx 或
## 7. 错误码与响应语义 ## 7. 错误码与响应语义
### 资金指令消费可靠性(2026-09-29)
`WalletCommandRequested` 先独立提交 eventId/hash 身份记录,再在处理事务使用 Inbox 行锁重新校验 hash;相同 ID 不同 hash 即使并发到达也不能执行钱包。资金变更、成功 Inbox 结果和结果 Outbox 同事务提交,任何结果写入失败均回滚资金变更,原事件保留身份并允许重试。
仅 `FIN-WALLET-INSUFFICIENT`、`FIN-WALLET-HOLD-409`、`FIN-IDEMPOTENCY-CONFLICT`、`FIN-REQ-400` 作为明确业务拒绝,在原事务回滚后重新锁定事件、确认无既有最终结果,再保存 FAILED 与结果 Outbox。临时数据库异常、处理中、乐观锁冲突、冻结依赖未到达及其他未分类异常继续抛出,不确认消费成功,不固化为最终业务失败。传输确认仍不等于资金业务成功,Lastleg 继续消费资金结果事件。
本条是当前消费者实现规则;单机去桥目标及统一 ACK 见[统一认证与服务通信契约](../统一认证与服务通信契约.md),后者尚未整体落地。
### 通用响应
错误码是跨服务稳定字符串,message 可本地化且不能作为程序判断依据: 错误码是跨服务稳定字符串,message 可本地化且不能作为程序判断依据:
| 错误码 | 语义 | 是否重试 | | 错误码 | 语义 | 是否重试 |
+3 -53
View File
@@ -1,55 +1,5 @@
# 跨区域认证与服务通信契约 # 跨区域认证与服务通信契约(已替代)
## 适用范围 自 2026-09-29 起,当前目标仅有一个测试环境,服务同机部署。旧双区域认证、独立海外网关及事件桥约束已由[统一认证与服务通信契约](统一认证与服务通信契约.md)替代;部署与切换见[测试环境单机部署与配置契约](测试环境单机部署与配置契约.md)。
- 本契约适用于 Admin、Client、国内头程服务、海外网关、尾程服务、海外仓资源服务及跨区域事件桥接。 此文件仅保留旧链接入口,不再定义有效规则。目标已确认不代表当前代码和环境已经迁移完成。
- 业务范围仍按对应阶段和模块文档确定;本文件只冻结跨区域账号、请求路由、服务鉴权和事件通信边界。
- 开发/测试同机共置及生产国内/海外双控制面的实际部署拓扑、Nacos、数据库和 Event Bridge 规划见[双区域部署与 Nacos 规划](双区域部署与Nacos规划.md)。
## 统一账号与 Token
- Admin、Client 只维护一套前端和一套用户账号体系;用户登录和 Token 签发统一归国内头程 Auth,不得为海外仓再创建独立登录、账号或权限体系。
- 统一使用 RS256/JWKS 信任链,但区分 Token 用途:国内登录/刷新时由同一 Auth 同时签发国内 Token 和短时海外 Token;海外 Token 限定海外 Audience,只携带稳定身份、客户范围与版本声明,不携带角色或权限集。
- 平台 `WAREHOUSE_PICKER` 必须在 IAM 成员关系中绑定一个启用的实际海外收货仓;Auth 将该绑定以可空 `overseas_warehouse_id` Claim 同步写入国内与海外 Token,海外 Token 同时携带账号 `token_version`。该 Claim 只用于已绑定的平台仓管员,页面和 PDA 请求不得传入或覆盖仓库身份;修改或清空仓绑定时 IAM 必须调用 Auth 撤销该账号全部会话并递增 `token_version`,随后重新签发 Token。
- 用户只登录一次,由前端统一认证模块按目标 API 自动选择 Token,不在页面或业务模块中分叉登录逻辑。
- JWKS 只暴露公钥验证能力,不暴露私钥;国内服务验证登录 Token 并结合 Redis 会话实现即时退出和权限变更,海外业务服务不访问国内 Redis。`gateway-overseas` 对普通 Admin/Client 海外接口验证海外 Token 的签名、Issuer、Audience、有效期、应用域和客户范围,再按 `userId/tenantId/permissionVersion` 从 Lastleg 安全投影取得当前海外授权快照;仅 `/api/pda/**` 在本地验签后,以内部服务身份向 Auth 发送 `userId/tokenVersion/overseasWarehouseId` 做无缓存实时核对。该调用不得传递 raw Token 或用户凭据,Auth 超时、不可用、账号停用、版本或仓绑定不一致均 fail-closed。
- 本期普通 Admin/Client 海外 Token 的即时失效范围固定为 IAM 投影的账号停用、客户停用和权限版本推进;Gateway 向 Lastleg 安全投影仅发送 `userId/tenantId/permissionVersion`,旧 Token 被拒绝后客户端必须退出并重新登录。`token_version` 仍是海外 JWT 必填 Claim,但其权威实时比对只用于上述 PDA→Auth 链;普通 Admin/Client 的退出、密码重置或普通会话撤销依赖短时 Token 自然过期,不得宣称已由 Lastleg 即时撤销。
## 区域 API 路由
- 一套前端使用国内、海外两个区域 API Base:国内业务直连 `gateway/`,海外仓业务直连 `gateway-overseas/`,再由海外网关路由到 `lastleg-service/`、`warehouse-overseas-service/` 和海外部署的公共服务。
- 日常海外请求不得经国内 Gateway 中转。区域地址、Token 选择和刷新由环境配置与统一 API/认证层处理,业务页面不得感知部署区域差异。
- 海外浏览器请求的具体 Audience、Claim 和路由以前端项目、`auth/`、`gateway-overseas/` 最近的 `AGENTS.md` 与实际配置为准;修改其中任一项时必须联查全部生产者和消费者。
## 跨区域事件与服务身份
- 头程与海外仓的数据流转使用 MQ 的 Outbox → Inbox、事件幂等、重试和死信机制。
- 事件使用版本化信封、事件 ID、业务键、来源/目标区域和 Payload 哈希,不携带用户 Access Token。
- 费用由海外仓发布事件,头程 Finance 消费并按来源快照入账;财务状态机和结算口径仍由财务契约冻结,海外服务不得自行定义。
- MQ 使用独立的服务身份、TLS 和 ACL;服务间事件鉴权与用户 JWT 鉴权分开。只有明确的同步 HTTP 内部接口才使用内部服务令牌。
- 修改事件时联查 `common-event-contract/`、`event-bridge-service/`、生产服务、消费服务、幂等记录、重试/死信和契约测试。
- 按 FBA 仓拆分的海外派送单在签收完成时,由 Lastleg 在同一事务按关联来源入仓单分别写 `OverseasDeliveryCompleted` V1 Outbox;Event Bridge 定向投递 Firstleg。Firstleg 校验事件信封、客户、来源入仓单/订单、入仓码和 FBA 仓后,只将该来源入仓单从 `LOADED` 推进到 `DELIVERED`;同一 Order 的全部有效入仓单均为 `DELIVERED` 后,才以内部服务身份幂等推进该 Order 到 `COMPLETED`。同车其他 FBA 派送单必须各自签收,不得随整车一起完成。
### 国内仓库目录同步读取
- 国内 `warehouse-service` 是 Warehouse ID、类型、状态、地址和能力的唯一权威。海外数据库不得复制仓库、地址或服务能力主表。
- `warehouse-overseas-service` 只保存库位、托盘、资源锁及其国内 `warehouseId` 引用;资源写入和 Lastleg PDA 仓绑定校验通过受内部服务令牌保护的国内只读目录完成。
- 只允许平台共享、`OVERSEAS`、`ACTIVE` 且启用 `RECEIVING` 的仓作为海外实际收货仓。低频正结果可缓存 30 分钟,空目录、不存在和停用结果不得长缓存。
- FBA 目的仓同样只以国内 `warehouse-service` 的平台公共主数据为权威,但语义与海外实际收货仓严格分离:Admin 候选使用 `warehouseType=FBA&status=ACTIVE` 的平台仓库分页;Lastleg 写入通过受内部服务令牌保护的 `/internal/warehouses/0/{warehouseId}/active` 读取当前事实,并继续校验 `warehouseType=FBA` 及 ID/编码/名称一致。`OVERSEAS`、`OVERSEAS_PARTNER` 或 `DOMESTIC` 均不得作为 FBA 目的仓。
### IAM 安全事件海外投影冻结
- `IamUserStatusChanged`、`IamTenantStatusChanged`、`IamPermissionVersionChanged` V1 固定由 Lastleg 独立安全入口 `/internal/lastleg/security/v1/events` 消费;不得投递到 Lastleg 的 LoadingCompletedConsumer。
- 安全状态只使用 `ACTIVE`/`DISABLED`:`IamTenantStatusChanged` 仅在 IAM 客户业务状态为 `ACTIVE` 时发布 `ACTIVE`,`PROFILE_REQUIRED`、`PENDING`、`REJECTED`、`DISABLED`、`ARCHIVED` 及其他不可用状态统一折叠为 `DISABLED`。Lastleg 只校验该两态安全快照,不解释国内建档/审核工作流。
- Event Bridge 只按冻结的 eventType→consumer URL 选择下游,不解析状态、权限版本或 payload 业务字段。海外业务事件仍投 Lastleg,国内回流事件仍投 Firstleg。
- Lastleg 以 MySQL `ll_security_event_inbox` 和 `ll_security_projection` 为可靠来源:eventId 相同 hash 相同幂等,异 hash 冲突;聚合版本只单调推进,旧版本标记 STALE,同版本异 hash 冲突。Redis 仅为提交后写入的可重建镜像,授权校验不依赖 Redis 默认放行。
- 海外 Gateway 对全部 `/api/**` 在本地 JWT 验签后,传递 `userId/tenantId/permissionVersion` 到 Lastleg 安全入口。Lastleg 校验通过时返回该版本的角色与海外权限快照,Gateway 清除外部伪造的授权头后,以内部服务令牌保护的可信头传给海外业务服务。业务服务必须同时验证 JWT 和内部服务令牌,不得从 JWT 回退读取完整权限集。用户停用返回 A0401;客户停用或 Token 权限版本不一致返回 A0403;安全投影、SQL 或调用链不可用均 fail-closed。PDA 在此基础上继续执行 Auth 仓绑定实时核验。
- Auth 的登录、刷新和海外 Token 兑换响应在响应体中返回当前 `roles/authorities` 授权快照;国内与海外 JWT 都只保留主体、客户、成员、应用、版本和海外仓绑定等最小身份 Claim,不携带角色或权限集合。客户端可用响应快照做入口展示或本地前置提示,但每次业务请求的最终授权仍由 Gateway/Lastleg 的实时投影决定;客户端不得再从 JWT 解析角色或权限,也不得把响应快照作为绕过服务端校验的依据。
- 新客户创建、审核激活以及新用户授权均由 IAM 在业务事务内写初始安全事件。开发阶段不提供历史账号长期 Bootstrap 或兼容入口;固定 `platform_admin` 由 Lastleg 数据库基线初始化 version=0 的 USER/AUTHORIZATION 投影,其中 AUTHORIZATION 冻结当前 `PLATFORM_ADMIN` 角色及 IAM 跨区前缀下的完整权限集合,空库重建后无需人工补投即可访问海外接口,后续 version>=1 的真实 IAM 事件单调覆盖。其他既有开发账号仍须由总控按 IAM 当前事实一次性重建授权快照;任何缺失投影继续 fail-closed,不能在 Lastleg 运行时代填或默认放行。
## 修改与验收
- Token、Audience、Claim、JWKS、API Base 或刷新策略变化时,至少联查 Auth、IAM、Admin/Client 统一认证层、国内/海外 Gateway、`common-security/` 和目标海外服务。
- `overseas_warehouse_id` 变化时还需联查 IAM 平台用户维护、海外 PDA、Lastleg 收货会话及 Warehouse Overseas 共享仓校验;验收必须同时覆盖未绑定拒绝、非仓管角色禁止绑定和换仓后旧 Token 失效。
- 跨区域事件变化时同步检查事件版本、Payload 哈希、Outbox、Inbox、重复投递、失败重试、死信和全部实际消费者。
- 本文件是跨区域通信的公共事实来源;项目和模块 `AGENTS.md` 只保留执行所需摘要及本文件入口,不复制完整协议。