Files
baiyue-firstleg/firstleg/src/main/resources/openapi/fba-pricing-v1.yaml
T

718 lines
45 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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/OptionalTenantId'}
- name: customerId
in: query
required: false
schema: {type: string, pattern: '^[1-9][0-9]*$'}
- {name: ruleCode, in: query, schema: {type: string, maxLength: 50}}
responses:
'200':
description: 成功或业务失败
content:
application/json:
schema: {$ref: '#/components/schemas/CustomerRuleVersionListApiResponse'}
'403': {description: 无权限}
/api/platform/v1/fba-pricing/customer-rules/versions:
post:
summary: 新建客户计费规则版本
description: 新增配置固定为未启用,可保存有效期重叠的多条配置;保存后通过设置默认规则接口启用其中一条。
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}/default:
put:
summary: 启用客户计费规则
description: 将指定配置设为当前客户唯一默认生效规则,并取消原默认规则。
parameters: [{$ref: '#/components/parameters/TenantId'}, {$ref: '#/components/parameters/Id'}]
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:
- {name: rateCode, in: query, schema: {type: string, maxLength: 50}}
responses: {'200': {description: 成功或业务失败}, '403': {description: 无权限}}
/api/platform/v1/fba-pricing/carrier-rates/versions:
post:
summary: 新建平台公共船司 FBA 价格版本
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/Id'}]
responses: {'200': {description: 成功或业务失败}, '403': {description: 无权限}}
delete:
summary: 停用船司 FBA 价格版本
parameters: [{$ref: '#/components/parameters/Id'}]
responses: {'200': {description: 成功或业务失败}, '403': {description: 无权限}}
/api/platform/v1/fba-pricing/carrier-rates/price-books:
get:
summary: 查询船期价格表版本
description: 需要 firstleg:fba-pricing:rate:view 权限;返回待确认上传、当前生效和历史替换版本。
parameters:
- {name: customerId, in: query, schema: {type: string, pattern: '^(0|[1-9][0-9]*)$', default: '0'}, description: 0 表示公共报价;正数表示客户专属报价}
- {name: status, in: query, schema: {$ref: '#/components/schemas/PriceBookStatus'}}
responses:
'200':
description: 成功或业务失败
content:
application/json:
schema:
type: array
items: {$ref: '#/components/schemas/PriceBookVersionSummary'}
'403': {description: 无权限}
post:
summary: 上传船期价格表并生成待确认记录
description: 仅上传和解析,生成待确认上传记录,不改变当前生效版本;customerId=0 为公共报价,customerId>0 为该客户的专属报价;需要 firstleg:fba-pricing:rate:edit 权限。
parameters:
- {name: customerId, in: query, schema: {type: string, pattern: '^(0|[1-9][0-9]*)$', default: '0'}}
requestBody:
required: true
content:
multipart/form-data:
schema: {$ref: '#/components/schemas/PriceBookUploadRequest'}
responses: {'200': {description: 成功或业务失败}, '403': {description: 无权限}}
/api/platform/v1/fba-pricing/carrier-rates/price-books/{versionId}:
get:
summary: 查询船期价格表版本详情和解析结果
parameters: [{$ref: '#/components/parameters/VersionId'}]
responses:
'200':
description: 成功或业务失败
content:
application/json:
schema: {$ref: '#/components/schemas/PriceBookVersionDetail'}
'403': {description: 无权限}
/api/platform/v1/fba-pricing/carrier-rates/price-books/{versionId}/publish:
post:
summary: 确认并立即生效船期价格表版本
description: 只确认上传表中的仓库映射,不允许在线改价;阻断错误必须为零。发布事务只替换同 customerId 作用域的上一 ACTIVE 版本。计价时优先使用客户专属 ACTIVE 版本,不存在时回退公共 ACTIVE 版本。
parameters: [{$ref: '#/components/parameters/VersionId'}]
requestBody: {required: true, content: {application/json: {schema: {$ref: '#/components/schemas/PriceBookConfirmationRequest'}}}}
responses: {'200': {description: 成功或业务失败}, '403': {description: 无权限}}
/api/platform/v1/fba-pricing/carrier-rates/price-books/{versionId}/void:
post:
summary: 作废待确认船期价格表版本
description: 仅允许作废 PENDING_CONFIRMATION 版本;保留版本、原始文件和审计记录,作废后不可再确认生效。需要 firstleg:fba-pricing:rate:edit 权限。
parameters: [{$ref: '#/components/parameters/VersionId'}]
requestBody: {required: true, content: {application/json: {schema: {$ref: '#/components/schemas/PriceBookVoidRequest'}}}}
responses: {'200': {description: 成功或业务失败}, '403': {description: 无权限}}
/api/platform/v1/fba-pricing/carrier-rates/price-books/{versionId}/source:
get:
summary: 下载船期价格表原始文件
description: 需要 firstleg:fba-pricing:rate:view 权限;由 Firstleg 代理 File 服务内部下载。
parameters: [{$ref: '#/components/parameters/VersionId'}]
responses:
'200': {description: 原始 XLSX 附件, content: {application/octet-stream: {schema: {type: string, format: binary}}}}
'403': {description: 无权限}
/api/merchant/v1/first-leg/pricing/channels:
get:
summary: 查询当前起运仓可选船期渠道
description: 客户只看到当前 ACTIVE 版本;不存在于当前版本的渠道不可选择。pricingTaxModes 来自当前起运仓下的生效价格行,前端不得写死包税选项。
parameters:
- {name: originWarehouseId, in: query, required: true, schema: {type: string, pattern: '^[1-9][0-9]*$'}}
responses:
'200':
description: 成功或业务失败
content:
application/json:
schema:
type: array
items: {$ref: '#/components/schemas/MerchantPricingChannel'}
/api/merchant/v1/first-leg/pricing/estimate:
post:
summary: 计算头程参考费用
description: 只返回基础参考费用,不包含复杂附加费和最终结算调整;pricingTaxMode 不复用订单 taxMode。
requestBody: {required: true, content: {application/json: {schema: {$ref: '#/components/schemas/PriceEstimateRequest'}}}}
responses: {'200': {description: 成功或业务失败}}
/api/platform/v1/inbounds/{inboundId}/fees/calculate:
post:
summary: 按审核通过测量快照试算 FBA 费用
description: 仅匹配当前唯一 ACTIVE 船期价格表中的 ACTIVE 价格行,按起运仓、渠道、目的仓、pricingTaxMode 和计费单位估价;不再以 carrierId、业务 customerId 或客户计费规则作为前置。区域阶梯渠道可按平台 FBA 仓或海外中转仓的邮编区域和重量阶梯匹配;测量审核后即使主流程已到 WAIT_SPLIT,也可独立试算且不回退主流程状态;需要 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: 成功或业务失败, content: {application/json: {schema: {$ref: '#/components/schemas/FeeSnapshotApiResponse'}}}}, '403': {description: 无权限}}
/api/platform/v1/inbounds/{inboundId}/fees/manual-quote:
post:
summary: FBA价格未命中时人工确定头程单价
description: 仅FBA且价格查询返回未命中时可用;按客户计费方式与选定测量重量、体积计算计费量,附加费为零。生成正式头程费用快照,后续复用确认与发送;需要 firstleg:inbound:confirm-send-fee 权限。
parameters: [{$ref: '#/components/parameters/TenantId'}, {$ref: '#/components/parameters/InboundId'}, {$ref: '#/components/parameters/IdempotencyKey'}]
requestBody: {required: true, content: {application/json: {schema: {$ref: '#/components/schemas/ManualQuoteRequest'}}}}
responses: {'200': {description: 成功或业务失败, content: {application/json: {schema: {$ref: '#/components/schemas/FeeSnapshotApiResponse'}}}}, '403': {description: 无权限}}
/api/platform/v1/inbounds/{inboundId}/fees/confirm:
post:
summary: 确认最新费用快照
description: 需要 firstleg:inbound:confirm-send-fee 或兼容权限 firstleg:fba-pricing:confirm。确认费用只更新费用状态;主流程已到 WAIT_SPLIT 时保持不变。
parameters: [{$ref: '#/components/parameters/TenantId'}, {$ref: '#/components/parameters/InboundId'}, {$ref: '#/components/parameters/IdempotencyKey'}]
responses: {'200': {description: 成功或业务失败, content: {application/json: {schema: {$ref: '#/components/schemas/FeeSnapshotApiResponse'}}}}, '403': {description: 无权限}}
/api/platform/v1/inbounds/{inboundId}/fees/send:
post:
summary: 发送已确认费用快照
description: 需要 firstleg:inbound:confirm-send-fee 或兼容权限 firstleg:inbound:send-fee。人工发布当前已确认版本;仅此动作将费用置为 SENT、生成 PUBLISHED 的 FBA_PRICING 只读派生明细并写入 Finance Outbox。入库单已到 WAIT_SPLIT 时不得回退或阻塞主流程。
parameters: [{$ref: '#/components/parameters/TenantId'}, {$ref: '#/components/parameters/InboundId'}, {$ref: '#/components/parameters/IdempotencyKey'}]
responses: {'200': {description: 成功或业务失败, content: {application/json: {schema: {$ref: '#/components/schemas/FeeSnapshotApiResponse'}}}}, '403': {description: 无权限}}
/api/platform/v1/inbounds/{inboundId}/fees/latest:
get:
summary: 查询 fl_inbound_fee 最新费用快照
description: fl_inbound_fee 是头程运费唯一事实源;fee-details 中 sourceType=FBA_PRICING 的记录仅为最新版本只读派生。
parameters: [{$ref: '#/components/parameters/TenantId'}, {$ref: '#/components/parameters/InboundId'}]
responses: {'200': {description: 成功或业务失败, content: {application/json: {schema: {$ref: '#/components/schemas/FeeSnapshotApiResponse'}}}}, '403': {description: 无权限}}
/api/platform/v1/inbounds/{inboundId}/fees/published:
put:
summary: 调整初算或已发布费用
description: 需要 firstleg:fba-pricing:adjust 权限;计费量只能在系统原计费量上下10%范围内(含边界),请求必须携带当前费用版本、必填原因及二次确认标志,越界或并发冲突返回A0409。小计与总额由服务端重算并生成新版本,不回退 WAIT_SPLIT 状态。调整 CALCULATED/CONFIRMED 时生成新的 CALCULATED 版本;调整 SENT 时生成新的 SENT 版本并发布调整事件。
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: 成功或业务失败, content: {application/json: {schema: {$ref: '#/components/schemas/FeeSnapshotApiResponse'}}}}, '403': {description: 无调整权限}}
/api/platform/v1/inbounds/{inboundId}/fee-details:
get:
summary: 查询入仓费用明细
description: 默认隐藏 publicationStatus=SUPERSEDED 的历史版本。FBA_PRICING 是 fl_inbound_fee 最新版本的只读派生;MANUAL 是独立新增、审核和版本调整的其他应收/应付。
parameters:
- {$ref: '#/components/parameters/AccountId'}
- {$ref: '#/components/parameters/InboundId'}
- {name: includeHistory, in: query, required: false, schema: {type: boolean, default: false}, description: true 时包含 SUPERSEDED 历史版本}
responses: {'200': {description: 成功或业务失败, content: {application/json: {schema: {$ref: '#/components/schemas/InboundFeeDetailListApiResponse'}}}}, '403': {description: 无权限}}
post:
summary: 新增 MANUAL 其他费用
description: 只允许创建 MANUAL 来源;FBA_PRICING 由系统从 fl_inbound_fee 派生。费用项目 PRIVATE_LAST_MILE_DELIVERY 是独立的私人仓尾程派送费,仅 destinationType=PRIVATE 的入库单可创建;服务端按稳定 feeCode 校验,不按中文名称判断。
parameters: [{$ref: '#/components/parameters/AccountId'}, {$ref: '#/components/parameters/InboundId'}]
requestBody: {required: true, content: {application/json: {schema: {$ref: '#/components/schemas/InboundFeeDetailSaveRequest'}}}}
responses: {'200': {description: 成功或业务失败, content: {application/json: {schema: {$ref: '#/components/schemas/InboundFeeDetailApiResponse'}}}}, '403': {description: 无权限}}
/api/platform/v1/inbounds/{inboundId}/fee-details/{detailId}:
put:
summary: 编辑待审核 MANUAL 费用
description: FBA_PRICING 只读派生禁止通过通用费用接口修改。
parameters: [{$ref: '#/components/parameters/AccountId'}, {$ref: '#/components/parameters/InboundId'}, {$ref: '#/components/parameters/DetailId'}]
requestBody: {required: true, content: {application/json: {schema: {$ref: '#/components/schemas/InboundFeeDetailSaveRequest'}}}}
responses: {'200': {description: 成功或业务失败, content: {application/json: {schema: {$ref: '#/components/schemas/InboundFeeDetailApiResponse'}}}}, '403': {description: 无权限}}
delete:
summary: 删除待审核 MANUAL 费用
description: FBA_PRICING 只读派生禁止删除。
parameters: [{$ref: '#/components/parameters/AccountId'}, {$ref: '#/components/parameters/InboundId'}, {$ref: '#/components/parameters/DetailId'}]
responses: {'200': {description: 成功或业务失败, content: {application/json: {schema: {$ref: '#/components/schemas/VoidApiResponse'}}}}, '403': {description: 无权限}}
/api/platform/v1/inbounds/{inboundId}/fee-details/{detailId}/approve:
post:
summary: 审核通过 MANUAL 费用当前版本
parameters: [{$ref: '#/components/parameters/AccountId'}, {$ref: '#/components/parameters/InboundId'}, {$ref: '#/components/parameters/DetailId'}]
responses: {'200': {description: 成功或业务失败, content: {application/json: {schema: {$ref: '#/components/schemas/VoidApiResponse'}}}}, '403': {description: 无权限}}
/api/platform/v1/inbounds/{inboundId}/fee-details/{detailId}/reject:
post:
summary: 驳回 MANUAL 费用当前版本
parameters: [{$ref: '#/components/parameters/AccountId'}, {$ref: '#/components/parameters/InboundId'}, {$ref: '#/components/parameters/DetailId'}]
requestBody: {required: true, content: {application/json: {schema: {$ref: '#/components/schemas/InboundFeeDetailRejectRequest'}}}}
responses: {'200': {description: 成功或业务失败, content: {application/json: {schema: {$ref: '#/components/schemas/VoidApiResponse'}}}}, '403': {description: 无权限}}
/api/platform/v1/inbounds/{inboundId}/fee-details/{detailId}/adjust:
post:
summary: 调整已审核 MANUAL 费用并创建新版本
description: 原版本置为 SUPERSEDED,新记录使用相同 sourceFeeId、sourceFeeVersion+1 并重新进入 PENDING/DRAFT;FBA_PRICING 必须通过头程费用调整接口处理。
parameters:
- {$ref: '#/components/parameters/AccountId'}
- {$ref: '#/components/parameters/InboundId'}
- {$ref: '#/components/parameters/DetailId'}
- {name: expectedSourceVersion, in: query, required: true, schema: {type: integer, minimum: 1}}
requestBody: {required: true, content: {application/json: {schema: {$ref: '#/components/schemas/InboundFeeDetailSaveRequest'}}}}
responses: {'200': {description: 成功或业务失败, content: {application/json: {schema: {$ref: '#/components/schemas/InboundFeeDetailApiResponse'}}}}, '403': {description: 无权限}}
/api/platform/v1/inbounds/{inboundId}/fee-details/{detailId}/void:
post:
summary: 作废已审核 MANUAL 费用当前版本
parameters: [{$ref: '#/components/parameters/AccountId'}, {$ref: '#/components/parameters/InboundId'}, {$ref: '#/components/parameters/DetailId'}]
requestBody: {required: true, content: {application/json: {schema: {$ref: '#/components/schemas/InboundFeeDetailVersionRequest'}}}}
responses: {'200': {description: 成功或业务失败, content: {application/json: {schema: {$ref: '#/components/schemas/VoidApiResponse'}}}}, '403': {description: 无权限}}
components:
securitySchemes:
bearerAuth: {type: http, scheme: bearer, bearerFormat: JWT}
parameters:
OptionalTenantId: {name: tenantId, in: query, required: false, description: 可选目标客户 ID;参数名为历史兼容,不传时查询全部企业, schema: {type: string, pattern: '^[1-9][0-9]*$'}}
TenantId: {name: tenantId, in: query, required: true, description: 目标客户 ID;参数名为历史兼容, schema: {type: string, pattern: '^[1-9][0-9]*$'}}
Id: {name: id, in: path, required: true, schema: {type: string, pattern: '^[1-9][0-9]*$'}}
InboundId: {name: inboundId, in: path, required: true, schema: {type: string, pattern: '^[1-9][0-9]*$'}}
DetailId: {name: detailId, in: path, required: true, schema: {type: string, pattern: '^[1-9][0-9]*$'}}
AccountId: {name: accountId, in: query, required: true, description: 目标客户 ID, schema: {type: string, pattern: '^[1-9][0-9]*$'}}
VersionId: {name: versionId, in: path, required: true, schema: {type: string, pattern: '^[1-9][0-9]*$'}}
IdempotencyKey: {name: Idempotency-Key, in: header, required: true, schema: {type: string, maxLength: 128}}
schemas:
CustomerRuleVersionListApiResponse:
type: object
required: [code, message, data, timestamp]
properties:
code: {type: string, example: '200'}
message: {type: string}
data:
type: array
items: {$ref: '#/components/schemas/CustomerRuleVersionResource'}
requestId: {type: string, nullable: true}
traceId: {type: string, nullable: true}
timestamp: {type: string, format: date-time}
CustomerRuleVersionResource:
type: object
properties:
id: {type: string, pattern: '^[1-9][0-9]*$'}
tenantId: {type: string, pattern: '^[1-9][0-9]*$'}
ruleCode: {type: string}
ruleVersion: {type: integer}
customerId: {type: string, pattern: '^[1-9][0-9]*$'}
customerName: {type: string}
businessType: {type: string}
chargeMode: {type: string}
taxMode: {type: string}
conversionFactor: {type: number}
roundingScale: {type: integer}
roundingMode: {type: string}
currency: {type: string}
effectiveFrom: {type: string, format: date-time}
effectiveTo: {type: string, format: date-time, nullable: true}
status: {type: string}
remark: {type: string, nullable: true}
createdBy: {type: string, nullable: true}
createdAt: {type: string, format: date-time, nullable: true}
updatedBy: {type: string, nullable: true}
updatedAt: {type: string, format: date-time, nullable: true}
deleted: {type: boolean, nullable: true}
version: {type: integer, nullable: true}
FeeSnapshotApiResponse:
type: object
required: [code, message, data]
properties:
code: {type: string}
message: {type: string}
data: {$ref: '#/components/schemas/FeeSnapshotResponse'}
requestId: {type: string, nullable: true}
traceId: {type: string, nullable: true}
timestamp: {type: string, format: date-time, nullable: true}
FeeSnapshotResponse:
type: object
description: fl_inbound_fee 当前版本快照;自动初算为 CALCULATED,人工确认后为 CONFIRMED,只有人工发布后为 SENT。
required: [feeId, feeNo, feeVersion, feeStatus, inboundId, conversionFactor, roundingScale, roundingMode, totalAmount, currency]
properties:
feeId: {type: string, pattern: '^[1-9][0-9]*$'}
feeNo: {type: string}
feeVersion: {type: integer, minimum: 1}
feeStatus: {type: string, enum: [CALCULATED, CONFIRMED, SENT, SUPERSEDED]}
inboundId: {type: string, pattern: '^[1-9][0-9]*$'}
inboundCode: {type: string, nullable: true}
measurementId: {type: string, nullable: true}
measurementSource: {type: string, nullable: true}
chargeRuleId: {type: string, nullable: true}
ruleCode: {type: string, nullable: true}
chargeRuleVersion: {type: integer, nullable: true}
carrierRateId: {type: string, nullable: true}
rateCode: {type: string, nullable: true}
carrierRateVersion: {type: integer, nullable: true}
priceBookVersionId: {type: string, nullable: true}
customerId: {type: string, nullable: true}
customerName: {type: string, nullable: true}
originWarehouseId: {type: string, nullable: true}
originWarehouseName: {type: string, nullable: true}
businessType: {type: string, nullable: true}
channelCode: {type: string, nullable: true}
carrierId: {type: string, nullable: true}
carrierName: {type: string, nullable: true}
destinationType: {type: string, nullable: true}
destinationWarehouseId: {type: string, nullable: true}
destinationName: {type: string, nullable: true}
destinationCode: {type: string, nullable: true}
taxMode: {type: string, nullable: true}
pricingTaxMode: {type: string, nullable: true}
chargeMode: {type: string, nullable: true}
conversionFactor: {type: number, description: 本费用版本实际使用的重量体积换算系数;FBA/区域重量阶梯按KG为167,FBA按CBM为363}
roundingScale: {type: integer, enum: [6], description: 本费用版本最终计费量实际保留的小数位数}
roundingMode: {type: string, enum: [HALF_UP], description: 本费用版本最终计费量实际使用的舍入方式}
actualWeightKg: {type: number, nullable: true}
actualVolumeCbm: {type: number, nullable: true}
convertedQuantity: {type: number, nullable: true}
baselineChargeableQuantity: {type: number, description: 系统按权威测量与生效报价计算的原计费量,人工调整后保持不变}
lowerChargeableQuantity: {type: number, description: 允许人工调整的计费量下界,包含边界}
upperChargeableQuantity: {type: number, description: 允许人工调整的计费量上界,包含边界}
tolerancePercent: {type: number, enum: [10.00], description: 相对系统原计费量允许的上下偏差百分比}
chargeableQuantity: {type: number, nullable: true}
chargeUnit: {type: string, nullable: true}
unitPrice: {type: number, nullable: true}
subtotalAmount: {type: number, nullable: true}
additionalAmount: {type: number, nullable: true}
totalAmount: {type: number}
currency: {type: string, pattern: '^[A-Z]{3}$'}
rateEffectiveFrom: {type: string, format: date-time, nullable: true}
rateEffectiveTo: {type: string, format: date-time, nullable: true}
calculatedAt: {type: string, format: date-time, nullable: true}
confirmedAt: {type: string, format: date-time, nullable: true}
sentAt: {type: string, format: date-time, nullable: true}
nextProcessStatus: {type: string, nullable: true, description: 费用动作后的入库主流程状态;审核完成后保持 WAIT_SPLIT}
customerConfirmationStatus: {type: string, enum: [PENDING_CONFIRMATION, CONFIRMED], description: 客户对当前费用版本的确认状态}
customerConfirmedBy: {type: string, nullable: true, description: 客户确认人用户ID}
customerConfirmedByName: {type: string, nullable: true, description: 客户确认人名称快照}
customerConfirmedAt: {type: string, format: date-time, nullable: true, description: 客户确认时间;非空后当前版本不可修改}
InboundFeeDetailSaveRequest:
type: object
required: [feeItemId, direction, businessDate, unitPrice, currency, amount]
properties:
feeItemId: {type: string, pattern: '^[1-9][0-9]*$'}
direction: {type: string, enum: [RECEIVABLE, PAYABLE]}
businessDate: {type: string, format: date}
unitPrice: {type: number, minimum: 0}
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
required: [expectedSourceVersion]
properties: {expectedSourceVersion: {type: integer, minimum: 1}}
InboundFeeDetailRejectRequest:
type: object
required: [reason]
properties: {reason: {type: string, minLength: 1, maxLength: 500}}
InboundFeeDetailResource:
type: object
description: 入仓费用展示记录。sourceType=FBA_PRICING 时是只读派生;sourceType=MANUAL 时按 sourceFeeId/sourceFeeVersion 独立版本化。
required: [id, tenantId, inboundId, feeItemId, sourceType, sourceFeeVersion, direction, businessDate, unitPrice, currency, amount, reviewStatus, publicationStatus]
properties:
id: {type: string, pattern: '^[1-9][0-9]*$'}
tenantId: {type: string, pattern: '^[1-9][0-9]*$'}
inboundId: {type: string, pattern: '^[1-9][0-9]*$'}
feeItemId: {type: string, pattern: '^[1-9][0-9]*$'}
sourceType: {type: string, enum: [MANUAL, FBA_PRICING]}
sourceFeeId: {type: string, nullable: true, description: FBA_PRICING 对应 fl_inbound_fee.id;MANUAL V2+ 指向稳定的首版本来源 ID}
sourceFeeVersion: {type: integer, minimum: 1}
sourceFeeNo: {type: string, nullable: true}
inboundCode: {type: string, nullable: true}
direction: {type: string, enum: [RECEIVABLE, PAYABLE]}
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}
invoiceTitle: {type: string, nullable: true}
feeCategorySnapshot: {type: string, nullable: true}
tradeScopeSnapshot: {type: string, nullable: true}
feeTypeNameSnapshot: {type: string, nullable: true}
channelCode: {type: string, nullable: true}
channelName: {type: string, nullable: true}
destinationCode: {type: string, nullable: true}
destinationName: {type: string, nullable: true}
packageCount: {type: integer, nullable: true}
actualGrossWeightKg: {type: number, nullable: true}
actualVolumeCbm: {type: number, nullable: true}
volumeWeightKg: {type: number, nullable: true}
chargeableWeightKg: {type: number, nullable: true}
chargeableVolumeCbm: {type: number, nullable: true}
chargeableQuantity: {type: number, nullable: true}
chargeUnit: {type: string, nullable: true}
unitPrice: {type: number}
currency: {type: string, pattern: '^[A-Z]{3}$'}
amount: {type: number}
remark: {type: string, nullable: true}
reviewStatus: {type: string, enum: [PENDING, APPROVED, REJECTED]}
reviewerId: {type: string, nullable: true}
reviewerName: {type: string, nullable: true}
reviewedAt: {type: string, format: date-time, nullable: true}
reviewReason: {type: string, nullable: true}
publicationStatus: {type: string, enum: [DRAFT, PUBLISHED, SUPERSEDED, VOIDED]}
publishedBy: {type: string, nullable: true}
publishedByName: {type: string, nullable: true}
publishedAt: {type: string, format: date-time, nullable: true}
inboundedAt: {type: string, format: date-time, nullable: true}
createdBy: {type: string, nullable: true}
createdAt: {type: string, format: date-time, nullable: true}
updatedBy: {type: string, nullable: true}
updatedAt: {type: string, format: date-time, nullable: true}
deleted: {type: boolean, nullable: true}
version: {type: integer, nullable: true}
InboundFeeDetailApiResponse:
type: object
required: [code, message, data]
properties:
code: {type: string}
message: {type: string}
data: {$ref: '#/components/schemas/InboundFeeDetailResource'}
requestId: {type: string, nullable: true}
traceId: {type: string, nullable: true}
timestamp: {type: string, format: date-time, nullable: true}
InboundFeeDetailListApiResponse:
type: object
required: [code, message, data]
properties:
code: {type: string}
message: {type: string}
data: {type: array, items: {$ref: '#/components/schemas/InboundFeeDetailResource'}}
requestId: {type: string, nullable: true}
traceId: {type: string, nullable: true}
timestamp: {type: string, format: date-time, nullable: true}
VoidApiResponse:
type: object
required: [code, message]
properties:
code: {type: string}
message: {type: string}
data: {nullable: true}
requestId: {type: string, nullable: true}
traceId: {type: string, nullable: true}
timestamp: {type: string, format: date-time, nullable: true}
AdjustFeeRequest:
type: object
required: [expectedFeeVersion, chargeableQuantity, unitPrice, additionalAmount, reason, toleranceConfirmed]
properties:
expectedFeeVersion: {type: integer, minimum: 1}
chargeableQuantity: {type: number, minimum: 0, exclusiveMinimum: true, description: 计费量,单位沿用当前费用快照的 chargeUnit}
unitPrice: {type: number, minimum: 0, description: 人工确认单价}
additionalAmount: {type: number, minimum: 0, multipleOf: 0.01}
reason: {type: string, minLength: 1, maxLength: 500}
toleranceConfirmed: {type: boolean, enum: [true], description: 前端展示上下界并由操作员二次确认后固定传true;服务端仍会重新校验范围与版本}
ManualQuoteRequest:
type: object
required: [selectedWeightKg, selectedVolumeCbm, unitPrice, reason]
properties:
selectedWeightKg: {type: number, exclusiveMinimum: true, minimum: 0}
selectedVolumeCbm: {type: number, exclusiveMinimum: true, minimum: 0}
unitPrice: {type: number, exclusiveMinimum: true, minimum: 0}
reason: {type: string, minLength: 2, maxLength: 500}
CalculateRequest:
type: object
properties:
pricingAt: {type: string, format: date-time, description: 缺省为服务端当前时间}
selectedWeightKg: {type: number, exclusiveMinimum: true, minimum: 0, nullable: true, description: 选定的权威重量快照}
selectedVolumeCbm: {type: number, exclusiveMinimum: true, minimum: 0, nullable: true, description: 选定的权威体积快照}
weightSource: {type: string, maxLength: 32, nullable: true}
volumeSource: {type: string, maxLength: 32, nullable: true}
CustomerRuleVersionRequest:
type: object
required: [ruleCode, customerId, customerName, businessType, chargeMode, taxMode, conversionFactor, roundingScale, roundingMode, currency, effectiveFrom]
properties:
ruleCode: {type: string, maxLength: 50}
customerId: {type: string, pattern: '^[1-9][0-9]*$'}
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, minimum: 0, exclusiveMinimum: true, 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, destinationType, chargeUnit, unitPrice, currency, additionalFee, effectiveFrom]
properties:
rateCode: {type: string, maxLength: 50}
originWarehouseId: {type: string, pattern: '^[1-9][0-9]*$'}
originWarehouseName: {type: string}
businessType: {type: string}
channelCode: {type: string}
carrierId: {type: string, pattern: '^[1-9][0-9]*$'}
carrierName: {type: string}
destinationType: {$ref: '#/components/schemas/PricingDestinationType'}
destinationCode: {type: string, nullable: true}
destinationWarehouseId: {type: string, pattern: '^[1-9][0-9]*$', nullable: true}
destinationName: {type: string, maxLength: 128, nullable: true}
chargeUnit: {type: string, enum: [KG, CBM]}
unitPrice: {type: number, minimum: 0, exclusiveMinimum: true}
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}
PriceBookStatus:
type: string
enum: [PENDING_CONFIRMATION, ACTIVE, SUPERSEDED, VOIDED, FAILED]
PriceModel:
type: string
enum: [FBA_WAREHOUSE_RATE, REGION_WEIGHT_TIER]
PricingTaxMode:
type: string
enum: [TAX_INCLUDED, TAX_EXCLUDED]
PricingDestinationType:
type: string
description: 价格明细支持的目的地类型;PRIVATE 本期不参与自动估价
enum: [FBA, OVERSEAS]
PriceBookUploadRequest:
type: object
required: [file]
properties:
file: {type: string, format: binary, description: 原始 XLSX 文件}
PriceBookVersionSummary:
type: object
properties:
id: {type: string, pattern: '^[1-9][0-9]*$'}
customerId: {type: string, pattern: '^(0|[1-9][0-9]*)$', description: 0 为公共报价,正数为客户专属报价}
versionNo: {type: integer}
originalFileName: {type: string, maxLength: 255}
sourceFileId: {type: string, pattern: '^[1-9][0-9]*$', nullable: true}
sourceSha256: {type: string, maxLength: 64, nullable: true}
status: {$ref: '#/components/schemas/PriceBookStatus'}
channelCount: {type: integer, minimum: 0}
rateCount: {type: integer, minimum: 0}
blockingErrorCount: {type: integer, minimum: 0}
warningCount: {type: integer, minimum: 0}
parseIssuesJson: {type: string, nullable: true, description: 上传解析问题及待确认重新校验结果JSON}
createdBy: {type: string, pattern: '^[1-9][0-9]*$'}
createdAt: {type: string, format: date-time}
publishedBy: {type: string, pattern: '^[1-9][0-9]*$', nullable: true}
publishedAt: {type: string, format: date-time, nullable: true}
supersededAt: {type: string, format: date-time, nullable: true}
voidedBy: {type: string, pattern: '^[1-9][0-9]*$', nullable: true}
voidedAt: {type: string, format: date-time, nullable: true}
voidReason: {type: string, maxLength: 500, nullable: true}
PriceBookVersionDetail:
type: object
required: [version, channels, rates, issues]
properties:
version: {$ref: '#/components/schemas/PriceBookVersionSummary'}
channels:
type: array
items: {$ref: '#/components/schemas/PriceBookParsedChannel'}
rates:
type: array
items: {$ref: '#/components/schemas/PriceBookParsedRate'}
issues:
type: array
items: {$ref: '#/components/schemas/PriceBookParseIssue'}
PriceBookParseIssue:
type: object
properties:
severity: {type: string}
issueCode: {type: string}
message: {type: string}
sourceSheetName: {type: string, nullable: true}
sourceRowNumber: {type: integer, minimum: 1, nullable: true}
sourceCell: {type: string, nullable: true}
PriceBookConfirmationRequest:
type: object
required: [originMappings]
properties:
originMappings:
type: array
minItems: 1
maxItems: 2
items: {$ref: '#/components/schemas/PriceBookOriginMapping'}
overseasMappings:
type: array
maxItems: 2
items: {$ref: '#/components/schemas/PriceBookOverseasMapping'}
PriceBookVoidRequest:
type: object
required: [reason]
properties:
reason: {type: string, minLength: 1, maxLength: 500, description: 人工作废原因}
PriceBookOriginMapping:
type: object
required: [originWarehouseCode, warehouseId]
properties:
originWarehouseCode: {type: string, maxLength: 64, description: 上传表识别出的起运仓稳定编码}
warehouseId: {type: string, pattern: '^[1-9][0-9]*$', description: 平台公共国内仓稳定ID}
PriceBookOverseasMapping:
type: object
required: [sourceDestinationName, warehouseId]
properties:
sourceDestinationName: {type: string, maxLength: 128, description: 上传表中的海外仓名称}
warehouseId: {type: string, pattern: '^[1-9][0-9]*$', description: 平台公共海外仓稳定ID}
PriceBookParsedChannel:
type: object
required: [channelCode, channelName, priceModel, sourceSheetName]
properties:
channelCode: {type: string, maxLength: 64}
channelName: {type: string, maxLength: 128}
priceModel: {$ref: '#/components/schemas/PriceModel'}
sourceSheetName: {type: string, maxLength: 128}
estimatedDepartureDate: {type: string, format: date}
estimatedDepartureText: {type: string, maxLength: 128}
latestWarehouseEntry: {type: string, maxLength: 128}
vesselName: {type: string, maxLength: 128}
voyageNo: {type: string, maxLength: 64}
referenceTransit: {type: string, maxLength: 128}
surchargeDescription: {type: string, maxLength: 2000}
remark: {type: string, maxLength: 2000}
PriceBookParsedRate:
type: object
required: [channelCode, priceModel, originWarehouseCode, originWarehouseName, chargeUnit, unitPrice, currency, sourceSheetName, sourceRowNumber]
properties:
id: {type: string, pattern: '^[1-9][0-9]*$'}
channelCode: {type: string, maxLength: 64}
priceModel: {$ref: '#/components/schemas/PriceModel'}
originWarehouseId: {type: string, pattern: '^[1-9][0-9]*$', nullable: true, description: 确认时绑定的平台公共国内仓稳定ID}
originWarehouseCode: {type: string, maxLength: 64}
originWarehouseName: {type: string, maxLength: 128}
destinationType: {$ref: '#/components/schemas/PricingDestinationType', nullable: true, description: FBA_WAREHOUSE_RATE 必填;REGION_WEIGHT_TIER 为空}
destinationCode: {type: string, maxLength: 32, nullable: true}
destinationWarehouseId: {type: string, pattern: '^[1-9][0-9]*$', nullable: true, description: 确认时绑定的平台海外仓稳定ID}
destinationName: {type: string, maxLength: 128, nullable: true, description: 目的仓名称快照}
regionCode: {type: string, maxLength: 16, nullable: true}
pricingTaxMode: {$ref: '#/components/schemas/PricingTaxMode'}
chargeUnit: {type: string, enum: [KG, CBM]}
weightFromKg: {type: number, minimum: 0, nullable: true}
unitPrice: {type: number, minimum: 0, exclusiveMinimum: true}
currency: {type: string, pattern: '^[A-Z]{3}$'}
sourceSheetName: {type: string, maxLength: 128}
sourceRowNumber: {type: integer, minimum: 1}
sourceDestinationText: {type: string, maxLength: 1000}
remark: {type: string, maxLength: 500}
MerchantPricingChannel:
type: object
required: [priceBookVersionId, channelCode, channelName, priceModel, pricingTaxModes]
properties:
priceBookVersionId: {type: string, pattern: '^[1-9][0-9]*$'}
channelCode: {type: string, maxLength: 64}
channelName: {type: string, maxLength: 128}
priceModel: {$ref: '#/components/schemas/PriceModel'}
pricingTaxModes:
type: array
description: 当前起运仓、当前渠道的生效价格行支持的报价税模式;可能只包含包税或不包税其中一种。
items: {$ref: '#/components/schemas/PricingTaxMode'}
estimatedDepartureDate: {type: string, format: date, nullable: true}
estimatedDepartureText: {type: string, maxLength: 128, nullable: true}
latestWarehouseEntry: {type: string, maxLength: 128, nullable: true}
referenceTransit: {type: string, maxLength: 128, nullable: true}
surchargeDescription: {type: string, maxLength: 2000, nullable: true}
remark: {type: string, maxLength: 2000, nullable: true}
PriceEstimateRequest:
type: object
required: [originWarehouseId, channelCode, destinationType]
properties:
originWarehouseId: {type: string, pattern: '^[1-9][0-9]*$'}
channelCode: {type: string, maxLength: 64}
destinationType: {$ref: '#/components/schemas/PricingDestinationType'}
destinationCode: {type: string, maxLength: 32}
destinationWarehouseId: {type: string, pattern: '^[1-9][0-9]*$', nullable: true}
destinationName: {type: string, maxLength: 128, nullable: true}
destinationRegion: {type: string, enum: [WEST, CENTRAL, EAST]}
pricingTaxMode: {$ref: '#/components/schemas/PricingTaxMode'}
chargeMode: {type: string, enum: [KG, CBM], description: 包税报价固定为KG;不包税报价必须与客户当前计费规则一致}
actualWeightKg: {type: number, minimum: 0}
actualVolumeCbm: {type: number, minimum: 0}