统一财务费用来源入池链路

This commit is contained in:
2026-09-09 16:39:20 +08:00
parent 9fdb199972
commit 17b9f3eb73
35 changed files with 442 additions and 195 deletions
@@ -163,22 +163,6 @@ CREATE TABLE IF NOT EXISTS ll_loading_order_status_history (
KEY idx_ll_loading_history_customer_order(customer_id,order_id,created_at)
) ENGINE=InnoDB COMMENT='尾程订单状态变更历史';
CREATE TABLE IF NOT EXISTS ll_order_fee (
id BIGINT NOT NULL COMMENT '费用明细主键',
customer_id VARCHAR(128) NOT NULL COMMENT '客户数据隔离键',
order_id BIGINT NOT NULL COMMENT '尾程订单ID',
fee_item VARCHAR(128) NOT NULL COMMENT '费用项目',
currency VARCHAR(3) NOT NULL COMMENT '币种代码',
amount DECIMAL(18,2) NOT NULL COMMENT '费用金额',
status VARCHAR(32) NOT NULL DEFAULT 'PENDING_REVIEW' COMMENT '费用状态:PENDING_REVIEW待审核、APPROVED审核通过、REJECTED已驳回',
supplier_description VARCHAR(500) NULL COMMENT '供应商或费用说明',
created_by VARCHAR(128) NOT 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),
KEY idx_ll_order_fee_customer_order(customer_id,order_id,created_at)
) ENGINE=InnoDB COMMENT='尾程订单费用明细';
CREATE TABLE IF NOT EXISTS ll_order_operation_log (
id BIGINT NOT NULL COMMENT '操作记录主键',
customer_id VARCHAR(128) NOT NULL COMMENT '客户数据隔离键',
@@ -302,12 +286,6 @@ SET @ddl = (SELECT IF(EXISTS (SELECT 1 FROM information_schema.columns WHERE tab
PREPARE delivery_detail_stmt FROM @ddl; EXECUTE delivery_detail_stmt; DEALLOCATE PREPARE delivery_detail_stmt;
SET @ddl = (SELECT IF(EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema=DATABASE() AND table_name='ll_delivery_order' AND column_name='total_weight_kg'), 'SELECT 1', 'ALTER TABLE ll_delivery_order ADD COLUMN total_weight_kg DECIMAL(18,4) NOT NULL DEFAULT 0 COMMENT ''总重量(千克)'', ADD COLUMN total_volume_cbm DECIMAL(18,4) NOT NULL DEFAULT 0 COMMENT ''总体积(立方米)'', ADD COLUMN planned_delivery_at DATETIME(3) NULL COMMENT ''预计派送时间'', ADD COLUMN dispatched_at DATETIME(3) NULL COMMENT ''实际派送时间'', ADD COLUMN expected_arrival_at DATETIME(3) NULL COMMENT ''预计到达时间'', ADD COLUMN signed_at DATETIME(3) NULL COMMENT ''签收时间'', ADD COLUMN remark VARCHAR(1000) NULL COMMENT ''派送备注'' AFTER pallet_count'));
PREPARE delivery_detail_stmt FROM @ddl; EXECUTE delivery_detail_stmt; DEALLOCATE PREPARE delivery_detail_stmt;
CREATE TABLE IF NOT EXISTS ll_delivery_fee (
id BIGINT NOT NULL COMMENT '派送费用主键', customer_id VARCHAR(128) NOT NULL COMMENT '客户数据隔离键', delivery_order_id BIGINT NOT NULL COMMENT '派送单ID',
fee_direction VARCHAR(16) NOT NULL DEFAULT 'PAYABLE' COMMENT '应收应付方向', fee_type VARCHAR(64) NOT NULL COMMENT '费用类型', currency VARCHAR(8) NOT NULL COMMENT '币种',
amount DECIMAL(18,2) NOT NULL COMMENT '费用金额', remark VARCHAR(500) NULL COMMENT '费用备注', created_by VARCHAR(128) NULL COMMENT '创建人ID',
created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间', PRIMARY KEY(id), KEY idx_ll_delivery_fee_order(customer_id,delivery_order_id,id)
) ENGINE=InnoDB COMMENT='派送单费用明细';
CREATE TABLE IF NOT EXISTS ll_delivery_document_revision (
id BIGINT NOT NULL COMMENT '派送资料历史ID',
customer_id VARCHAR(128) NOT NULL COMMENT '派送所属客户隔离键',
@@ -194,11 +194,12 @@ paths:
/api/platform/v1/last-leg/orders/{id}/fees:
post:
summary: 新增尾程订单费用
description: 权限 platform:overseas-warehouse:last-mile-order:edit;在订单客户范围内新增费用并记录操作人和处理结果。
description: 权限 platform:overseas-warehouse:last-mile-order:edit;在订单客户范围内创建统一费用来源并提交财务审核。
security: [{ bearerAuth: [] }]
parameters:
- { name: id, in: path, required: true, schema: { type: integer, format: int64 } }
- { name: customerId, in: query, required: false, schema: { type: string, pattern: '^[1-9][0-9]*$' } }
- { name: Idempotency-Key, in: header, required: true, schema: { type: string, minLength: 1, maxLength: 128 } }
requestBody:
required: true
content: { application/json: { schema: { $ref: '#/components/schemas/LastMileFeeCreate' } } }
@@ -1331,28 +1332,44 @@ components:
plannedArrivalAt: { type: string, format: date-time, nullable: true, description: ll_order.estimated_warehouse_at }
LastMileFeeCreate:
type: object
required: [feeItem, currency, amount, status]
required: [feeItemCode, feeItemName, direction, currency, amount, businessDate]
properties:
feeItem: { type: string, minLength: 1, maxLength: 128 }
currency: { type: string, pattern: '^[A-Z]{3}$', example: USD }
feeItemCode: { type: string, minLength: 1, maxLength: 64 }
feeItemName: { type: string, minLength: 1, maxLength: 128 }
direction: { type: string, enum: [RECEIVABLE, PAYABLE] }
currency: { type: string, enum: [CNY, USD] }
amount: { type: number, format: decimal, minimum: 0.01 }
status: { type: string, enum: [PENDING_REVIEW, APPROVED, REJECTED] }
supplierDescription: { type: string, maxLength: 500 }
businessDate: { type: string, format: date }
supplierId: { type: string, pattern: '^[1-9][0-9]*$' }
supplierName: { type: string, maxLength: 200 }
supplierCategory: { type: string, maxLength: 32 }
settlementMode: { type: string, enum: [ON_ACCOUNT, DIRECT_PAID] }
chargeableQuantity: { type: number, exclusiveMinimum: 0 }
quantityUnit: { type: string, maxLength: 32 }
unitPrice: { type: number, exclusiveMinimum: 0 }
periodStart: { type: string, format: date }
periodEnd: { type: string, format: date }
LastMileFee:
type: object
required: [id, customerId, orderId, feeItem, currency, amount, status, createdBy, createdAt, updatedAt]
required: [id, sourceFeeId, sourceVersion, customerId, feeItemCode, feeItemName, direction, currency, amount, originalCurrency, originalAmount, reviewStatus, publicationStatus, sourceStatus]
properties:
id: { type: integer, format: int64 }
id: { type: string, pattern: '^[1-9][0-9]*$' }
sourceFeeId: { type: string, pattern: '^[1-9][0-9]*$' }
sourceVersion: { type: integer, minimum: 1 }
customerId: { type: string }
orderId: { type: integer, format: int64 }
feeItem: { type: string }
currency: { type: string }
orderId: { type: string, pattern: '^[1-9][0-9]*$' }
feeItemCode: { type: string }
feeItemName: { type: string }
direction: { type: string, enum: [RECEIVABLE, PAYABLE] }
currency: { type: string, enum: [CNY] }
amount: { type: number, format: decimal }
status: { type: string }
supplierDescription: { type: string, nullable: true }
createdBy: { type: string }
createdAt: { type: string, format: date-time }
updatedAt: { type: string, format: date-time }
originalCurrency: { type: string, enum: [CNY, USD] }
originalAmount: { type: number, format: decimal }
exchangeRate: { type: number, format: decimal }
exchangeRateMonth: { type: string, pattern: '^\\d{4}-\\d{2}$' }
reviewStatus: { type: string, enum: [DRAFT, PENDING, APPROVED, REJECTED] }
publicationStatus: { type: string }
sourceStatus: { type: string }
LastMileFeeApiResponse:
type: object
required: [code, message, data]
@@ -1842,11 +1859,22 @@ components:
enum: [START_PROCESSING, COMPLETE_EXCEPTION, CANCEL_EXCEPTION]
DeliveryFeeInput:
type: object
required: [feeType, currency, amount]
required: [feeType, feeName, direction, currency, amount]
properties:
feeType: { type: string, maxLength: 64 }
currency: { type: string, maxLength: 8 }
amount: { type: number, minimum: 0 }
feeName: { type: string, maxLength: 128 }
direction: { type: string, enum: [RECEIVABLE, PAYABLE] }
currency: { type: string, enum: [CNY, USD] }
amount: { type: number, exclusiveMinimum: 0 }
supplierId: { type: string, pattern: '^[1-9][0-9]*$' }
supplierName: { type: string, maxLength: 200 }
supplierCategory: { type: string, maxLength: 32 }
settlementMode: { type: string, enum: [ON_ACCOUNT, DIRECT_PAID] }
chargeableQuantity: { type: number, exclusiveMinimum: 0 }
quantityUnit: { type: string, maxLength: 32 }
unitPrice: { type: number, exclusiveMinimum: 0 }
periodStart: { type: string, format: date }
periodEnd: { type: string, format: date }
remark: { type: string, nullable: true, maxLength: 500 }
OneClickOutboundCreate:
type: object
@@ -42,7 +42,7 @@ paths:
responses: { '200': { description: 当前费用来源版本 }, '409': { description: 状态、版本或幂等冲突 } }
components:
schemas:
BusinessType: { type: string, enum: [OVERSEAS_INBOUND, OVERSEAS_PROCUREMENT, US_TRUCK, LOCAL_LOOSEBOARD, WAREHOUSE_SERVICE, OVERSEAS_CONTAINER] }
BusinessType: { type: string, enum: [OVERSEAS_INBOUND, OVERSEAS_PROCUREMENT, PROCUREMENT_FEE, US_TRUCK, LOCAL_LOOSEBOARD, WAREHOUSE_SERVICE, OVERSEAS_CONTAINER, LASTLEG_ORDER, DELIVERY_ORDER, RELABEL_ORDER] }
OverseasContainerFeeItem:
type: string
description: 海外阶段柜级费用项目:港口费、堆存费、修箱费、吊机费、码头拖车费、其他。
@@ -70,7 +70,7 @@ components:
required: [customerId, sourceType, businessType, businessNo, feeItemCode, feeItemName, direction, businessDate, currency, amount]
properties:
customerId: { type: string }
sourceType: { type: string, enum: [OVERSEAS_INBOUND_FEE, OVERSEAS_PROCUREMENT_FEE, OVERSEAS_TRUCK_FEE, OVERSEAS_LOOSEBOARD_FEE, OVERSEAS_WAREHOUSE_FEE, OVERSEAS_CONTAINER_FEE] }
sourceType: { type: string, enum: [OVERSEAS_INBOUND_FEE, OVERSEAS_PROCUREMENT_FEE, OVERSEAS_TRUCK_FEE, OVERSEAS_LOOSEBOARD_FEE, OVERSEAS_WAREHOUSE_FEE, OVERSEAS_CONTAINER_FEE, OVERSEAS_ORDER_FEE, OVERSEAS_DELIVERY_FEE, OVERSEAS_RELABEL_FEE] }
businessType: { $ref: '#/components/schemas/BusinessType' }
businessId: { type: string, pattern: '^[1-9][0-9]*$', nullable: true }
businessNo: { type: string, maxLength: 128 }