feat: support shared FBA appointments and arrival calendar
This commit is contained in:
@@ -1626,9 +1626,10 @@ CREATE TABLE IF NOT EXISTS ll_pda_inventory_move (
|
||||
|
||||
CREATE TABLE IF NOT EXISTS ll_inbound_fba_appointment (
|
||||
id BIGINT NOT NULL COMMENT '主键ID',
|
||||
customer_id VARCHAR(128) NOT NULL COMMENT '客户租户ID',
|
||||
appointment_no VARCHAR(64) NOT NULL COMMENT '预约单号',
|
||||
appointment_at DATETIME(3) NOT NULL COMMENT '预约时间',
|
||||
appointment_end_at DATETIME(3) NULL COMMENT '预约结束时间,未明确时为空',
|
||||
version INT NOT NULL DEFAULT 0 COMMENT '并发版本',
|
||||
expected_loading_at DATETIME(3) NOT NULL COMMENT '预计装车时间',
|
||||
appointment_status VARCHAR(32) NOT NULL DEFAULT 'PENDING' COMMENT '预约状态',
|
||||
appointment_remark VARCHAR(1000) NULL COMMENT '预约备注',
|
||||
@@ -1638,13 +1639,14 @@ CREATE TABLE IF NOT EXISTS ll_inbound_fba_appointment (
|
||||
created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间',
|
||||
updated_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3) COMMENT '更新时间',
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE KEY uk_ll_fba_appointment_no (customer_id, appointment_no),
|
||||
KEY idx_ll_fba_appointment_list (customer_id, appointment_status, fba_warehouse_code, created_at)
|
||||
UNIQUE KEY uk_ll_fba_appointment_no (appointment_no),
|
||||
KEY idx_ll_fba_appointment_list (appointment_at, appointment_status, fba_warehouse_code)
|
||||
) ENGINE=InnoDB COMMENT='FBA入仓预约单';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS ll_inbound_fba_appointment_item (
|
||||
id BIGINT NOT NULL COMMENT '主键ID',
|
||||
appointment_id BIGINT NOT NULL COMMENT '预约单ID',
|
||||
customer_id VARCHAR(128) NOT NULL COMMENT '本票货物客户ID',
|
||||
plan_id BIGINT NOT NULL COMMENT '入仓计划ID',
|
||||
line_id BIGINT NOT NULL COMMENT '入仓计划明细ID',
|
||||
order_id BIGINT NOT NULL COMMENT '订单ID',
|
||||
@@ -1653,36 +1655,11 @@ CREATE TABLE IF NOT EXISTS ll_inbound_fba_appointment_item (
|
||||
created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间',
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE KEY uk_ll_fba_appointment_item_line (appointment_id, line_id),
|
||||
KEY idx_ll_fba_appointment_item_cargo (line_id,appointment_id),
|
||||
KEY idx_ll_fba_appointment_item_plan (plan_id),
|
||||
KEY idx_ll_fba_appointment_item_order (order_id)
|
||||
) ENGINE=InnoDB COMMENT='FBA入仓预约明细';
|
||||
|
||||
-- Upgrade the pre-customer-scope appointment table created by older deployments.
|
||||
SET @ddl = (SELECT IF(
|
||||
NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema=DATABASE()
|
||||
AND table_name='ll_inbound_fba_appointment' AND column_name='customer_id')
|
||||
AND EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema=DATABASE()
|
||||
AND table_name='ll_inbound_fba_appointment' AND column_name='tenant_id'),
|
||||
'ALTER TABLE ll_inbound_fba_appointment CHANGE COLUMN tenant_id customer_id VARCHAR(128) NOT NULL COMMENT ''客户租户ID''',
|
||||
'SELECT 1'));
|
||||
PREPARE fba_appointment_customer_scope FROM @ddl; EXECUTE fba_appointment_customer_scope; DEALLOCATE PREPARE fba_appointment_customer_scope;
|
||||
|
||||
SET @ddl = (SELECT IF(EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema=DATABASE()
|
||||
AND table_name='ll_inbound_fba_appointment' AND column_name='expected_loading_at'),
|
||||
'SELECT 1',
|
||||
'ALTER TABLE ll_inbound_fba_appointment ADD COLUMN expected_loading_at DATETIME(3) NULL COMMENT ''预计装车时间'' AFTER appointment_at'));
|
||||
PREPARE fba_appointment_expected_loading FROM @ddl; EXECUTE fba_appointment_expected_loading; DEALLOCATE PREPARE fba_appointment_expected_loading;
|
||||
|
||||
UPDATE ll_inbound_fba_appointment
|
||||
SET expected_loading_at=appointment_at
|
||||
WHERE expected_loading_at IS NULL;
|
||||
|
||||
SET @ddl = (SELECT IF(EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema=DATABASE()
|
||||
AND table_name='ll_inbound_fba_appointment' AND column_name='expected_loading_at' AND is_nullable='YES'),
|
||||
'ALTER TABLE ll_inbound_fba_appointment MODIFY COLUMN expected_loading_at DATETIME(3) NOT NULL COMMENT ''预计装车时间''',
|
||||
'SELECT 1'));
|
||||
PREPARE fba_appointment_expected_loading_required FROM @ddl; EXECUTE fba_appointment_expected_loading_required; DEALLOCATE PREPARE fba_appointment_expected_loading_required;
|
||||
|
||||
ALTER TABLE ll_loading_order_status_history
|
||||
MODIFY COLUMN id BIGINT NOT NULL AUTO_INCREMENT COMMENT '状态历史主键',
|
||||
MODIFY COLUMN order_id BIGINT NOT NULL COMMENT '尾程订单 ID',
|
||||
|
||||
@@ -0,0 +1,147 @@
|
||||
openapi: 3.0.3
|
||||
info:
|
||||
title: 跨客户 FBA 预约与日历
|
||||
version: 1.0.0
|
||||
description: 按同一目的FBA仓合并多个客户的货物,预约号全局唯一。货物明细保留客户归属,只有平台可读取或维护完整预约;不改变库存与客户订单归属。
|
||||
security:
|
||||
- bearerAuth: []
|
||||
paths:
|
||||
/api/platform/v1/last-leg/inbound-plans/fba-appointments/batch:
|
||||
post:
|
||||
summary: 为同一目的仓的跨客户入仓明细创建预约
|
||||
description: '权限:platform:overseas-warehouse:inbound-order:fba-appointment。平台身份限定。客户归属由服务端入仓计划确定,不接受预约主单customerId;同号同内容重放返回原预约,异内容拒绝。已有有效预约的货物不能重复建约。'
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
allOf:
|
||||
- {$ref: '#/components/schemas/AppointmentWrite'}
|
||||
- type: object
|
||||
required: [lineIds, appointmentNo]
|
||||
properties:
|
||||
lineIds: {type: array, minItems: 1, maxItems: 500, items: {type: string}}
|
||||
appointmentNo: {type: string, maxLength: 64}
|
||||
responses:
|
||||
'200': {$ref: '#/components/responses/AppointmentResult'}
|
||||
'403': {description: 非平台身份或无写权限}
|
||||
/api/platform/v1/last-leg/inbound-plans/fba-appointments/{appointmentNo}:
|
||||
parameters:
|
||||
- name: appointmentNo
|
||||
in: path
|
||||
required: true
|
||||
schema: {type: string}
|
||||
delete:
|
||||
summary: 删除未关联有效排车的预约
|
||||
description: '平台专用,权限platform:appointment:delete。校验当前版本后原子删除预约及预约明细,不删除客户货物。已有关联有效排车时拒绝。'
|
||||
parameters:
|
||||
- {name: version, in: query, required: true, schema: {type: integer, minimum: 0}}
|
||||
responses:
|
||||
'200': {description: 业务响应,成功code为字符串200;版本冲突或已关联排车返回业务错误}
|
||||
'403': {description: 无删除权限}
|
||||
get:
|
||||
summary: 读取完整跨客户预约
|
||||
description: '仅平台,权限:platform:appointment:list 或 platform:overseas-warehouse:inbound-order:list。客户只能经原订单/入仓单接口读取自己的货物,不开放整张预约。'
|
||||
responses:
|
||||
'200': {$ref: '#/components/responses/AppointmentResult'}
|
||||
'403': {description: 无读取权限}
|
||||
put:
|
||||
summary: 按版本更新预约
|
||||
description: '权限:platform:overseas-warehouse:inbound-order:fba-appointment。平台限定,版本冲突拒绝;取消不删除货物。恢复时重新校验货物是否已被其他有效预约占用。'
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
allOf:
|
||||
- {$ref: '#/components/schemas/AppointmentWrite'}
|
||||
- type: object
|
||||
required: [version]
|
||||
properties:
|
||||
version: {type: integer, minimum: 0}
|
||||
responses:
|
||||
'200': {$ref: '#/components/responses/AppointmentResult'}
|
||||
'403': {description: 无写权限}
|
||||
/api/platform/v1/last-leg/inbound-plans/fba-appointments/calendar:
|
||||
get:
|
||||
operationId: fbaAppointmentCalendar
|
||||
summary: 按日期范围查询 FBA 预约
|
||||
description: '权限:platform:appointment:list。仅平台身份可读取跨客户预约。固定批量查询预约及关联明细,不逐预约查详情。'
|
||||
parameters:
|
||||
- name: from
|
||||
in: query
|
||||
required: true
|
||||
description: 包含该日期零点,以现有预约业务日期为准。
|
||||
schema: {type: string, format: date}
|
||||
- name: to
|
||||
in: query
|
||||
required: true
|
||||
description: 不包含该日期零点;必须晚于from,间隔不超过42天。
|
||||
schema: {type: string, format: date}
|
||||
responses:
|
||||
'200':
|
||||
description: 业务响应;成功code为字符串200,空区间返回空数组。
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
code: {type: string}
|
||||
message: {type: string}
|
||||
data:
|
||||
type: array
|
||||
items: {$ref: '#/components/schemas/Appointment'}
|
||||
'401': {description: 未登录或会话失效}
|
||||
'403': {description: 无列表权限}
|
||||
components:
|
||||
responses:
|
||||
AppointmentResult:
|
||||
description: 业务响应,成功code为字符串200,业务冲突返回对应业务错误码。
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
code: {type: string}
|
||||
message: {type: string}
|
||||
data: {$ref: '#/components/schemas/Appointment'}
|
||||
securitySchemes:
|
||||
bearerAuth: {type: http, scheme: bearer, bearerFormat: JWT}
|
||||
schemas:
|
||||
AppointmentWrite:
|
||||
type: object
|
||||
required: [appointmentAt, expectedLoadingAt, appointmentStatus]
|
||||
properties:
|
||||
appointmentAt: {type: string, description: 预约开始日期时间}
|
||||
appointmentEndAt: {type: string, nullable: true, description: 明确结束时间时必须晚于开始时间;未知留空,不推算}
|
||||
expectedLoadingAt: {type: string}
|
||||
appointmentStatus: {type: string, enum: [PENDING, SUCCESS, FAILED, CANCELLED]}
|
||||
appointmentRemark: {type: string, maxLength: 1000, nullable: true}
|
||||
Appointment:
|
||||
type: object
|
||||
properties:
|
||||
id: {type: string, description: 内部标识,不作为展示编号}
|
||||
appointmentNo: {type: string}
|
||||
appointmentAt: {type: string, description: 业务日期时间,不含时区偏移}
|
||||
appointmentEndAt: {type: string, nullable: true}
|
||||
version: {type: integer, minimum: 0}
|
||||
expectedLoadingAt: {type: string}
|
||||
appointmentStatus: {type: string, enum: [PENDING, SUCCESS, FAILED, CANCELLED]}
|
||||
appointmentRemark: {type: string, nullable: true}
|
||||
fbaWarehouseCode: {type: string}
|
||||
selectedCount: {type: integer}
|
||||
createdBy: {type: string, nullable: true}
|
||||
createdAt: {type: string}
|
||||
updatedAt: {type: string}
|
||||
items:
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
id: {type: string}
|
||||
customerId: {type: string, description: 本票货物客户归属,不在预约主单指定客户}
|
||||
planId: {type: string}
|
||||
lineId: {type: string}
|
||||
orderId: {type: string}
|
||||
inboundCode: {type: string}
|
||||
fbaWarehouseCode: {type: string}
|
||||
Reference in New Issue
Block a user