优化
This commit is contained in:
@@ -43,7 +43,11 @@ paths:
|
||||
- $ref: '#/components/parameters/UnifiedPage'
|
||||
- $ref: '#/components/parameters/UnifiedSize'
|
||||
responses:
|
||||
'200': {description: 成功或业务失败,响应体 code 为字符串 200 时成功}
|
||||
'200':
|
||||
description: 成功或业务失败,响应体 code 为字符串 200 时成功
|
||||
content:
|
||||
application/json:
|
||||
schema: {$ref: '#/components/schemas/UnifiedOrderPageEnvelope'}
|
||||
'403': {description: 需要平台身份和 platform:order:list 权限}
|
||||
/api/platform/v1/orders/{orderId}:
|
||||
get:
|
||||
@@ -53,7 +57,11 @@ paths:
|
||||
- $ref: '#/components/parameters/UnifiedOrderId'
|
||||
- $ref: '#/components/parameters/UnifiedTenantId'
|
||||
responses:
|
||||
'200': {description: 成功或业务失败,按响应体 code 判断}
|
||||
'200':
|
||||
description: 成功或业务失败,按响应体 code 判断
|
||||
content:
|
||||
application/json:
|
||||
schema: {$ref: '#/components/schemas/UnifiedOrderDetailEnvelope'}
|
||||
'403': {description: 需要平台身份和 platform:order:list 权限}
|
||||
/api/platform/v1/orders/{orderId}/internal-notes:
|
||||
post:
|
||||
@@ -105,7 +113,11 @@ paths:
|
||||
- $ref: '#/components/parameters/UnifiedPage'
|
||||
- $ref: '#/components/parameters/UnifiedSize'
|
||||
responses:
|
||||
'200': {description: 成功或业务失败,按响应体 code 判断}
|
||||
'200':
|
||||
description: 成功或业务失败,按响应体 code 判断
|
||||
content:
|
||||
application/json:
|
||||
schema: {$ref: '#/components/schemas/UnifiedOrderPageEnvelope'}
|
||||
'403': {description: 需要 merchant:order:list 权限}
|
||||
/api/merchant/v1/orders/{orderId}:
|
||||
get:
|
||||
@@ -118,7 +130,7 @@ paths:
|
||||
description: 成功或业务失败,按响应体 code 判断
|
||||
content:
|
||||
application/json:
|
||||
schema: {$ref: '#/components/schemas/FirstLegOrderSummary'}
|
||||
schema: {$ref: '#/components/schemas/UnifiedOrderDetailEnvelope'}
|
||||
'403': {description: 需要 merchant:order:view 权限}
|
||||
/api/merchant/v1/orders/first-leg:
|
||||
get:
|
||||
@@ -295,6 +307,146 @@ components:
|
||||
scheme: bearer
|
||||
bearerFormat: JWT
|
||||
schemas:
|
||||
UnifiedMainStatus:
|
||||
type: string
|
||||
enum: [PENDING_REVIEW, WAIT_MEASURE, INBOUNDED, LOADING, LOADED, DELIVERED]
|
||||
description: >-
|
||||
统一订单产品主状态。历史内部状态 WAIT_SPLIT 仅作为查询入参兼容,所有列表、详情和时间线响应均归并为 INBOUNDED。
|
||||
UnifiedOrderPageEnvelope:
|
||||
type: object
|
||||
properties:
|
||||
code: {type: string, example: '200'}
|
||||
message: {type: string}
|
||||
data: {$ref: '#/components/schemas/UnifiedOrderPage'}
|
||||
UnifiedOrderPage:
|
||||
type: object
|
||||
properties:
|
||||
records: {type: array, items: {$ref: '#/components/schemas/UnifiedOrderRow'}}
|
||||
page: {type: integer, format: int64, minimum: 1}
|
||||
size: {type: integer, format: int64, minimum: 1}
|
||||
total: {type: integer, format: int64, minimum: 0}
|
||||
pages: {type: integer, format: int64, minimum: 0}
|
||||
UnifiedOrderDetailEnvelope:
|
||||
type: object
|
||||
properties:
|
||||
code: {type: string, example: '200'}
|
||||
message: {type: string}
|
||||
data: {$ref: '#/components/schemas/UnifiedOrderDetail'}
|
||||
UnifiedOrderDetail:
|
||||
type: object
|
||||
properties:
|
||||
summary: {$ref: '#/components/schemas/UnifiedOrderRow'}
|
||||
order:
|
||||
type: object
|
||||
properties:
|
||||
order: {type: object, description: Order 服务订单主实体}
|
||||
cargoes: {type: array, items: {type: object}}
|
||||
parties: {type: array, items: {type: object}}
|
||||
internalNotes: {type: array, items: {type: object}, description: 客户详情始终为空数组}
|
||||
statusHistory: {type: array, items: {type: object}}
|
||||
timeline: {type: array, items: {$ref: '#/components/schemas/UnifiedOrderTimelineEvent'}}
|
||||
UnifiedOrderRow:
|
||||
type: object
|
||||
properties:
|
||||
orderId: {type: integer, format: int64}
|
||||
tenantId: {type: integer, format: int64}
|
||||
orderNo: {type: string}
|
||||
mainStatus: {$ref: '#/components/schemas/UnifiedMainStatus'}
|
||||
nextAction: {type: string, nullable: true}
|
||||
relation: {$ref: '#/components/schemas/UnifiedOrderRelation'}
|
||||
internalOrderStatus: {type: string, enum: [DRAFT, SUBMITTED, APPROVED, ACCEPTED, REJECTED, CANCELLED, PROCESSING, COMPLETED], nullable: true}
|
||||
customerId: {type: integer, format: int64, nullable: true}
|
||||
customerName: {type: string, nullable: true}
|
||||
channelName: {type: string, nullable: true}
|
||||
receivingWarehouseId: {type: integer, format: int64, nullable: true}
|
||||
receivingWarehouseName: {type: string, nullable: true}
|
||||
destinationWarehouseId: {type: integer, format: int64, nullable: true}
|
||||
destinationWarehouseName: {type: string, nullable: true}
|
||||
inboundId: {type: integer, format: int64, nullable: true}
|
||||
inboundVersion: {type: integer, nullable: true, description: C04 loading/complete 的 expectedVersion}
|
||||
inboundCode: {type: string, nullable: true}
|
||||
expectedShipDate: {type: string, format: date, nullable: true}
|
||||
totalPackageCount: {type: integer, nullable: true}
|
||||
recommendedPalletType: {type: string, nullable: true}
|
||||
locationCodes: {type: string, nullable: true}
|
||||
actualGrossWeightKg: {type: number, nullable: true}
|
||||
actualVolumeCbm: {type: number, nullable: true}
|
||||
measurement: {$ref: '#/components/schemas/UnifiedMeasurementSummary'}
|
||||
preload: {$ref: '#/components/schemas/UnifiedPreloadSummary'}
|
||||
loading: {$ref: '#/components/schemas/UnifiedLoadingSummary'}
|
||||
delivery: {$ref: '#/components/schemas/UnifiedDeliverySummary'}
|
||||
transport: {$ref: '#/components/schemas/UnifiedTransportSummary'}
|
||||
customerRemark: {type: string, nullable: true}
|
||||
latestInternalNote: {type: string, nullable: true, description: 客户详情不返回平台内部备注}
|
||||
createdAt: {type: string, format: date-time, nullable: true}
|
||||
updatedAt: {type: string, format: date-time, nullable: true}
|
||||
UnifiedOrderRelation:
|
||||
type: object
|
||||
nullable: true
|
||||
properties:
|
||||
role: {type: string, enum: [PARENT, CHILD]}
|
||||
rootOrderId: {type: integer, format: int64, nullable: true}
|
||||
parentOrderId: {type: integer, format: int64, nullable: true}
|
||||
splitSequence: {type: integer, nullable: true}
|
||||
childCount: {type: integer, nullable: true}
|
||||
UnifiedMeasurementSummary:
|
||||
type: object
|
||||
nullable: true
|
||||
properties:
|
||||
reviewStatus: {type: string, nullable: true}
|
||||
actualGrossWeightKg: {type: number, nullable: true}
|
||||
actualVolumeCbm: {type: number, nullable: true}
|
||||
chargeableWeightKg: {type: number, nullable: true}
|
||||
completedAt: {type: string, format: date-time, nullable: true}
|
||||
UnifiedPreloadSummary:
|
||||
type: object
|
||||
nullable: true
|
||||
properties:
|
||||
status: {type: string, nullable: true}
|
||||
version: {type: integer, nullable: true}
|
||||
itemCount: {type: integer, nullable: true}
|
||||
updatedAt: {type: string, format: date-time, nullable: true}
|
||||
UnifiedLoadingSummary:
|
||||
type: object
|
||||
nullable: true
|
||||
properties:
|
||||
status: {type: string, nullable: true}
|
||||
loadingVersion: {type: integer, nullable: true, description: 当前为 pickingVersion 兼容别名}
|
||||
pickingVersion: {type: integer, nullable: true}
|
||||
expectedCount: {type: integer, nullable: true}
|
||||
pickedCount: {type: integer, nullable: true}
|
||||
evidenceCount: {type: integer, nullable: true}
|
||||
sealNo: {type: string, nullable: true}
|
||||
updatedAt: {type: string, format: date-time, nullable: true}
|
||||
UnifiedDeliverySummary:
|
||||
type: object
|
||||
nullable: true
|
||||
properties:
|
||||
status: {type: string, nullable: true}
|
||||
completedAt: {type: string, format: date-time, nullable: true}
|
||||
trackingNo: {type: string, nullable: true}
|
||||
UnifiedTransportSummary:
|
||||
type: object
|
||||
nullable: true
|
||||
properties:
|
||||
loadingStatus: {type: string, nullable: true}
|
||||
containerNo: {type: string, nullable: true}
|
||||
cabinetNo: {type: string, nullable: true}
|
||||
vesselName: {type: string, nullable: true}
|
||||
voyageNo: {type: string, nullable: true}
|
||||
sailingAt: {type: string, format: date-time, nullable: true}
|
||||
portArrivalAt: {type: string, format: date-time, nullable: true}
|
||||
UnifiedOrderTimelineEvent:
|
||||
type: object
|
||||
properties:
|
||||
source: {type: string}
|
||||
eventType: {type: string}
|
||||
mainStatus: {$ref: '#/components/schemas/UnifiedMainStatus'}
|
||||
action: {type: string, nullable: true}
|
||||
remark: {type: string, nullable: true}
|
||||
operatorId: {type: integer, format: int64, nullable: true}
|
||||
operatorName: {type: string, nullable: true}
|
||||
occurredAt: {type: string, format: date-time, nullable: true}
|
||||
FulfillmentSplitQuantityLine:
|
||||
type: object
|
||||
required: [sourceDetailId, packageCount]
|
||||
@@ -459,9 +611,10 @@ components:
|
||||
name: mainStatus
|
||||
in: query
|
||||
required: false
|
||||
description: 历史值 WAIT_SPLIT 仍可作为兼容筛选传入,但响应 mainStatus 始终归并为 INBOUNDED
|
||||
schema:
|
||||
type: string
|
||||
enum: [PENDING_REVIEW, WAIT_MEASURE, INBOUNDED, LOADING, LOADED, DELIVERED]
|
||||
enum: [PENDING_REVIEW, WAIT_MEASURE, INBOUNDED, LOADING, LOADED, DELIVERED, WAIT_SPLIT]
|
||||
UnifiedInboundCode:
|
||||
{name: inboundCode, in: query, required: false, description: 客户提交后生成的入仓码,待审核订单同样可查询, schema: {type: string, maxLength: 40}}
|
||||
UnifiedInternalOrderStatus:
|
||||
|
||||
@@ -39,7 +39,24 @@ class UnifiedOrderApiContractTest {
|
||||
Map<String, Object> mainStatus = stringMap(parameters.get("UnifiedMainStatus"));
|
||||
Map<String, Object> schema = stringMap(mainStatus.get("schema"));
|
||||
assertThat(stringList(schema.get("enum"))).containsExactly(
|
||||
"PENDING_REVIEW", "WAIT_MEASURE", "INBOUNDED", "LOADING", "LOADED", "DELIVERED", "WAIT_SPLIT");
|
||||
assertThat(mainStatus.get("description").toString())
|
||||
.contains("WAIT_SPLIT", "INBOUNDED");
|
||||
|
||||
Map<String, Object> schemas = stringMap(components.get("schemas"));
|
||||
Map<String, Object> responseStatus = stringMap(schemas.get("UnifiedMainStatus"));
|
||||
assertThat(stringList(responseStatus.get("enum"))).containsExactly(
|
||||
"PENDING_REVIEW", "WAIT_MEASURE", "INBOUNDED", "LOADING", "LOADED", "DELIVERED");
|
||||
assertThat(responseStatus.get("description").toString()).contains("WAIT_SPLIT", "INBOUNDED");
|
||||
|
||||
Map<String, Object> row = stringMap(schemas.get("UnifiedOrderRow"));
|
||||
assertThat(stringMap(row.get("properties"))).containsKeys(
|
||||
"orderId", "mainStatus", "inboundId", "inboundVersion", "measurement", "preload",
|
||||
"loading", "delivery", "transport", "customerRemark", "latestInternalNote");
|
||||
assertThat(responseSchema(paths, "/api/platform/v1/orders", "get"))
|
||||
.containsEntry("$ref", "#/components/schemas/UnifiedOrderPageEnvelope");
|
||||
assertThat(responseSchema(paths, "/api/merchant/v1/orders/{orderId}", "get"))
|
||||
.containsEntry("$ref", "#/components/schemas/UnifiedOrderDetailEnvelope");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -61,4 +78,11 @@ class UnifiedOrderApiContractTest {
|
||||
private static List<String> stringList(Object value) {
|
||||
return (List<String>) value;
|
||||
}
|
||||
|
||||
private static Map<String, Object> responseSchema(Map<String, Object> paths, String path, String method) {
|
||||
Map<String, Object> operation = stringMap(stringMap(paths.get(path)).get(method));
|
||||
Map<String, Object> response = stringMap(stringMap(operation.get("responses")).get("200"));
|
||||
Map<String, Object> content = stringMap(response.get("content"));
|
||||
return stringMap(stringMap(content.get("application/json")).get("schema"));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user