openapi: 3.0.3 info: title: 车次直接运营成本 version: 1.0.0 description: 运营登记与分摊,不生成客户账单、财务应付或付款事实。不同币种分别汇总;仅从不可变DEPART实物装载和BOUND外接实收形成权重。DRAFT/CANCELLED预订不参与,其他未完成关联的有效预订阻止自动分摊,不得归为自有货。 security: - bearerAuth: [] paths: /api/platform/v1/last-leg/fleet/trips/{tripNo}/costs: parameters: - $ref: '#/components/parameters/TripNo' get: description: platform:fleet:trip:list;分页记录和整趟汇总使用同一只读快照。没有登记成本时totals为空,不显示为已知零成本。 parameters: - $ref: '#/components/parameters/Page' - $ref: '#/components/parameters/Size' responses: '200': description: 业务响应,成功code为200 content: application/json: schema: allOf: - $ref: '#/components/schemas/Envelope' - type: object properties: data: { $ref: '#/components/schemas/Listing' } post: description: platform:fleet:trip:cost-create;按车次和操作人锁定创建幂等键,异载荷同键拒绝。金额末尾零与空白备注按同一内容核对;成本与当时汇总历史同事务保存。 requestBody: required: true content: application/json: schema: type: object required: [idempotencyKey, details] properties: idempotencyKey: { type: string, minLength: 8, maxLength: 128 } details: { $ref: '#/components/schemas/Draft' } responses: '200': { $ref: '#/components/responses/Cost' } /api/platform/v1/last-leg/fleet/trips/{tripNo}/costs/{costNo}: parameters: - $ref: '#/components/parameters/TripNo' - $ref: '#/components/parameters/CostNo' put: description: platform:fleet:trip:cost-edit;核对成本版本与车次归属,更正保留旧记录及当时分摊快照。原因选填,缺省使用标准动作说明。内容未变化返回原版本,不追加历史;旧版本即使内容相同仍拒绝。 requestBody: required: true content: application/json: schema: type: object required: [recordVersion, details] properties: recordVersion: { type: integer, format: int64, minimum: 0 } details: { $ref: '#/components/schemas/Draft' } reason: { type: string, maxLength: 1000 } responses: '200': { $ref: '#/components/responses/Cost' } /api/platform/v1/last-leg/fleet/trips/{tripNo}/costs/{costNo}/history: parameters: - $ref: '#/components/parameters/TripNo' - $ref: '#/components/parameters/CostNo' get: description: platform:fleet:trip:list;只返回指定车次成本的不可变更正历史,金额为当时原始币种。 parameters: - $ref: '#/components/parameters/Page' - $ref: '#/components/parameters/Size' responses: '200': description: 历史分页,data包含records/page/size/total/pages content: application/json: schema: allOf: - $ref: '#/components/schemas/Envelope' - type: object properties: data: allOf: - $ref: '#/components/schemas/Page' - type: object properties: records: { type: array, items: { $ref: '#/components/schemas/History' } } components: securitySchemes: bearerAuth: { type: http, scheme: bearer, bearerFormat: JWT } parameters: TripNo: { name: tripNo, in: path, required: true, schema: { type: string } } CostNo: { name: costNo, in: path, required: true, schema: { type: string } } Page: { name: page, in: query, schema: { type: integer, minimum: 1, default: 1 } } Size: { name: size, in: query, schema: { type: integer, minimum: 1, maximum: 100, default: 10 } } responses: Cost: description: 业务响应;A0404归属不存在,A0409版本或幂等冲突,A0422输入校验,实际发生时间不可为将来 content: application/json: schema: allOf: - $ref: '#/components/schemas/Envelope' - type: object properties: data: { $ref: '#/components/schemas/Cost' } schemas: Envelope: type: object properties: code: { type: string } message: { type: string } requestId: { type: string } traceId: { type: string } Page: type: object properties: page: { type: integer, format: int64 } size: { type: integer, format: int64 } total: { type: integer, format: int64 } pages: { type: integer, format: int64 } Draft: type: object required: [category, currency, amount, incurredAt] properties: category: { type: string, enum: [FUEL, DRIVER, TOLL, PARKING, OTHER] } currency: { type: string, enum: [CNY, USD] } amount: { type: number, minimum: 0, maximum: 999999999999.99, multipleOf: 0.01 } incurredAt: { type: string, format: date-time, description: 实际发生时间,统一按毫秒精度保存和核对 } remark: { type: string, nullable: true, maxLength: 1000 } Cost: type: object properties: costNo: { type: string } tripNo: { type: string } details: { $ref: '#/components/schemas/Draft' } recordVersion: { type: integer, format: int64 } updatedAt: { type: string, format: date-time } Allocation: type: object properties: businessNo: { type: string, description: 自有货排车单号或外接预订业务号 } sourceType: { type: string, enum: [OWN, EXTERNAL] } dispatchNo: { type: string } palletSpaces: { type: integer, format: int64 } amount: { type: number } Total: type: object properties: currency: { type: string } directCost: { type: number } allocations: { type: array, items: { $ref: '#/components/schemas/Allocation' } } ownCost: { type: number, nullable: true } externalCost: { type: number, nullable: true } Summary: type: object properties: departureVersion: { type: integer, format: int64, nullable: true } manifestHash: { type: string, nullable: true } allocationMethod: { type: string, nullable: true, enum: [SAME_ROUTE_PALLET_SPACES] } allocationBlockReason: { type: string, nullable: true } totals: { type: array, items: { $ref: '#/components/schemas/Total' } } Listing: type: object properties: page: allOf: - $ref: '#/components/schemas/Page' - type: object properties: records: { type: array, items: { $ref: '#/components/schemas/Cost' } } summary: { $ref: '#/components/schemas/Summary' } Snapshot: type: object properties: cost: { $ref: '#/components/schemas/Cost' } summary: { $ref: '#/components/schemas/Summary' } History: type: object properties: recordVersion: { type: integer, format: int64 } action: { type: string, enum: [CREATE, UPDATE] } reason: { type: string } occurredAt: { type: string, format: date-time } snapshot: { $ref: '#/components/schemas/Snapshot' }