feat(fleet): integrate costs quotes operations and in-transit handovers
This commit is contained in:
@@ -1212,6 +1212,138 @@ CREATE TABLE ll_fleet_trip_history (
|
||||
CONSTRAINT fk_fleet_trip_history FOREIGN KEY (trip_id) REFERENCES ll_fleet_trip(id)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='运输车次操作历史';
|
||||
|
||||
CREATE TABLE ll_fleet_trip_operations_record (
|
||||
id BIGINT NOT NULL COMMENT '出车实测历史主键',
|
||||
trip_no VARCHAR(64) NOT NULL COMMENT '车次业务编号',
|
||||
record_version BIGINT NOT NULL COMMENT '实测记录版本从一递增',
|
||||
details_json JSON NOT NULL COMMENT '实际里程英里油耗升与备注快照',
|
||||
reason VARCHAR(1000) NOT NULL COMMENT '实测更正说明',
|
||||
operator_id VARCHAR(64) NOT NULL COMMENT '实测操作人标识',
|
||||
request_key VARCHAR(128) NOT NULL COMMENT '实测保存幂等键',
|
||||
request_hash CHAR(64) NOT NULL COMMENT '实测请求内容摘要',
|
||||
occurred_at DATETIME(3) NOT NULL COMMENT '实测保存时间UTC',
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE KEY uk_fleet_operations_version (trip_no,record_version),
|
||||
UNIQUE KEY uk_fleet_operations_request (trip_no,operator_id,request_key)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='车次里程油耗不可变更正记录';
|
||||
|
||||
CREATE TABLE ll_fleet_trip_handover (
|
||||
id BIGINT NOT NULL COMMENT '内部主键',
|
||||
trip_id BIGINT NOT NULL COMMENT '所属车次',
|
||||
trip_version BIGINT NOT NULL COMMENT '交接对应车次历史版本',
|
||||
trip_no VARCHAR(32) NOT NULL COMMENT '车次业务编号',
|
||||
handover_no VARCHAR(32) NOT NULL COMMENT '交接业务编号',
|
||||
request_key VARCHAR(128) NOT NULL COMMENT '交接请求幂等键',
|
||||
request_hash CHAR(64) NOT NULL COMMENT '交接请求摘要',
|
||||
record_version BIGINT NOT NULL DEFAULT 0 COMMENT '资源结束并发版本',
|
||||
handed_over_at DATETIME(3) NOT NULL COMMENT '实际交接UTC时间',
|
||||
snapshot_json JSON NOT NULL COMMENT '不可变资源及剩余货物交接快照',
|
||||
vehicle_release_json JSON NULL COMMENT '原车辆任务结束及幂等结果',
|
||||
driver_release_json JSON NULL COMMENT '原司机任务结束及幂等结果',
|
||||
created_by VARCHAR(64) NOT NULL COMMENT '记录操作人',
|
||||
created_at DATETIME(3) NOT NULL COMMENT '记录UTC时间',
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE KEY uk_fleet_handover_no (handover_no),
|
||||
UNIQUE KEY uk_fleet_handover_request (trip_id, request_key),
|
||||
UNIQUE KEY uk_fleet_handover_version (trip_id, trip_version),
|
||||
KEY idx_fleet_handover_page (trip_id, id),
|
||||
CONSTRAINT fk_fleet_handover_trip FOREIGN KEY (trip_id) REFERENCES ll_fleet_trip(id)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='在途车辆司机交接';
|
||||
|
||||
CREATE TABLE ll_fleet_finance_source (
|
||||
id BIGINT UNSIGNED NOT NULL COMMENT '来源提交主键',
|
||||
record_id BIGINT UNSIGNED NOT NULL COMMENT '车辆运维记录主键',
|
||||
source_version BIGINT UNSIGNED NOT NULL COMMENT '独立财务来源版本,从1递增',
|
||||
record_version BIGINT UNSIGNED NOT NULL COMMENT '提交时运维记录版本',
|
||||
operator_id VARCHAR(64) NOT NULL COMMENT '提交操作人标识',
|
||||
request_key VARCHAR(128) NOT NULL COMMENT '原请求幂等键',
|
||||
request_hash VARCHAR(71) NOT NULL COMMENT '规范请求摘要,含sha256前缀',
|
||||
event_id VARCHAR(128) NOT NULL COMMENT '关联公共Outbox事件ID',
|
||||
payload_json JSON NOT NULL COMMENT '不可变公司成本来源快照',
|
||||
created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '提交时间UTC',
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE KEY uk_fleet_finance_source_version (record_id,source_version),
|
||||
UNIQUE KEY uk_fleet_finance_source_request (record_id,operator_id,request_key),
|
||||
UNIQUE KEY uk_fleet_finance_source_event (event_id),
|
||||
CONSTRAINT chk_fleet_finance_source_version CHECK (source_version>0)
|
||||
) ENGINE=InnoDB COMMENT='维修救援公司成本提交来源,不保存付款推定';
|
||||
|
||||
CREATE TABLE ll_fleet_quote (
|
||||
id BIGINT PRIMARY KEY COMMENT '报价记录主键',
|
||||
quote_no VARCHAR(64) NOT NULL COMMENT '报价业务编号',
|
||||
kind VARCHAR(16) NOT NULL COMMENT '报价用途采购或销售',
|
||||
party_id BIGINT NOT NULL COMMENT '供应商或客户主档标识',
|
||||
party_name VARCHAR(160) NOT NULL COMMENT '往来单位名称快照',
|
||||
origin_city VARCHAR(128) NOT NULL COMMENT '发货城市',
|
||||
destination_code VARCHAR(64) NOT NULL COMMENT '目的仓业务编码',
|
||||
valid_from DATE NOT NULL COMMENT '报价生效日期',
|
||||
valid_to DATE NOT NULL COMMENT '报价失效日期含当天',
|
||||
status VARCHAR(16) NOT NULL COMMENT '报价启停或删除状态',
|
||||
natural_key CHAR(64) NOT NULL COMMENT '报价组合去重摘要',
|
||||
details_json JSON NOT NULL COMMENT '完整报价明细快照',
|
||||
record_version BIGINT NOT NULL COMMENT '报价记录版本',
|
||||
create_key VARCHAR(128) NOT NULL COMMENT '创建幂等键',
|
||||
create_hash CHAR(64) NOT NULL COMMENT '创建请求含导入批次内容摘要',
|
||||
created_by VARCHAR(64) NOT NULL COMMENT '创建操作人标识',
|
||||
created_at DATETIME(3) NOT NULL COMMENT '创建时间UTC',
|
||||
updated_at DATETIME(3) NOT NULL COMMENT '更新时间UTC',
|
||||
UNIQUE KEY uk_fleet_quote_no (quote_no),
|
||||
UNIQUE KEY uk_fleet_quote_natural (natural_key),
|
||||
UNIQUE KEY uk_fleet_quote_create (created_by,create_key),
|
||||
KEY idx_fleet_quote_search (kind,status,valid_from,valid_to)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='车辆采购与外接销售报价';
|
||||
|
||||
CREATE TABLE ll_fleet_quote_history (
|
||||
id BIGINT PRIMARY KEY COMMENT '报价历史主键',
|
||||
quote_id BIGINT NOT NULL COMMENT '报价记录标识',
|
||||
record_version BIGINT NOT NULL COMMENT '报价记录版本',
|
||||
action VARCHAR(24) NOT NULL COMMENT '报价操作类型',
|
||||
operator_id VARCHAR(64) NOT NULL COMMENT '操作人标识',
|
||||
occurred_at DATETIME(3) NOT NULL COMMENT '操作时间UTC',
|
||||
snapshot_json JSON NOT NULL COMMENT '报价完整版本快照',
|
||||
UNIQUE KEY uk_fleet_quote_history_version (quote_id,record_version)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='车辆报价不可变版本历史';
|
||||
|
||||
CREATE TABLE ll_fleet_trip_cost (
|
||||
id BIGINT NOT NULL COMMENT '内部主键',
|
||||
trip_id BIGINT NOT NULL COMMENT '车次内部引用',
|
||||
cost_no VARCHAR(32) NOT NULL COMMENT '车次成本业务编号',
|
||||
category VARCHAR(16) NOT NULL COMMENT '直接成本类别FUEL/DRIVER/TOLL/PARKING/OTHER',
|
||||
currency VARCHAR(3) NOT NULL COMMENT '原始成本币种CNY/USD,不混币汇总',
|
||||
amount DECIMAL(14,2) NOT NULL COMMENT '运营登记金额,不代表付款',
|
||||
incurred_at DATETIME(3) NOT NULL COMMENT '实际费用发生UTC时间',
|
||||
remark VARCHAR(1000) NULL COMMENT '费用备注',
|
||||
record_version BIGINT NOT NULL COMMENT '成本记录版本',
|
||||
request_key VARCHAR(128) NOT NULL COMMENT '创建幂等键',
|
||||
request_hash CHAR(64) NOT NULL COMMENT '创建请求摘要',
|
||||
created_by VARCHAR(64) NOT NULL COMMENT '登记人',
|
||||
updated_by VARCHAR(64) NOT NULL COMMENT '最近更正人',
|
||||
created_at DATETIME(3) NOT NULL COMMENT '登记UTC时间',
|
||||
updated_at DATETIME(3) NOT NULL COMMENT '更正UTC时间',
|
||||
PRIMARY KEY(id),
|
||||
UNIQUE KEY uk_fleet_trip_cost_no(cost_no),
|
||||
UNIQUE KEY uk_fleet_trip_cost_request(trip_id,created_by,request_key),
|
||||
KEY idx_fleet_trip_cost_page(trip_id,incurred_at,id),
|
||||
CONSTRAINT fk_fleet_trip_cost_trip FOREIGN KEY(trip_id) REFERENCES ll_fleet_trip(id),
|
||||
CONSTRAINT ck_fleet_trip_cost_amount CHECK(amount>=0),
|
||||
CONSTRAINT ck_fleet_trip_cost_currency CHECK(currency IN ('CNY','USD')),
|
||||
CONSTRAINT ck_fleet_trip_cost_category CHECK(category IN ('FUEL','DRIVER','TOLL','PARKING','OTHER'))
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='车次直接运营成本,不生成客户账单或付款';
|
||||
|
||||
CREATE TABLE ll_fleet_trip_cost_history (
|
||||
id BIGINT NOT NULL COMMENT '内部主键',
|
||||
cost_id BIGINT NOT NULL COMMENT '成本记录内部引用',
|
||||
record_version BIGINT NOT NULL COMMENT '成本更正后版本',
|
||||
action VARCHAR(16) NOT NULL COMMENT '成本操作CREATE/UPDATE',
|
||||
reason VARCHAR(1000) NULL COMMENT '登记或更正说明',
|
||||
operator_id VARCHAR(64) NOT NULL COMMENT '操作人',
|
||||
occurred_at DATETIME(3) NOT NULL COMMENT '操作UTC时间',
|
||||
snapshot_json JSON NOT NULL COMMENT '成本与当时整趟汇总及分摊快照',
|
||||
PRIMARY KEY(id),
|
||||
UNIQUE KEY uk_fleet_trip_cost_history(cost_id,record_version),
|
||||
CONSTRAINT fk_fleet_trip_cost_history FOREIGN KEY(cost_id) REFERENCES ll_fleet_trip_cost(id)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='车次成本不可变更正历史';
|
||||
|
||||
SET @ddl = (SELECT IF(EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema=DATABASE() AND table_name='ll_event_outbox' AND column_name='locked_at'), 'SELECT 1', 'ALTER TABLE ll_event_outbox ADD COLUMN locked_at DATETIME(3) NULL COMMENT ''投递租约获取时间'' AFTER published_at'));
|
||||
PREPARE ll_outbox_lease_stmt FROM @ddl; EXECUTE ll_outbox_lease_stmt; DEALLOCATE PREPARE ll_outbox_lease_stmt;
|
||||
SET @ddl = (SELECT IF(EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema=DATABASE() AND table_name='ll_event_outbox' AND column_name='locked_by'), 'SELECT 1', 'ALTER TABLE ll_event_outbox ADD COLUMN locked_by VARCHAR(128) NULL COMMENT ''投递租约持有者'' AFTER locked_at'));
|
||||
|
||||
@@ -0,0 +1,290 @@
|
||||
openapi: 3.0.3
|
||||
info:
|
||||
title: 车辆在途交接
|
||||
version: 1.0.0
|
||||
description: 从不可变DEPART及真实派送终态核对剩余货物。交接不重新出库或收费,不重写原始发车。旧车辆和司机分别确认实际任务结束后释放。
|
||||
security:
|
||||
- bearerAuth: []
|
||||
paths:
|
||||
/api/pda/v1/last-leg/dispatches/{dispatchNo}/handover-status:
|
||||
get:
|
||||
description: lastleg:pda:operate及ROLE_OVERSEAS_WAREHOUSE_PDA_OPERATOR;只读,仓库来自Token。只返回所选排车的原发车资源、逐派送当前资源及涉及该排车的最近交接,不返回其他客户货物或内部ID。不提供PDA交接确认写接口。
|
||||
parameters:
|
||||
- { name: dispatchNo, in: path, required: true, schema: { type: string } }
|
||||
responses:
|
||||
'200':
|
||||
description: 当前排车运输及交接状态
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/Envelope'
|
||||
- type: object
|
||||
properties:
|
||||
data:
|
||||
type: object
|
||||
properties:
|
||||
dispatchNo: { type: string }
|
||||
tripNo: { type: string }
|
||||
tripStatus: { type: string, enum: [IN_TRANSIT, COMPLETED] }
|
||||
tripRecordVersion: { type: string }
|
||||
originalDeparture: { $ref: '#/components/schemas/Transport' }
|
||||
deliveries:
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
deliveryNo: { type: string }
|
||||
status: { type: string }
|
||||
packages: { type: integer }
|
||||
terminalAt: { type: string, format: date-time, nullable: true }
|
||||
transport: { $ref: '#/components/schemas/Transport' }
|
||||
latestHandover:
|
||||
type: object
|
||||
nullable: true
|
||||
properties:
|
||||
handoverNo: { type: string }
|
||||
handedOverAt: { type: string, format: date-time }
|
||||
location: { type: string }
|
||||
previous: { $ref: '#/components/schemas/Transport' }
|
||||
replacement: { $ref: '#/components/schemas/Transport' }
|
||||
/api/platform/v1/last-leg/fleet/trips/{tripNo}/handovers:
|
||||
parameters:
|
||||
- $ref: '#/components/parameters/TripNo'
|
||||
get:
|
||||
description: platform:fleet:trip:list;按车次分页读取交接及原资源任务结束记录。
|
||||
parameters:
|
||||
- { name: page, in: query, schema: { type: integer, minimum: 1, default: 1 } }
|
||||
- { name: size, in: query, schema: { type: integer, minimum: 1, maximum: 100, default: 20 } }
|
||||
responses:
|
||||
'200':
|
||||
description: 业务响应
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/Envelope'
|
||||
- type: object
|
||||
properties:
|
||||
data:
|
||||
type: object
|
||||
required: [records, page, size, total, pages]
|
||||
properties:
|
||||
records: { type: array, items: { $ref: '#/components/schemas/Handover' } }
|
||||
page: { type: integer }
|
||||
size: { type: integer }
|
||||
total: { type: integer, format: int64 }
|
||||
pages: { type: integer }
|
||||
post:
|
||||
description: platform:fleet:trip:handover;同车次请求键唯一,异内容拒绝;先锁车次及新资源,再锁原客户执行单复核。原资源仍占用,车次保持IN_TRANSIT,仅未完成派送更新资源。失败整体回滚。
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
required: [selection, cargoHash, location, idempotencyKey]
|
||||
properties:
|
||||
selection: { $ref: '#/components/schemas/Selection' }
|
||||
cargoHash: { type: string, pattern: '^[0-9a-f]{64}$' }
|
||||
location: { type: string, minLength: 1, maxLength: 500 }
|
||||
reason: { type: string, maxLength: 1000 }
|
||||
idempotencyKey: { type: string, minLength: 8, maxLength: 128 }
|
||||
responses:
|
||||
'200': { $ref: '#/components/responses/Handover' }
|
||||
/api/platform/v1/last-leg/fleet/trips/{tripNo}/handovers/preview:
|
||||
parameters:
|
||||
- $ref: '#/components/parameters/TripNo'
|
||||
post:
|
||||
description: platform:fleet:trip:list;只核对不写入。资格、容量、占用和派送事实变化使cargoHash失效。已签收后另退货使用原签收事实,未签收退回必须有RETURN_COMPLETED证据。部分同托仍用原整托实测,不按箱数比例猜重量体积。
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema: { $ref: '#/components/schemas/Selection' }
|
||||
responses:
|
||||
'200':
|
||||
description: 交接预览
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/Envelope'
|
||||
- type: object
|
||||
properties:
|
||||
data:
|
||||
type: object
|
||||
required: [tripNo, recordVersion, cargoHash, previous, replacement, capacity, cargo, driverQualification]
|
||||
properties:
|
||||
tripNo: { type: string }
|
||||
recordVersion: { type: integer, format: int64 }
|
||||
cargoHash: { type: string }
|
||||
previous: { $ref: '#/components/schemas/Resource' }
|
||||
replacement: { $ref: '#/components/schemas/Resource' }
|
||||
capacity: { $ref: '#/components/schemas/Load' }
|
||||
cargo: { $ref: '#/components/schemas/Inspection' }
|
||||
driverQualification:
|
||||
type: object
|
||||
properties:
|
||||
canDispatch: { type: boolean }
|
||||
expiringSoon: { type: boolean }
|
||||
reason: { type: string }
|
||||
licenseExpiresOn: { type: string, format: date, nullable: true }
|
||||
/api/platform/v1/last-leg/fleet/trips/{tripNo}/handovers/{handoverNo}/resources/release:
|
||||
parameters:
|
||||
- $ref: '#/components/parameters/TripNo'
|
||||
- { name: handoverNo, in: path, required: true, schema: { type: string } }
|
||||
post:
|
||||
description: platform:fleet:trip:release;分别结束被接替车辆或司机任务,可早于整车货物结案。未变化资源仍由原车次结案后释放。原请求重放不操作后续占用,车辆状态与结束记录同事务提交。
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
required: [recordVersion, resourceKind, actualEndAt, location, idempotencyKey]
|
||||
properties:
|
||||
recordVersion: { type: integer, format: int64, minimum: 0, description: 交接记录版本 }
|
||||
resourceKind: { type: string, enum: [VEHICLE, DRIVER] }
|
||||
actualEndAt: { type: string, format: date-time }
|
||||
location: { type: string, minLength: 1, maxLength: 500 }
|
||||
vehicleStatus: { type: string, nullable: true, enum: [IN_SERVICE, MAINTENANCE, INACTIVE, RETURNED], description: 结束原车辆必填;司机不得提交 }
|
||||
idempotencyKey: { type: string, minLength: 8, maxLength: 128 }
|
||||
responses:
|
||||
'200': { $ref: '#/components/responses/Handover' }
|
||||
components:
|
||||
securitySchemes:
|
||||
bearerAuth: { type: http, scheme: bearer, bearerFormat: JWT }
|
||||
parameters:
|
||||
TripNo: { name: tripNo, in: path, required: true, schema: { type: string } }
|
||||
responses:
|
||||
Handover:
|
||||
description: 已保存的交接事实及资源结束状态
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/Envelope'
|
||||
- type: object
|
||||
properties:
|
||||
data: { $ref: '#/components/schemas/Handover' }
|
||||
schemas:
|
||||
Transport:
|
||||
type: object
|
||||
properties:
|
||||
vehiclePlate: { type: string, nullable: true }
|
||||
driverName: { type: string, nullable: true }
|
||||
driverPhone: { type: string, nullable: true }
|
||||
Envelope:
|
||||
type: object
|
||||
required: [code]
|
||||
properties:
|
||||
code: { type: string, example: '200' }
|
||||
message: { type: string }
|
||||
Selection:
|
||||
type: object
|
||||
required: [recordVersion, vehicleId, driverId, expectedDriverEndAt, handedOverAt]
|
||||
properties:
|
||||
recordVersion: { type: integer, format: int64, minimum: 0 }
|
||||
vehicleId: { type: string, pattern: '^[1-9][0-9]*$' }
|
||||
driverId: { type: string, pattern: '^[1-9][0-9]*$' }
|
||||
expectedDriverEndAt: { type: string, format: date-time }
|
||||
handedOverAt: { type: string, format: date-time }
|
||||
Resource:
|
||||
type: object
|
||||
properties:
|
||||
vehicleId: { type: string }
|
||||
vehiclePlate: { type: string, nullable: true }
|
||||
driverId: { type: string }
|
||||
driverName: { type: string, nullable: true }
|
||||
driverPhone: { type: string, nullable: true }
|
||||
Load:
|
||||
type: object
|
||||
properties:
|
||||
palletSpaces: { type: integer }
|
||||
weightKg: { type: number }
|
||||
volumeCbm: { type: number }
|
||||
Cargo:
|
||||
type: object
|
||||
properties:
|
||||
customerId: { type: string, description: 隔离键,不作客户名称展示 }
|
||||
dispatchNo: { type: string }
|
||||
itemId: { type: string, description: 内部核对键,不作业务编号展示 }
|
||||
palletId: { type: string, description: 内部核对键,不作托盘码展示 }
|
||||
destinationKey: { type: string, description: 匹配键,私人地址摘要不可作地址展示 }
|
||||
packages: { type: integer }
|
||||
Delivery:
|
||||
type: object
|
||||
properties:
|
||||
customerId: { type: string }
|
||||
dispatchNo: { type: string }
|
||||
deliveryNo: { type: string }
|
||||
destinationKey: { type: string }
|
||||
packages: { type: integer }
|
||||
terminalAt: { type: string, format: date-time, nullable: true }
|
||||
Inspection:
|
||||
type: object
|
||||
properties:
|
||||
remainingCargo: { type: array, items: { $ref: '#/components/schemas/Cargo' } }
|
||||
completedDeliveries: { type: array, items: { $ref: '#/components/schemas/Delivery' } }
|
||||
remainingPalletIds: { type: array, uniqueItems: true, items: { type: string } }
|
||||
occupied: { $ref: '#/components/schemas/Load' }
|
||||
Snapshot:
|
||||
type: object
|
||||
properties:
|
||||
previous: { $ref: '#/components/schemas/Resource' }
|
||||
replacement: { $ref: '#/components/schemas/Resource' }
|
||||
handedOverAt: { type: string, format: date-time }
|
||||
location: { type: string }
|
||||
reason: { type: string }
|
||||
expectedDriverEndAt: { type: string, format: date-time }
|
||||
capacity: { $ref: '#/components/schemas/Load' }
|
||||
cargo: { $ref: '#/components/schemas/Inspection' }
|
||||
executionEvidence:
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
dispatchNo: { type: string }
|
||||
customerId: { type: string }
|
||||
warehouseId: { type: string }
|
||||
shippedPackages: { type: integer }
|
||||
deliveries:
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
cargo: { $ref: '#/components/schemas/Delivery' }
|
||||
status: { type: string }
|
||||
recordVersion: { type: integer, format: int64 }
|
||||
transport: { $ref: '#/components/schemas/Transport' }
|
||||
operatorId: { type: string, description: 审计身份,不作姓名展示 }
|
||||
carriedDeliveries:
|
||||
type: array
|
||||
description: 当次实际交接的未完成派送身份,用于车辆运输区段查询
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
customerId: { type: string }
|
||||
deliveryNo: { type: string }
|
||||
recordedAt: { type: string, format: date-time }
|
||||
Released:
|
||||
type: object
|
||||
nullable: true
|
||||
properties:
|
||||
idempotencyKey: { type: string }
|
||||
requestHash: { type: string }
|
||||
actualEndAt: { type: string, format: date-time }
|
||||
location: { type: string }
|
||||
vehicleStatus: { type: string, nullable: true }
|
||||
operatorId: { type: string }
|
||||
recordedAt: { type: string, format: date-time }
|
||||
Handover:
|
||||
type: object
|
||||
properties:
|
||||
handoverNo: { type: string }
|
||||
tripNo: { type: string }
|
||||
recordVersion: { type: integer, format: int64 }
|
||||
snapshot: { $ref: '#/components/schemas/Snapshot' }
|
||||
vehicleRelease: { $ref: '#/components/schemas/Released' }
|
||||
driverRelease: { $ref: '#/components/schemas/Released' }
|
||||
@@ -0,0 +1,928 @@
|
||||
{
|
||||
"openapi": "3.0.3",
|
||||
"info": {
|
||||
"title": "真实出车与自有外接运营统计",
|
||||
"version": "1.0.0",
|
||||
"description": "仅实际departed_at非空车次;使用DEPART不可变快照,一车次计一次,跨客户或多目的地不重复。物理托盘去重;自有与外接箱数以BOUND外接实收归属核算,支持同排车/同托混货。全筛选汇总与分页同快照;sourceType筛选含该类货的整车,并非裁切另一类货物。from含、to不含,UTC,最多366天/5000车次。发车车牌/司机使用历史,货物结案状态使用当前事实。约定金额按币种分别累计,不是财务应收/实收;财务未查询明确NOT_QUERIED;成本只通过FleetTripCostService.summaries(Collection<String>)按最多100车次一批读取,保持现有trip:list成本读权限。无权限为FORBIDDEN,既有车次无登记为NOT_RECORDED;可读汇总仅包含已登记直接成本,返回未登记及未能分摊车次数,未知分摊值为null。查询不跨服务逐行HTTP,不写执行状态。 图表与分页共用全筛选快照:按UTC日展示实运托盘及外接约定金额,目的地按稳定键统计涉及车次。按托均价仅包含PALLET计价,用该币种约定总金额除确认计价标准托位,ORDER报价排除。里程mile、油耗L是授权补充事实,与车辆档案累计里程和直接成本独立。"
|
||||
},
|
||||
"security": [
|
||||
{
|
||||
"bearerAuth": []
|
||||
}
|
||||
],
|
||||
"paths": {
|
||||
"/api/platform/v1/last-leg/fleet/operations": {
|
||||
"get": {
|
||||
"description": "platform:fleet:operations:list;一次查询返回分页与全范围汇总",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "page",
|
||||
"in": "query",
|
||||
"required": false,
|
||||
"schema": {
|
||||
"type": "integer",
|
||||
"default": 1,
|
||||
"minimum": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "size",
|
||||
"in": "query",
|
||||
"required": false,
|
||||
"schema": {
|
||||
"type": "integer",
|
||||
"default": 20,
|
||||
"minimum": 1,
|
||||
"maximum": 200
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "from",
|
||||
"in": "query",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string",
|
||||
"format": "date-time"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "to",
|
||||
"in": "query",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string",
|
||||
"format": "date-time"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "warehouseId",
|
||||
"in": "query",
|
||||
"required": false,
|
||||
"schema": {
|
||||
"type": "integer",
|
||||
"format": "int64",
|
||||
"minimum": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "keyword",
|
||||
"in": "query",
|
||||
"required": false,
|
||||
"schema": {
|
||||
"type": "string",
|
||||
"maxLength": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "sourceType",
|
||||
"in": "query",
|
||||
"required": false,
|
||||
"schema": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"OWN",
|
||||
"EXTERNAL"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "status",
|
||||
"in": "query",
|
||||
"required": false,
|
||||
"schema": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"IN_TRANSIT",
|
||||
"COMPLETED"
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "业务响应;成功code为200,业务失败不代表写入成功",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"code": {
|
||||
"type": "string"
|
||||
},
|
||||
"message": {
|
||||
"type": "string"
|
||||
},
|
||||
"data": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"page": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"records": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/Row"
|
||||
}
|
||||
},
|
||||
"page": {
|
||||
"type": "integer",
|
||||
"minimum": 0
|
||||
},
|
||||
"size": {
|
||||
"type": "integer",
|
||||
"minimum": 0
|
||||
},
|
||||
"total": {
|
||||
"type": "integer",
|
||||
"minimum": 0
|
||||
},
|
||||
"pages": {
|
||||
"type": "integer",
|
||||
"minimum": 0
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"records",
|
||||
"page",
|
||||
"size",
|
||||
"total",
|
||||
"pages"
|
||||
]
|
||||
},
|
||||
"summary": {
|
||||
"$ref": "#/components/schemas/Summary"
|
||||
},
|
||||
"charts": {
|
||||
"$ref": "#/components/schemas/Charts"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"page",
|
||||
"summary",
|
||||
"charts"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"code",
|
||||
"message",
|
||||
"data"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/platform/v1/last-leg/fleet/operations/export": {
|
||||
"get": {
|
||||
"description": "platform:fleet:operations:export;同筛选同事实来源的CSV",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "page",
|
||||
"in": "query",
|
||||
"required": false,
|
||||
"schema": {
|
||||
"type": "integer",
|
||||
"default": 1,
|
||||
"minimum": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "size",
|
||||
"in": "query",
|
||||
"required": false,
|
||||
"schema": {
|
||||
"type": "integer",
|
||||
"default": 20,
|
||||
"minimum": 1,
|
||||
"maximum": 200
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "from",
|
||||
"in": "query",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string",
|
||||
"format": "date-time"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "to",
|
||||
"in": "query",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string",
|
||||
"format": "date-time"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "warehouseId",
|
||||
"in": "query",
|
||||
"required": false,
|
||||
"schema": {
|
||||
"type": "integer",
|
||||
"format": "int64",
|
||||
"minimum": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "keyword",
|
||||
"in": "query",
|
||||
"required": false,
|
||||
"schema": {
|
||||
"type": "string",
|
||||
"maxLength": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "sourceType",
|
||||
"in": "query",
|
||||
"required": false,
|
||||
"schema": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"OWN",
|
||||
"EXTERNAL"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "status",
|
||||
"in": "query",
|
||||
"required": false,
|
||||
"schema": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"IN_TRANSIT",
|
||||
"COMPLETED"
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "UTF-8 BOM CSV",
|
||||
"content": {
|
||||
"text/csv": {
|
||||
"schema": {
|
||||
"type": "string",
|
||||
"format": "binary"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/platform/v1/last-leg/fleet/operations/{tripNo}/record": {
|
||||
"parameters": [
|
||||
{
|
||||
"name": "tripNo",
|
||||
"in": "path",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"get": {
|
||||
"description": "platform:fleet:operations:list;仅实际已发车车次;尚未登记返回版本0和空值,不伪造零里程/油耗",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "业务响应,成功code为200",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"code": {
|
||||
"type": "string"
|
||||
},
|
||||
"message": {
|
||||
"type": "string"
|
||||
},
|
||||
"data": {
|
||||
"$ref": "#/components/schemas/MeasuredRecord"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"code",
|
||||
"message",
|
||||
"data"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"put": {
|
||||
"description": "platform:fleet:operations:edit;父车次行锁、版本与原操作人请求键校验,原请求返回原快照,更正追加不可变历史。空值区别零,说明选填。不修改主档里程、车次执行、库存或费用。",
|
||||
"requestBody": {
|
||||
"required": true,
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"recordVersion": {
|
||||
"type": "integer",
|
||||
"minimum": 0
|
||||
},
|
||||
"idempotencyKey": {
|
||||
"type": "string",
|
||||
"minLength": 8,
|
||||
"maxLength": 128
|
||||
},
|
||||
"details": {
|
||||
"$ref": "#/components/schemas/Measured"
|
||||
},
|
||||
"reason": {
|
||||
"type": "string",
|
||||
"maxLength": 1000,
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"recordVersion",
|
||||
"idempotencyKey",
|
||||
"details",
|
||||
"reason"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "业务响应,成功code为200",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"code": {
|
||||
"type": "string"
|
||||
},
|
||||
"message": {
|
||||
"type": "string"
|
||||
},
|
||||
"data": {
|
||||
"$ref": "#/components/schemas/MeasuredRecord"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"code",
|
||||
"message",
|
||||
"data"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/platform/v1/last-leg/fleet/operations/{tripNo}/record/history": {
|
||||
"parameters": [
|
||||
{
|
||||
"name": "tripNo",
|
||||
"in": "path",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"get": {
|
||||
"description": "platform:fleet:operations:list;实测更正历史,按版本倒序分页",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "page",
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"type": "integer",
|
||||
"minimum": 1,
|
||||
"default": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "size",
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"type": "integer",
|
||||
"minimum": 1,
|
||||
"maximum": 100,
|
||||
"default": 20
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "业务响应,成功code为200",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"code": {
|
||||
"type": "string"
|
||||
},
|
||||
"message": {
|
||||
"type": "string"
|
||||
},
|
||||
"data": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"records": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/MeasuredHistory"
|
||||
}
|
||||
},
|
||||
"page": {
|
||||
"type": "integer",
|
||||
"minimum": 0
|
||||
},
|
||||
"size": {
|
||||
"type": "integer",
|
||||
"minimum": 0
|
||||
},
|
||||
"total": {
|
||||
"type": "integer",
|
||||
"minimum": 0
|
||||
},
|
||||
"pages": {
|
||||
"type": "integer",
|
||||
"minimum": 0
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"records",
|
||||
"page",
|
||||
"size",
|
||||
"total",
|
||||
"pages"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"code",
|
||||
"message",
|
||||
"data"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
"securitySchemes": {
|
||||
"bearerAuth": {
|
||||
"type": "http",
|
||||
"scheme": "bearer",
|
||||
"bearerFormat": "JWT"
|
||||
}
|
||||
},
|
||||
"schemas": {
|
||||
"Money": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"currency": {
|
||||
"type": "string"
|
||||
},
|
||||
"amount": {
|
||||
"type": "number",
|
||||
"minimum": 0
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"currency",
|
||||
"amount"
|
||||
]
|
||||
},
|
||||
"Row": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"tripNo": {
|
||||
"type": "string"
|
||||
},
|
||||
"status": {
|
||||
"type": "string"
|
||||
},
|
||||
"vehiclePlate": {
|
||||
"type": "string",
|
||||
"nullable": true
|
||||
},
|
||||
"driverName": {
|
||||
"type": "string",
|
||||
"nullable": true
|
||||
},
|
||||
"warehouseName": {
|
||||
"type": "string",
|
||||
"nullable": true
|
||||
},
|
||||
"departedAt": {
|
||||
"type": "string",
|
||||
"format": "date-time"
|
||||
},
|
||||
"completedAt": {
|
||||
"type": "string",
|
||||
"format": "date-time",
|
||||
"nullable": true
|
||||
},
|
||||
"destinations": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/Destination"
|
||||
}
|
||||
},
|
||||
"physicalPallets": {
|
||||
"type": "integer",
|
||||
"minimum": 0
|
||||
},
|
||||
"palletSpaces": {
|
||||
"type": "integer",
|
||||
"minimum": 0
|
||||
},
|
||||
"ownPackages": {
|
||||
"type": "integer",
|
||||
"minimum": 0
|
||||
},
|
||||
"externalPackages": {
|
||||
"type": "integer",
|
||||
"minimum": 0
|
||||
},
|
||||
"externalAgreedAmounts": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/Money"
|
||||
}
|
||||
},
|
||||
"financeStatus": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"NOT_QUERIED"
|
||||
]
|
||||
},
|
||||
"costStatus": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"FORBIDDEN",
|
||||
"NOT_RECORDED",
|
||||
"AVAILABLE"
|
||||
]
|
||||
},
|
||||
"externalPalletRates": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/PalletRate"
|
||||
}
|
||||
},
|
||||
"measured": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/Measured"
|
||||
}
|
||||
],
|
||||
"nullable": true
|
||||
},
|
||||
"costs": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "./fleet-trip-costs-v1.yaml#/components/schemas/Summary"
|
||||
}
|
||||
],
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"tripNo",
|
||||
"status",
|
||||
"vehiclePlate",
|
||||
"driverName",
|
||||
"warehouseName",
|
||||
"departedAt",
|
||||
"completedAt",
|
||||
"destinations",
|
||||
"physicalPallets",
|
||||
"palletSpaces",
|
||||
"ownPackages",
|
||||
"externalPackages",
|
||||
"externalAgreedAmounts",
|
||||
"financeStatus",
|
||||
"costStatus",
|
||||
"externalPalletRates",
|
||||
"measured",
|
||||
"costs"
|
||||
]
|
||||
},
|
||||
"Summary": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"trips": {
|
||||
"type": "integer",
|
||||
"minimum": 0
|
||||
},
|
||||
"inTransit": {
|
||||
"type": "integer",
|
||||
"minimum": 0
|
||||
},
|
||||
"completed": {
|
||||
"type": "integer",
|
||||
"minimum": 0
|
||||
},
|
||||
"physicalPallets": {
|
||||
"type": "integer",
|
||||
"minimum": 0
|
||||
},
|
||||
"palletSpaces": {
|
||||
"type": "integer",
|
||||
"minimum": 0
|
||||
},
|
||||
"ownPackages": {
|
||||
"type": "integer",
|
||||
"minimum": 0
|
||||
},
|
||||
"externalPackages": {
|
||||
"type": "integer",
|
||||
"minimum": 0
|
||||
},
|
||||
"externalAgreedAmounts": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/Money"
|
||||
}
|
||||
},
|
||||
"costs": {
|
||||
"$ref": "#/components/schemas/CostSummary"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"trips",
|
||||
"inTransit",
|
||||
"completed",
|
||||
"physicalPallets",
|
||||
"palletSpaces",
|
||||
"ownPackages",
|
||||
"externalPackages",
|
||||
"externalAgreedAmounts",
|
||||
"costs"
|
||||
]
|
||||
},
|
||||
"Measured": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"actualDistanceMiles": {
|
||||
"type": "number",
|
||||
"minimum": 0,
|
||||
"nullable": true,
|
||||
"multipleOf": 0.1
|
||||
},
|
||||
"actualFuelLitres": {
|
||||
"type": "number",
|
||||
"minimum": 0,
|
||||
"nullable": true,
|
||||
"multipleOf": 0.1
|
||||
},
|
||||
"remark": {
|
||||
"type": "string",
|
||||
"nullable": true,
|
||||
"maxLength": 1000
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"actualDistanceMiles",
|
||||
"actualFuelLitres",
|
||||
"remark"
|
||||
]
|
||||
},
|
||||
"Destination": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"key": {
|
||||
"type": "string"
|
||||
},
|
||||
"label": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"key",
|
||||
"label"
|
||||
]
|
||||
},
|
||||
"PalletRate": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"currency": {
|
||||
"type": "string"
|
||||
},
|
||||
"pricedPalletSpaces": {
|
||||
"type": "integer",
|
||||
"minimum": 0
|
||||
},
|
||||
"agreedAmount": {
|
||||
"type": "number",
|
||||
"minimum": 0
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"currency",
|
||||
"pricedPalletSpaces",
|
||||
"agreedAmount"
|
||||
]
|
||||
},
|
||||
"Series": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"label": {
|
||||
"type": "string"
|
||||
},
|
||||
"unit": {
|
||||
"type": "string"
|
||||
},
|
||||
"points": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"label": {
|
||||
"type": "string"
|
||||
},
|
||||
"value": {
|
||||
"type": "number",
|
||||
"minimum": 0
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"label",
|
||||
"value"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"label",
|
||||
"unit",
|
||||
"points"
|
||||
]
|
||||
},
|
||||
"Charts": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"physicalPallets": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/Series"
|
||||
}
|
||||
},
|
||||
"destinationTrips": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/Series"
|
||||
}
|
||||
},
|
||||
"externalAgreedAmounts": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/Series"
|
||||
}
|
||||
},
|
||||
"externalPalletRates": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/Series"
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"physicalPallets",
|
||||
"destinationTrips",
|
||||
"externalAgreedAmounts",
|
||||
"externalPalletRates"
|
||||
]
|
||||
},
|
||||
"MeasuredRecord": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"tripNo": {
|
||||
"type": "string"
|
||||
},
|
||||
"recordVersion": {
|
||||
"type": "integer",
|
||||
"format": "int64",
|
||||
"minimum": 0
|
||||
},
|
||||
"details": {
|
||||
"$ref": "#/components/schemas/Measured"
|
||||
},
|
||||
"updatedAt": {
|
||||
"type": "string",
|
||||
"format": "date-time",
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"tripNo",
|
||||
"recordVersion",
|
||||
"details",
|
||||
"updatedAt"
|
||||
]
|
||||
},
|
||||
"MeasuredHistory": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"recordVersion": {
|
||||
"type": "integer",
|
||||
"minimum": 0
|
||||
},
|
||||
"reason": {
|
||||
"type": "string"
|
||||
},
|
||||
"occurredAt": {
|
||||
"type": "string",
|
||||
"format": "date-time"
|
||||
},
|
||||
"details": {
|
||||
"$ref": "#/components/schemas/Measured"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"recordVersion",
|
||||
"reason",
|
||||
"occurredAt",
|
||||
"details"
|
||||
]
|
||||
},
|
||||
"CostTotal": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"currency": {
|
||||
"type": "string"
|
||||
},
|
||||
"directCost": {
|
||||
"type": "number",
|
||||
"minimum": 0
|
||||
},
|
||||
"ownCost": {
|
||||
"type": "number",
|
||||
"minimum": 0,
|
||||
"nullable": true
|
||||
},
|
||||
"externalCost": {
|
||||
"type": "number",
|
||||
"minimum": 0,
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"currency",
|
||||
"directCost",
|
||||
"ownCost",
|
||||
"externalCost"
|
||||
]
|
||||
},
|
||||
"CostSummary": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"visible": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"unrecordedTrips": {
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"nullable": true
|
||||
},
|
||||
"unallocatedTrips": {
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"nullable": true
|
||||
},
|
||||
"totals": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/CostTotal"
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"visible",
|
||||
"unrecordedTrips",
|
||||
"unallocatedTrips",
|
||||
"totals"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"x-integration-database": {
|
||||
"owner": "总控负责集成模块基线与海外统一初始化SQL,专项不执行SQL。新增权限platform:fleet:operations:edit。",
|
||||
"ddl": "CREATE TABLE ll_fleet_trip_operations_record (\n id BIGINT NOT NULL COMMENT '出车实测历史主键',\n trip_no VARCHAR(64) NOT NULL COMMENT '车次业务编号',\n record_version BIGINT NOT NULL COMMENT '实测记录版本从一递增',\n details_json JSON NOT NULL COMMENT '实际里程英里油耗升与备注快照',\n reason VARCHAR(1000) NOT NULL COMMENT '实测更正说明',\n operator_id VARCHAR(64) NOT NULL COMMENT '实测操作人标识',\n request_key VARCHAR(128) NOT NULL COMMENT '实测保存幂等键',\n request_hash CHAR(64) NOT NULL COMMENT '实测请求内容摘要',\n occurred_at DATETIME(3) NOT NULL COMMENT '实测保存时间UTC',\n PRIMARY KEY (id),\n UNIQUE KEY uk_fleet_operations_version (trip_no,record_version),\n UNIQUE KEY uk_fleet_operations_request (trip_no,operator_id,request_key)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='车次里程油耗不可变更正记录';"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,887 @@
|
||||
{
|
||||
"openapi": "3.0.3",
|
||||
"info": {
|
||||
"title": "车辆采购与外接销售报价库",
|
||||
"version": "1.0.0",
|
||||
"description": "采购价关联公共TRUCKING+OVERSEAS有效供应商,销售价关联有效且具备下单资格的客户。报价仅为价格库,不写入成本/应收/应付,不自动覆盖车次成交快照。整车自提与整车派送按单,散板派送按托。日期为路线业务日(含失效当天),未自动匹配成交;同维度同有效期禁止重复,重叠有效期须由运营明确选择具体报价版本。CSV导入界面解析后提交结构化行,整批原子写入;不支持部分成功。查询/导出最多5000条,导入最多200行。历史接口仅返回最新200版。"
|
||||
},
|
||||
"security": [
|
||||
{
|
||||
"bearerAuth": []
|
||||
}
|
||||
],
|
||||
"paths": {
|
||||
"/api/platform/v1/last-leg/fleet/quotes": {
|
||||
"get": {
|
||||
"description": "platform:fleet:quote:list;包含详情只读",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "page",
|
||||
"in": "query",
|
||||
"required": false,
|
||||
"schema": {
|
||||
"type": "integer",
|
||||
"minimum": 1,
|
||||
"default": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "size",
|
||||
"in": "query",
|
||||
"required": false,
|
||||
"schema": {
|
||||
"type": "integer",
|
||||
"minimum": 1,
|
||||
"maximum": 200,
|
||||
"default": 20
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "kind",
|
||||
"in": "query",
|
||||
"required": false,
|
||||
"schema": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"PURCHASE",
|
||||
"SALE"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "keyword",
|
||||
"in": "query",
|
||||
"required": false,
|
||||
"schema": {
|
||||
"type": "string",
|
||||
"maxLength": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "status",
|
||||
"in": "query",
|
||||
"required": false,
|
||||
"schema": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"ACTIVE",
|
||||
"INACTIVE"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "effectiveOn",
|
||||
"in": "query",
|
||||
"required": false,
|
||||
"schema": {
|
||||
"type": "string",
|
||||
"format": "date"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "业务响应;成功code为200,业务失败不代表写入成功",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"code": {
|
||||
"type": "string"
|
||||
},
|
||||
"message": {
|
||||
"type": "string"
|
||||
},
|
||||
"data": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"records": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/Quote"
|
||||
}
|
||||
},
|
||||
"page": {
|
||||
"type": "integer",
|
||||
"minimum": 0
|
||||
},
|
||||
"size": {
|
||||
"type": "integer",
|
||||
"minimum": 0
|
||||
},
|
||||
"total": {
|
||||
"type": "integer",
|
||||
"minimum": 0
|
||||
},
|
||||
"pages": {
|
||||
"type": "integer",
|
||||
"minimum": 0
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"records",
|
||||
"page",
|
||||
"size",
|
||||
"total",
|
||||
"pages"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"code",
|
||||
"message",
|
||||
"data"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"post": {
|
||||
"description": "platform:fleet:quote:create;原操作人+幂等键唯一,异内容拒绝。目录校验失败不写入。",
|
||||
"requestBody": {
|
||||
"required": true,
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"idempotencyKey": {
|
||||
"type": "string",
|
||||
"minLength": 8,
|
||||
"maxLength": 128
|
||||
},
|
||||
"details": {
|
||||
"$ref": "#/components/schemas/Draft"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"idempotencyKey",
|
||||
"details"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "业务响应;成功code为200,业务失败不代表写入成功",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"code": {
|
||||
"type": "string"
|
||||
},
|
||||
"message": {
|
||||
"type": "string"
|
||||
},
|
||||
"data": {
|
||||
"$ref": "#/components/schemas/Quote"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"code",
|
||||
"message",
|
||||
"data"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/platform/v1/last-leg/fleet/quotes/{quoteNo}": {
|
||||
"parameters": [
|
||||
{
|
||||
"name": "quoteNo",
|
||||
"in": "path",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"get": {
|
||||
"description": "platform:fleet:quote:list",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "业务响应;成功code为200,业务失败不代表写入成功",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"code": {
|
||||
"type": "string"
|
||||
},
|
||||
"message": {
|
||||
"type": "string"
|
||||
},
|
||||
"data": {
|
||||
"$ref": "#/components/schemas/Quote"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"code",
|
||||
"message",
|
||||
"data"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"put": {
|
||||
"description": "platform:fleet:quote:edit;行锁+版本,更正保留旧版,用途不可变",
|
||||
"requestBody": {
|
||||
"required": true,
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"recordVersion": {
|
||||
"type": "integer",
|
||||
"minimum": 0
|
||||
},
|
||||
"details": {
|
||||
"$ref": "#/components/schemas/Draft"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"recordVersion",
|
||||
"details"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "业务响应;成功code为200,业务失败不代表写入成功",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"code": {
|
||||
"type": "string"
|
||||
},
|
||||
"message": {
|
||||
"type": "string"
|
||||
},
|
||||
"data": {
|
||||
"$ref": "#/components/schemas/Quote"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"code",
|
||||
"message",
|
||||
"data"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"delete": {
|
||||
"description": "platform:fleet:quote:delete;保存DELETED历史,退出报价库;不删除已成交业务快照",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "recordVersion",
|
||||
"in": "query",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "integer",
|
||||
"minimum": 0
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "业务响应;成功code为200,业务失败不代表写入成功",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"code": {
|
||||
"type": "string"
|
||||
},
|
||||
"message": {
|
||||
"type": "string"
|
||||
},
|
||||
"data": {
|
||||
"$ref": "#/components/schemas/Quote"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"code",
|
||||
"message",
|
||||
"data"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/platform/v1/last-leg/fleet/quotes/{quoteNo}/status": {
|
||||
"parameters": [
|
||||
{
|
||||
"name": "quoteNo",
|
||||
"in": "path",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"patch": {
|
||||
"description": "platform:fleet:quote:status;启用时重新校验目录",
|
||||
"requestBody": {
|
||||
"required": true,
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"recordVersion": {
|
||||
"type": "integer",
|
||||
"minimum": 0
|
||||
},
|
||||
"status": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"ACTIVE",
|
||||
"INACTIVE"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"recordVersion",
|
||||
"status"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "业务响应;成功code为200,业务失败不代表写入成功",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"code": {
|
||||
"type": "string"
|
||||
},
|
||||
"message": {
|
||||
"type": "string"
|
||||
},
|
||||
"data": {
|
||||
"$ref": "#/components/schemas/Quote"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"code",
|
||||
"message",
|
||||
"data"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/platform/v1/last-leg/fleet/quotes/{quoteNo}/history": {
|
||||
"parameters": [
|
||||
{
|
||||
"name": "quoteNo",
|
||||
"in": "path",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"get": {
|
||||
"description": "platform:fleet:quote:list;最新200个不可变版本",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "业务响应;成功code为200,业务失败不代表写入成功",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"code": {
|
||||
"type": "string"
|
||||
},
|
||||
"message": {
|
||||
"type": "string"
|
||||
},
|
||||
"data": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/History"
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"code",
|
||||
"message",
|
||||
"data"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/platform/v1/last-leg/fleet/quotes/customer-options": {
|
||||
"get": {
|
||||
"description": "platform:fleet:quote:list;复用IAM有效客户目录。供应商候选由Admin调用现有/platform/v1/suppliers,须platform:supplier:list,非此接口扩权。",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "keyword",
|
||||
"in": "query",
|
||||
"required": false,
|
||||
"schema": {
|
||||
"type": "string",
|
||||
"maxLength": 128
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "业务响应;成功code为200,业务失败不代表写入成功",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"code": {
|
||||
"type": "string"
|
||||
},
|
||||
"message": {
|
||||
"type": "string"
|
||||
},
|
||||
"data": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"code": {
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"contactName": {
|
||||
"type": "string",
|
||||
"nullable": true
|
||||
},
|
||||
"contactPhone": {
|
||||
"type": "string",
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"id",
|
||||
"code",
|
||||
"name",
|
||||
"contactName",
|
||||
"contactPhone"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"code",
|
||||
"message",
|
||||
"data"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/platform/v1/last-leg/fleet/quotes/import": {
|
||||
"post": {
|
||||
"description": "platform:fleet:quote:import;最多200行,所有行与审计同事务提交;原批次键的行数或内容变化拒绝",
|
||||
"requestBody": {
|
||||
"required": true,
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"idempotencyKey": {
|
||||
"type": "string",
|
||||
"minLength": 8,
|
||||
"maxLength": 100
|
||||
},
|
||||
"rows": {
|
||||
"type": "array",
|
||||
"minItems": 1,
|
||||
"maxItems": 200,
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/Draft"
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"idempotencyKey",
|
||||
"rows"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "业务响应;成功code为200,业务失败不代表写入成功",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"code": {
|
||||
"type": "string"
|
||||
},
|
||||
"message": {
|
||||
"type": "string"
|
||||
},
|
||||
"data": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"importedRows": {
|
||||
"type": "integer",
|
||||
"minimum": 0
|
||||
},
|
||||
"records": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/Quote"
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"importedRows",
|
||||
"records"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"code",
|
||||
"message",
|
||||
"data"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/platform/v1/last-leg/fleet/quotes/export": {
|
||||
"get": {
|
||||
"description": "platform:fleet:quote:export;全筛选CSV,最多5000行,公式注入转义,空报价保留空值,币种不混合",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "page",
|
||||
"in": "query",
|
||||
"required": false,
|
||||
"schema": {
|
||||
"type": "integer",
|
||||
"minimum": 1,
|
||||
"default": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "size",
|
||||
"in": "query",
|
||||
"required": false,
|
||||
"schema": {
|
||||
"type": "integer",
|
||||
"minimum": 1,
|
||||
"maximum": 200,
|
||||
"default": 20
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "kind",
|
||||
"in": "query",
|
||||
"required": false,
|
||||
"schema": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"PURCHASE",
|
||||
"SALE"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "keyword",
|
||||
"in": "query",
|
||||
"required": false,
|
||||
"schema": {
|
||||
"type": "string",
|
||||
"maxLength": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "status",
|
||||
"in": "query",
|
||||
"required": false,
|
||||
"schema": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"ACTIVE",
|
||||
"INACTIVE"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "effectiveOn",
|
||||
"in": "query",
|
||||
"required": false,
|
||||
"schema": {
|
||||
"type": "string",
|
||||
"format": "date"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "UTF-8 BOM CSV",
|
||||
"content": {
|
||||
"text/csv": {
|
||||
"schema": {
|
||||
"type": "string",
|
||||
"format": "binary"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
"securitySchemes": {
|
||||
"bearerAuth": {
|
||||
"type": "http",
|
||||
"scheme": "bearer",
|
||||
"bearerFormat": "JWT"
|
||||
}
|
||||
},
|
||||
"schemas": {
|
||||
"Draft": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"kind": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"PURCHASE",
|
||||
"SALE"
|
||||
]
|
||||
},
|
||||
"partyId": {
|
||||
"type": "integer",
|
||||
"format": "int64",
|
||||
"minimum": 1
|
||||
},
|
||||
"originCity": {
|
||||
"type": "string",
|
||||
"maxLength": 128
|
||||
},
|
||||
"destinationCode": {
|
||||
"type": "string",
|
||||
"maxLength": 64
|
||||
},
|
||||
"distanceMiles": {
|
||||
"type": "number",
|
||||
"minimum": 0,
|
||||
"multipleOf": 0.1
|
||||
},
|
||||
"currency": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"USD",
|
||||
"CNY"
|
||||
]
|
||||
},
|
||||
"selfPickupPrice": {
|
||||
"type": "number",
|
||||
"minimum": 0,
|
||||
"nullable": true
|
||||
},
|
||||
"fullDeliveryPrice": {
|
||||
"type": "number",
|
||||
"minimum": 0,
|
||||
"nullable": true
|
||||
},
|
||||
"looseDeliveryPrice": {
|
||||
"type": "number",
|
||||
"minimum": 0,
|
||||
"nullable": true
|
||||
},
|
||||
"validFrom": {
|
||||
"type": "string",
|
||||
"format": "date"
|
||||
},
|
||||
"validTo": {
|
||||
"type": "string",
|
||||
"format": "date"
|
||||
},
|
||||
"remark": {
|
||||
"type": "string",
|
||||
"nullable": true,
|
||||
"maxLength": 1000
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"kind",
|
||||
"partyId",
|
||||
"originCity",
|
||||
"destinationCode",
|
||||
"distanceMiles",
|
||||
"currency",
|
||||
"validFrom",
|
||||
"validTo"
|
||||
]
|
||||
},
|
||||
"Quote": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"quoteNo": {
|
||||
"type": "string"
|
||||
},
|
||||
"details": {
|
||||
"$ref": "#/components/schemas/Draft"
|
||||
},
|
||||
"partyName": {
|
||||
"type": "string"
|
||||
},
|
||||
"status": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"ACTIVE",
|
||||
"INACTIVE",
|
||||
"DELETED"
|
||||
]
|
||||
},
|
||||
"recordVersion": {
|
||||
"type": "integer",
|
||||
"format": "int64",
|
||||
"minimum": 0
|
||||
},
|
||||
"updatedAt": {
|
||||
"type": "string",
|
||||
"format": "date-time"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"quoteNo",
|
||||
"details",
|
||||
"partyName",
|
||||
"status",
|
||||
"recordVersion",
|
||||
"updatedAt"
|
||||
]
|
||||
},
|
||||
"History": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"recordVersion": {
|
||||
"type": "integer",
|
||||
"minimum": 0
|
||||
},
|
||||
"action": {
|
||||
"type": "string"
|
||||
},
|
||||
"occurredAt": {
|
||||
"type": "string",
|
||||
"format": "date-time"
|
||||
},
|
||||
"snapshot": {
|
||||
"$ref": "#/components/schemas/Quote"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"recordVersion",
|
||||
"action",
|
||||
"occurredAt",
|
||||
"snapshot"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"x-integration-database": {
|
||||
"owner": "总控集成:lastleg.sql及海外统一初始化SQL;本文件仅为字段与索引清单,不执行SQL",
|
||||
"tables": {
|
||||
"ll_fleet_quote": {
|
||||
"comment": "车辆采购与外接销售报价",
|
||||
"columns": {
|
||||
"id": "BIGINT PRIMARY KEY COMMENT '报价记录主键'",
|
||||
"quote_no": "VARCHAR(64) NOT NULL COMMENT '报价业务编号'",
|
||||
"kind": "VARCHAR(16) NOT NULL COMMENT '报价用途采购或销售'",
|
||||
"party_id": "BIGINT NOT NULL COMMENT '供应商或客户主档标识'",
|
||||
"party_name": "VARCHAR(160) NOT NULL COMMENT '往来单位名称快照'",
|
||||
"origin_city": "VARCHAR(128) NOT NULL COMMENT '发货城市'",
|
||||
"destination_code": "VARCHAR(64) NOT NULL COMMENT '目的仓业务编码'",
|
||||
"valid_from": "DATE NOT NULL COMMENT '报价生效日期'",
|
||||
"valid_to": "DATE NOT NULL COMMENT '报价失效日期含当天'",
|
||||
"status": "VARCHAR(16) NOT NULL COMMENT '报价启停或删除状态'",
|
||||
"natural_key": "CHAR(64) NOT NULL COMMENT '报价组合去重摘要'",
|
||||
"details_json": "JSON NOT NULL COMMENT '完整报价明细快照'",
|
||||
"record_version": "BIGINT NOT NULL COMMENT '报价记录版本'",
|
||||
"create_key": "VARCHAR(128) NOT NULL COMMENT '创建幂等键'",
|
||||
"create_hash": "CHAR(64) NOT NULL COMMENT '创建请求含导入批次内容摘要'",
|
||||
"created_by": "VARCHAR(64) NOT NULL COMMENT '创建操作人标识'",
|
||||
"created_at": "DATETIME(3) NOT NULL COMMENT '创建时间UTC'",
|
||||
"updated_at": "DATETIME(3) NOT NULL COMMENT '更新时间UTC'"
|
||||
},
|
||||
"indexes": [
|
||||
"UNIQUE KEY uk_fleet_quote_no (quote_no)",
|
||||
"UNIQUE KEY uk_fleet_quote_natural (natural_key)",
|
||||
"UNIQUE KEY uk_fleet_quote_create (created_by,create_key)",
|
||||
"KEY idx_fleet_quote_search (kind,status,valid_from,valid_to)"
|
||||
]
|
||||
},
|
||||
"ll_fleet_quote_history": {
|
||||
"comment": "车辆报价不可变版本历史",
|
||||
"columns": {
|
||||
"id": "BIGINT PRIMARY KEY COMMENT '报价历史主键'",
|
||||
"quote_id": "BIGINT NOT NULL COMMENT '报价记录标识'",
|
||||
"record_version": "BIGINT NOT NULL COMMENT '报价记录版本'",
|
||||
"action": "VARCHAR(24) NOT NULL COMMENT '报价操作类型'",
|
||||
"operator_id": "VARCHAR(64) NOT NULL COMMENT '操作人标识'",
|
||||
"occurred_at": "DATETIME(3) NOT NULL COMMENT '操作时间UTC'",
|
||||
"snapshot_json": "JSON NOT NULL COMMENT '报价完整版本快照'"
|
||||
},
|
||||
"indexes": [
|
||||
"UNIQUE KEY uk_fleet_quote_history_version (quote_id,record_version)"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,183 @@
|
||||
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' }
|
||||
@@ -4,9 +4,9 @@ info:
|
||||
version: 1.0.0
|
||||
description: >-
|
||||
平台按稳定车辆ID读取Lastleg本库履约事实,不按当前车牌文本反查,不修改单据或历史。
|
||||
计划中的派送归当前分配车辆;实际发车后按不可变DEPART历史中的车辆身份归属。
|
||||
计划中的派送归当前分配车辆;实际发车后按不可变DEPART及在途交接快照中的车辆身份归属。接替车辆仅关联交接时未完成且属于原客户的派送。
|
||||
关联排车和派送时同时匹配客户归属,不返回财务、附件、联系人或内部数据库主键。
|
||||
更换记录依据相邻车次版本的ASSIGN快照,首次分配和资源未变化的操作不算更换。
|
||||
更换记录依据相邻车次版本的ASSIGN或HANDOVER快照;在途交接仅列实际剩余货物涉及的排车单,首次分配和资源未变化的操作不算更换。
|
||||
旧车和新车均能读取同一更换事实;仅换司机也保留。返回历史车牌/姓名,不用当前主档覆盖。
|
||||
不生成原型示例记录;没有正式车次关联的旧派送不通过车牌猜测归属。
|
||||
security: [{bearerAuth: []}]
|
||||
|
||||
@@ -10,10 +10,70 @@ info:
|
||||
照片最多20张,每张非空JPG/PNG且最多10MiB;File按平台0、FLEET_VEHICLE_RECORD_PHOTO和记录内部主键复合归属,验证内容签名。
|
||||
维修和救援项目、地点独立保存;处理中或已完成须有处理人,异常须有明确分类。
|
||||
费用只是运维申报金额,填金额则必须填有效币种;未填金额和零金额有区别,不生成应付或付款。
|
||||
维修/救援paymentStatus当前固定UNLINKED表示未关联财务,不得由processingStatus推定为已付款,其他类型为空。
|
||||
运维响应paymentStatus为空,不保存可变财务结论;维修/救援通过finance-status批量读取公司财务状态,不得由processingStatus推定付款。
|
||||
显式提交公司成本时取已保存申报金额、服务端供应商与月份汇率,来源映射及Outbox同事务保存;不会自动入账或付款。
|
||||
已提交费用须先在Finance作废才可修改费用项目/金额/币种或重新提交;处理进度、地点和处理人仍可独立更新。
|
||||
不提供物理删除;编辑与上传历史同事务不可变保存。本接口不提供财务结算或车辆占用/状态自动变更。
|
||||
security: [{bearerAuth: []}]
|
||||
paths:
|
||||
/api/platform/v1/last-leg/fleet/vehicles/{vehicleId}/records/finance-status:
|
||||
parameters: [{$ref: '#/components/parameters/Vehicle'}]
|
||||
post:
|
||||
description: platform:overseas-master-data:vehicle:list;校验本车维修/救援记录,最多100条批量读取,不逐行调用Finance;依赖失败明确返回错误,不能伪造未关联或付款状态
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
required: [recordNos]
|
||||
properties:
|
||||
recordNos: {type: array, minItems: 1, maxItems: 100, items: {type: string, minLength: 1, maxLength: 64}}
|
||||
responses:
|
||||
'200':
|
||||
description: ApiResponse;data为每条请求记录的状态;Finance接收状态PENDING为待入账,APPROVED为已入账未付,不等于付款
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
code: {type: string}
|
||||
data: {type: array, items: {$ref: '#/components/schemas/FinanceStatus'}}
|
||||
/api/platform/v1/last-leg/fleet/vehicles/{vehicleId}/records/{recordNo}/finance:
|
||||
parameters:
|
||||
- {$ref: '#/components/parameters/Vehicle'}
|
||||
- {name: recordNo, in: path, required: true, schema: {type: string}}
|
||||
post:
|
||||
description: platform:overseas-master-data:vehicle:record-finance-submit;不复用普通运维编辑权限。前端选择供应商候选另需platform:supplier:list。首次提交或Finance已作废后才可登记新来源版本,未知结果保留原键重试
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
required: [recordVersion, supplierId, businessDate, idempotencyKey]
|
||||
properties:
|
||||
recordVersion: {type: integer, format: int64, minimum: 0}
|
||||
supplierId: {type: integer, format: int64, minimum: 1}
|
||||
businessDate: {type: string, format: date, description: 明确选择实际费用业务日期,用于获取业务月份有效汇率}
|
||||
idempotencyKey: {type: string, minLength: 8, maxLength: 128}
|
||||
responses:
|
||||
'200':
|
||||
description: ApiResponse;仅表示提交请求已登记,PENDING_FINANCE不是已入账或付款
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
code: {type: string}
|
||||
data:
|
||||
type: object
|
||||
properties:
|
||||
recordNo: {type: string}
|
||||
sourceVersion: {type: integer, format: int64}
|
||||
submittedRecordVersion: {type: integer, format: int64}
|
||||
replayed: {type: boolean}
|
||||
status: {type: string, enum: [PENDING_FINANCE]}
|
||||
/api/platform/v1/last-leg/fleet/vehicles/{vehicleId}/records:
|
||||
parameters: [{$ref: '#/components/parameters/Vehicle'}]
|
||||
get:
|
||||
@@ -172,4 +232,12 @@ components:
|
||||
recordVersion: {type: integer, format: int64, minimum: 0}
|
||||
updatedBy: {type: string}
|
||||
updatedAt: {type: string, format: date-time}
|
||||
paymentStatus: {type: string, nullable: true, readOnly: true, enum: [UNLINKED], description: 维修/救援未关联财务时为UNLINKED,其余为空;不可用处理完成推定已付款}
|
||||
paymentStatus: {type: string, nullable: true, readOnly: true, description: 运维快照不记录可变财务状态,当前为空;读取finance-status获取财务事实}
|
||||
FinanceStatus:
|
||||
type: object
|
||||
properties:
|
||||
recordNo: {type: string}
|
||||
status: {type: string, enum: [UNLINKED, PENDING_FINANCE, FINANCE_ATTENTION, PENDING, APPROVED, PARTIALLY_PAID, PAID, VOIDED]}
|
||||
sourceVersion: {type: integer, format: int64, nullable: true}
|
||||
submittedRecordVersion: {type: integer, format: int64, nullable: true}
|
||||
finance: {type: object, nullable: true, description: Finance公司费用Cost完整只读快照;来源版本及内容须与本地提交一致;未接收不虚构金额,具体结构见finance-vehicle-costs-v1.yaml的Cost}
|
||||
|
||||
Reference in New Issue
Block a user