382 lines
21 KiB
YAML
382 lines
21 KiB
YAML
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: ruleCode, in: query, schema: {type: string, maxLength: 50}}
|
|
responses:
|
|
'200':
|
|
description: 成功或业务失败
|
|
content:
|
|
application/json:
|
|
schema: {$ref: '#/components/schemas/CustomerRuleVersionSummary'}
|
|
'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:
|
|
- {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: 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: 仅上传和解析,生成待确认上传记录,不改变当前生效版本;需要 firstleg:fba-pricing:rate:edit 权限。
|
|
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: 只确认上传表中的仓库映射,不允许在线改价;阻断错误必须为零。发布事务将上一 ACTIVE 版本标记为 SUPERSEDED,始终只保留一份 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}/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: 成功或业务失败}, '403': {description: 无权限}}
|
|
/api/platform/v1/inbounds/{inboundId}/fees/confirm:
|
|
post:
|
|
summary: 确认最新费用快照
|
|
description: 确认费用只更新费用状态;主流程已到 WAIT_SPLIT 时保持不变。
|
|
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 权限;人工修改计费量、单价和附加费,小计与总额由服务端重算并生成新版本,不回退 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: 成功或业务失败}, '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]*$'}}
|
|
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:
|
|
AdjustFeeRequest:
|
|
type: object
|
|
required: [expectedFeeVersion, chargeableQuantity, unitPrice, additionalAmount, reason]
|
|
properties:
|
|
expectedFeeVersion: {type: integer, minimum: 1}
|
|
chargeableQuantity: {type: number, exclusiveMinimum: 0, description: 计费量,单位沿用当前费用快照的 chargeUnit}
|
|
unitPrice: {type: number, minimum: 0, description: 人工确认单价}
|
|
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: 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, 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, 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, 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}
|
|
PriceBookStatus:
|
|
type: string
|
|
enum: [PENDING_CONFIRMATION, ACTIVE, SUPERSEDED, 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]*$'}
|
|
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}
|
|
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'}
|
|
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, exclusiveMinimum: 0}
|
|
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'}
|
|
actualWeightKg: {type: number, minimum: 0}
|
|
actualVolumeCbm: {type: number, minimum: 0}
|