二期内容提交
This commit is contained in:
@@ -23,6 +23,11 @@ spring:
|
||||
baiyue:
|
||||
security:
|
||||
jwt-secret: ${JWT_SECRET:change-me-to-at-least-32-bytes-long-before-start}
|
||||
firstleg:
|
||||
inbound:
|
||||
allow-rejected-measurement: false
|
||||
default-pallet-capacity-cbm: ${DEFAULT_PALLET_CAPACITY_CBM:1.200000}
|
||||
reservation-ttl: ${PALLET_RESERVATION_TTL:30m}
|
||||
management.endpoints.web.exposure.include: health,info,prometheus
|
||||
|
||||
logging:
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
SET NAMES utf8mb4;
|
||||
USE baiyue_firstleg;
|
||||
|
||||
-- 二期 FBA 计费增量迁移。通过 information_schema 判断,允许重复部署。
|
||||
DROP PROCEDURE IF EXISTS phase2_fba_add_column;
|
||||
DELIMITER $$
|
||||
CREATE PROCEDURE phase2_fba_add_column(IN p_table VARCHAR(64), IN p_column VARCHAR(64), IN p_definition TEXT)
|
||||
BEGIN
|
||||
IF NOT EXISTS (
|
||||
SELECT 1 FROM information_schema.COLUMNS
|
||||
WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = p_table AND COLUMN_NAME = p_column
|
||||
) THEN
|
||||
SET @sql = CONCAT('ALTER TABLE `', p_table, '` ADD COLUMN `', p_column, '` ', p_definition);
|
||||
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
|
||||
END IF;
|
||||
END$$
|
||||
DELIMITER ;
|
||||
|
||||
CALL phase2_fba_add_column('fl_inbound_order', 'carrier_id', "BIGINT UNSIGNED NULL COMMENT '计费船司逻辑ID' AFTER channel_name");
|
||||
CALL phase2_fba_add_column('fl_inbound_order', 'carrier_name', "VARCHAR(128) NULL COMMENT '计费船司名称快照' AFTER carrier_id");
|
||||
CALL phase2_fba_add_column('fl_carrier_fba_rate', 'business_type', "VARCHAR(32) NOT NULL DEFAULT 'FBA' COMMENT '业务或计费类型' AFTER origin_warehouse_name");
|
||||
CALL phase2_fba_add_column('fl_customer_charge_rule', 'version', "INT NOT NULL DEFAULT 0 COMMENT '乐观锁版本号' AFTER deleted");
|
||||
CALL phase2_fba_add_column('fl_carrier_fba_rate', 'version', "INT NOT NULL DEFAULT 0 COMMENT '乐观锁版本号' AFTER deleted");
|
||||
CALL phase2_fba_add_column('fl_inbound_fee', 'rule_code', "VARCHAR(50) NOT NULL DEFAULT '' COMMENT '客户规则编码快照' AFTER carrier_rate_version");
|
||||
CALL phase2_fba_add_column('fl_inbound_fee', 'customer_id', "BIGINT UNSIGNED NOT NULL DEFAULT 0 COMMENT '客户ID快照' AFTER rule_code");
|
||||
CALL phase2_fba_add_column('fl_inbound_fee', 'customer_name', "VARCHAR(128) NOT NULL DEFAULT '' COMMENT '客户名称快照' AFTER customer_id");
|
||||
CALL phase2_fba_add_column('fl_inbound_fee', 'business_type', "VARCHAR(32) NOT NULL DEFAULT '' COMMENT '业务类型快照' AFTER customer_name");
|
||||
CALL phase2_fba_add_column('fl_inbound_fee', 'tax_mode', "VARCHAR(24) NULL COMMENT '包税模式快照' AFTER business_type");
|
||||
CALL phase2_fba_add_column('fl_inbound_fee', 'rounding_scale', "TINYINT UNSIGNED NOT NULL DEFAULT 3 COMMENT '计费量保留位数快照' AFTER tax_mode");
|
||||
CALL phase2_fba_add_column('fl_inbound_fee', 'rounding_mode', "VARCHAR(24) NOT NULL DEFAULT 'CEILING' COMMENT '舍入方式快照' AFTER rounding_scale");
|
||||
CALL phase2_fba_add_column('fl_inbound_fee', 'rule_effective_from', "DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '客户规则生效开始快照' AFTER rounding_mode");
|
||||
CALL phase2_fba_add_column('fl_inbound_fee', 'rule_effective_to', "DATETIME(3) NULL COMMENT '客户规则生效结束快照' AFTER rule_effective_from");
|
||||
CALL phase2_fba_add_column('fl_inbound_fee', 'rate_code', "VARCHAR(50) NOT NULL DEFAULT '' COMMENT '船司价格编码快照' AFTER rule_effective_to");
|
||||
CALL phase2_fba_add_column('fl_inbound_fee', 'origin_warehouse_id', "BIGINT UNSIGNED NOT NULL DEFAULT 0 COMMENT '起运仓ID快照' AFTER rate_code");
|
||||
CALL phase2_fba_add_column('fl_inbound_fee', 'origin_warehouse_name', "VARCHAR(128) NOT NULL DEFAULT '' COMMENT '起运仓名称快照' AFTER origin_warehouse_id");
|
||||
CALL phase2_fba_add_column('fl_inbound_fee', 'channel_code', "VARCHAR(64) NOT NULL DEFAULT '' COMMENT '渠道编码快照' AFTER origin_warehouse_name");
|
||||
CALL phase2_fba_add_column('fl_inbound_fee', 'carrier_id', "BIGINT UNSIGNED NOT NULL DEFAULT 0 COMMENT '船司ID快照' AFTER channel_code");
|
||||
CALL phase2_fba_add_column('fl_inbound_fee', 'carrier_name', "VARCHAR(128) NOT NULL DEFAULT '' COMMENT '船司名称快照' AFTER carrier_id");
|
||||
CALL phase2_fba_add_column('fl_inbound_fee', 'destination_code', "VARCHAR(32) NOT NULL DEFAULT '' COMMENT 'FBA仓编码快照' AFTER carrier_name");
|
||||
CALL phase2_fba_add_column('fl_inbound_fee', 'rate_effective_from', "DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '价格生效开始快照' AFTER destination_code");
|
||||
CALL phase2_fba_add_column('fl_inbound_fee', 'rate_effective_to', "DATETIME(3) NULL COMMENT '价格生效结束快照' AFTER rate_effective_from");
|
||||
CALL phase2_fba_add_column('fl_inbound_idempotency', 'result_resource_id', "BIGINT UNSIGNED NULL COMMENT '成功结果资源ID' AFTER result_json");
|
||||
|
||||
DROP PROCEDURE IF EXISTS phase2_fba_add_column;
|
||||
|
||||
-- 旧索引可能缺少业务类型、船司和结束时间;用新索引名并存,避免破坏线上依赖。
|
||||
SET @idx_exists = (SELECT COUNT(*) FROM information_schema.STATISTICS
|
||||
WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'fl_carrier_fba_rate' AND INDEX_NAME = 'idx_fba_rate_unique_match');
|
||||
SET @sql = IF(@idx_exists = 0,
|
||||
'ALTER TABLE fl_carrier_fba_rate ADD INDEX idx_fba_rate_unique_match (tenant_id, origin_warehouse_id, business_type, channel_code, carrier_id, destination_code, charge_unit, status, effective_from, effective_to)',
|
||||
'SELECT 1');
|
||||
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
|
||||
@@ -0,0 +1,90 @@
|
||||
-- 二期入库测量与 OCR 维护增量(只增不删,可重复执行)。
|
||||
-- 执行顺序:phase2-inbound-schema.sql 后执行本文件;已有二期库只需执行本文件。
|
||||
SET NAMES utf8mb4;
|
||||
USE baiyue_firstleg;
|
||||
|
||||
DROP PROCEDURE IF EXISTS phase2_measure_add_column;
|
||||
DELIMITER $$
|
||||
CREATE PROCEDURE phase2_measure_add_column(
|
||||
IN p_table_name VARCHAR(64),
|
||||
IN p_column_name VARCHAR(64),
|
||||
IN p_column_definition TEXT
|
||||
)
|
||||
BEGIN
|
||||
IF NOT EXISTS (
|
||||
SELECT 1 FROM information_schema.columns
|
||||
WHERE table_schema = DATABASE()
|
||||
AND table_name = p_table_name
|
||||
AND column_name = p_column_name
|
||||
) THEN
|
||||
SET @phase2_measure_sql = CONCAT(
|
||||
'ALTER TABLE `', REPLACE(p_table_name, '`', '``'),
|
||||
'` ADD COLUMN `', REPLACE(p_column_name, '`', '``'), '` ', p_column_definition
|
||||
);
|
||||
PREPARE phase2_measure_statement FROM @phase2_measure_sql;
|
||||
EXECUTE phase2_measure_statement;
|
||||
DEALLOCATE PREPARE phase2_measure_statement;
|
||||
END IF;
|
||||
END$$
|
||||
DELIMITER ;
|
||||
|
||||
CALL phase2_measure_add_column('fl_inbound_measurement', 'original_document_no',
|
||||
'VARCHAR(64) NULL COMMENT ''原单据号码快照'' AFTER raw_payload_json');
|
||||
CALL phase2_measure_add_column('fl_inbound_measurement', 'original_gross_weight_kg',
|
||||
'DECIMAL(18,3) NULL COMMENT ''原单据毛重kg'' AFTER original_document_no');
|
||||
CALL phase2_measure_add_column('fl_inbound_measurement', 'original_volume_cbm',
|
||||
'DECIMAL(18,4) NULL COMMENT ''原单据体积或材积m3'' AFTER original_gross_weight_kg');
|
||||
CALL phase2_measure_add_column('fl_inbound_measurement', 'actual_goods_name',
|
||||
'VARCHAR(255) NULL COMMENT ''实际品名'' AFTER original_volume_cbm');
|
||||
CALL phase2_measure_add_column('fl_inbound_measurement', 'volume_weight_kg',
|
||||
'DECIMAL(18,3) NULL COMMENT ''本批次总材积重kg'' AFTER total_volume_cbm');
|
||||
CALL phase2_measure_add_column('fl_inbound_measurement', 'version',
|
||||
'INT NOT NULL DEFAULT 0 COMMENT ''乐观锁版本号'' AFTER updated_at');
|
||||
|
||||
CALL phase2_measure_add_column('fl_inbound_measurement_item', 'box_specification',
|
||||
'VARCHAR(64) NOT NULL DEFAULT '''' COMMENT ''箱规标识'' AFTER item_no');
|
||||
CALL phase2_measure_add_column('fl_inbound_measurement_item', 'girth_cm',
|
||||
'DECIMAL(12,3) NOT NULL DEFAULT 0 COMMENT ''周长cm,规则为长+2*(宽+高)'' AFTER height_cm');
|
||||
CALL phase2_measure_add_column('fl_inbound_measurement_item', 'unit_weight_kg',
|
||||
'DECIMAL(18,3) NULL COMMENT ''单箱重量kg'' AFTER girth_cm');
|
||||
CALL phase2_measure_add_column('fl_inbound_measurement_item', 'unit_volume_cbm',
|
||||
'DECIMAL(18,4) NOT NULL DEFAULT 0 COMMENT ''单箱业务体积m3'' AFTER unit_weight_kg');
|
||||
CALL phase2_measure_add_column('fl_inbound_measurement_item', 'total_weight_kg',
|
||||
'DECIMAL(18,3) NULL COMMENT ''本箱规总重量kg'' AFTER volume_cbm');
|
||||
CALL phase2_measure_add_column('fl_inbound_measurement_item', 'total_volume_cbm',
|
||||
'DECIMAL(18,4) NOT NULL DEFAULT 0 COMMENT ''本箱规总体积m3'' AFTER total_weight_kg');
|
||||
CALL phase2_measure_add_column('fl_inbound_measurement_item', 'volume_weight_kg',
|
||||
'DECIMAL(18,3) NOT NULL DEFAULT 0 COMMENT ''本箱规材积重kg'' AFTER total_volume_cbm');
|
||||
CALL phase2_measure_add_column('fl_inbound_measurement_item', 'over_limit_warning',
|
||||
'VARCHAR(500) NULL COMMENT ''超线提醒快照'' AFTER source_image_file_id');
|
||||
CALL phase2_measure_add_column('fl_inbound_measurement_item', 'outer_length_cm',
|
||||
'DECIMAL(12,3) NULL COMMENT ''外箱规长度cm'' AFTER over_limit_warning');
|
||||
CALL phase2_measure_add_column('fl_inbound_measurement_item', 'outer_width_cm',
|
||||
'DECIMAL(12,3) NULL COMMENT ''外箱规宽度cm'' AFTER outer_length_cm');
|
||||
CALL phase2_measure_add_column('fl_inbound_measurement_item', 'outer_height_cm',
|
||||
'DECIMAL(12,3) NULL COMMENT ''外箱规高度cm'' AFTER outer_width_cm');
|
||||
|
||||
DROP PROCEDURE IF EXISTS phase2_measure_add_column;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS fl_inbound_weight_revision (
|
||||
id BIGINT UNSIGNED NOT NULL COMMENT 'OCR重量修订记录ID',
|
||||
tenant_id BIGINT UNSIGNED NOT NULL COMMENT '数据所属租户ID',
|
||||
inbound_id BIGINT UNSIGNED NOT NULL COMMENT '入库单ID',
|
||||
weight_result_id BIGINT UNSIGNED NOT NULL COMMENT 'OCR重量结果ID',
|
||||
revision_no INT UNSIGNED NOT NULL COMMENT '结果版本号,与乐观锁版本一致',
|
||||
action VARCHAR(24) NOT NULL COMMENT '动作:CORRECT或CONFIRM',
|
||||
before_weight_value DECIMAL(18,3) NULL COMMENT '变更前原单位重量',
|
||||
before_weight_unit VARCHAR(8) NULL COMMENT '变更前单位',
|
||||
after_weight_value DECIMAL(18,3) NULL COMMENT '变更后原单位重量',
|
||||
after_weight_unit VARCHAR(8) NULL COMMENT '变更后单位',
|
||||
final_weight_kg DECIMAL(18,3) NULL COMMENT '确认时统一换算后的重量kg',
|
||||
reason VARCHAR(500) NULL COMMENT '人工修正原因',
|
||||
operator_id BIGINT UNSIGNED NOT NULL COMMENT '操作人ID',
|
||||
operator_name VARCHAR(64) NULL COMMENT '操作人名称快照',
|
||||
operated_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '操作时间',
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE KEY uk_weight_revision_no (tenant_id, weight_result_id, revision_no),
|
||||
KEY idx_weight_revision_time (tenant_id, inbound_id, operated_at),
|
||||
CONSTRAINT fk_weight_revision_inbound FOREIGN KEY (inbound_id) REFERENCES fl_inbound_order (id),
|
||||
CONSTRAINT fk_weight_revision_result FOREIGN KEY (weight_result_id) REFERENCES fl_inbound_weight_result (id)
|
||||
) ENGINE=InnoDB COMMENT='OCR重量人工修正和确认的不可变版本历史';
|
||||
@@ -0,0 +1,533 @@
|
||||
SET NAMES utf8mb4;
|
||||
|
||||
CREATE DATABASE IF NOT EXISTS baiyue_firstleg
|
||||
DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
|
||||
USE baiyue_firstleg;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS fl_inbound_order (
|
||||
id BIGINT UNSIGNED NOT NULL COMMENT '入库单ID(雪花ID)',
|
||||
tenant_id BIGINT UNSIGNED NOT NULL COMMENT '数据所属租户ID',
|
||||
task_id BIGINT UNSIGNED NULL COMMENT '头程履约任务ID',
|
||||
order_id BIGINT UNSIGNED NOT NULL COMMENT '订单服务订单ID,不建立跨库外键',
|
||||
order_no VARCHAR(32) NOT NULL COMMENT '订单号快照',
|
||||
inbound_code VARCHAR(40) NOT NULL COMMENT '租户内唯一入仓码',
|
||||
process_status VARCHAR(24) NOT NULL DEFAULT 'WAIT_MEASURE' COMMENT '入库流程状态',
|
||||
order_status_snapshot VARCHAR(24) NOT NULL COMMENT '订单状态快照',
|
||||
measure_review_status VARCHAR(24) NOT NULL DEFAULT 'NOT_SUBMITTED' COMMENT '测量数据审核状态',
|
||||
fee_status VARCHAR(24) NOT NULL DEFAULT 'UNPRICED' COMMENT '费用业务状态',
|
||||
fee_review_status VARCHAR(24) NOT NULL DEFAULT 'NOT_SUBMITTED' COMMENT '费用审核状态',
|
||||
notification_status VARCHAR(24) NOT NULL DEFAULT 'NOT_CREATED' COMMENT '客户通知状态',
|
||||
expected_arrival_at DATETIME(3) NULL COMMENT '预计到达时间',
|
||||
customer_id BIGINT UNSIGNED NULL COMMENT '客户逻辑ID',
|
||||
customer_name VARCHAR(128) NOT NULL COMMENT '客户名称快照',
|
||||
company_id BIGINT UNSIGNED NULL COMMENT '运营公司逻辑ID',
|
||||
company_name VARCHAR(128) NULL COMMENT '运营公司名称快照',
|
||||
warehouse_id BIGINT UNSIGNED NOT NULL COMMENT '实际作业仓库ID',
|
||||
warehouse_name VARCHAR(128) NOT NULL COMMENT '实际作业仓库名称快照',
|
||||
delivery_warehouse_id BIGINT UNSIGNED NULL COMMENT '交货仓逻辑ID',
|
||||
delivery_warehouse_name VARCHAR(128) NULL COMMENT '交货仓名称快照',
|
||||
business_type VARCHAR(32) NOT NULL COMMENT '业务类型',
|
||||
channel_code VARCHAR(64) NULL COMMENT '渠道编码',
|
||||
channel_name VARCHAR(128) NULL COMMENT '渠道名称快照',
|
||||
carrier_id BIGINT UNSIGNED NULL COMMENT '计费船司逻辑ID',
|
||||
carrier_name VARCHAR(128) NULL COMMENT '计费船司名称快照',
|
||||
tax_mode VARCHAR(24) NULL COMMENT '买单或退税模式',
|
||||
container_mode VARCHAR(24) NULL COMMENT '整柜或散货模式',
|
||||
customs_inspection TINYINT(1) NULL COMMENT '是否商检',
|
||||
destination_type VARCHAR(24) NULL COMMENT '目的仓类型',
|
||||
destination_warehouse_id BIGINT UNSIGNED NULL COMMENT '目的仓逻辑ID',
|
||||
destination_code VARCHAR(32) NULL COMMENT '目的仓编码,例如FBA仓编码',
|
||||
destination_name VARCHAR(128) NULL COMMENT '目的仓名称快照',
|
||||
hold_flag TINYINT(1) NOT NULL DEFAULT 0 COMMENT '当前是否扣货',
|
||||
current_hold_reason VARCHAR(500) NULL COMMENT '当前扣货理由快照',
|
||||
total_package_count INT UNSIGNED NULL COMMENT '确认后的总箱数',
|
||||
actual_gross_weight_kg DECIMAL(18,3) NULL COMMENT '确认后的实际总毛重kg',
|
||||
chargeable_weight_kg DECIMAL(18,3) NULL COMMENT '当前费用快照的计费重量kg',
|
||||
actual_volume_cbm DECIMAL(18,4) NULL COMMENT '确认后的实际总体积m3',
|
||||
chargeable_volume_cbm DECIMAL(18,4) NULL COMMENT '当前费用快照的计费体积m3',
|
||||
pallet_count INT UNSIGNED NULL COMMENT '已分配总托盘数快照',
|
||||
volume_weight_kg DECIMAL(18,3) NULL COMMENT '总材积重kg',
|
||||
actual_net_weight_kg DECIMAL(18,3) NULL COMMENT '总净重kg',
|
||||
measure_completed_at DATETIME(3) NULL COMMENT '测量完成时间',
|
||||
inbounded_at DATETIME(3) NULL COMMENT '入库完成时间',
|
||||
express_company_code VARCHAR(64) NULL COMMENT '快递公司编码快照',
|
||||
express_company_name VARCHAR(128) NULL COMMENT '快递公司名称快照',
|
||||
express_tracking_no VARCHAR(128) NULL COMMENT '快递单号快照',
|
||||
public_remark VARCHAR(1000) NULL COMMENT '客户可见备注',
|
||||
created_by BIGINT UNSIGNED NOT NULL COMMENT '创建人ID',
|
||||
created_by_name VARCHAR(64) NULL COMMENT '创建人名称快照',
|
||||
created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间',
|
||||
updated_by BIGINT UNSIGNED NOT NULL COMMENT '最后修改人ID',
|
||||
updated_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3) COMMENT '更新时间',
|
||||
deleted TINYINT(1) NOT NULL DEFAULT 0 COMMENT '逻辑删除标记',
|
||||
version INT NOT NULL DEFAULT 0 COMMENT '乐观锁版本号',
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE KEY uk_inbound_tenant_code (tenant_id, inbound_code),
|
||||
UNIQUE KEY uk_inbound_tenant_order (tenant_id, order_id),
|
||||
KEY idx_inbound_process_time (tenant_id, process_status, created_at, id),
|
||||
KEY idx_inbound_measure_time (tenant_id, measure_review_status, created_at, id),
|
||||
KEY idx_inbound_fee_time (tenant_id, fee_review_status, created_at, id),
|
||||
KEY idx_inbound_warehouse_status (tenant_id, warehouse_id, process_status, created_at),
|
||||
KEY idx_inbound_customer_time (tenant_id, customer_id, created_at),
|
||||
KEY idx_inbound_company_time (tenant_id, company_id, created_at),
|
||||
KEY idx_inbound_arrival (tenant_id, expected_arrival_at),
|
||||
KEY idx_inbound_destination (tenant_id, destination_code, created_at),
|
||||
KEY idx_inbound_channel (tenant_id, channel_code, created_at),
|
||||
CONSTRAINT fk_inbound_task FOREIGN KEY (task_id) REFERENCES fl_fulfillment_task (id)
|
||||
) ENGINE=InnoDB COMMENT='二期头程入库单聚合根和列表查询快照';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS fl_inbound_pickup_snapshot (
|
||||
id BIGINT UNSIGNED NOT NULL COMMENT '提货信息快照ID',
|
||||
tenant_id BIGINT UNSIGNED NOT NULL COMMENT '数据所属租户ID',
|
||||
inbound_id BIGINT UNSIGNED NOT NULL COMMENT '入库单ID',
|
||||
pickup_method VARCHAR(24) NULL COMMENT '提货方式',
|
||||
pickup_at DATETIME(3) NULL COMMENT '提货时间',
|
||||
contact_name VARCHAR(64) NULL COMMENT '提货联系人',
|
||||
contact_phone VARCHAR(32) NULL COMMENT '提货联系人电话',
|
||||
contact_email VARCHAR(128) NULL COMMENT '提货联系人邮箱',
|
||||
country_code CHAR(2) NULL COMMENT '国家二字码',
|
||||
province VARCHAR(64) NULL COMMENT '省或州',
|
||||
city VARCHAR(64) NULL COMMENT '城市',
|
||||
district VARCHAR(64) NULL COMMENT '区县',
|
||||
address_line VARCHAR(512) NULL COMMENT '提货详细地址',
|
||||
postal_code VARCHAR(20) NULL COMMENT '提货邮编',
|
||||
created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间',
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE KEY uk_pickup_inbound (tenant_id, inbound_id),
|
||||
CONSTRAINT fk_pickup_inbound FOREIGN KEY (inbound_id) REFERENCES fl_inbound_order (id)
|
||||
) ENGINE=InnoDB COMMENT='入库单提货信息不可变快照';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS fl_inbound_destination_snapshot (
|
||||
id BIGINT UNSIGNED NOT NULL COMMENT '目的仓地址快照ID',
|
||||
tenant_id BIGINT UNSIGNED NOT NULL COMMENT '数据所属租户ID',
|
||||
inbound_id BIGINT UNSIGNED NOT NULL COMMENT '入库单ID',
|
||||
destination_type VARCHAR(24) NULL COMMENT '目的仓类型',
|
||||
destination_code VARCHAR(32) NULL COMMENT '目的仓编码',
|
||||
destination_name VARCHAR(128) NULL COMMENT '目的仓名称',
|
||||
country_code CHAR(2) NULL COMMENT '国家二字码',
|
||||
state_province VARCHAR(100) NULL COMMENT '省或州',
|
||||
city VARCHAR(100) NULL COMMENT '城市',
|
||||
address_line VARCHAR(512) NULL COMMENT '详细地址',
|
||||
postal_code VARCHAR(20) NULL COMMENT '邮编',
|
||||
contact_name VARCHAR(64) NULL COMMENT '联系人',
|
||||
contact_phone VARCHAR(32) NULL COMMENT '联系人电话',
|
||||
created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间',
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE KEY uk_destination_inbound (tenant_id, inbound_id),
|
||||
CONSTRAINT fk_destination_inbound FOREIGN KEY (inbound_id) REFERENCES fl_inbound_order (id)
|
||||
) ENGINE=InnoDB COMMENT='入库单目的仓地址和联系人快照';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS fl_inbound_transport_snapshot (
|
||||
id BIGINT UNSIGNED NOT NULL COMMENT '运输信息快照ID',
|
||||
tenant_id BIGINT UNSIGNED NOT NULL COMMENT '数据所属租户ID',
|
||||
inbound_id BIGINT UNSIGNED NOT NULL COMMENT '入库单ID',
|
||||
loading_status VARCHAR(24) NULL COMMENT '配载状态快照',
|
||||
container_no VARCHAR(64) NULL COMMENT '集装箱号',
|
||||
cabinet_no VARCHAR(64) NULL COMMENT '柜号或内部柜单号',
|
||||
vessel_name VARCHAR(128) NULL COMMENT '船名',
|
||||
voyage_no VARCHAR(64) NULL COMMENT '航次',
|
||||
sailing_at DATETIME(3) NULL COMMENT '开船时间',
|
||||
port_arrival_at DATETIME(3) NULL COMMENT '到港时间',
|
||||
source_updated_at DATETIME(3) NULL COMMENT '上游数据更新时间',
|
||||
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_transport_inbound (tenant_id, inbound_id),
|
||||
KEY idx_transport_container (tenant_id, container_no),
|
||||
KEY idx_transport_cabinet (tenant_id, cabinet_no),
|
||||
KEY idx_transport_loading (tenant_id, loading_status, sailing_at),
|
||||
CONSTRAINT fk_transport_inbound FOREIGN KEY (inbound_id) REFERENCES fl_inbound_order (id)
|
||||
) ENGINE=InnoDB COMMENT='入库单关联运输信息只读快照';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS fl_inbound_measurement (
|
||||
id BIGINT UNSIGNED NOT NULL COMMENT '测量批次ID',
|
||||
tenant_id BIGINT UNSIGNED NOT NULL COMMENT '数据所属租户ID',
|
||||
inbound_id BIGINT UNSIGNED NOT NULL COMMENT '入库单ID',
|
||||
source_type VARCHAR(24) NOT NULL COMMENT '数据来源:THIRD_PARTY或MANUAL',
|
||||
source_code VARCHAR(64) NULL COMMENT '第三方应用或来源编码',
|
||||
external_event_no VARCHAR(128) NULL COMMENT '第三方事件号',
|
||||
device_code VARCHAR(64) NULL COMMENT '测量设备编码',
|
||||
warehouse_code VARCHAR(50) NULL COMMENT '第三方回传仓库编码',
|
||||
measured_at DATETIME(3) NULL COMMENT '设备测量时间',
|
||||
status VARCHAR(24) NOT NULL DEFAULT 'RECEIVED' COMMENT '测量批次状态',
|
||||
raw_payload_json JSON NULL COMMENT '第三方原始报文',
|
||||
original_document_no VARCHAR(64) NULL COMMENT '原单据号码快照',
|
||||
original_gross_weight_kg DECIMAL(18,3) NULL COMMENT '原单据毛重kg',
|
||||
original_volume_cbm DECIMAL(18,4) NULL COMMENT '原单据体积或材积m3',
|
||||
actual_goods_name VARCHAR(255) NULL COMMENT '实际品名',
|
||||
total_package_count INT UNSIGNED NULL COMMENT '本批次总箱数',
|
||||
total_volume_raw_cbm DECIMAL(18,6) NULL COMMENT '本批次原始总体积m3',
|
||||
total_volume_cbm DECIMAL(18,4) NULL COMMENT '本批次业务总体积m3',
|
||||
volume_weight_kg DECIMAL(18,3) NULL COMMENT '本批次总材积重kg',
|
||||
created_by BIGINT UNSIGNED NULL COMMENT '创建人或系统主体ID',
|
||||
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 '更新时间',
|
||||
version INT NOT NULL DEFAULT 0 COMMENT '乐观锁版本号',
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE KEY uk_measure_external_event (tenant_id, source_code, external_event_no),
|
||||
KEY idx_measure_inbound_time (tenant_id, inbound_id, created_at),
|
||||
CONSTRAINT fk_measure_inbound FOREIGN KEY (inbound_id) REFERENCES fl_inbound_order (id)
|
||||
) ENGINE=InnoDB COMMENT='入库长宽高测量批次和第三方原始数据';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS fl_inbound_measurement_item (
|
||||
id BIGINT UNSIGNED NOT NULL COMMENT '测量明细ID',
|
||||
tenant_id BIGINT UNSIGNED NOT NULL COMMENT '数据所属租户ID',
|
||||
measurement_id BIGINT UNSIGNED NOT NULL COMMENT '测量批次ID',
|
||||
item_no VARCHAR(32) NOT NULL COMMENT '批次内明细号',
|
||||
box_specification VARCHAR(64) NOT NULL COMMENT '箱规标识',
|
||||
package_count INT UNSIGNED NOT NULL COMMENT '相同箱规箱数',
|
||||
length_cm DECIMAL(12,3) NOT NULL COMMENT '原始长度cm',
|
||||
width_cm DECIMAL(12,3) NOT NULL COMMENT '原始宽度cm',
|
||||
height_cm DECIMAL(12,3) NOT NULL COMMENT '原始高度cm',
|
||||
girth_cm DECIMAL(12,3) NOT NULL COMMENT '周长cm,规则为长+2*(宽+高)',
|
||||
unit_weight_kg DECIMAL(18,3) NULL COMMENT '单箱重量kg,第三方仅回传尺寸时可为空',
|
||||
unit_volume_cbm DECIMAL(18,4) NOT NULL COMMENT '单箱业务体积m3',
|
||||
volume_raw_cbm DECIMAL(18,6) NOT NULL COMMENT '原始体积m3',
|
||||
volume_cbm DECIMAL(18,4) NOT NULL COMMENT '业务体积m3',
|
||||
total_weight_kg DECIMAL(18,3) NULL COMMENT '本箱规总重量kg',
|
||||
total_volume_cbm DECIMAL(18,4) NOT NULL COMMENT '本箱规总体积m3',
|
||||
volume_weight_kg DECIMAL(18,3) NOT NULL COMMENT '本箱规材积重kg',
|
||||
calculation_rule_version VARCHAR(32) NOT NULL COMMENT '体积计算和舍入规则版本',
|
||||
source_image_file_id BIGINT UNSIGNED NULL COMMENT '测量设备图片文件ID',
|
||||
over_limit_warning VARCHAR(500) NULL COMMENT '超线提醒快照',
|
||||
outer_length_cm DECIMAL(12,3) NULL COMMENT '外箱规长度cm',
|
||||
outer_width_cm DECIMAL(12,3) NULL COMMENT '外箱规宽度cm',
|
||||
outer_height_cm DECIMAL(12,3) NULL COMMENT '外箱规高度cm',
|
||||
remark VARCHAR(500) NULL COMMENT '测量明细备注',
|
||||
created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间',
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE KEY uk_measure_item_no (tenant_id, measurement_id, item_no),
|
||||
CONSTRAINT fk_measure_item_batch FOREIGN KEY (measurement_id) REFERENCES fl_inbound_measurement (id)
|
||||
) ENGINE=InnoDB COMMENT='入库长宽高和箱数测量明细';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS fl_inbound_weight_result (
|
||||
id BIGINT UNSIGNED NOT NULL COMMENT 'OCR重量结果ID',
|
||||
tenant_id BIGINT UNSIGNED NOT NULL COMMENT '数据所属租户ID',
|
||||
inbound_id BIGINT UNSIGNED NOT NULL COMMENT '入库单ID',
|
||||
file_id BIGINT UNSIGNED NOT NULL COMMENT '称重图片文件ID',
|
||||
ocr_provider VARCHAR(64) NULL COMMENT 'OCR服务商编码',
|
||||
ocr_raw_text VARCHAR(1000) NULL COMMENT 'OCR原始文本',
|
||||
ocr_weight_value DECIMAL(18,3) NULL COMMENT 'OCR识别原始重量值',
|
||||
ocr_weight_unit VARCHAR(8) NULL COMMENT 'OCR识别原始单位',
|
||||
confidence DECIMAL(6,5) NULL COMMENT '识别置信度',
|
||||
adjusted_weight_value DECIMAL(18,3) NULL COMMENT '人工修正后的原单位重量',
|
||||
adjusted_weight_unit VARCHAR(8) NULL COMMENT '人工修正后的单位',
|
||||
final_weight_kg DECIMAL(18,3) NULL COMMENT '确认并统一换算后的重量kg',
|
||||
recognition_status VARCHAR(24) NOT NULL DEFAULT 'PENDING' COMMENT '识别和确认状态',
|
||||
adjustment_reason VARCHAR(500) NULL COMMENT '人工修正原因',
|
||||
adjusted_by BIGINT UNSIGNED NULL COMMENT '修正人ID',
|
||||
adjusted_at DATETIME(3) NULL COMMENT '修正时间',
|
||||
confirmed_by BIGINT UNSIGNED NULL COMMENT '确认人ID',
|
||||
confirmed_at DATETIME(3) NULL COMMENT '确认时间',
|
||||
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 '更新时间',
|
||||
deleted TINYINT(1) NOT NULL DEFAULT 0 COMMENT '逻辑删除标记',
|
||||
version INT NOT NULL DEFAULT 0 COMMENT '乐观锁版本号',
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE KEY uk_weight_inbound_file (tenant_id, inbound_id, file_id),
|
||||
KEY idx_weight_inbound_status (tenant_id, inbound_id, recognition_status),
|
||||
CONSTRAINT fk_weight_inbound FOREIGN KEY (inbound_id) REFERENCES fl_inbound_order (id)
|
||||
) ENGINE=InnoDB COMMENT='称重图片OCR原值、人工修正值和确认重量';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS fl_inbound_weight_revision (
|
||||
id BIGINT UNSIGNED NOT NULL COMMENT 'OCR重量修订记录ID',
|
||||
tenant_id BIGINT UNSIGNED NOT NULL COMMENT '数据所属租户ID',
|
||||
inbound_id BIGINT UNSIGNED NOT NULL COMMENT '入库单ID',
|
||||
weight_result_id BIGINT UNSIGNED NOT NULL COMMENT 'OCR重量结果ID',
|
||||
revision_no INT UNSIGNED NOT NULL COMMENT '结果版本号,与乐观锁版本一致',
|
||||
action VARCHAR(24) NOT NULL COMMENT '动作:CORRECT或CONFIRM',
|
||||
before_weight_value DECIMAL(18,3) NULL COMMENT '变更前原单位重量',
|
||||
before_weight_unit VARCHAR(8) NULL COMMENT '变更前单位',
|
||||
after_weight_value DECIMAL(18,3) NULL COMMENT '变更后原单位重量',
|
||||
after_weight_unit VARCHAR(8) NULL COMMENT '变更后单位',
|
||||
final_weight_kg DECIMAL(18,3) NULL COMMENT '确认时统一换算后的重量kg',
|
||||
reason VARCHAR(500) NULL COMMENT '人工修正原因',
|
||||
operator_id BIGINT UNSIGNED NOT NULL COMMENT '操作人ID',
|
||||
operator_name VARCHAR(64) NULL COMMENT '操作人名称快照',
|
||||
operated_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '操作时间',
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE KEY uk_weight_revision_no (tenant_id, weight_result_id, revision_no),
|
||||
KEY idx_weight_revision_time (tenant_id, inbound_id, operated_at),
|
||||
CONSTRAINT fk_weight_revision_inbound FOREIGN KEY (inbound_id) REFERENCES fl_inbound_order (id),
|
||||
CONSTRAINT fk_weight_revision_result FOREIGN KEY (weight_result_id) REFERENCES fl_inbound_weight_result (id)
|
||||
) ENGINE=InnoDB COMMENT='OCR重量人工修正和确认的不可变版本历史';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS fl_measure_review_record (
|
||||
id BIGINT UNSIGNED NOT NULL COMMENT '测量审核记录ID',
|
||||
tenant_id BIGINT UNSIGNED NOT NULL COMMENT '数据所属租户ID',
|
||||
inbound_id BIGINT UNSIGNED NOT NULL COMMENT '入库单ID',
|
||||
measurement_id BIGINT UNSIGNED NULL COMMENT '被审核的测量批次ID',
|
||||
review_result VARCHAR(24) NOT NULL COMMENT '审核结果',
|
||||
review_reason VARCHAR(1000) NULL COMMENT '审核或驳回原因',
|
||||
exception_release TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否异常放行',
|
||||
release_reason VARCHAR(1000) NULL COMMENT '异常放行原因',
|
||||
allow_rejected_config TINYINT(1) NOT NULL DEFAULT 0 COMMENT '操作时Nacos异常放行开关值',
|
||||
reviewer_id BIGINT UNSIGNED NOT NULL COMMENT '审核人ID',
|
||||
reviewer_name VARCHAR(64) NULL COMMENT '审核人名称快照',
|
||||
reviewed_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '审核时间',
|
||||
PRIMARY KEY (id),
|
||||
KEY idx_review_inbound_time (tenant_id, inbound_id, reviewed_at),
|
||||
KEY idx_review_exception_release (tenant_id, inbound_id, exception_release, reviewed_at),
|
||||
CONSTRAINT fk_review_inbound FOREIGN KEY (inbound_id) REFERENCES fl_inbound_order (id),
|
||||
CONSTRAINT fk_review_measurement FOREIGN KEY (measurement_id) REFERENCES fl_inbound_measurement (id)
|
||||
) ENGINE=InnoDB COMMENT='测量审核、驳回和异常放行不可变记录';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS fl_customer_charge_rule (
|
||||
id BIGINT UNSIGNED NOT NULL COMMENT '客户计费规则ID',
|
||||
tenant_id BIGINT UNSIGNED NOT NULL COMMENT '数据所属租户ID',
|
||||
rule_code VARCHAR(50) NOT NULL COMMENT '租户内规则编码',
|
||||
rule_version INT UNSIGNED NOT NULL COMMENT '规则版本号',
|
||||
customer_id BIGINT UNSIGNED NOT NULL COMMENT '客户逻辑ID',
|
||||
customer_name VARCHAR(128) NOT NULL COMMENT '客户名称快照',
|
||||
business_type VARCHAR(32) NOT NULL COMMENT '业务类型',
|
||||
charge_mode VARCHAR(16) NOT NULL COMMENT '计费口径:KG或CBM',
|
||||
tax_mode VARCHAR(24) NULL COMMENT '包税或不包税类型',
|
||||
conversion_factor DECIMAL(18,6) NOT NULL COMMENT '重量体积换算系数',
|
||||
rounding_scale TINYINT UNSIGNED NOT NULL DEFAULT 3 COMMENT '结果保留小数位数',
|
||||
rounding_mode VARCHAR(24) NOT NULL DEFAULT 'CEILING' COMMENT '舍入方式',
|
||||
currency CHAR(3) NOT NULL COMMENT '默认币种',
|
||||
effective_from DATETIME(3) NOT NULL COMMENT '生效开始时间',
|
||||
effective_to DATETIME(3) NULL COMMENT '生效结束时间',
|
||||
status VARCHAR(16) NOT NULL DEFAULT 'ACTIVE' COMMENT '规则状态',
|
||||
remark VARCHAR(500) NULL COMMENT '规则备注',
|
||||
created_by BIGINT UNSIGNED NOT NULL COMMENT '创建人ID',
|
||||
created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间',
|
||||
updated_by BIGINT UNSIGNED NOT NULL COMMENT '最后修改人ID',
|
||||
updated_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3) COMMENT '更新时间',
|
||||
deleted TINYINT(1) NOT NULL DEFAULT 0 COMMENT '逻辑删除标记',
|
||||
version INT NOT NULL DEFAULT 0 COMMENT '乐观锁版本号',
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE KEY uk_charge_rule_version (tenant_id, rule_code, rule_version),
|
||||
KEY idx_charge_rule_match (tenant_id, customer_id, business_type, status, effective_from, effective_to)
|
||||
) ENGINE=InnoDB COMMENT='客户头程计费规则版本';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS fl_carrier_fba_rate (
|
||||
id BIGINT UNSIGNED NOT NULL COMMENT '船司FBA价格ID',
|
||||
tenant_id BIGINT UNSIGNED NOT NULL COMMENT '数据所属租户ID',
|
||||
rate_code VARCHAR(50) NOT NULL COMMENT '租户内价格编码',
|
||||
rate_version INT UNSIGNED NOT NULL COMMENT '价格版本号',
|
||||
origin_warehouse_id BIGINT UNSIGNED NOT NULL COMMENT '起运仓逻辑ID',
|
||||
origin_warehouse_name VARCHAR(128) NOT NULL COMMENT '起运仓名称快照',
|
||||
business_type VARCHAR(32) NOT NULL COMMENT '业务或计费类型',
|
||||
channel_code VARCHAR(64) NULL COMMENT '渠道编码',
|
||||
carrier_id BIGINT UNSIGNED NULL COMMENT '船司逻辑ID',
|
||||
carrier_name VARCHAR(128) NOT NULL COMMENT '船司名称快照',
|
||||
destination_code VARCHAR(32) NOT NULL COMMENT 'FBA目的仓编码',
|
||||
charge_unit VARCHAR(16) NOT NULL COMMENT '计费单位:KG或CBM',
|
||||
unit_price DECIMAL(18,6) NOT NULL COMMENT '基础单价',
|
||||
currency CHAR(3) NOT NULL COMMENT '币种',
|
||||
additional_fee DECIMAL(18,2) NOT NULL DEFAULT 0 COMMENT '固定附加费',
|
||||
effective_from DATETIME(3) NOT NULL COMMENT '生效开始时间',
|
||||
effective_to DATETIME(3) NULL COMMENT '生效结束时间',
|
||||
status VARCHAR(16) NOT NULL DEFAULT 'ACTIVE' COMMENT '价格状态',
|
||||
remark VARCHAR(500) NULL COMMENT '价格备注',
|
||||
created_by BIGINT UNSIGNED NOT NULL COMMENT '创建人ID',
|
||||
created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间',
|
||||
updated_by BIGINT UNSIGNED NOT NULL COMMENT '最后修改人ID',
|
||||
updated_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3) COMMENT '更新时间',
|
||||
deleted TINYINT(1) NOT NULL DEFAULT 0 COMMENT '逻辑删除标记',
|
||||
version INT NOT NULL DEFAULT 0 COMMENT '乐观锁版本号',
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE KEY uk_fba_rate_version (tenant_id, rate_code, rate_version),
|
||||
KEY idx_fba_rate_match (tenant_id, origin_warehouse_id, business_type, channel_code, carrier_id, destination_code, charge_unit, status, effective_from, effective_to)
|
||||
) ENGINE=InnoDB COMMENT='船司FBA目的仓价格版本';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS fl_inbound_fee (
|
||||
id BIGINT UNSIGNED NOT NULL COMMENT '入库费用ID',
|
||||
tenant_id BIGINT UNSIGNED NOT NULL COMMENT '数据所属租户ID',
|
||||
inbound_id BIGINT UNSIGNED NOT NULL COMMENT '入库单ID',
|
||||
fee_no VARCHAR(40) NOT NULL COMMENT '租户内唯一费用单号',
|
||||
fee_version INT UNSIGNED NOT NULL DEFAULT 1 COMMENT '费用快照版本',
|
||||
charge_rule_id BIGINT UNSIGNED NOT NULL COMMENT '客户计费规则ID',
|
||||
charge_rule_version INT UNSIGNED NOT NULL COMMENT '客户规则版本快照',
|
||||
carrier_rate_id BIGINT UNSIGNED NOT NULL COMMENT '船司FBA价格ID',
|
||||
carrier_rate_version INT UNSIGNED NOT NULL COMMENT '船司价格版本快照',
|
||||
rule_code VARCHAR(50) NOT NULL COMMENT '客户规则编码快照',
|
||||
customer_id BIGINT UNSIGNED NOT NULL COMMENT '客户ID快照',
|
||||
customer_name VARCHAR(128) NOT NULL COMMENT '客户名称快照',
|
||||
business_type VARCHAR(32) NOT NULL COMMENT '业务类型快照',
|
||||
tax_mode VARCHAR(24) NULL COMMENT '包税模式快照',
|
||||
rounding_scale TINYINT UNSIGNED NOT NULL COMMENT '计费量保留位数快照',
|
||||
rounding_mode VARCHAR(24) NOT NULL COMMENT '舍入方式快照',
|
||||
rule_effective_from DATETIME(3) NOT NULL COMMENT '客户规则生效开始快照',
|
||||
rule_effective_to DATETIME(3) NULL COMMENT '客户规则生效结束快照',
|
||||
rate_code VARCHAR(50) NOT NULL COMMENT '船司价格编码快照',
|
||||
origin_warehouse_id BIGINT UNSIGNED NOT NULL COMMENT '起运仓ID快照',
|
||||
origin_warehouse_name VARCHAR(128) NOT NULL COMMENT '起运仓名称快照',
|
||||
channel_code VARCHAR(64) NOT NULL COMMENT '渠道编码快照',
|
||||
carrier_id BIGINT UNSIGNED NOT NULL COMMENT '船司ID快照',
|
||||
carrier_name VARCHAR(128) NOT NULL COMMENT '船司名称快照',
|
||||
destination_code VARCHAR(32) NOT NULL COMMENT 'FBA仓编码快照',
|
||||
rate_effective_from DATETIME(3) NOT NULL COMMENT '价格生效开始快照',
|
||||
rate_effective_to DATETIME(3) NULL COMMENT '价格生效结束快照',
|
||||
charge_mode VARCHAR(16) NOT NULL COMMENT '计费口径:KG或CBM',
|
||||
conversion_factor DECIMAL(18,6) NOT NULL COMMENT '使用的换算系数快照',
|
||||
actual_weight_kg DECIMAL(18,3) NOT NULL COMMENT '试算时实际重量kg',
|
||||
actual_volume_cbm DECIMAL(18,4) NOT NULL COMMENT '试算时实际体积m3',
|
||||
converted_quantity DECIMAL(18,4) NOT NULL COMMENT '换算后的重量或体积',
|
||||
chargeable_quantity DECIMAL(18,4) NOT NULL COMMENT '最终计费量',
|
||||
charge_unit VARCHAR(16) NOT NULL COMMENT '计费单位',
|
||||
currency CHAR(3) NOT NULL COMMENT '币种',
|
||||
subtotal_amount DECIMAL(18,2) NOT NULL COMMENT '基础费用金额',
|
||||
additional_amount DECIMAL(18,2) NOT NULL DEFAULT 0 COMMENT '附加费金额',
|
||||
total_amount DECIMAL(18,2) NOT NULL COMMENT '总金额',
|
||||
fee_status VARCHAR(24) NOT NULL DEFAULT 'CALCULATED' COMMENT '费用状态',
|
||||
review_status VARCHAR(24) NOT NULL DEFAULT 'NOT_SUBMITTED' COMMENT '费用审核状态',
|
||||
exception_release TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否基于测量异常放行生成',
|
||||
calculated_by BIGINT UNSIGNED NOT NULL COMMENT '试算人ID',
|
||||
calculated_at DATETIME(3) NOT NULL COMMENT '试算时间',
|
||||
confirmed_by BIGINT UNSIGNED NULL COMMENT '确认人ID',
|
||||
confirmed_at DATETIME(3) NULL COMMENT '确认时间',
|
||||
sent_by BIGINT UNSIGNED NULL COMMENT '发送人ID',
|
||||
sent_at DATETIME(3) NULL COMMENT '发送客户时间',
|
||||
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_inbound_fee_no (tenant_id, fee_no),
|
||||
UNIQUE KEY uk_inbound_fee_version (tenant_id, inbound_id, fee_version),
|
||||
KEY idx_inbound_fee_status (tenant_id, inbound_id, fee_status, review_status),
|
||||
CONSTRAINT fk_fee_inbound FOREIGN KEY (inbound_id) REFERENCES fl_inbound_order (id),
|
||||
CONSTRAINT fk_fee_charge_rule FOREIGN KEY (charge_rule_id) REFERENCES fl_customer_charge_rule (id),
|
||||
CONSTRAINT fk_fee_carrier_rate FOREIGN KEY (carrier_rate_id) REFERENCES fl_carrier_fba_rate (id)
|
||||
) ENGINE=InnoDB COMMENT='入库头程费用计算和确认快照';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS fl_inbound_fee_item (
|
||||
id BIGINT UNSIGNED NOT NULL COMMENT '费用明细ID',
|
||||
tenant_id BIGINT UNSIGNED NOT NULL COMMENT '数据所属租户ID',
|
||||
fee_id BIGINT UNSIGNED NOT NULL COMMENT '费用头ID',
|
||||
item_no INT UNSIGNED NOT NULL COMMENT '费用单内序号',
|
||||
fee_code VARCHAR(50) NOT NULL COMMENT '费用项目编码',
|
||||
fee_name VARCHAR(128) NOT NULL COMMENT '费用项目名称快照',
|
||||
quantity DECIMAL(18,4) NOT NULL COMMENT '计费数量',
|
||||
unit VARCHAR(16) NOT NULL COMMENT '计费单位',
|
||||
unit_price DECIMAL(18,6) NOT NULL COMMENT '单价',
|
||||
amount DECIMAL(18,2) NOT NULL COMMENT '金额',
|
||||
currency CHAR(3) NOT NULL COMMENT '币种',
|
||||
automatic_flag TINYINT(1) NOT NULL DEFAULT 1 COMMENT '是否自动计算',
|
||||
remark VARCHAR(500) NULL COMMENT '费用备注',
|
||||
created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间',
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE KEY uk_fee_item_no (tenant_id, fee_id, item_no),
|
||||
CONSTRAINT fk_fee_item_header FOREIGN KEY (fee_id) REFERENCES fl_inbound_fee (id)
|
||||
) ENGINE=InnoDB COMMENT='入库头程费用项目明细';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS fl_inbound_pallet_allocation (
|
||||
id BIGINT UNSIGNED NOT NULL COMMENT '头程托盘分配引用ID',
|
||||
tenant_id BIGINT UNSIGNED NOT NULL COMMENT '数据所属租户ID',
|
||||
inbound_id BIGINT UNSIGNED NOT NULL COMMENT '入库单ID',
|
||||
allocation_no INT UNSIGNED NOT NULL COMMENT '入库单内分配序号',
|
||||
warehouse_id BIGINT UNSIGNED NOT NULL COMMENT '仓库服务仓库ID',
|
||||
pallet_id BIGINT UNSIGNED NOT NULL COMMENT '仓库服务托盘ID',
|
||||
pallet_code VARCHAR(50) NOT NULL COMMENT '托盘编码快照',
|
||||
pallet_capacity_cbm DECIMAL(18,4) NOT NULL COMMENT '托盘可用容积快照',
|
||||
allocated_volume_cbm DECIMAL(18,4) NOT NULL COMMENT '本托盘分配体积',
|
||||
allocated_package_count INT UNSIGNED NULL COMMENT '本托盘分配箱数',
|
||||
location_id BIGINT UNSIGNED NOT NULL COMMENT '仓库服务库位ID',
|
||||
location_code VARCHAR(50) NOT NULL COMMENT '库位编码快照',
|
||||
reservation_no VARCHAR(64) NOT NULL COMMENT '仓库库位预占单号',
|
||||
allocation_status VARCHAR(24) NOT NULL DEFAULT 'RESERVED' COMMENT '分配状态',
|
||||
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_pallet_allocation_no (tenant_id, inbound_id, allocation_no),
|
||||
UNIQUE KEY uk_pallet_allocation_pallet (tenant_id, inbound_id, pallet_id),
|
||||
KEY idx_allocation_location (tenant_id, warehouse_id, location_id, allocation_status),
|
||||
CONSTRAINT fk_allocation_inbound FOREIGN KEY (inbound_id) REFERENCES fl_inbound_order (id)
|
||||
) ENGINE=InnoDB COMMENT='头程侧托盘、库位和仓库预占结果引用';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS fl_inbound_file (
|
||||
id BIGINT UNSIGNED NOT NULL COMMENT '入库单文件关系ID',
|
||||
tenant_id BIGINT UNSIGNED NOT NULL COMMENT '数据所属租户ID',
|
||||
inbound_id BIGINT UNSIGNED NOT NULL COMMENT '入库单ID',
|
||||
file_id BIGINT UNSIGNED NOT NULL COMMENT '文件服务文件ID',
|
||||
file_type VARCHAR(24) NOT NULL COMMENT '文件类型:RELATED、MARK、PC_ORDER、MEASURE或WEIGHT',
|
||||
file_name_snapshot VARCHAR(255) NOT NULL COMMENT '文件名快照',
|
||||
visibility VARCHAR(16) NOT NULL DEFAULT 'INTERNAL' COMMENT '可见范围',
|
||||
file_version INT UNSIGNED NOT NULL DEFAULT 1 COMMENT '业务文件版本',
|
||||
uploaded_by BIGINT UNSIGNED NOT NULL COMMENT '上传人ID',
|
||||
uploaded_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '上传时间',
|
||||
deleted TINYINT(1) NOT NULL DEFAULT 0 COMMENT '逻辑删除标记',
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE KEY uk_inbound_file_relation (tenant_id, inbound_id, file_id, file_type),
|
||||
KEY idx_inbound_file_type (tenant_id, inbound_id, file_type, deleted),
|
||||
CONSTRAINT fk_file_inbound FOREIGN KEY (inbound_id) REFERENCES fl_inbound_order (id)
|
||||
) ENGINE=InnoDB COMMENT='入库单与文件中心对象的分类关系';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS fl_inbound_hold_record (
|
||||
id BIGINT UNSIGNED NOT NULL COMMENT '扣货记录ID',
|
||||
tenant_id BIGINT UNSIGNED NOT NULL COMMENT '数据所属租户ID',
|
||||
inbound_id BIGINT UNSIGNED NOT NULL COMMENT '入库单ID',
|
||||
hold_action VARCHAR(16) NOT NULL COMMENT '动作:HOLD或RELEASE',
|
||||
reason VARCHAR(1000) NOT NULL COMMENT '扣货或解除原因',
|
||||
evidence_file_id BIGINT UNSIGNED NULL COMMENT '证据文件ID',
|
||||
operator_id BIGINT UNSIGNED NOT NULL COMMENT '操作人ID',
|
||||
operator_name VARCHAR(64) NULL COMMENT '操作人名称快照',
|
||||
operated_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '操作时间',
|
||||
PRIMARY KEY (id),
|
||||
KEY idx_hold_inbound_time (tenant_id, inbound_id, operated_at),
|
||||
CONSTRAINT fk_hold_inbound FOREIGN KEY (inbound_id) REFERENCES fl_inbound_order (id)
|
||||
) ENGINE=InnoDB COMMENT='入库单扣货和解除扣货不可变历史';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS fl_inbound_internal_note (
|
||||
id BIGINT UNSIGNED NOT NULL COMMENT '客服内部备注ID',
|
||||
tenant_id BIGINT UNSIGNED NOT NULL COMMENT '数据所属租户ID',
|
||||
inbound_id BIGINT UNSIGNED NOT NULL COMMENT '入库单ID',
|
||||
content VARCHAR(2000) NOT NULL COMMENT '仅内部可见备注',
|
||||
created_by BIGINT UNSIGNED NOT NULL COMMENT '创建人ID',
|
||||
created_by_name VARCHAR(64) NULL COMMENT '创建人名称快照',
|
||||
created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间',
|
||||
PRIMARY KEY (id),
|
||||
KEY idx_internal_note_time (tenant_id, inbound_id, created_at),
|
||||
CONSTRAINT fk_internal_note_inbound FOREIGN KEY (inbound_id) REFERENCES fl_inbound_order (id)
|
||||
) ENGINE=InnoDB COMMENT='入库单客服内部备注历史';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS fl_inbound_status_history (
|
||||
id BIGINT UNSIGNED NOT NULL COMMENT '入库状态历史ID',
|
||||
tenant_id BIGINT UNSIGNED NOT NULL COMMENT '数据所属租户ID',
|
||||
inbound_id BIGINT UNSIGNED NOT NULL COMMENT '入库单ID',
|
||||
from_status VARCHAR(24) NULL COMMENT '变更前状态',
|
||||
to_status VARCHAR(24) NOT NULL COMMENT '变更后状态',
|
||||
action VARCHAR(32) NOT NULL COMMENT '触发动作',
|
||||
reason VARCHAR(1000) NULL COMMENT '变更原因',
|
||||
operator_id BIGINT UNSIGNED NOT NULL COMMENT '操作人ID',
|
||||
operator_name VARCHAR(64) NULL COMMENT '操作人名称快照',
|
||||
occurred_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '发生时间',
|
||||
PRIMARY KEY (id),
|
||||
KEY idx_inbound_history_time (tenant_id, inbound_id, occurred_at),
|
||||
CONSTRAINT fk_history_inbound FOREIGN KEY (inbound_id) REFERENCES fl_inbound_order (id)
|
||||
) ENGINE=InnoDB COMMENT='入库单流程状态不可变历史';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS fl_inbound_outbox (
|
||||
id BIGINT UNSIGNED NOT NULL COMMENT '领域事件全局ID',
|
||||
tenant_id BIGINT UNSIGNED NOT NULL COMMENT '事件所属租户ID',
|
||||
aggregate_type VARCHAR(32) NOT NULL DEFAULT 'INBOUND' COMMENT '聚合类型',
|
||||
aggregate_id BIGINT UNSIGNED NOT NULL COMMENT '入库单ID',
|
||||
event_type VARCHAR(64) NOT NULL COMMENT '事件类型',
|
||||
payload_json JSON NOT NULL COMMENT '事件负载快照',
|
||||
publish_status VARCHAR(16) NOT NULL DEFAULT 'PENDING' COMMENT '发布状态',
|
||||
retry_count INT NOT NULL DEFAULT 0 COMMENT '重试次数',
|
||||
next_retry_at DATETIME(3) NULL COMMENT '下次重试时间',
|
||||
published_at DATETIME(3) NULL COMMENT '发布时间',
|
||||
created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间',
|
||||
PRIMARY KEY (id),
|
||||
KEY idx_inbound_outbox_publish (publish_status, next_retry_at, created_at)
|
||||
) ENGINE=InnoDB COMMENT='入库事务Outbox事件表';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS fl_inbound_idempotency (
|
||||
id BIGINT UNSIGNED NOT NULL COMMENT '入库写操作幂等记录ID',
|
||||
tenant_id BIGINT UNSIGNED NOT NULL COMMENT '租户ID',
|
||||
operation VARCHAR(40) NOT NULL COMMENT '操作类型',
|
||||
operator_id BIGINT UNSIGNED NOT NULL DEFAULT 0 COMMENT '操作者或外部应用ID',
|
||||
inbound_id BIGINT UNSIGNED NOT NULL DEFAULT 0 COMMENT '入库单ID,创建前可为0',
|
||||
idempotency_key VARCHAR(128) NOT NULL COMMENT '幂等键',
|
||||
request_hash CHAR(64) NOT NULL COMMENT '请求内容摘要',
|
||||
status VARCHAR(16) NOT NULL COMMENT '处理状态',
|
||||
result_json JSON NULL COMMENT '成功结果摘要',
|
||||
result_resource_id BIGINT UNSIGNED NULL COMMENT '成功结果资源ID',
|
||||
completed_at DATETIME(3) NULL COMMENT '完成时间',
|
||||
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_inbound_idempotency (tenant_id, operation, operator_id, idempotency_key),
|
||||
KEY idx_inbound_idempotency_created (created_at)
|
||||
) ENGINE=InnoDB COMMENT='第三方测量、审核、费用发送和入库写操作幂等记录';
|
||||
@@ -0,0 +1,13 @@
|
||||
-- 业务块4增量迁移:既有二期库补齐异常放行关口查询索引。
|
||||
-- 可重复执行;新库仍先执行 phase2-inbound-schema.sql。
|
||||
USE baiyue_firstleg;
|
||||
SET NAMES utf8mb4;
|
||||
|
||||
SET @ddl = IF(
|
||||
EXISTS(SELECT 1 FROM information_schema.statistics
|
||||
WHERE table_schema = DATABASE() AND table_name = 'fl_measure_review_record'
|
||||
AND index_name = 'idx_review_exception_release'),
|
||||
'SELECT 1',
|
||||
'ALTER TABLE fl_measure_review_record ADD INDEX idx_review_exception_release (tenant_id, inbound_id, exception_release, reviewed_at)'
|
||||
);
|
||||
PREPARE stmt FROM @ddl; EXECUTE stmt; DEALLOCATE PREPARE stmt;
|
||||
@@ -0,0 +1,30 @@
|
||||
SET NAMES utf8mb4;
|
||||
USE baiyue_firstleg;
|
||||
|
||||
-- 既有二期数据库增量:先确保 phase2-inbound-schema.sql 中的测量和幂等表已存在。
|
||||
CREATE TABLE IF NOT EXISTS fl_third_party_call_log (
|
||||
id BIGINT UNSIGNED NOT NULL COMMENT '第三方调用日志ID(雪花ID)',
|
||||
tenant_id BIGINT UNSIGNED NOT NULL DEFAULT 0 COMMENT '识别出的租户ID,未知应用为0',
|
||||
app_key VARCHAR(128) NULL COMMENT '第三方应用标识',
|
||||
signature_subject VARCHAR(128) NULL COMMENT '签名主体快照',
|
||||
request_method VARCHAR(8) NOT NULL COMMENT 'HTTP方法',
|
||||
request_path VARCHAR(255) NOT NULL COMMENT '签名使用的规范路径',
|
||||
request_timestamp VARCHAR(32) NULL COMMENT '请求头Unix毫秒时间戳原值',
|
||||
nonce VARCHAR(128) NULL COMMENT '请求Nonce',
|
||||
idempotency_key VARCHAR(128) NULL COMMENT 'HTTP幂等键,查询接口为空',
|
||||
idempotency_anchor TINYINT UNSIGNED NULL COMMENT '签名通过后首个请求为1,重复调用为空',
|
||||
signature_value VARCHAR(128) NULL COMMENT '第三方签名原值',
|
||||
request_hash CHAR(64) NOT NULL COMMENT '原始请求体SHA-256小写十六进制',
|
||||
raw_payload LONGTEXT NOT NULL COMMENT '未经重新序列化的UTF-8原始请求体',
|
||||
processing_status VARCHAR(16) NOT NULL COMMENT 'PROCESSING、ACCEPTED或REJECTED',
|
||||
result_code VARCHAR(32) NULL COMMENT '统一响应业务码',
|
||||
result_message VARCHAR(1000) NULL COMMENT '处理结果或失败原因',
|
||||
result_json JSON NULL COMMENT '首次成功结果快照',
|
||||
requested_at DATETIME(3) NOT NULL COMMENT '服务端接收时间',
|
||||
processed_at DATETIME(3) NULL COMMENT '处理完成时间',
|
||||
PRIMARY KEY (id),
|
||||
KEY idx_third_call_app_time (tenant_id, app_key, requested_at),
|
||||
KEY idx_third_call_idempotency (tenant_id, app_key, idempotency_key),
|
||||
KEY idx_third_call_nonce (tenant_id, app_key, nonce),
|
||||
UNIQUE KEY uk_third_call_idempotency_owner (tenant_id, app_key, idempotency_key, idempotency_anchor)
|
||||
) ENGINE=InnoDB COMMENT='第三方测量开放接口原始请求、签名主体和处理结果留档';
|
||||
@@ -0,0 +1,138 @@
|
||||
openapi: 3.0.3
|
||||
info:
|
||||
title: 柏悦二期 FBA 计费 API
|
||||
version: 2.0.0
|
||||
description: 业务成功和失败均使用 HTTP 200;仅响应体 code 为字符串 "200" 时表示成功。
|
||||
security:
|
||||
- bearerAuth: []
|
||||
paths:
|
||||
/api/platform/v1/fba-pricing/customer-rules:
|
||||
get:
|
||||
summary: 查询客户计费规则版本
|
||||
description: 需要 firstleg:fba-pricing:rule:view 权限
|
||||
parameters: [{$ref: '#/components/parameters/TenantId'}]
|
||||
responses: {'200': {description: 成功或业务失败}, '403': {description: 无权限}}
|
||||
/api/platform/v1/fba-pricing/customer-rules/versions:
|
||||
post:
|
||||
summary: 新建客户计费规则版本
|
||||
description: 版本内容不可原地修改;有效期使用 [effectiveFrom,effectiveTo) 半开区间。
|
||||
parameters: [{$ref: '#/components/parameters/TenantId'}]
|
||||
requestBody: {required: true, content: {application/json: {schema: {$ref: '#/components/schemas/CustomerRuleVersionRequest'}}}}
|
||||
responses: {'200': {description: 成功或业务失败}, '403': {description: 无权限}}
|
||||
/api/platform/v1/fba-pricing/customer-rules/{id}:
|
||||
get:
|
||||
summary: 查询客户计费规则版本详情
|
||||
parameters: [{$ref: '#/components/parameters/TenantId'}, {$ref: '#/components/parameters/Id'}]
|
||||
responses: {'200': {description: 成功或业务失败}, '403': {description: 无权限}}
|
||||
delete:
|
||||
summary: 停用客户计费规则版本
|
||||
parameters: [{$ref: '#/components/parameters/TenantId'}, {$ref: '#/components/parameters/Id'}]
|
||||
responses: {'200': {description: 成功或业务失败}, '403': {description: 无权限}}
|
||||
/api/platform/v1/fba-pricing/carrier-rates:
|
||||
get:
|
||||
summary: 查询船司 FBA 价格版本
|
||||
description: 需要 firstleg:fba-pricing:rate:view 权限
|
||||
parameters: [{$ref: '#/components/parameters/TenantId'}]
|
||||
responses: {'200': {description: 成功或业务失败}, '403': {description: 无权限}}
|
||||
/api/platform/v1/fba-pricing/carrier-rates/versions:
|
||||
post:
|
||||
summary: 新建船司 FBA 价格版本
|
||||
parameters: [{$ref: '#/components/parameters/TenantId'}]
|
||||
requestBody: {required: true, content: {application/json: {schema: {$ref: '#/components/schemas/CarrierRateVersionRequest'}}}}
|
||||
responses: {'200': {description: 成功或业务失败}, '403': {description: 无权限}}
|
||||
/api/platform/v1/fba-pricing/carrier-rates/{id}:
|
||||
get:
|
||||
summary: 查询船司 FBA 价格版本详情
|
||||
parameters: [{$ref: '#/components/parameters/TenantId'}, {$ref: '#/components/parameters/Id'}]
|
||||
responses: {'200': {description: 成功或业务失败}, '403': {description: 无权限}}
|
||||
delete:
|
||||
summary: 停用船司 FBA 价格版本
|
||||
parameters: [{$ref: '#/components/parameters/TenantId'}, {$ref: '#/components/parameters/Id'}]
|
||||
responses: {'200': {description: 成功或业务失败}, '403': {description: 无权限}}
|
||||
/api/platform/v1/inbounds/{inboundId}/fees/calculate:
|
||||
post:
|
||||
summary: 按审核通过测量快照试算 FBA 费用
|
||||
description: 精确匹配唯一客户规则和唯一船司价格;需要 firstleg:fba-pricing:calculate 权限。
|
||||
parameters: [{$ref: '#/components/parameters/TenantId'}, {$ref: '#/components/parameters/InboundId'}, {$ref: '#/components/parameters/IdempotencyKey'}]
|
||||
requestBody: {content: {application/json: {schema: {$ref: '#/components/schemas/CalculateRequest'}}}}
|
||||
responses: {'200': {description: 成功或业务失败}, '403': {description: 无权限}}
|
||||
/api/platform/v1/inbounds/{inboundId}/fees/confirm:
|
||||
post:
|
||||
summary: 确认最新费用快照
|
||||
parameters: [{$ref: '#/components/parameters/TenantId'}, {$ref: '#/components/parameters/InboundId'}, {$ref: '#/components/parameters/IdempotencyKey'}]
|
||||
responses: {'200': {description: 成功或业务失败}, '403': {description: 无权限}}
|
||||
/api/platform/v1/inbounds/{inboundId}/fees/send:
|
||||
post:
|
||||
summary: 手工恢复发送费用快照
|
||||
description: 仅作为异常恢复接口;正常业务由客服测量审核通过后自动计费、发布并完成入库。
|
||||
parameters: [{$ref: '#/components/parameters/TenantId'}, {$ref: '#/components/parameters/InboundId'}, {$ref: '#/components/parameters/IdempotencyKey'}]
|
||||
responses: {'200': {description: 成功或业务失败}, '403': {description: 无权限}}
|
||||
/api/platform/v1/inbounds/{inboundId}/fees/latest:
|
||||
get:
|
||||
summary: 查询最新费用快照
|
||||
parameters: [{$ref: '#/components/parameters/TenantId'}, {$ref: '#/components/parameters/InboundId'}]
|
||||
responses: {'200': {description: 成功或业务失败}, '403': {description: 无权限}}
|
||||
/api/platform/v1/inbounds/{inboundId}/fees/published:
|
||||
put:
|
||||
summary: 调整已发布费用
|
||||
description: 需要 firstleg:fba-pricing:adjust 权限;生成新 SENT 版本并将旧版本标记 SUPERSEDED,不回退 INBOUNDED 状态。
|
||||
parameters: [{$ref: '#/components/parameters/TenantId'}, {$ref: '#/components/parameters/InboundId'}, {$ref: '#/components/parameters/IdempotencyKey'}]
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema: {$ref: '#/components/schemas/AdjustFeeRequest'}
|
||||
responses: {'200': {description: 成功或业务失败}, '403': {description: 无调整权限}}
|
||||
components:
|
||||
securitySchemes:
|
||||
bearerAuth: {type: http, scheme: bearer, bearerFormat: JWT}
|
||||
parameters:
|
||||
TenantId: {name: tenantId, in: query, required: true, schema: {type: integer, format: int64, minimum: 1}}
|
||||
Id: {name: id, in: path, required: true, schema: {type: integer, format: int64}}
|
||||
InboundId: {name: inboundId, in: path, required: true, schema: {type: integer, format: int64}}
|
||||
IdempotencyKey: {name: Idempotency-Key, in: header, required: true, schema: {type: string, maxLength: 128}}
|
||||
schemas:
|
||||
AdjustFeeRequest:
|
||||
type: object
|
||||
required: [subtotalAmount, additionalAmount, reason]
|
||||
properties:
|
||||
subtotalAmount: {type: number, minimum: 0, multipleOf: 0.01}
|
||||
additionalAmount: {type: number, minimum: 0, multipleOf: 0.01}
|
||||
reason: {type: string, minLength: 1, maxLength: 500}
|
||||
CalculateRequest:
|
||||
type: object
|
||||
properties: {pricingAt: {type: string, format: date-time, description: 缺省为服务端当前时间}}
|
||||
CustomerRuleVersionRequest:
|
||||
type: object
|
||||
required: [ruleCode, customerId, customerName, businessType, chargeMode, taxMode, conversionFactor, roundingScale, roundingMode, currency, effectiveFrom]
|
||||
properties:
|
||||
ruleCode: {type: string, maxLength: 50}
|
||||
customerId: {type: integer, format: int64}
|
||||
customerName: {type: string, maxLength: 128}
|
||||
businessType: {type: string, maxLength: 32}
|
||||
chargeMode: {type: string, enum: [KG, CBM]}
|
||||
taxMode: {type: string, enum: [TAX_INCLUDED, TAX_EXCLUDED]}
|
||||
conversionFactor: {type: number, exclusiveMinimum: 0, example: 167}
|
||||
roundingScale: {type: integer, minimum: 0, maximum: 4}
|
||||
roundingMode: {type: string, enum: [UP, DOWN, CEILING, FLOOR, HALF_UP, HALF_DOWN, HALF_EVEN]}
|
||||
currency: {type: string, pattern: '^[A-Z]{3}$'}
|
||||
effectiveFrom: {type: string, format: date-time}
|
||||
effectiveTo: {type: string, format: date-time, nullable: true}
|
||||
CarrierRateVersionRequest:
|
||||
type: object
|
||||
required: [rateCode, originWarehouseId, originWarehouseName, businessType, channelCode, carrierId, carrierName, destinationCode, chargeUnit, unitPrice, currency, additionalFee, effectiveFrom]
|
||||
properties:
|
||||
rateCode: {type: string, maxLength: 50}
|
||||
originWarehouseId: {type: integer, format: int64}
|
||||
originWarehouseName: {type: string}
|
||||
businessType: {type: string}
|
||||
channelCode: {type: string}
|
||||
carrierId: {type: integer, format: int64}
|
||||
carrierName: {type: string}
|
||||
destinationCode: {type: string}
|
||||
chargeUnit: {type: string, enum: [KG, CBM]}
|
||||
unitPrice: {type: number, exclusiveMinimum: 0}
|
||||
currency: {type: string, pattern: '^[A-Z]{3}$'}
|
||||
additionalFee: {type: number, minimum: 0}
|
||||
effectiveFrom: {type: string, format: date-time}
|
||||
effectiveTo: {type: string, format: date-time, nullable: true}
|
||||
@@ -67,13 +67,160 @@ paths:
|
||||
responses:
|
||||
'200': {description: 成功或业务失败,按响应体 code 判断}
|
||||
'403': {description: 无分配权限}
|
||||
/openapi/v1/inbound-measurements:
|
||||
post:
|
||||
summary: 提交第三方长宽高测量结果
|
||||
description: >-
|
||||
只写 fl_third_party_call_log、fl_inbound_measurement、fl_inbound_measurement_item
|
||||
和 HTTP 幂等结果,不审核、不计费、不入库,也不改变入库单状态。
|
||||
签名串依次为 METHOD、原始 PATH、X-Timestamp、X-Nonce、Idempotency-Key、
|
||||
原始 UTF-8 body 的 SHA-256 小写十六进制,六部分使用 LF(\n)连接且末尾不追加换行。
|
||||
三层语义:Nonce 防短时重放;Idempotency-Key 标识一次 HTTP 写操作;
|
||||
appKey + eventNo 标识第三方业务事件。
|
||||
security:
|
||||
- measurementAppKey: []
|
||||
measurementTimestamp: []
|
||||
measurementNonce: []
|
||||
measurementSignature: []
|
||||
parameters:
|
||||
- {$ref: '#/components/parameters/XTimestamp'}
|
||||
- {$ref: '#/components/parameters/XNonce'}
|
||||
- {$ref: '#/components/parameters/IdempotencyKey'}
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema: {$ref: '#/components/schemas/InboundMeasurementCallbackRequest'}
|
||||
responses:
|
||||
'200': {description: 成功或业务失败,按响应体字符串 code 判断;非法签名返回 A0401}
|
||||
'413': {description: 请求体超过网关限制}
|
||||
'415': {description: Content-Type 不支持}
|
||||
/openapi/v1/inbound-measurements/events/{eventNo}:
|
||||
get:
|
||||
summary: 查询第三方测量事件状态
|
||||
description: GET 签名串的 Idempotency-Key 行为空字符串,body 摘要为空字节 SHA-256。
|
||||
security:
|
||||
- measurementAppKey: []
|
||||
measurementTimestamp: []
|
||||
measurementNonce: []
|
||||
measurementSignature: []
|
||||
parameters:
|
||||
- name: eventNo
|
||||
in: path
|
||||
required: true
|
||||
schema: {type: string, pattern: '^[A-Za-z0-9._:-]{1,128}$'}
|
||||
- {$ref: '#/components/parameters/XTimestamp'}
|
||||
- {$ref: '#/components/parameters/XNonce'}
|
||||
responses:
|
||||
'200': {description: 成功或业务失败,按响应体字符串 code 判断}
|
||||
/api/platform/inbounds:
|
||||
get:
|
||||
summary: 分页查询入库单
|
||||
description: 需要 platform:firstleg:inbound:list 权限;仅使用 V2 四个页签
|
||||
parameters:
|
||||
- {name: tenantId, in: query, required: true, schema: {type: string, pattern: '^[1-9][0-9]*$'}}
|
||||
- {name: tab, in: query, schema: {type: string, enum: [WAIT_MEASURE, WAIT_REVIEW, WAIT_FEE_SEND, INBOUNDED]}}
|
||||
responses:
|
||||
'200': {description: 成功或业务失败,按响应体 code 判断}
|
||||
'403': {description: 无查询权限}
|
||||
/api/platform/inbounds/{inboundId}:
|
||||
get:
|
||||
summary: 查询入库单详情
|
||||
description: 需要 platform:firstleg:inbound:view 权限
|
||||
parameters:
|
||||
- {name: tenantId, in: query, required: true, schema: {type: string, pattern: '^[1-9][0-9]*$'}}
|
||||
- {name: inboundId, in: path, required: true, schema: {type: string, pattern: '^[1-9][0-9]*$'}}
|
||||
responses:
|
||||
'200': {description: 成功或业务失败,按响应体 code 判断}
|
||||
'403': {description: 无查看权限}
|
||||
/api/platform/v1/inbounds/{inboundId}/measurements/approve:
|
||||
post:
|
||||
summary: 审核通过测量
|
||||
description: 需要 firstleg:inbound:measurement-review 权限;客服审核通过后自动计费、发布费用给客户并完成入库,客户无需确认。
|
||||
parameters:
|
||||
- {name: inboundId, in: path, required: true, schema: {type: string, pattern: '^[1-9][0-9]*$'}}
|
||||
- {name: Idempotency-Key, in: header, required: true, schema: {type: string}}
|
||||
responses:
|
||||
'200': {description: 成功或业务失败}
|
||||
/api/platform/v1/inbounds/{inboundId}/measurements/reject:
|
||||
post:
|
||||
summary: 驳回测量
|
||||
description: 需要 firstleg:inbound:measurement-review 权限;只退回测量数据修改,已确认托盘和库位占用保持不动。
|
||||
parameters:
|
||||
- {name: inboundId, in: path, required: true, schema: {type: string, pattern: '^[1-9][0-9]*$'}}
|
||||
- {name: Idempotency-Key, in: header, required: true, schema: {type: string}}
|
||||
responses:
|
||||
'200': {description: 成功或业务失败}
|
||||
/api/platform/v1/inbounds/{inboundId}/measurements/submit:
|
||||
post:
|
||||
summary: 提交测量完成
|
||||
description: 测量提交后立即按总体积拆分普通托盘、分配并确认占用库位,再进入客服待审核;无普通空闲位时共享 A0。
|
||||
parameters:
|
||||
- {name: tenantId, in: query, required: true, schema: {type: string, pattern: '^[1-9][0-9]*$'}}
|
||||
- {name: inboundId, in: path, required: true, schema: {type: string, pattern: '^[1-9][0-9]*$'}}
|
||||
responses:
|
||||
'200': {description: 成功时 processStatus=MEASURE_PENDING、measureReviewStatus=PENDING,且库位已 OCCUPIED}
|
||||
'403': {description: 无测量提交权限}
|
||||
/api/merchant/v1/first-leg/orders/{orderId}/inbound-billing:
|
||||
get:
|
||||
summary: 客户查询已完成入库结果和最新已发布费用
|
||||
description: 需要 merchant:order:view 权限;客户只读查看,不需要确认费用,未完成客服审核发布时不可见。
|
||||
parameters:
|
||||
- {name: orderId, in: path, required: true, schema: {type: string, pattern: '^[1-9][0-9]*$'}}
|
||||
responses:
|
||||
'200': {description: 成功或业务失败,按响应体 code 判断}
|
||||
'403': {description: 非本租户或无订单查看权限}
|
||||
/api/platform/v1/inbounds/{inboundId}/measurements/exception-release:
|
||||
post:
|
||||
summary: 测量异常放行
|
||||
description: 需要 firstleg:inbound:exception-release 权限
|
||||
parameters:
|
||||
- {name: inboundId, in: path, required: true, schema: {type: string, pattern: '^[1-9][0-9]*$'}}
|
||||
- {name: Idempotency-Key, in: header, required: true, schema: {type: string}}
|
||||
responses:
|
||||
'200': {description: 成功或业务失败}
|
||||
components:
|
||||
securitySchemes:
|
||||
bearerAuth:
|
||||
type: http
|
||||
scheme: bearer
|
||||
bearerFormat: JWT
|
||||
measurementAppKey:
|
||||
type: apiKey
|
||||
in: header
|
||||
name: X-App-Key
|
||||
description: 分配给测量服务商的应用标识
|
||||
measurementTimestamp:
|
||||
type: apiKey
|
||||
in: header
|
||||
name: X-Timestamp
|
||||
description: Unix 毫秒时间戳
|
||||
measurementNonce:
|
||||
type: apiKey
|
||||
in: header
|
||||
name: X-Nonce
|
||||
description: 每次请求唯一的随机串
|
||||
measurementSignature:
|
||||
type: apiKey
|
||||
in: header
|
||||
name: X-Signature
|
||||
description: HMAC-SHA256 小写十六进制签名
|
||||
parameters:
|
||||
XTimestamp:
|
||||
name: X-Timestamp
|
||||
in: header
|
||||
required: true
|
||||
schema: {type: string, pattern: '^[0-9]{13}$', example: '1785551400000'}
|
||||
XNonce:
|
||||
name: X-Nonce
|
||||
in: header
|
||||
required: true
|
||||
schema: {type: string, minLength: 1, maxLength: 128}
|
||||
IdempotencyKey:
|
||||
name: Idempotency-Key
|
||||
in: header
|
||||
required: true
|
||||
schema: {type: string, minLength: 1, maxLength: 128}
|
||||
TenantId:
|
||||
name: tenantId
|
||||
in: query
|
||||
@@ -93,6 +240,39 @@ components:
|
||||
in: query
|
||||
schema: {type: integer, format: int64, minimum: 1, maximum: 200, default: 20}
|
||||
schemas:
|
||||
InboundMeasurementCallbackRequest:
|
||||
type: object
|
||||
required: [eventNo, warehouseCode, inboundCode, deviceCode, measuredAt, items]
|
||||
properties:
|
||||
eventNo: {type: string, maxLength: 128, pattern: '^[A-Za-z0-9._:-]+$', example: M202608010001}
|
||||
warehouseCode: {type: string, maxLength: 50, example: CN-YW-01}
|
||||
inboundCode: {type: string, maxLength: 40, example: RK202608010001}
|
||||
deviceCode: {type: string, maxLength: 64, example: DEVICE-01}
|
||||
measuredAt: {type: string, format: date-time, example: '2026-08-01T10:30:00+08:00'}
|
||||
items:
|
||||
type: array
|
||||
minItems: 1
|
||||
maxItems: 500
|
||||
items: {$ref: '#/components/schemas/InboundMeasurementItem'}
|
||||
InboundMeasurementItem:
|
||||
type: object
|
||||
required: [itemNo, boxSpecification, lengthCm, widthCm, heightCm, quantity]
|
||||
properties:
|
||||
itemNo: {type: string, maxLength: 32, example: '001'}
|
||||
boxSpecification: {type: string, maxLength: 64, example: '61.5x42x42cm', description: 入库单绑定的箱规明细}
|
||||
lengthCm: {type: number, exclusiveMinimum: true, minimum: 0, example: 50.20}
|
||||
widthCm: {type: number, exclusiveMinimum: true, minimum: 0, example: 40.10}
|
||||
heightCm: {type: number, exclusiveMinimum: true, minimum: 0, example: 30.00}
|
||||
quantity: {type: integer, minimum: 1, maximum: 1000000, example: 5}
|
||||
sourceImageUrl: {type: string, maxLength: 2048, nullable: true, description: 仅随原始报文留档,不直接写文件中心}
|
||||
InboundMeasurementEventResponse:
|
||||
type: object
|
||||
properties:
|
||||
eventNo: {type: string}
|
||||
inboundCode: {type: string}
|
||||
accepted: {type: boolean}
|
||||
status: {type: string, enum: [RECEIVED]}
|
||||
receivedAt: {type: string, format: date-time}
|
||||
AssignRequest:
|
||||
type: object
|
||||
required: [assigneeId, assigneeName]
|
||||
|
||||
Reference in New Issue
Block a user