Files
LabelChange-server/小包接口文档.md
2026-06-01 16:30:29 +08:00

954 lines
20 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 小包接口文档
## 1. 接口概述
小包模块提供了一系列RESTful API接口用于标签替换、扫描记录管理以及相关操作。本文档详细描述了这些接口的使用方法、请求参数和响应格式。
**测试环境请求地址http://172.232.21.79:5002**
**正式环境请求地址https://lr.tooexp.com**
### 1.1 接口基础信息
- **基础URL**`http://{服务器地址}:{端口}/api/Label`
- **请求方式**POST/GET
- **数据格式**JSON
- **响应格式**JSON
### 1.2 状态码说明
| 状态码 | 描述 |
|-------|------|
| 200 | 操作成功 |
| 400 | 请求参数错误或操作失败 |
| 401 | 身份验证失败 |
| 404 | 资源不存在 |
| 500 | 服务器内部错误 |
## 2. 接口详细说明
### 2.1 根据跟踪单号获取标签替换请求记录
**接口路径**`/label-replace/tracking/{trackingNumber}`
**请求方法**GET
**功能描述**:根据跟踪单号获取标签替换请求记录
#### 请求参数
| 参数名 | 类型 | 必填 | 描述 | 示例值 |
|-------|------|------|------|--------|
| trackingNumber | string | 是 | 跟踪单号 | "1Z999AA10123456789" |
#### 请求示例
```
GET /api/Label/label-replace/tracking/1Z999AA10123456789
```
#### 响应格式
**成功响应**
```json
{
"status": "ok",
"timestamp": "2026-03-30T12:00:00Z",
"trackingNumber": "1Z999AA10123456789",
"count": 1,
"data": [
{
"Id": 1,
"NeutralWaybillNumber": "TEST001",
"FinalMileTrackingNumber": "1Z999AA10123456789",
"ReplaceStatus": "Y",
"CreatedAt": "2026-03-30T10:00:00Z"
}
]
}
```
**失败响应**
```json
{
"status": "error",
"message": "Tracking number is required"
}
```
### 2.2 根据中性面单单号获取标签替换请求记录
**接口路径**`/label-replace/waybill/{waybillNumber}`
**请求方法**GET
**功能描述**:根据中性面单单号获取标签替换请求记录
#### 请求参数
| 参数名 | 类型 | 必填 | 描述 | 示例值 |
|-------|------|------|------|--------|
| waybillNumber | string | 是 | 中性面单单号 | "TEST001" |
#### 请求示例
```
GET /api/Label/label-replace/waybill/TEST001
```
#### 响应格式
**成功响应**
```json
{
"status": "ok",
"timestamp": "2026-03-30T12:00:00Z",
"waybillNumber": "TEST001",
"data": {
"Id": 1,
"NeutralWaybillNumber": "TEST001",
"FinalMileTrackingNumber": "1Z999AA10123456789",
"ReplaceStatus": "Y",
"CreatedAt": "2026-03-30T10:00:00Z"
}
}
```
**失败响应**
```json
{
"status": "error",
"message": "Waybill number is required"
}
```
### 2.3 根据中性面单单号获取标签文件并返回字节流
**接口路径**`/label-replace/waybill/{waybillNumber}/download`
**请求方法**GET
**功能描述**:根据中性面单单号获取标签文件并返回字节流
#### 请求参数
| 参数名 | 类型 | 必填 | 描述 | 示例值 |
|-------|------|------|------|--------|
| waybillNumber | string | 是 | 中性面单单号 | "TEST001" |
#### 请求示例
```
GET /api/Label/label-replace/waybill/TEST001/download
```
#### 响应格式
**成功响应**
- 响应类型:`application/pdf`
- 响应内容标签文件的PDF字节流
- 文件名:`label_TEST001.pdf`
**失败响应**
```json
{
"status": "error",
"message": "Label replace request not found for the provided waybill number"
}
```
### 2.4 获取打印预览页面
**接口路径**`/print-preview`
**请求方法**GET
**功能描述**:获取打印预览页面
#### 请求参数
#### 请求示例
```
GET /api/Label/print-preview
```
#### 响应格式
**成功响应**
- 响应类型:`text/html`
- 响应内容打印预览页面的HTML内容
**失败响应**
- 404 Not Found
### 2.5 测试讯通回传接口
**接口路径**`/label-scan/test-xuntong-webhook`
**请求方法**POST
**功能描述**:测试讯通回传接口
#### 请求参数
| 参数名 | 类型 | 必填 | 描述 | 示例值 |
|-------|------|------|------|--------|
| WaybillNumber | string | 是 | 中性面单单号 | "TEST001" |
| Success | bool | 否 | 是否成功默认true | true |
| Description | string | 否 | 描述 | "Test webhook" |
#### 请求示例
```json
{
"WaybillNumber": "TEST001",
"Success": true,
"Description": "Test webhook"
}
```
#### 响应格式
**成功响应**
```json
{
"status": "ok",
"message": "Test webhook sent successfully"
}
```
**失败响应**
```json
{
"status": "error",
"message": "Waybill number is required"
}
```
### 2.6 记录标签扫描
**接口路径**`/label-scan/record`
**请求方法**POST
**功能描述**:记录标签扫描
#### 请求参数
| 参数名 | 类型 | 必填 | 描述 | 示例值 |
|-------|------|------|------|--------|
| CustomerId | int | 否 | 客户ID | 1 |
| NeutralWaybillNumber | string | 是 | 中性面单单号 | "TEST001" |
| Result | int | 是 | 扫描结果 | 0 |
| CreatedBy | string | 是 | 创建人 | "system" |
| ReferenceNumber | string | 否 | 参考号 | "REF001" |
| FinalMileTrackingNumber | string | 否 | 尾程跟踪单号 | "1Z999AA10123456789" |
| Description | string | 否 | 描述 | "标签扫描" |
#### 请求示例
```json
{
"CustomerId": 1,
"NeutralWaybillNumber": "TEST001",
"Result": 0,
"CreatedBy": "system",
"ReferenceNumber": "REF001",
"FinalMileTrackingNumber": "1Z999AA10123456789",
"Description": "标签扫描"
}
```
#### 响应格式
**成功响应**
```json
{
"status": "ok",
"timestamp": "2026-03-30T12:00:00Z",
"scanRecord": {
"Id": 1,
"NeutralWaybillNumber": "TEST001",
"Result": 0,
"CreatedBy": "system",
"CreatedAt": "2026-03-30T12:00:00Z"
}
}
```
**失败响应**
```json
{
"status": "error",
"message": "Neutral waybill number is required"
}
```
### 2.7 根据中性面单查询扫描记录列表
**接口路径**`/label-scan/waybill/{waybillNumber}`
**请求方法**GET
**功能描述**:根据中性面单查询扫描记录列表
#### 请求参数
| 参数名 | 类型 | 必填 | 描述 | 示例值 |
|-------|------|------|------|--------|
| waybillNumber | string | 是 | 中性面单单号 | "TEST001" |
#### 请求示例
```
GET /api/Label/label-scan/waybill/TEST001
```
#### 响应格式
**成功响应**
```json
{
"status": "ok",
"timestamp": "2026-03-30T12:00:00Z",
"waybillNumber": "TEST001",
"count": 1,
"data": [
{
"Id": 1,
"NeutralWaybillNumber": "TEST001",
"Result": 0,
"CreatedBy": "system",
"CreatedAt": "2026-03-30T10:00:00Z"
}
]
}
```
**失败响应**
```json
{
"status": "error",
"message": "Waybill number is required"
}
```
### 2.8 根据客户ID查询扫描记录列表
**接口路径**`/label-scan/customer/{customerId}`
**请求方法**GET
**功能描述**根据客户ID查询扫描记录列表
#### 请求参数
| 参数名 | 类型 | 必填 | 描述 | 示例值 |
|-------|------|------|------|--------|
| customerId | int | 是 | 客户ID | 1 |
#### 请求示例
```
GET /api/Label/label-scan/customer/1
```
#### 响应格式
**成功响应**
```json
{
"status": "ok",
"timestamp": "2026-03-30T12:00:00Z",
"customerId": 1,
"count": 2,
"data": [
{
"Id": 1,
"NeutralWaybillNumber": "TEST001",
"Result": 0,
"CreatedBy": "system",
"CreatedAt": "2026-03-30T10:00:00Z"
},
{
"Id": 2,
"NeutralWaybillNumber": "TEST002",
"Result": 0,
"CreatedBy": "system",
"CreatedAt": "2026-03-30T11:00:00Z"
}
]
}
```
**失败响应**
```json
{
"status": "error",
"message": "An unexpected error occurred during scan record retrieval.",
"errorDetails": "错误信息"
}
```
### 2.9 获取客户的扫描记录统计
**接口路径**`/label-scan/stats/customer/{customerId}`
**请求方法**GET
**功能描述**:获取客户的扫描记录统计
#### 请求参数
| 参数名 | 类型 | 必填 | 描述 | 示例值 |
|-------|------|------|------|--------|
| customerId | int | 是 | 客户ID | 1 |
#### 请求示例
```
GET /api/Label/label-scan/stats/customer/1
```
#### 响应格式
**成功响应**
```json
{
"status": "ok",
"timestamp": "2026-03-30T12:00:00Z",
"customerId": 1,
"stats": {
"totalScans": 10,
"successfulScans": 8,
"failedScans": 2
}
}
```
**失败响应**
```json
{
"status": "error",
"message": "An unexpected error occurred during scan statistics retrieval.",
"errorDetails": "错误信息"
}
```
### 2.10 批量查询标签替换请求
**接口路径**`/label-replace/batch`
**请求方法**GET
**功能描述**:批量查询标签替换请求
#### 请求参数
| 参数名 | 类型 | 必填 | 描述 | 示例值 |
|-------|------|------|------|--------|
| page | int | 否 | 页码默认1 | 1 |
| pageSize | int | 否 | 每页数量默认10 | 10 |
| sortBy | string | 否 | 排序字段默认CreatedAt | "CreatedAt" |
| sortOrder | string | 否 | 排序方向默认desc | "desc" |
| billOfLadingNumber | string | 否 | 提单号 | "BOL001" |
| masterPackageNumber | string | 否 | 大包号 | "MP001" |
| referenceNumber | string | 否 | 参考号 | "REF001" |
| neutralWaybillNumber | string | 否 | 中性面单单号 | "TEST001" |
| finalMileTrackingNumber | string | 否 | 尾程跟踪单号 | "1Z999AA10123456789" |
| replaceStatus | string | 否 | 换单状态 | "Y" |
| customerId | int | 否 | 客户ID | 1 |
| callback | string | 否 | JSONP回调函数名 | "callback" |
#### 请求示例
```
GET /api/Label/label-replace/batch?page=1&pageSize=10&sortBy=CreatedAt&sortOrder=desc
```
#### 响应格式
**成功响应**
```json
{
"status": "ok",
"timestamp": "2026-03-30T12:00:00Z",
"totalCount": 100,
"page": 1,
"pageSize": 10,
"totalPages": 10,
"data": [
{
"Id": 1,
"NeutralWaybillNumber": "TEST001",
"FinalMileTrackingNumber": "1Z999AA10123456789",
"ReplaceStatus": "Y",
"CreatedAt": "2026-03-30T10:00:00Z"
},
...
]
}
```
**失败响应**
```json
{
"status": "error",
"message": "An unexpected error occurred during batch retrieval.",
"errorDetails": "错误信息"
}
```
### 2.11 批量查询标签扫描记录
**接口路径**`/label-scan/batch`
**请求方法**GET
**功能描述**:批量查询标签扫描记录
#### 请求参数
| 参数名 | 类型 | 必填 | 描述 | 示例值 |
|-------|------|------|------|--------|
| page | int | 否 | 页码默认1 | 1 |
| pageSize | int | 否 | 每页数量默认10 | 10 |
| sortBy | string | 否 | 排序字段默认CreatedAt | "CreatedAt" |
| sortOrder | string | 否 | 排序方向默认desc | "desc" |
| customerId | int | 否 | 客户ID | 1 |
| referenceNumber | string | 否 | 参考号 | "REF001" |
| neutralWaybillNumber | string | 否 | 中性面单单号 | "TEST001" |
| finalMileTrackingNumber | string | 否 | 尾程跟踪单号 | "1Z999AA10123456789" |
| result | int | 否 | 扫描结果 | 0 |
| callback | string | 否 | JSONP回调函数名 | "callback" |
#### 请求示例
```
GET /api/Label/label-scan/batch?page=1&pageSize=10&sortBy=CreatedAt&sortOrder=desc
```
#### 响应格式
**成功响应**
```json
{
"status": "ok",
"timestamp": "2026-03-30T12:00:00Z",
"totalCount": 50,
"page": 1,
"pageSize": 10,
"totalPages": 5,
"data": [
{
"Id": 1,
"NeutralWaybillNumber": "TEST001",
"Result": 0,
"CreatedBy": "system",
"CreatedAt": "2026-03-30T10:00:00Z"
},
...
]
}
```
**失败响应**
```json
{
"status": "error",
"message": "An unexpected error occurred during batch retrieval.",
"errorDetails": "错误信息"
}
```
### 2.12 导出标签替换请求为Excel
**接口路径**`/label-replace/export-excel`
**请求方法**GET
**功能描述**导出标签替换请求为Excel
#### 请求参数
| 参数名 | 类型 | 必填 | 描述 | 示例值 |
|-------|------|------|------|--------|
| billOfLadingNumber | string | 否 | 提单号 | "BOL001" |
| masterPackageNumber | string | 否 | 大包号 | "MP001" |
| referenceNumber | string | 否 | 参考号 | "REF001" |
| neutralWaybillNumber | string | 否 | 中性面单单号 | "TEST001" |
| finalMileTrackingNumber | string | 否 | 尾程跟踪单号 | "1Z999AA10123456789" |
| replaceStatus | string | 否 | 换单状态 | "Y" |
| customerId | int | 否 | 客户ID | 1 |
#### 请求示例
```
GET /api/Label/label-replace/export-excel?customerId=1&replaceStatus=Y
```
#### 响应格式
**成功响应**
- 响应类型:`application/vnd.openxmlformats-officedocument.spreadsheetml.sheet`
- 响应内容Excel文件字节流
- 文件名:`LabelReplaceRequests_20260330_120000.xlsx`
**失败响应**
```json
{
"status": "error",
"message": "An unexpected error occurred during export.",
"errorDetails": "错误信息"
}
```
### 2.13 批量取消订单
**接口路径**`/label-replace/batch-cancel`
**请求方法**POST
**功能描述**:批量取消订单
#### 请求参数
| 参数名 | 类型 | 必填 | 描述 | 示例值 |
|-------|------|------|------|--------|
| CustomerCode | string | 是 | 客户代码 | "TEST" |
| ApiKey | string | 是 | API密钥 | "api_key_123" |
| WaybillNumbers | array | 是 | 中性面单单号列表 | ["TEST001", "TEST002"] |
#### 请求示例
```json
{
"CustomerCode": "TEST",
"ApiKey": "api_key_123",
"WaybillNumbers": ["TEST001", "TEST002"]
}
```
#### 响应格式
**成功响应**
```json
{
"status": "ok",
"timestamp": "2026-03-30T12:00:00Z",
"successCount": 2,
"failedCount": 0,
"failedItems": [],
"message": "Batch cancel completed successfully"
}
```
**失败响应**
```json
{
"status": "error",
"message": "Waybill numbers are required"
}
```
### 2.14 导出标签扫描记录为Excel
**接口路径**`/label-scan/export-excel`
**请求方法**GET
**功能描述**导出标签扫描记录为Excel
#### 请求参数
| 参数名 | 类型 | 必填 | 描述 | 示例值 |
|-------|------|------|------|--------|
| customerId | int | 否 | 客户ID | 1 |
| referenceNumber | string | 否 | 参考号 | "REF001" |
| neutralWaybillNumber | string | 否 | 中性面单单号 | "TEST001" |
| finalMileTrackingNumber | string | 否 | 尾程跟踪单号 | "1Z999AA10123456789" |
| result | int | 否 | 扫描结果 | 0 |
#### 请求示例
```
GET /api/Label/label-scan/export-excel?customerId=1&result=0
```
#### 响应格式
**成功响应**
- 响应类型:`application/vnd.openxmlformats-officedocument.spreadsheetml.sheet`
- 响应内容Excel文件字节流
- 文件名:`LabelScanRecords_20260330_120000.xlsx`
**失败响应**
```json
{
"status": "error",
"message": "An unexpected error occurred during export.",
"errorDetails": "错误信息"
}
```
### 2.15 获取客户列表
**接口路径**`/customers`
**请求方法**GET
**功能描述**:获取客户列表
#### 请求参数
| 参数名 | 类型 | 必填 | 描述 | 示例值 |
|-------|------|------|------|--------|
| callback | string | 否 | JSONP回调函数名 | "callback" |
#### 请求示例
```
GET /api/Label/customers
```
#### 响应格式
**成功响应**
```json
{
"status": "ok",
"timestamp": "2026-03-30T12:00:00Z",
"data": [
{
"Id": 1,
"CustomerCode": "TEST",
"CustomerName": "测试客户"
},
...
]
}
```
**失败响应**
```json
{
"status": "error",
"message": "An unexpected error occurred during customers retrieval.",
"errorDetails": "错误信息"
}
```
### 2.16 批量查询换单状态
**接口路径**`/label-replace/status`
**请求方法**POST
**功能描述**:批量查询换单状态
#### 请求参数
**请求头**
| 参数名 | 类型 | 必填 | 描述 | 示例值 |
|-------|------|------|------|--------|
| customerCode | string | 是 | 客户代码 | "TEST" |
| apiKey | string | 是 | API密钥 | "api_key_123" |
**请求体**
| 参数名 | 类型 | 必填 | 描述 | 示例值 |
|-------|------|------|------|--------|
| numbers | array | 是 | 单号列表(中性面单或尾程单号) | ["TEST001", "1Z999AA10123456789"] |
#### 请求示例
```json
{
"numbers": ["TEST001", "1Z999AA10123456789"]
}
```
#### 响应格式
**成功响应**
```json
{
"code": 200,
"timestamp": "2026-03-30T12:00:00Z",
"count": 2,
"data": [
{
"number": "TEST001",
"status": "Y",
"message": "Success"
},
{
"number": "1Z999AA10123456789",
"status": "Y",
"message": "Success"
}
]
}
```
**失败响应**
```json
{
"code": 400,
"message": "customerCode and apiKey are required in headers"
}
```
## 3. 接口调用示例
### 3.1 使用cURL调用
#### 根据跟踪单号获取标签替换请求记录
```bash
curl -X GET "http://localhost:5002/api/Label/label-replace/tracking/1Z999AA10123456789"
```
#### 根据中性面单单号获取标签文件
```bash
curl -X GET "http://localhost:5002/api/Label/label-replace/waybill/TEST001/download" -o "label_TEST001.pdf"
```
#### 记录标签扫描
```bash
curl -X POST "http://localhost:5002/api/Label/label-scan/record" \
-H "Content-Type: application/json" \
-d '{"NeutralWaybillNumber": "TEST001", "Result": 0, "CreatedBy": "system"}'
```
#### 批量查询换单状态
```bash
curl -X POST "http://localhost:5002/api/Label/label-replace/status" \
-H "Content-Type: application/json" \
-H "customerCode: TEST" \
-H "apiKey: api_key_123" \
-d '{"numbers": ["TEST001", "1Z999AA10123456789"]}'
```
### 3.2 使用PowerShell调用
#### 根据跟踪单号获取标签替换请求记录
```powershell
Invoke-RestMethod -Uri "http://localhost:5002/api/Label/label-replace/tracking/1Z999AA10123456789" `
-Method GET
```
#### 根据中性面单单号获取标签文件
```powershell
Invoke-WebRequest -Uri "http://localhost:5002/api/Label/label-replace/waybill/TEST001/download" `
-Method GET `
-OutFile "label_TEST001.pdf"
```
#### 记录标签扫描
```powershell
Invoke-RestMethod -Uri "http://localhost:5002/api/Label/label-scan/record" `
-Method POST `
-ContentType "application/json" `
-Body '{"NeutralWaybillNumber": "TEST001", "Result": 0, "CreatedBy": "system"}'
```
#### 批量查询换单状态
```powershell
Invoke-RestMethod -Uri "http://localhost:5002/api/Label/label-replace/status" `
-Method POST `
-ContentType "application/json" `
-Headers @{"customerCode"="TEST"; "apiKey"="api_key_123"} `
-Body '{"numbers": ["TEST001", "1Z999AA10123456789"]}'
```
## 4. 业务流程示例
### 4.1 标签下载流程
1. **查询标签替换记录**:根据中性面单单号查询标签替换记录
2. **下载标签文件**:获取标签文件并返回字节流
3. **记录扫描**:记录标签扫描操作
### 4.2 流程示例
```
# 1. 查询标签替换记录
GET /api/Label/label-replace/waybill/TEST001
# 2. 下载标签文件
GET /api/Label/label-replace/waybill/TEST001/download
# 3. 记录扫描
POST /api/Label/label-scan/record
{"NeutralWaybillNumber": "TEST001", "Result": 0, "CreatedBy": "system"}
```
## 5. 注意事项
### 5.1 接口调用限制
- 批量操作时建议单次处理数量不超过100个
- 频繁的接口调用可能会影响系统性能,建议合理控制调用频率
### 5.2 数据验证
- 中性面单单号不能为空
- 跟踪单号不能为空
- 批量操作时,单号列表不能为空
### 5.3 认证要求
- 部分接口需要在请求头中提供customerCode和apiKey进行认证
- 请确保使用正确的API凭证进行调用
## 6. 常见问题
### 6.1 标签下载失败
**可能原因**
- 中性面单单号不存在
- 标签数据不可用
- 订单被冻结
**解决方案**
- 检查中性面单单号是否正确
- 确认订单状态是否正常
- 联系系统管理员获取帮助
### 6.2 认证失败
**可能原因**
- customerCode或apiKey不正确
- 认证信息未在请求头中提供
**解决方案**
- 确保在请求头中提供正确的customerCode和apiKey
- 联系系统管理员获取正确的API凭证
### 6.3 批量操作失败
**可能原因**
- 单号列表为空
- 部分单号不存在或状态异常
**解决方案**
- 确保单号列表不为空
- 检查单号是否正确且状态正常
## 7. 接口版本管理
| 版本 | 变更内容 | 发布日期 |
|------|----------|----------|
| v1.0 | 初始版本,包含所有基础接口 | 2026-03-30 |
## 8. 联系信息
如有接口使用问题,请联系系统管理员或开发团队。