This commit is contained in:
2026-10-20 21:47:51 +08:00
parent 34b90f311a
commit 137efc6809
54 changed files with 1434 additions and 63 deletions
@@ -1208,6 +1208,7 @@ CREATE TABLE ll_fleet_external_booking (
binding_key VARCHAR(128) NULL COMMENT '关联发运请求键',
binding_hash CHAR(64) NULL COMMENT '关联发运摘要',
offer_id BIGINT NULL COMMENT '来源运力发布,普通车次预订为空',
source_looseboard_order_id BIGINT NULL COMMENT '客户原始散板商业单ID,取消后保留来源',
sales_owner_user_id VARCHAR(64) NULL COMMENT '登录身份冻结的销售负责人',
business_type VARCHAR(32) NULL COMMENT '本土商业类型LOCAL_LOOSEBOARD或US_TRUCK',
delivery_mode VARCHAR(32) NULL COMMENT '客户送仓或人工安排提货回仓',
@@ -1222,6 +1223,7 @@ CREATE TABLE ll_fleet_external_booking (
KEY idx_fleet_booking_sales(sales_owner_user_id,offer_id,id),
CONSTRAINT fk_fleet_booking_offer FOREIGN KEY(offer_id) REFERENCES ll_fleet_capacity_offer(id),
CONSTRAINT chk_fleet_booking_expected_pallet CHECK(expected_pallet_count IS NULL OR expected_pallet_count > 0),
KEY idx_booking_looseboard_source (customer_id,source_looseboard_order_id,status),
PRIMARY KEY(id),
UNIQUE KEY uk_fleet_booking_no(booking_no),
UNIQUE KEY uk_fleet_booking_create(trip_id,created_by,idempotency_key),
@@ -1898,6 +1900,7 @@ CREATE TABLE IF NOT EXISTS ll_inbound_stock_receipt (
CREATE TABLE IF NOT EXISTS ll_dispatch_order (
id BIGINT NOT NULL COMMENT '整车排车主单内部主键',
dispatch_no VARCHAR(64) NOT NULL COMMENT '真实排车业务号',
task_type VARCHAR(32) NOT NULL DEFAULT 'DELIVERY' COMMENT '任务类型:仓库派送、到仓取货、本土卡车',
trip_id BIGINT NOT NULL COMMENT '本趟唯一车辆资源记录ID',
overseas_warehouse_id VARCHAR(128) NOT NULL COMMENT '真实起运海外仓ID',
overseas_warehouse_code VARCHAR(128) NULL COMMENT '起运海外仓编码快照',
@@ -4639,3 +4642,28 @@ CREATE TABLE IF NOT EXISTS ll_fleet_owned_business_history (
CONSTRAINT fk_owned_business_history_dispatch FOREIGN KEY (dispatch_id) REFERENCES ll_dispatch_order(id),
CONSTRAINT ck_owned_business_history_version CHECK (record_version>0)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='原排车自有业务附加运营不可变历史';
-- 运输原单接入现有排车,不产生仓内库存事实。
USE baiyue_lastleg;
CREATE TABLE IF NOT EXISTS ll_dispatch_truck_task (
dispatch_no VARCHAR(64) NOT NULL COMMENT '排车业务号',
trip_no VARCHAR(64) NOT NULL COMMENT '本次运输资源记录号',
customer_id VARCHAR(128) NOT NULL COMMENT '本土卡车原单客户标识',
order_no VARCHAR(64) NOT NULL COMMENT '本土卡车原单业务号',
active_order VARCHAR(193) NULL COMMENT '有效原单唯一键;取消置空,完成保留',
PRIMARY KEY(dispatch_no), UNIQUE KEY uk_transport_trip(trip_no), UNIQUE KEY uk_transport_source(active_order),
KEY idx_transport_order(customer_id,order_no)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='排车与本土卡车原单关联';
CREATE TABLE IF NOT EXISTS ll_dispatch_transport_create (
trip_no VARCHAR(64) NOT NULL PRIMARY KEY COMMENT '本次运输资源记录号',
request_hash CHAR(64) NOT NULL COMMENT '首次安排请求摘要'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='本土卡车排车创建请求账本';
CREATE TABLE IF NOT EXISTS ll_dispatch_transport_command (
dispatch_no VARCHAR(64) NOT NULL COMMENT '排车业务号',
request_key VARCHAR(128) NOT NULL COMMENT '客户端幂等请求键',
request_hash CHAR(64) NOT NULL COMMENT '执行命令请求摘要',
evidence_json JSON NULL COMMENT '已确认运输完成凭证标识列表',
created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '业务命令提交时间',
PRIMARY KEY(dispatch_no,request_key)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='排车运输执行命令与凭证账本';
@@ -0,0 +1,99 @@
openapi: 3.0.3
info:
title: 现有排车运输任务
version: 1.0.0
description: >-
平台主体(tenantId=0)在现有排车列表内安排到仓取货、本土卡车,使用真实PC排车号。
请求经统一Gateway与Bearer认证;JSON响应HTTP200,业务code=200成功,A0400参数错误、A0403权限不足、A0404不存在、A0409版本或状态冲突。
list读取、create安排、edit分配/执行/释放、depart发车、cancel取消权限前缀均为platform:overseas-warehouse:dispatch:。
创建及执行使用稳定idempotencyKey;重试保留完整原载荷。取消仅限未发车;完成后分别释放司机、车辆。
到仓取货逐原单确认实提和送仓,送仓只开放仓库收货门禁;本土卡车同步原单运输状态,完成须本任务凭证。
servers:
- url: /api/platform/v1/last-leg/dispatches/transport-tasks
security:
- bearerAuth: []
paths:
/pickup-candidates:
get:
summary: 同仓上门取货候选(list,page/size/keyword/warehouseId)
responses: &response
'200':
description: 业务响应信封;data为对应详情、候选或操作结果
/truck-candidates:
get:
summary: 待派车且未被运输或拼车占用的本土卡车候选(list)
responses: *response
/pickup:
post:
summary: 同一海外仓多客户取货安排(create)
description: sources为customerId/transferNo数组,plannedDepartureAt和expectedDriverEndAt为ISO时刻;idempotencyKey必填,remark可选。返回Detail。
responses: *response
/truck:
post:
summary: 本土卡车原单接入排车(create)
description: customerId、orderNo、warehouseId、plannedDepartureAt、expectedDriverEndAt、idempotencyKey必填;原单须PENDING_DISPATCH且未被占用。返回Detail。
responses: *response
/{number}:
parameters: &number
- { name: number, in: path, required: true, schema: { type: string }, description: 真实PC排车业务号 }
get:
summary: 排车运输详情(list)
description: data包含dispatchNo、taskType(PICKUP/LOCAL_TRUCK)、execution(现有资源与执行详情)、customerId、orderNo、pickups、completionEvidence(已确认凭证)。
responses: *response
/{number}/{action}:
parameters:
- { name: number, in: path, required: true, schema: { type: string } }
- { name: action, in: path, required: true, schema: { type: string, enum: [assign, cancel, resource-occupancy, release] } }
post:
summary: 分配、取消、资源可用性查询与实际任务释放
description: >-
assign(edit):recordVersion、vehicleId、driverId、reason;cancel(cancel):recordVersion、reason。
resource-occupancy(list):kind=VEHICLE/DRIVER、resourceIds数组。
release(edit):recordVersion、resourceKind、actualEndAt、endLocation、vehicleStatus(车辆必填)、idempotencyKey、reason。
responses: *response
/{number}/{kind}/{action}:
parameters:
- { name: number, in: path, required: true, schema: { type: string } }
- { name: kind, in: path, required: true, schema: { type: string, enum: [pickup, truck] } }
- { name: action, in: path, required: true, schema: { type: string, enum: [depart, complete] } }
post:
summary: 运输发车(depart)或完成(edit)
description: recordVersion、idempotencyKey、reason必填。本土卡车complete还须至少一份evidenceFileIds,文件归属本任务。取货complete要求所有原单已送仓。
responses: *response
/{number}/pickup/{customer}/{source}/{action}:
parameters:
- { name: number, in: path, required: true, schema: { type: string } }
- { name: customer, in: path, required: true, schema: { type: string } }
- { name: source, in: path, required: true, schema: { type: string }, description: 仓储转运单号 }
- { name: action, in: path, required: true, schema: { type: string, enum: [picked, arrive, files] } }
post:
summary: 按原单上传凭证、确认实提或送仓(edit)
description: files使用multipart字段file;picked使用recordVersion、idempotencyKey、actualPackages、evidenceFileIds、remark;arrive使用recordVersion、idempotencyKey、reason。凭证不能跨客户原单使用。
responses: *response
/{number}/truck/files:
parameters: *number
post:
summary: 本土卡车凭证上传(edit)
description: multipart字段file,非空且不超过10MB,只能在计划或运输中上传。上传不等于完成,须通过complete命令确认文件引用。
responses: *response
/{number}/truck/files/{fileId}:
parameters:
- { name: number, in: path, required: true, schema: { type: string } }
- { name: fileId, in: path, required: true, schema: { type: integer, format: int64 } }
get:
summary: 已确认本土卡车完成凭证鉴权下载(list)
responses:
'200': { description: application/octet-stream文件;失败返回业务响应信封 }
/{number}/pickup/{customer}/{source}/files/{fileId}:
parameters:
- { name: number, in: path, required: true, schema: { type: string } }
- { name: customer, in: path, required: true, schema: { type: string } }
- { name: source, in: path, required: true, schema: { type: string } }
- { name: fileId, in: path, required: true, schema: { type: integer, format: int64 } }
get:
summary: 当前排车原单已确认取货凭证鉴权下载(list)
responses:
'200': { description: application/octet-stream文件;当前排车及原单归属不符时拒绝 }
components:
securitySchemes:
bearerAuth: { type: http, scheme: bearer, bearerFormat: JWT }
@@ -373,6 +373,36 @@ paths:
application/json:
schema:
$ref: '#/components/schemas/OfferCommand'
/api/platform/v1/last-leg/fleet/capacity-offers/pending-looseboard-demands:
get:
summary: 分页读取客户已提交的待匹配散板原单
description: 权限:platform:fleet:capacity-offer:manage 或 (platform:fleet:capacity-offer:list 且 platform:fleet:capacity-offer:inquiry-create)。仅返回待接单、没有独立尾程来源且没有生效匹配的原单;取消未确认登记后恢复候选。下单及登记不占位,确认承运才占位。旧独立履约单不回填来源。
parameters:
- { name: page, in: query, schema: { type: integer, minimum: 1, default: 1 } }
- { name: size, in: query, schema: { type: integer, minimum: 1, maximum: 100, default: 20 } }
- { name: keyword, in: query, schema: { type: string, maxLength: 128 } }
responses:
'200':
description: 统一业务响应
content:
application/json:
schema:
type: object
properties:
code: { type: string }
message: { type: string }
data:
type: object
properties:
records:
type: array
items: { $ref: '#/components/schemas/LooseboardDemand' }
page: { type: integer }
size: { type: integer }
total: { type: integer }
pages: { type: integer }
'401': { description: 未登录 }
'403': { description: 无需求匹配权限 }
/api/platform/v1/last-leg/fleet/capacity-offers/inquiries:
get:
summary: 分页查询本人或获准的全部意向
@@ -1310,6 +1340,24 @@ components:
minimum: 0
- type: string
pattern: ^[0-9]+$
LooseboardDemand:
type: object
description: 原单待匹配投影;不含创建幂等键、请求哈希和操作人技术身份。
properties:
orderNo: { type: string }
customerId: { type: string }
version: { type: integer, format: int64 }
origin: { type: string }
destination: { type: string }
productName: { type: string, nullable: true }
estimatedPalletCount: { type: integer, nullable: true }
packageCount: { type: integer, nullable: true }
totalWeightKg: { type: number, nullable: true }
totalVolumeCbm: { type: number, nullable: true }
currency: { type: string }
originContactName: { type: string, nullable: true }
originContactPhone: { type: string, nullable: true }
remark: { type: string, nullable: true }
InquiryWrite:
type: object
required:
@@ -1321,6 +1369,18 @@ components:
- cargo
- idempotencyKey
properties:
sourceOrderNo:
type: string
maxLength: 64
nullable: true
description: 从待匹配散板选择原商业单;仅LOCAL_LOOSEBOARD支持。确认承运复用原单,不另开商业单。
sourceOrderVersion:
type: integer
format: int64
minimum: 0
nullable: true
description: 创建匹配时与原单号一起提交;已匹配登记不可替换来源。
tripRecordVersion:
oneOf:
- type: integer