# Conflicts:
#	scripts/admin-test-env-modules/orders.mjs
#	scripts/admin-test-env-modules/phase3-container-loading.mjs
This commit is contained in:
2026-08-20 18:24:23 +08:00
57 changed files with 1135 additions and 95 deletions
@@ -74,6 +74,11 @@ CREATE TABLE IF NOT EXISTS fl_container_fee_detail (
supplier_id BIGINT UNSIGNED NULL COMMENT '应付Warehouse供应商ID快照;应收为空',
supplier_name VARCHAR(200) NULL COMMENT '应付Warehouse供应商名称快照;应收为空',
supplier_category VARCHAR(16) NULL COMMENT '费用项目供应商类别约束快照;为空表示任意启用供应商',
settlement_mode VARCHAR(16) NULL COMMENT '仅PAYABLE:ON_ACCOUNT账期应付、DIRECT_PAID业务已付;RECEIVABLE为空',
paid_at DATETIME(3) NULL COMMENT 'DIRECT_PAID业务已付时间',
payment_method VARCHAR(32) NULL COMMENT 'DIRECT_PAID付款方式',
payment_reference_no VARCHAR(128) NULL COMMENT 'DIRECT_PAID付款流水号',
payment_voucher_file_ids JSON NULL COMMENT 'DIRECT_PAID付款凭证File ID数组',
business_date DATE NOT NULL COMMENT '费用业务日期',
amount DECIMAL(18,2) NOT NULL COMMENT 'CNY费用金额',
currency CHAR(3) NOT NULL DEFAULT 'CNY' COMMENT '币种,首期固定CNY',
@@ -96,6 +101,15 @@ CREATE TABLE IF NOT EXISTS fl_container_fee_detail (
CONSTRAINT chk_container_fee_currency CHECK (currency = 'CNY'),
CONSTRAINT chk_container_fee_amount CHECK (amount >= 0),
CONSTRAINT chk_container_fee_review CHECK (review_status IN ('PENDING', 'APPROVED', 'REJECTED')),
CONSTRAINT chk_container_fee_settlement CHECK (
(direction='RECEIVABLE' AND settlement_mode IS NULL AND paid_at IS NULL AND payment_method IS NULL
AND payment_reference_no IS NULL AND payment_voucher_file_ids IS NULL)
OR (direction='PAYABLE' AND settlement_mode='ON_ACCOUNT' AND paid_at IS NULL AND payment_method IS NULL
AND payment_reference_no IS NULL AND payment_voucher_file_ids IS NULL)
OR (direction='PAYABLE' AND settlement_mode='DIRECT_PAID' AND paid_at IS NOT NULL
AND payment_method IN ('ONLINE','BANK_TRANSFER','CASH','OTHER')
AND (payment_reference_no IS NOT NULL OR JSON_LENGTH(payment_voucher_file_ids)>0))
),
CONSTRAINT chk_container_fee_source CHECK (source_status IN ('ACTIVE', 'VOIDED'))
) ENGINE=InnoDB COMMENT='柜次级人工应收应付费用来源;审核通过后自动同步Finance';
@@ -114,6 +128,11 @@ CREATE TABLE IF NOT EXISTS fl_container_fee_source_snapshot (
supplier_id BIGINT UNSIGNED NULL COMMENT 'Warehouse供应商ID快照',
supplier_name VARCHAR(200) NULL COMMENT 'Warehouse供应商名称快照',
supplier_category VARCHAR(16) NULL COMMENT '费用项目供应商类别约束快照;为空表示任意启用供应商',
settlement_mode VARCHAR(16) NULL COMMENT '仅PAYABLE:ON_ACCOUNT账期应付、DIRECT_PAID业务已付;RECEIVABLE为空',
paid_at DATETIME(3) NULL COMMENT 'DIRECT_PAID业务已付时间',
payment_method VARCHAR(32) NULL COMMENT 'DIRECT_PAID付款方式',
payment_reference_no VARCHAR(128) NULL COMMENT 'DIRECT_PAID付款流水号',
payment_voucher_file_ids JSON NULL COMMENT 'DIRECT_PAID付款凭证File ID数组',
business_date DATE NOT NULL COMMENT '费用业务日期',
amount DECIMAL(18,2) NOT NULL COMMENT 'CNY费用金额',
currency CHAR(3) NOT NULL DEFAULT 'CNY' COMMENT '币种,首期固定CNY',
@@ -157,12 +176,42 @@ CALL firstleg_finance_add_column('fl_container_fee_detail', 'supplier_name',
"VARCHAR(200) NULL COMMENT '应付Warehouse供应商名称快照;应收为空' AFTER supplier_id");
CALL firstleg_finance_add_column('fl_container_fee_detail', 'supplier_category',
"VARCHAR(16) NULL COMMENT '费用项目供应商类别约束快照;为空表示任意启用供应商' AFTER supplier_name");
CALL firstleg_finance_add_column('fl_container_fee_detail', 'settlement_mode',
"VARCHAR(16) NULL COMMENT '仅PAYABLE:ON_ACCOUNT或DIRECT_PAID' AFTER supplier_category");
CALL firstleg_finance_add_column('fl_container_fee_detail', 'paid_at',
"DATETIME(3) NULL COMMENT 'DIRECT_PAID业务已付时间' AFTER settlement_mode");
CALL firstleg_finance_add_column('fl_container_fee_detail', 'payment_method',
"VARCHAR(32) NULL COMMENT 'DIRECT_PAID付款方式' AFTER paid_at");
CALL firstleg_finance_add_column('fl_container_fee_detail', 'payment_reference_no',
"VARCHAR(128) NULL COMMENT 'DIRECT_PAID付款流水号' AFTER payment_method");
CALL firstleg_finance_add_column('fl_container_fee_detail', 'payment_voucher_file_ids',
"JSON NULL COMMENT 'DIRECT_PAID付款凭证File ID数组' AFTER payment_reference_no");
CALL firstleg_finance_add_column('fl_container_fee_source_snapshot', 'settlement_mode',
"VARCHAR(16) NULL COMMENT '仅PAYABLE:ON_ACCOUNT或DIRECT_PAID' AFTER supplier_category");
CALL firstleg_finance_add_column('fl_container_fee_source_snapshot', 'paid_at',
"DATETIME(3) NULL COMMENT 'DIRECT_PAID业务已付时间' AFTER settlement_mode");
CALL firstleg_finance_add_column('fl_container_fee_source_snapshot', 'payment_method',
"VARCHAR(32) NULL COMMENT 'DIRECT_PAID付款方式' AFTER paid_at");
CALL firstleg_finance_add_column('fl_container_fee_source_snapshot', 'payment_reference_no',
"VARCHAR(128) NULL COMMENT 'DIRECT_PAID付款流水号' AFTER payment_method");
CALL firstleg_finance_add_column('fl_container_fee_source_snapshot', 'payment_voucher_file_ids',
"JSON NULL COMMENT 'DIRECT_PAID付款凭证File ID数组' AFTER payment_reference_no");
CALL firstleg_finance_add_column('fl_inbound_fee_detail', 'supplier_id',
"BIGINT UNSIGNED NULL COMMENT '应付Warehouse供应商ID快照;应收为空' AFTER direction");
CALL firstleg_finance_add_column('fl_inbound_fee_detail', 'supplier_name',
"VARCHAR(200) NULL COMMENT '应付Warehouse供应商名称快照;应收为空' AFTER supplier_id");
CALL firstleg_finance_add_column('fl_inbound_fee_detail', 'supplier_category',
"VARCHAR(16) NULL COMMENT '费用项目供应商类别约束快照;为空表示任意启用供应商' AFTER supplier_name");
CALL firstleg_finance_add_column('fl_inbound_fee_detail', 'settlement_mode',
"VARCHAR(16) NULL COMMENT '仅PAYABLE:ON_ACCOUNT或DIRECT_PAID' AFTER supplier_category");
CALL firstleg_finance_add_column('fl_inbound_fee_detail', 'paid_at',
"DATETIME(3) NULL COMMENT 'DIRECT_PAID业务已付时间' AFTER settlement_mode");
CALL firstleg_finance_add_column('fl_inbound_fee_detail', 'payment_method',
"VARCHAR(32) NULL COMMENT 'DIRECT_PAID付款方式' AFTER paid_at");
CALL firstleg_finance_add_column('fl_inbound_fee_detail', 'payment_reference_no',
"VARCHAR(128) NULL COMMENT 'DIRECT_PAID付款流水号' AFTER payment_method");
CALL firstleg_finance_add_column('fl_inbound_fee_detail', 'payment_voucher_file_ids',
"JSON NULL COMMENT 'DIRECT_PAID付款凭证File ID数组' AFTER payment_reference_no");
DROP PROCEDURE IF EXISTS firstleg_finance_add_column;
DROP PROCEDURE IF EXISTS firstleg_finance_assert_schema;
@@ -185,12 +234,22 @@ BEGIN
END IF;
IF (SELECT COUNT(*) FROM information_schema.columns
WHERE table_schema = DATABASE() AND table_name = 'fl_container_fee_detail'
AND column_name IN ('supplier_id', 'supplier_name', 'supplier_category')) <> 3 THEN
AND column_name IN ('supplier_id', 'supplier_name', 'supplier_category', 'settlement_mode',
'paid_at', 'payment_method', 'payment_reference_no',
'payment_voucher_file_ids')) <> 8 THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Firstleg Finance迁移失败:柜次费用供应商快照字段不完整';
END IF;
IF (SELECT COUNT(*) FROM information_schema.columns
WHERE table_schema = DATABASE() AND table_name = 'fl_container_fee_source_snapshot'
AND column_name IN ('settlement_mode', 'paid_at', 'payment_method',
'payment_reference_no', 'payment_voucher_file_ids')) <> 5 THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Firstleg Finance迁移失败:柜次费用已付版本快照字段不完整';
END IF;
IF (SELECT COUNT(*) FROM information_schema.columns
WHERE table_schema = DATABASE() AND table_name = 'fl_inbound_fee_detail'
AND column_name IN ('supplier_id', 'supplier_name', 'supplier_category')) <> 3 THEN
AND column_name IN ('supplier_id', 'supplier_name', 'supplier_category', 'settlement_mode',
'paid_at', 'payment_method', 'payment_reference_no',
'payment_voucher_file_ids')) <> 8 THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Firstleg Finance迁移失败:入库费用供应商快照字段不完整';
END IF;
END$$
@@ -40,6 +40,11 @@ CREATE TABLE IF NOT EXISTS fl_inbound_fee_detail (
supplier_id BIGINT UNSIGNED NULL COMMENT '应付Warehouse供应商ID快照;应收为空',
supplier_name VARCHAR(200) NULL COMMENT '应付Warehouse供应商名称快照;应收为空',
supplier_category VARCHAR(16) NULL COMMENT '费用项目供应商类别快照;应收为空',
settlement_mode VARCHAR(16) NULL COMMENT '仅PAYABLE:ON_ACCOUNT账期应付、DIRECT_PAID业务已付;RECEIVABLE为空',
paid_at DATETIME(3) NULL COMMENT 'DIRECT_PAID业务已付时间',
payment_method VARCHAR(32) NULL COMMENT 'DIRECT_PAID付款方式',
payment_reference_no VARCHAR(128) NULL COMMENT 'DIRECT_PAID付款流水号',
payment_voucher_file_ids JSON NULL COMMENT 'DIRECT_PAID付款凭证File ID数组',
business_date DATE NOT NULL COMMENT '业务发生日',
fee_category_snapshot VARCHAR(64) NOT NULL COMMENT '费用分类快照',
trade_scope_snapshot VARCHAR(20) NOT NULL COMMENT '国内国际快照',
@@ -73,6 +78,15 @@ CREATE TABLE IF NOT EXISTS fl_inbound_fee_detail (
KEY idx_inbound_fee_detail (tenant_id, inbound_id, business_date, deleted),
KEY idx_inbound_fee_review (tenant_id, review_status, business_date, deleted),
KEY idx_inbound_fee_item (tenant_id, fee_item_id, deleted),
CONSTRAINT chk_inbound_fee_settlement CHECK (
(direction='RECEIVABLE' AND settlement_mode IS NULL AND paid_at IS NULL AND payment_method IS NULL
AND payment_reference_no IS NULL AND payment_voucher_file_ids IS NULL)
OR (direction='PAYABLE' AND settlement_mode='ON_ACCOUNT' AND paid_at IS NULL AND payment_method IS NULL
AND payment_reference_no IS NULL AND payment_voucher_file_ids IS NULL)
OR (direction='PAYABLE' AND settlement_mode='DIRECT_PAID' AND paid_at IS NOT NULL
AND payment_method IN ('ONLINE','BANK_TRANSFER','CASH','OTHER')
AND (payment_reference_no IS NOT NULL OR JSON_LENGTH(payment_voucher_file_ids)>0))
),
CONSTRAINT fk_inbound_fee_detail_order FOREIGN KEY (inbound_id) REFERENCES fl_inbound_order (id),
CONSTRAINT fk_inbound_fee_detail_item FOREIGN KEY (fee_item_id) REFERENCES fl_fee_item (id)
) ENGINE=InnoDB COMMENT='入库单应收应付费用明细';
@@ -304,6 +304,11 @@ components:
currency: {type: string, pattern: '^[A-Z]{3}$'}
amount: {type: number, minimum: 0}
supplierId: {type: string, nullable: true}
settlementMode: {type: string, enum: [ON_ACCOUNT, DIRECT_PAID], nullable: true, description: 仅PAYABLE必填;ON_ACCOUNT账期应付,DIRECT_PAID业务已付}
paidAt: {type: string, format: date-time, nullable: true, description: DIRECT_PAID必填;ON_ACCOUNT与RECEIVABLE为空}
paymentMethod: {type: string, enum: [ONLINE, BANK_TRANSFER, CASH, OTHER], nullable: true, description: DIRECT_PAID必填}
paymentReferenceNo: {type: string, maxLength: 128, nullable: true}
paymentVoucherFileIds: {type: array, maxItems: 20, nullable: true, items: {type: string, pattern: '^[1-9][0-9]*$'}, description: DIRECT_PAID时与paymentReferenceNo至少一项;File按当前客户失败关闭校验}
remark: {type: string, maxLength: 500, nullable: true}
InboundFeeDetailVersionRequest:
type: object
@@ -331,6 +336,11 @@ components:
supplierId: {type: string, nullable: true}
supplierName: {type: string, nullable: true, readOnly: true}
supplierCategory: {type: string, enum: [BOOKING, CUSTOMS, TRUCKING, CERTIFICATE], nullable: true, description: 费用项目供应商类别约束快照;为空表示仅要求供应商ACTIVE}
settlementMode: {type: string, enum: [ON_ACCOUNT, DIRECT_PAID], nullable: true}
paidAt: {type: string, format: date-time, nullable: true}
paymentMethod: {type: string, enum: [ONLINE, BANK_TRANSFER, CASH, OTHER], nullable: true}
paymentReferenceNo: {type: string, nullable: true}
paymentVoucherFileIds: {type: array, nullable: true, items: {type: string}}
businessDate: {type: string, format: date}
customerId: {type: string, nullable: true}
customerName: {type: string, nullable: true}
@@ -881,7 +881,7 @@ paths:
summary: 调整已审核柜次费用的日期和金额
description: >-
仅 ACTIVE、APPROVED 且 sourceVersion 匹配的费用可调整。成功后 sourceVersion 加一并重新进入
PENDING;费用方向、费用项目、供应商、币种和备注保持原快照。业务字段需要变化时,
PENDING;费用方向、费用项目、供应商、结算方式、已付快照、币种和备注保持原快照。业务字段需要变化时,
必须作废原费用并新增。同一 expectedSourceVersion、businessDate、amount 的原样重试只读返回已生成的
PENDING 版本;旧版本异参、已作废或非已审核状态返回 A0409 且零写入。
parameters:
@@ -1887,6 +1887,11 @@ components:
supplierId: {type: integer, format: int64, nullable: true}
supplierName: {type: string, nullable: true}
supplierCategory: {type: string, enum: [BOOKING, CUSTOMS, TRUCKING, CERTIFICATE], nullable: true, description: PAYABLE供应商类别约束;为空时仅要求供应商ACTIVE}
settlementMode: {type: string, enum: [ON_ACCOUNT, DIRECT_PAID], nullable: true, description: 仅PAYABLE;ON_ACCOUNT可进入AP,DIRECT_PAID仅计成本且禁止进入AP}
paidAt: {type: string, format: date-time, nullable: true}
paymentMethod: {type: string, enum: [ONLINE, BANK_TRANSFER, CASH, OTHER], nullable: true}
paymentReferenceNo: {type: string, nullable: true}
paymentVoucherFileIds: {type: array, nullable: true, items: {type: integer, format: int64}}
feeItemId: {type: integer, format: int64, nullable: true}
feeItemCode: {type: string, nullable: true}
feeItemName: {type: string}