feat(appointment): integrate work calendar and stable cargo batches
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
-- DDL proposal only. The coordinator must integrate the approved baseline; do not execute from this task.
|
||||
CREATE TABLE IF NOT EXISTS ll_dispatch_appointment_allocation (
|
||||
dispatch_id BIGINT NOT NULL,
|
||||
dispatch_item_id BIGINT NOT NULL,
|
||||
plan_pallet_id BIGINT NOT NULL,
|
||||
batch_key VARCHAR(96) NOT NULL,
|
||||
customer_id VARCHAR(64) NOT NULL,
|
||||
source_key VARCHAR(160) NOT NULL,
|
||||
destination_key VARCHAR(160) NOT NULL,
|
||||
package_count INT NOT NULL,
|
||||
PRIMARY KEY(dispatch_item_id,batch_key,source_key,destination_key),
|
||||
KEY idx_dispatch_appointment_batch(batch_key,customer_id),
|
||||
KEY idx_dispatch_appointment_dispatch(dispatch_id)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='排车实物与预约批次逐票分配,原执行域事实';
|
||||
CREATE TABLE IF NOT EXISTS ll_appointment_work_commitment (
|
||||
entity_key VARCHAR(160) NOT NULL,
|
||||
state_json LONGTEXT NOT NULL COMMENT '原业务命令产生的只读语义影响基线,不是第二份可编辑计划',
|
||||
impact_version BIGINT NOT NULL DEFAULT 0,
|
||||
PRIMARY KEY (entity_key)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='工作事项承诺影响审计基线';
|
||||
CREATE TABLE IF NOT EXISTS ll_appointment_work_guard (
|
||||
id INT NOT NULL COMMENT '工作事项协调锁,固定1',
|
||||
scan_cursor VARCHAR(128) NULL COMMENT '已开船来源同步游标',
|
||||
initialized BOOLEAN NOT NULL DEFAULT FALSE COMMENT '是否完成首次完整来源扫描',
|
||||
scope_version VARCHAR(128) NULL COMMENT '完整同步已确认的权威来源集合版本',
|
||||
scan_scope_version VARCHAR(128) NULL COMMENT '当前扫描来源集合版本,防跨页漂移',
|
||||
completed_at DATETIME(3) NULL COMMENT '最近完整同步UTC时间',
|
||||
requirement_version BIGINT NOT NULL DEFAULT 0 COMMENT '原域命令在同一事务推进的需求版本',
|
||||
synchronized_requirement_version BIGINT NOT NULL DEFAULT 0 COMMENT '完整扫描已消费需求版本',
|
||||
scan_requirement_version BIGINT NOT NULL DEFAULT 0 COMMENT '当前扫描需求版本,防跨页漂移',
|
||||
PRIMARY KEY (id)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='预约工作事项同步与命令串行守卫';
|
||||
INSERT INTO ll_appointment_work_guard(id,initialized) SELECT 1,FALSE WHERE NOT EXISTS(SELECT 1 FROM ll_appointment_work_guard WHERE id=1);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS ll_appointment_work (
|
||||
work_item_key VARCHAR(96) NOT NULL COMMENT '不可变事项键,业务身份确定性生成',
|
||||
container_booking_id VARCHAR(64) NOT NULL COMMENT '来源柜次内部关联标识,不作展示编号',
|
||||
version INT NOT NULL DEFAULT 0 COMMENT '工作命令乐观锁版本',
|
||||
retired BOOLEAN NOT NULL DEFAULT FALSE COMMENT '已替代或已完成路线需求,不计活动工作',
|
||||
state_json LONGTEXT NOT NULL COMMENT '工作关系责任跟进及影响基线,不保存可编辑业务执行事实',
|
||||
PRIMARY KEY (work_item_key),
|
||||
KEY idx_appointment_work_container (container_booking_id,retired)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='预约工作事项需求与关系';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS ll_appointment_work_history (
|
||||
id VARCHAR(36) NOT NULL COMMENT '历史记录标识',
|
||||
work_item_key VARCHAR(96) NOT NULL COMMENT '事项稳定键',
|
||||
operator_id VARCHAR(64) NOT NULL COMMENT '真实操作人员标识',
|
||||
operator_name VARCHAR(128) NULL COMMENT '操作人显示名称',
|
||||
action VARCHAR(48) NOT NULL COMMENT '工作命令或观察动作',
|
||||
summary VARCHAR(2000) NOT NULL COMMENT '处理或责任变更依据',
|
||||
command_key VARCHAR(64) NULL COMMENT '请求幂等键,观察记录为空',
|
||||
request_hash VARCHAR(64) NULL COMMENT '包含操作者的规范请求摘要',
|
||||
response_json LONGTEXT NULL COMMENT '原命令响应快照,重放不随当前状态改变',
|
||||
occurred_at DATETIME(3) NOT NULL COMMENT '历史发生UTC时间',
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE KEY uk_appointment_work_command (work_item_key,command_key),
|
||||
KEY idx_appointment_work_history (work_item_key,occurred_at)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='预约工作事项历史与幂等命令';
|
||||
@@ -1667,6 +1667,9 @@ CREATE TABLE IF NOT EXISTS ll_inbound_fba_appointment (
|
||||
appointment_remark VARCHAR(1000) NULL COMMENT '备注或取消原因',
|
||||
fba_warehouse_code VARCHAR(128) NOT NULL COMMENT 'FBA目的仓编码',
|
||||
selected_count INT NOT NULL DEFAULT 0 COMMENT '真实货源票数',
|
||||
replacement_nos_json LONGTEXT NULL COMMENT '分批或合并后的新预约业务号列表,非空时原批次只读',
|
||||
replacement_keys_json LONGTEXT NULL COMMENT '替代批次不可变键列表,只用于内部业务关联',
|
||||
repartition_reason VARCHAR(1000) NULL COMMENT '分批或合并原因,原安排及来源明细保留',
|
||||
created_by VARCHAR(128) NOT NULL COMMENT '登录操作人',
|
||||
created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建UTC时间',
|
||||
updated_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '更新UTC时间',
|
||||
@@ -1686,19 +1689,42 @@ CREATE TABLE IF NOT EXISTS ll_inbound_fba_appointment_item (
|
||||
order_id BIGINT NULL COMMENT '尚未形成尾程订单时为空',
|
||||
inbound_code VARCHAR(128) NULL COMMENT '真实入仓码,不伪造',
|
||||
fba_warehouse_code VARCHAR(128) NOT NULL COMMENT '目的FBA仓编码',
|
||||
package_count INT NULL COMMENT '所选整票预报箱数,未知保持空',
|
||||
package_count INT NULL COMMENT '本批分配箱数,未知保持空;同一原来源总量守恒',
|
||||
cargo_verification_version INT NULL COMMENT '采用的预约货物核实版本,未核实时为空',
|
||||
shipment_references_json LONGTEXT NULL COMMENT '本次采用的货件或追踪号核实快照',
|
||||
active TINYINT(1) NOT NULL DEFAULT 1 COMMENT '取消或失败后释放货源占用',
|
||||
active_source_key VARCHAR(160) GENERATED ALWAYS AS (CASE WHEN active=1 THEN source_key ELSE NULL END) STORED COMMENT '有效货源唯一占用键',
|
||||
active_order_id BIGINT GENERATED ALWAYS AS (CASE WHEN active=1 THEN order_id ELSE NULL END) STORED COMMENT '有效订单唯一占用键',
|
||||
created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建UTC时间',
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE KEY uk_ll_fba_item_source (appointment_id,source_key),
|
||||
UNIQUE KEY uk_ll_fba_active_source (active_source_key),
|
||||
UNIQUE KEY uk_ll_fba_active_order (active_order_id),
|
||||
KEY idx_ll_fba_active_source (customer_id,source_key,active),
|
||||
KEY idx_ll_fba_active_order (customer_id,order_id,active),
|
||||
KEY idx_ll_fba_item_source_lookup (source_key,customer_id),
|
||||
KEY idx_ll_fba_item_customer_order (customer_id,order_id)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='入仓前后共用的预约真实货源';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS ll_appointment_cargo_verification (
|
||||
id BIGINT NOT NULL COMMENT '核实记录主键',
|
||||
customer_id VARCHAR(128) NOT NULL COMMENT '原货源所属客户',
|
||||
source_key VARCHAR(160) NOT NULL COMMENT '稳定ORDER或BOOKING原来源键',
|
||||
destination_key VARCHAR(160) NOT NULL COMMENT '核实时的原目的地',
|
||||
source_version VARCHAR(160) NULL COMMENT '核实时的原来源版本',
|
||||
source_packages INT NULL COMMENT '核实时的原来源箱数,未知为空',
|
||||
version INT NOT NULL COMMENT '同一来源的核实版本,从一递增',
|
||||
package_count INT NULL COMMENT '独立核实箱数,不回写原订单',
|
||||
shipment_references_json LONGTEXT NOT NULL COMMENT '本票货件号或追踪号列表,不回写原订单',
|
||||
remark VARCHAR(1000) NULL COMMENT '核实说明',
|
||||
operator_id VARCHAR(128) NOT NULL COMMENT '登录操作人',
|
||||
operator_name VARCHAR(200) NULL COMMENT '操作人名称快照',
|
||||
command_key VARCHAR(64) NOT NULL COMMENT '来源内幂等命令键',
|
||||
request_hash CHAR(64) NOT NULL COMMENT '来源、操作人及请求摘要',
|
||||
created_at DATETIME(3) NOT NULL COMMENT '核实UTC时间',
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE KEY uk_ll_cargo_verification_version (customer_id,source_key,version),
|
||||
UNIQUE KEY uk_ll_cargo_verification_command (customer_id,source_key,command_key),
|
||||
CONSTRAINT chk_ll_cargo_verification_quantity CHECK (package_count IS NULL OR package_count > 0),
|
||||
CONSTRAINT chk_ll_cargo_verification_version CHECK (version > 0)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='预约货物核实资料及不可覆盖的版本历史';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS ll_fba_appointment_command (
|
||||
command_key VARCHAR(128) NOT NULL COMMENT '持久化幂等键',
|
||||
request_hash CHAR(64) NOT NULL COMMENT '操作、操作者和请求摘要',
|
||||
@@ -4082,3 +4108,65 @@ CREATE TABLE IF NOT EXISTS ll_selfop_inventory_daily (
|
||||
KEY idx_selfop_daily_identity (customer_code,sku_code,day_version_id),
|
||||
CONSTRAINT chk_selfop_daily_quantity CHECK ((quality_status='VALID' AND physical_quantity IS NOT NULL AND physical_quantity>=0) OR (quality_status='UNKNOWN' AND physical_quantity IS NULL))
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin COMMENT='历史日末分货主商品品质实物库存';
|
||||
|
||||
|
||||
-- Appointment work scope, audit and physical batch allocation.
|
||||
USE baiyue_lastleg;
|
||||
CREATE TABLE IF NOT EXISTS ll_dispatch_appointment_allocation (
|
||||
dispatch_id BIGINT NOT NULL,
|
||||
dispatch_item_id BIGINT NOT NULL,
|
||||
plan_pallet_id BIGINT NOT NULL,
|
||||
batch_key VARCHAR(96) NOT NULL,
|
||||
customer_id VARCHAR(64) NOT NULL,
|
||||
source_key VARCHAR(160) NOT NULL,
|
||||
destination_key VARCHAR(160) NOT NULL,
|
||||
package_count INT NOT NULL,
|
||||
PRIMARY KEY(dispatch_item_id,batch_key,source_key,destination_key),
|
||||
KEY idx_dispatch_appointment_batch(batch_key,customer_id),
|
||||
KEY idx_dispatch_appointment_dispatch(dispatch_id)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='排车实物与预约批次逐票分配,原执行域事实';
|
||||
CREATE TABLE IF NOT EXISTS ll_appointment_work_commitment (
|
||||
entity_key VARCHAR(160) NOT NULL,
|
||||
state_json LONGTEXT NOT NULL COMMENT '原业务命令产生的只读语义影响基线,不是第二份可编辑计划',
|
||||
impact_version BIGINT NOT NULL DEFAULT 0,
|
||||
PRIMARY KEY (entity_key)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='工作事项承诺影响审计基线';
|
||||
CREATE TABLE IF NOT EXISTS ll_appointment_work_guard (
|
||||
id INT NOT NULL COMMENT '工作事项协调锁,固定1',
|
||||
scan_cursor VARCHAR(128) NULL COMMENT '已开船来源同步游标',
|
||||
initialized BOOLEAN NOT NULL DEFAULT FALSE COMMENT '是否完成首次完整来源扫描',
|
||||
scope_version VARCHAR(128) NULL COMMENT '完整同步已确认的权威来源集合版本',
|
||||
scan_scope_version VARCHAR(128) NULL COMMENT '当前扫描来源集合版本,防跨页漂移',
|
||||
completed_at DATETIME(3) NULL COMMENT '最近完整同步UTC时间',
|
||||
requirement_version BIGINT NOT NULL DEFAULT 0 COMMENT '原域命令在同一事务推进的需求版本',
|
||||
synchronized_requirement_version BIGINT NOT NULL DEFAULT 0 COMMENT '完整扫描已消费需求版本',
|
||||
scan_requirement_version BIGINT NOT NULL DEFAULT 0 COMMENT '当前扫描需求版本,防跨页漂移',
|
||||
PRIMARY KEY (id)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='预约工作事项同步与命令串行守卫';
|
||||
INSERT INTO ll_appointment_work_guard(id,initialized) SELECT 1,FALSE WHERE NOT EXISTS(SELECT 1 FROM ll_appointment_work_guard WHERE id=1);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS ll_appointment_work (
|
||||
work_item_key VARCHAR(96) NOT NULL COMMENT '不可变事项键,业务身份确定性生成',
|
||||
container_booking_id VARCHAR(64) NOT NULL COMMENT '来源柜次内部关联标识,不作展示编号',
|
||||
version INT NOT NULL DEFAULT 0 COMMENT '工作命令乐观锁版本',
|
||||
retired BOOLEAN NOT NULL DEFAULT FALSE COMMENT '已替代或已完成路线需求,不计活动工作',
|
||||
state_json LONGTEXT NOT NULL COMMENT '工作关系责任跟进及影响基线,不保存可编辑业务执行事实',
|
||||
PRIMARY KEY (work_item_key),
|
||||
KEY idx_appointment_work_container (container_booking_id,retired)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='预约工作事项需求与关系';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS ll_appointment_work_history (
|
||||
id VARCHAR(36) NOT NULL COMMENT '历史记录标识',
|
||||
work_item_key VARCHAR(96) NOT NULL COMMENT '事项稳定键',
|
||||
operator_id VARCHAR(64) NOT NULL COMMENT '真实操作人员标识',
|
||||
operator_name VARCHAR(128) NULL COMMENT '操作人显示名称',
|
||||
action VARCHAR(48) NOT NULL COMMENT '工作命令或观察动作',
|
||||
summary VARCHAR(2000) NOT NULL COMMENT '处理或责任变更依据',
|
||||
command_key VARCHAR(64) NULL COMMENT '请求幂等键,观察记录为空',
|
||||
request_hash VARCHAR(64) NULL COMMENT '包含操作者的规范请求摘要',
|
||||
response_json LONGTEXT NULL COMMENT '原命令响应快照,重放不随当前状态改变',
|
||||
occurred_at DATETIME(3) NOT NULL COMMENT '历史发生UTC时间',
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE KEY uk_appointment_work_command (work_item_key,command_key),
|
||||
KEY idx_appointment_work_history (work_item_key,occurred_at)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='预约工作事项历史与幂等命令';
|
||||
|
||||
@@ -0,0 +1,136 @@
|
||||
openapi: 3.0.3
|
||||
info:
|
||||
title: 预约货物分批与合并
|
||||
version: 1.0.0
|
||||
description: 原子重新分配已有未确认批次。保留原来源、客户、柜及历史;不创建车次、库存或外部确认。
|
||||
security:
|
||||
- bearerAuth: []
|
||||
paths:
|
||||
/api/platform/v1/last-leg/appointment-planning/batches/{batchKey}:
|
||||
get:
|
||||
operationId: getFbaAppointmentBatchContext
|
||||
summary: 按不可变批次键读取分批资料和操作条件
|
||||
description: >-
|
||||
仅平台,需预约列表及尾程订单列表权限。batchKey为FBA_APPOINTMENT加内部不可变主键,仅供关联,不作为展示编号。
|
||||
返回appointment原快照、sources当前逐来源可用于重新分配的本批数量、allowedActions和blockReasons。
|
||||
原批次箱数未知且已独立核实总量时,本批数量由核实总量减其他活动批次分配量计算;不修改旧快照。
|
||||
已替代、已确认或关联排车时不开放分批合并。原来源或核实事实读取失败明确报错,不以空列表冒充无货。
|
||||
allowedActions表示业务资格,前端与FBA预约写权限取交集;实际写入仍在事务内重验。
|
||||
parameters:
|
||||
- {name: batchKey, in: path, required: true, schema: {type: string, pattern: '^FBA_APPOINTMENT:[1-9][0-9]*$'}}
|
||||
responses:
|
||||
'200':
|
||||
description: code=200时data为批次上下文
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
code: {type: string}
|
||||
data:
|
||||
type: object
|
||||
properties:
|
||||
appointment: {$ref: './fba-appointment-calendar-v1.yaml#/components/schemas/Appointment'}
|
||||
sources:
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
customerId: {type: string}
|
||||
sourceKey: {type: string}
|
||||
destinationKey: {type: string}
|
||||
packageCount: {type: integer, nullable: true, description: 本批分配量或可从独立核实资料确认的本批量}
|
||||
originalPackages: {type: integer, nullable: true, description: 原订单/登记箱数,独立核实不回写}
|
||||
sourceVersion: {type: string, nullable: true}
|
||||
cargoVerificationVersion: {type: integer, nullable: true}
|
||||
shipmentReferences: {type: array, items: {type: string}}
|
||||
allowedActions: {type: array, items: {type: string, enum: [VERIFY_CARGO, SPLIT, MERGE]}}
|
||||
blockReasons: {type: array, items: {type: string}}
|
||||
'400': {description: 批次键格式无效}
|
||||
'403': {description: 非平台或缺少读取权限}
|
||||
'404': {description: 批次或原来源不存在}
|
||||
'409': {description: 原来源变化,需重新核实资料}
|
||||
'503': {description: 原来源权威目录不可用}
|
||||
/api/platform/v1/last-leg/appointment-planning/appointments/repartition:
|
||||
post:
|
||||
operationId: repartitionFbaAppointments
|
||||
summary: 一批分多批或多批合一批
|
||||
description: >-
|
||||
仅平台,需platform:appointment:list、platform:overseas-warehouse:last-mile-order:list及platform:overseas-warehouse:inbound-order:fba-appointment。
|
||||
originals为一条且batches多条表示分批;originals多条且batches一条表示合并,其他组合拒绝。
|
||||
原批次必须同起运仓、同目的仓,尚未正式确认、未被替代且没有有效关联排车。
|
||||
先按业务号有序锁原预约,再锁原BOOKING/订单;版本、来源资格、客户归属及数量均在锁内重新核对。
|
||||
按每个稳定来源分别比较调整前后总量,不能只比较合计箱数或跨客户挪量;逐来源预期版本及核实版本必须与最新资料一致。
|
||||
原批次箱数未知时可采用刚保存的独立核实总量,无需先登记预约确认;仍未知则拒绝。
|
||||
全部旧明细释放、新批次和来源明细建立、替代关系及幂等结果在同一事务内;任一失败全部回滚。
|
||||
原批次仍可详情读取,replacementAppointmentNos和repartitionReason标识替代关系,不能再次编辑或取消;日历和未定时列表只返回当前批次。
|
||||
新批次都是PENDING,仅保存显式计划日期,确认号和确认时段为空;旧柜级提柜、接仓、还空不复制。
|
||||
同键同操作人同请求返回原结果,后续编辑不会改变原重试快照;同键异内容、并发版本或已安排冲突返回409。
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema: {$ref: '#/components/schemas/Repartition'}
|
||||
responses:
|
||||
'200':
|
||||
description: code=200时data为原批次业务号及新批次快照,按请求batches顺序返回
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
code: {type: string}
|
||||
data:
|
||||
type: object
|
||||
properties:
|
||||
replacedBatchKeys: {type: array, items: {type: string}, description: 被替代的稳定批次键,用于协调原工作需求}
|
||||
replacedAppointmentNos: {type: array, items: {type: string}}
|
||||
appointments: {type: array, items: {$ref: './fba-appointment-calendar-v1.yaml#/components/schemas/Appointment'}}
|
||||
'400': {description: 分组不合法、客户/来源替换、数量不守恒或跨起讫点}
|
||||
'403': {description: 非平台或权限不足}
|
||||
'404': {description: 原批次或货源不存在}
|
||||
'409': {description: 原版本变化、来源待核实、已有确认或有效排车、幂等内容冲突}
|
||||
'503': {description: 权威仓库目录或时区暂不可用}
|
||||
components:
|
||||
securitySchemes:
|
||||
bearerAuth: {type: http, scheme: bearer, bearerFormat: JWT}
|
||||
schemas:
|
||||
Repartition:
|
||||
type: object
|
||||
required: [originals, batches, reason, idempotencyKey]
|
||||
properties:
|
||||
originals:
|
||||
type: array
|
||||
minItems: 1
|
||||
maxItems: 20
|
||||
items:
|
||||
type: object
|
||||
required: [appointmentNo, version]
|
||||
properties:
|
||||
appointmentNo: {type: string, minLength: 1, maxLength: 64}
|
||||
version: {type: integer, minimum: 0}
|
||||
batches:
|
||||
type: array
|
||||
minItems: 1
|
||||
maxItems: 20
|
||||
items:
|
||||
type: object
|
||||
required: [allocations]
|
||||
properties:
|
||||
plannedDate: {type: string, format: date, nullable: true}
|
||||
remark: {type: string, maxLength: 1000, nullable: true}
|
||||
allocations:
|
||||
type: array
|
||||
minItems: 1
|
||||
maxItems: 100
|
||||
items:
|
||||
type: object
|
||||
required: [customerId, sourceKey, packageCount]
|
||||
properties:
|
||||
customerId: {type: string, minLength: 1, maxLength: 128}
|
||||
sourceKey: {type: string, minLength: 1, maxLength: 160}
|
||||
packageCount: {type: integer, minimum: 1, description: 本批来自该原来源的箱数;不使用零数量占位行}
|
||||
expectedSourceVersion: {type: string, maxLength: 160, nullable: true, description: 批次上下文sources的sourceVersion;空值也须一致}
|
||||
expectedVerificationVersion: {type: integer, minimum: 1, nullable: true, description: 批次上下文sources的cargoVerificationVersion,无独立核实时为空}
|
||||
reason: {type: string, minLength: 1, maxLength: 1000}
|
||||
idempotencyKey: {type: string, minLength: 1, maxLength: 64}
|
||||
@@ -0,0 +1,114 @@
|
||||
openapi: 3.0.3
|
||||
info:
|
||||
title: 预约货物核实资料
|
||||
version: 1.0.0
|
||||
description: >-
|
||||
按原ORDER或BOOKING货源保存独立核实资料,不修改订单、登记、库存或预约确认状态。
|
||||
未取得预约确认也可保存箱数和各票货件号。核实记录逐版本追加,取消预约不删除资料。
|
||||
security:
|
||||
- bearerAuth: []
|
||||
paths:
|
||||
/api/platform/v1/last-leg/appointment-planning/sources/{sourceKey}/cargo-verification:
|
||||
parameters:
|
||||
- {name: sourceKey, in: path, required: true, schema: {type: string, maxLength: 160}, description: 原稳定货源键;外接货来货前后均使用BOOKING键}
|
||||
- {name: customerId, in: query, required: true, schema: {type: string, maxLength: 128}, description: 服务端核对的原客户归属}
|
||||
get:
|
||||
operationId: getAppointmentCargoVerification
|
||||
summary: 读取本票独立核实资料和分配总量
|
||||
description: >-
|
||||
仅平台,需platform:appointment:list与platform:overseas-warehouse:last-mile-order:list。
|
||||
source为权威原来源,verification为空表示尚无独立核实记录。
|
||||
原版本、目的地或原箱数变化后sourceChanged为true,可分配量返回null,重新核实前不得采用旧资料。
|
||||
allocatedPackages合计当前活动预约明细;未知分配单独计数,不当作零。
|
||||
availablePackages为当前有效总量减已分配量,未知、超量或待复核时为空,不虚构可用量。
|
||||
allowedActions表示业务资格;前端仍须与当前用户写权限取交集。
|
||||
parameters:
|
||||
- {name: destinationKey, in: query, schema: {type: string, maxLength: 160}, description: 可传选择时的目的地;与原来源不符则拒绝}
|
||||
responses:
|
||||
'200':
|
||||
description: 业务响应,data为核实上下文
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
code: {type: string}
|
||||
data: {$ref: '#/components/schemas/CargoContext'}
|
||||
'400': {description: 来源格式或目的地不符}
|
||||
'403': {description: 非平台身份或权限不足}
|
||||
'404': {description: 原来源不存在或客户不匹配}
|
||||
'503': {description: 权威仓库目录不可用}
|
||||
post:
|
||||
operationId: saveAppointmentCargoVerification
|
||||
summary: 独立保存箱数和本票货件或追踪号
|
||||
description: >-
|
||||
仅平台,需两个读取权限及platform:overseas-warehouse:inbound-order:fba-appointment。
|
||||
操作人取登录身份。原货源锁与预约写命令共用,锁后重读来源和版本;expectedVersion首次为0。
|
||||
原来源已知箱数时,核实量不得超过原来源;任何情况下不得低于活动预约已分配量。
|
||||
原来源箱数未知时允许独立核实总量,原来源仍为空。
|
||||
可以暂缺箱数或货件,保存不会自动确认预约;正式确认仍需完整材料。
|
||||
同来源客户内的同幂等键、同操作人、同请求返回原核实版本,即使此后又有新版本。
|
||||
同键异内容、并发版本冲突或原来源变化返回409;记录与业务写入处于同一事务。
|
||||
后续预约写入采用核实版本及货件快照;单独再次核实不会改写已保存预约快照。
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema: {$ref: '#/components/schemas/SaveCargoVerification'}
|
||||
responses:
|
||||
'200':
|
||||
description: 保存或重试原命令的核实资料快照
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
code: {type: string}
|
||||
data: {$ref: '#/components/schemas/CargoVerification'}
|
||||
'400': {description: 请求字段无效}
|
||||
'403': {description: 非平台身份或缺少独立写权限}
|
||||
'404': {description: 原来源不存在或客户不匹配}
|
||||
'409': {description: 原来源或核实版本变化、幂等冲突、箱数越界或来源不可安排}
|
||||
'503': {description: 权威仓库目录不可用}
|
||||
components:
|
||||
securitySchemes:
|
||||
bearerAuth: {type: http, scheme: bearer, bearerFormat: JWT}
|
||||
schemas:
|
||||
SaveCargoVerification:
|
||||
type: object
|
||||
required: [destinationKey, expectedVersion, shipmentReferences, idempotencyKey]
|
||||
properties:
|
||||
destinationKey: {type: string, minLength: 1, maxLength: 160}
|
||||
expectedSourceVersion: {type: string, maxLength: 160, nullable: true, description: 读取上下文中的原来源版本,空值也须一致}
|
||||
expectedVersion: {type: integer, minimum: 0}
|
||||
packageCount: {type: integer, minimum: 1, nullable: true}
|
||||
shipmentReferences: {type: array, maxItems: 100, items: {type: string, minLength: 1, maxLength: 128}, description: 本票货件号或追踪号,允许暂时空列表;保存时去首尾空格并去重}
|
||||
remark: {type: string, maxLength: 1000, nullable: true}
|
||||
idempotencyKey: {type: string, minLength: 1, maxLength: 64}
|
||||
CargoVerification:
|
||||
type: object
|
||||
required: [version, destinationKey, shipmentReferences, verifiedAt]
|
||||
properties:
|
||||
version: {type: integer, minimum: 1}
|
||||
sourceVersion: {type: string, nullable: true}
|
||||
destinationKey: {type: string}
|
||||
sourcePackages: {type: integer, nullable: true}
|
||||
packageCount: {type: integer, nullable: true}
|
||||
shipmentReferences: {type: array, items: {type: string}}
|
||||
remark: {type: string, nullable: true}
|
||||
operatorName: {type: string, nullable: true}
|
||||
verifiedAt: {type: string, format: date-time, description: UTC时间}
|
||||
CargoContext:
|
||||
type: object
|
||||
properties:
|
||||
source: {$ref: './appointment-planning-v1.yaml#/components/schemas/PlanningSource'}
|
||||
verification:
|
||||
allOf: [{$ref: '#/components/schemas/CargoVerification'}]
|
||||
nullable: true
|
||||
allocatedPackages: {type: integer, format: int64}
|
||||
unknownAllocationCount: {type: integer, format: int64}
|
||||
effectivePackages: {type: integer, nullable: true, description: 独立核实箱数;没有核实记录时采用原来源箱数}
|
||||
availablePackages: {type: integer, format: int64, nullable: true}
|
||||
sourceChanged: {type: boolean}
|
||||
allowedActions: {type: array, items: {type: string, enum: [VERIFY_CARGO]}}
|
||||
blockReasons: {type: array, items: {type: string}}
|
||||
@@ -6,6 +6,37 @@ info:
|
||||
security:
|
||||
- bearerAuth: []
|
||||
paths:
|
||||
/api/platform/v1/last-leg/appointment-planning/sources/resolve-order:
|
||||
get:
|
||||
operationId: resolveOrderAppointmentSource
|
||||
summary: 从实际订单读取规范原货源及预约覆盖
|
||||
description: >-
|
||||
仅平台;同时要求platform:appointment:list与platform:overseas-warehouse:last-mile-order:list。
|
||||
入仓列表只知道订单时使用此只读入口;服务端保留外接登记BOOKING键,其他来源返回ORDER键,核对客户、订单关联及目的地。
|
||||
前端后续核实和预约命令必须使用返回的source.sourceKey,不将外接来货改写为ORDER别名。
|
||||
parameters:
|
||||
- {name: orderId, in: query, required: true, schema: {type: integer, format: int64, minimum: 1}}
|
||||
- {name: customerId, in: query, required: true, schema: {type: string, minLength: 1, maxLength: 128}}
|
||||
- {name: destinationKey, in: query, schema: {type: string}}
|
||||
responses:
|
||||
'200':
|
||||
description: 真实原来源和当前活动预约覆盖
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
code: {type: string}
|
||||
data:
|
||||
type: object
|
||||
properties:
|
||||
source: {$ref: '#/components/schemas/PlanningSource'}
|
||||
coverage: {$ref: '#/components/schemas/Coverage'}
|
||||
'400': {description: 订单、客户或目的地参数无效}
|
||||
'403': {description: 非平台或缺少任一读取权限}
|
||||
'404': {description: 当前客户下来源不存在}
|
||||
'409': {description: 订单与原来源关联变化}
|
||||
'503': {description: 权威目录不可用}
|
||||
/api/platform/v1/last-leg/appointment-planning/external-candidates:
|
||||
get:
|
||||
operationId: listExternalAppointmentCandidates
|
||||
@@ -52,7 +83,7 @@ paths:
|
||||
仅平台;同时需要platform:appointment:list、platform:overseas-warehouse:last-mile-order:list及platform:overseas-warehouse:inbound-order:fba-appointment。
|
||||
与入仓明细入口共用同一FBA预约聚合;系统生成AP单号,不创建入仓计划、库存或车次。
|
||||
PENDING允许日期、时段、外部约号及箱数暂缺。SUCCESS必须有权威目的仓时区、真实货件材料、确定箱数及外部约号和确认时段。
|
||||
实际客户、起运仓、目的仓及原BOOKING由服务端核对;活动来源与已形成订单均唯一占用,取消后释放并保留历史。
|
||||
实际客户、起运仓、目的仓及原BOOKING由服务端核对;锁原来源后按剩余未分配箱数建立新安排,分批总量不能超过独立核实或原来源总量。取消只释放本批数量并保留历史。
|
||||
命令与主单、明细同事务;同键同操作人同内容重试返回原快照,不受后来编辑影响。异内容或来源占用冲突拒绝。
|
||||
requestBody:
|
||||
required: true
|
||||
@@ -117,7 +148,7 @@ paths:
|
||||
description: >-
|
||||
只读核对,不保存预约安排、不占货、不确认预约。仅平台,同时要求platform:appointment:list与platform:overseas-warehouse:last-mile-order:list。
|
||||
最多100票,批量查询货源、实际开船节点和美国仓目录,支持ORDER与已确认承运BOOKING混合;同一订单重复别名拒绝。
|
||||
必须同美国起运仓及同美国FBA目的仓;暂扣、多目的地、已有有效预约或已取消完成货源拒绝;未知箱数保留待核实,不填0。
|
||||
必须同美国起运仓及同美国FBA目的仓;暂扣、多目的地、已分配完或已取消完成货源拒绝;部分分配后仍可选择剩余量。未知箱数保留待核实,不填0。
|
||||
未建入仓计划及尚未来货的已确认BOOKING不伪造计划、库存或入仓码;正式确认前必须核实箱数。
|
||||
未接入权威备妥窗口时返回readinessIncomplete及READY_WINDOW_UNVERIFIED,不拿到港/到仓预测代替。
|
||||
requestBody:
|
||||
@@ -156,6 +187,7 @@ paths:
|
||||
destinationWarehouseCode: {type: string}
|
||||
destinationTimezone: {type: string, nullable: true, description: 当前目的仓主档IANA时区;主档为空时为null,读取失败返回错误,不使用历史预约快照}
|
||||
sources: {type: array, items: {$ref: '#/components/schemas/PlanningSource'}}
|
||||
cargoVerification: {type: array, items: {$ref: './appointment-cargo-verification-v1.yaml#/components/schemas/CargoContext'}, description: 各原来源当前独立核实及剩余分配量,sources本身仍保留原事实}
|
||||
missingFields: {type: array, items: {type: string}}
|
||||
group:
|
||||
type: object
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -229,6 +229,10 @@ components:
|
||||
properties:
|
||||
id: {type: string, description: 内部标识,不作为展示编号}
|
||||
appointmentNo: {type: string, description: 系统生成AP业务单号}
|
||||
batchKey: {type: string, description: FBA_APPOINTMENT加不可变主键,用于工作事项关联,不展示内部键}
|
||||
replacementBatchKeys: {type: array, items: {type: string}, description: 分批/合并后的稳定批次键;旧批次历史保留}
|
||||
replacementAppointmentNos: {type: array, items: {type: string}, description: 替代批次业务号;非空时原批次只读}
|
||||
repartitionReason: {type: string, nullable: true}
|
||||
confirmationNo: {type: string, nullable: true, description: 对方正式外部确认号}
|
||||
plannedDate: {type: string, format: date, nullable: true}
|
||||
plannedAt: {type: string, nullable: true}
|
||||
@@ -255,8 +259,11 @@ components:
|
||||
id: {type: string}
|
||||
customerId: {type: string, description: 本票货物客户归属,不在预约主单指定客户}
|
||||
sourceKey: {type: string}
|
||||
destinationKey: {type: string, description: 本票目的地FBA加仓码,与原来源归属一同保留}
|
||||
sourceVersion: {type: string, nullable: true}
|
||||
orderId: {type: string, nullable: true}
|
||||
inboundCode: {type: string, nullable: true}
|
||||
packageCount: {type: integer, nullable: true}
|
||||
cargoVerificationVersion: {type: integer, nullable: true, description: 本次采用的独立核实版本,后续单独核实不改写此快照}
|
||||
shipmentReferences: {type: array, items: {type: string}, description: 本次采用的独立核实货件或追踪号快照,无核实资料时为空列表}
|
||||
fbaWarehouseCode: {type: string}
|
||||
|
||||
@@ -29,12 +29,12 @@ security:
|
||||
paths:
|
||||
/api/platform/v1/last-leg/fleet/trips/calendar:
|
||||
get:
|
||||
summary: 读取美国车次计划日历来源
|
||||
summary: 读取美国车次用车日历来源
|
||||
description: >-
|
||||
仅PLATFORM且平台公共主体(tenantId=0),权限 platform:fleet:trip:list。from/to 是明确UTC时间点,按计划发车时间读取半开区间,最多44天;
|
||||
仅PLATFORM且平台公共主体(tenantId=0),权限 platform:fleet:trip:list。from/to 是明确UTC时间点,已发车按实际发车时间、尚未发车按计划发车时间读取半开区间,最多44天;
|
||||
该保护性窗口供界面最多42个当地日历日加时区边界使用,不扩大界面范围。
|
||||
最多2000条候选,超限明确拒绝并要求缩小日期范围,不分页扫描、不静默截断。
|
||||
一车一条,保留取消及完成状态;记录只表示用车计划,不表示收货预约已确认。
|
||||
一车一条,保留取消及完成状态;保留原计划与实际时间,已执行事实不随计划改期移动,不表示收货预约已确认。
|
||||
已知非美国仓排除;未知仓库/国家/地理IANA时区进入unresolvedRecords,不落入美国当地日槽。
|
||||
一次车次查询加一次仓库批量资料请求,包含停用仓历史资料,资料服务失败返回错误而非空日历。
|
||||
parameters:
|
||||
|
||||
@@ -512,7 +512,7 @@ paths:
|
||||
- { name: destinationWarehouseCode, in: query, schema: { type: string } }
|
||||
- { name: warehouse, in: query, schema: { type: string } }
|
||||
- { name: fbaWarehouseCode, in: query, schema: { type: string } }
|
||||
- { name: appointmentStatus, in: query, schema: { type: string, enum: [UNAPPOINTED, PENDING, SUCCESS, FAILED, CANCELLED] } }
|
||||
- { name: appointmentStatus, in: query, schema: { type: string, enum: [UNAPPOINTED, PENDING, SUCCESS, FAILED, CANCELLED, MULTIPLE] } }
|
||||
- { name: dispatchStatus, in: query, schema: { type: string, enum: [UNSCHEDULED, SCHEDULED] } }
|
||||
- { name: createdFrom, in: query, schema: { type: string, format: date-time } }
|
||||
- { name: createdTo, in: query, schema: { type: string, format: date-time } }
|
||||
@@ -1372,7 +1372,7 @@ paths:
|
||||
- { name: status, in: query, schema: { type: string } }
|
||||
- { name: overseasWarehouseId, in: query, schema: { type: string } }
|
||||
- { name: destinationWarehouseCode, in: query, schema: { type: string } }
|
||||
- { name: appointmentStatus, in: query, schema: { type: string, enum: [UNAPPOINTED, PENDING, SUCCESS, FAILED, CANCELLED] } }
|
||||
- { name: appointmentStatus, in: query, schema: { type: string, enum: [UNAPPOINTED, PENDING, SUCCESS, FAILED, CANCELLED, MULTIPLE] } }
|
||||
- { name: dispatchStatus, in: query, schema: { type: string, enum: [UNSCHEDULED, SCHEDULED] } }
|
||||
- { name: createdFrom, in: query, schema: { type: string, format: date-time } }
|
||||
- { name: createdTo, in: query, schema: { type: string, format: date-time } }
|
||||
@@ -2698,6 +2698,7 @@ components:
|
||||
draftContainerId: { type: integer, format: int64 }
|
||||
planPalletIds: { type: array, maxItems: 500, items: { type: integer, format: int64 } }
|
||||
returnReceiptIds: { type: array, maxItems: 500, items: { type: integer, format: int64 } }
|
||||
batchAllocations: { type: array, maxItems: 1000, items: { $ref: './appointment-work-v1.yaml#/components/schemas/DispatchBatchAllocation' } }
|
||||
SmartDispatchDraftGroupResult:
|
||||
type: object
|
||||
required: [draftContainerId, dispatch]
|
||||
@@ -2708,6 +2709,11 @@ components:
|
||||
type: object
|
||||
description: planPalletIds与returnReceiptIds是两类正式来源,合计至少一项且最多500项。退回来源仅接受实际入账生成的实收记录,不得用退回实收ID冒充计划托盘ID;同一实物托盘不可重复选择。
|
||||
properties:
|
||||
batchAllocations:
|
||||
type: array
|
||||
maxItems: 1000
|
||||
description: 已有预约批次的FBA实物必须逐票绑定,整托总量或可变预约号不能替代;发车再次校验实物与原预约。
|
||||
items: { $ref: './appointment-work-v1.yaml#/components/schemas/DispatchBatchAllocation' }
|
||||
planPalletIds: { type: array, maxItems: 500, uniqueItems: true, items: { type: string } }
|
||||
returnReceiptIds: { type: array, maxItems: 500, uniqueItems: true, items: { type: string }, description: 原订单实际退回入账来源ID }
|
||||
fbaAppointmentNo: { type: string, nullable: true, maxLength: 64 }
|
||||
|
||||
Reference in New Issue
Block a user