# 面单标签PDF缓存系统 API 文档 ## 概述 本文档描述了面单标签PDF缓存系统的API接口。该系统用于存储和管理物流面单的PDF标签字节流,支持批量解析、条码识别和缓存统计功能。 --- ## 基础信息 ### API基地址 ``` http://[服务器地址]:[端口]/api/label ``` ### 支持的HTTP方法 - `GET` - 获取数据 - `POST` - 创建或提交数据 ### 响应格式 所有API响应都是JSON格式,包含以下顶层字段: - `status` - 状态标识 (`success` 或 `error`) - `message` - 状态消息 - `data` - 响应数据(成功时)或 `errorDetails` - 错误详情(失败时) --- ## API 接口列表 ### 1. 批量解析标签数据 #### 接口信息 - **路由**: `/batch-parse` - **方法**: `POST` - **URL**: `/api/label/batch-parse` - **描述**: 批量解析订单标签数据,支持多种模式。可用于补充解析已有的订单标签。 #### 请求参数 | 参数名 | 类型 | 必需 | 说明 | |--------|------|------|------| | Mode | string | 是 | 解析模式,必须是以下值之一:`all`、`range`、`customer`、`single` | | WaybillNumber | string | 否 | 中性面单单号。在 `single` 模式下必需 | | CustomerId | int | 否 | 客户ID。在 `customer` 模式下必需 | | StartDate | datetime | 否 | 开始日期。在 `range` 模式下必需,格式:`YYYY-MM-DD` 或 ISO 8601 | | EndDate | datetime | 否 | 结束日期。在 `range` 模式下必需,格式:`YYYY-MM-DD` 或 ISO 8601 | | Limit | int | 否 | 限制返回的最大数量。默认值:1000 | #### 模式说明 | 模式 | 说明 | 必需参数 | |------|------|---------| | `all` | 处理所有有标签的订单 | 无 | | `range` | 按时间范围处理 | StartDate, EndDate | | `customer` | 按指定客户处理 | CustomerId | | `single` | 处理单条订单 | WaybillNumber | #### 请求示例 **模式1: 处理所有有标签的订单** ```json { "mode": "all", "limit": 500 } ``` **模式2: 按时间范围处理** ```json { "mode": "range", "startDate": "2024-01-01", "endDate": "2024-01-31", "limit": 1000 } ``` **模式3: 按客户处理** ```json { "mode": "customer", "customerId": 123, "limit": 500 } ``` **模式4: 处理单条订单** ```json { "mode": "single", "waybillNumber": "1Z999AA10123456784" } ``` #### 成功响应示例 ```json { "status": "success", "message": "批量解析完成", "data": { "totalProcessed": 100, "successCount": 98, "errorCount": 2, "mode": "all" } } ``` #### 失败响应示例 **参数验证失败** ```json { "status": "error", "message": "请提供有效的请求参数" } ``` **模式参数缺失** ```json { "status": "error", "message": "时间范围模式需要 StartDate 和 EndDate 参数" } ``` 或 ```json { "status": "error", "message": "客户模式需要 CustomerId 参数" } ``` 或 ```json { "status": "error", "message": "单条模式需要 WaybillNumber 参数" } ``` **无效的处理模式** ```json { "status": "error", "message": "无效的处理模式,请使用: all, range, customer, single" } ``` **系统异常** ```json { "status": "error", "message": "批量解析失败", "errorDetails": "[具体错误信息]" } ``` #### 响应字段说明 **成功响应 (data 字段)** | 字段 | 类型 | 说明 | |------|------|------| | totalProcessed | int | 处理的总订单数量 | | successCount | int | 成功处理的订单数量 | | errorCount | int | 处理失败的订单数量 | | mode | string | 使用的解析模式 | #### HTTP状态码 - `200` - 请求成功处理(即使业务逻辑返回error状态也是200) - `400` - 请求参数错误 --- ### 2. 查看缓存统计信息 #### 接口信息 - **路由**: `/cache-statistics` - **方法**: `GET` - **URL**: `/api/label/cache-statistics` - **描述**: 获取PDF标签缓存的统计信息,包括总数、成功数、失败数、性能指标等。 #### 请求参数 无 #### 成功响应示例 ```json { "status": "success", "message": "缓存统计信息", "data": { "totalRecords": 5000, "successRecords": 4950, "failedRecords": 30, "invalidRecords": 15, "pendingRecords": 5, "withBarcodeRecords": 4890, "averageParseDurationMs": 245.5, "maxParseDurationMs": 1200, "minParseDurationMs": 50 } } ``` #### 失败响应示例 ```json { "status": "error", "message": "获取统计信息失败", "errorDetails": "[具体错误信息]" } ``` #### 响应字段说明 **data 字段** | 字段 | 类型 | 说明 | |------|------|------| | totalRecords | int | 缓存表中的总记录数 | | successRecords | int | 处理成功的记录数(Status=1) | | failedRecords | int | 处理失败的记录数(Status=2) | | invalidRecords | int | 无效的记录数(Status=3) | | pendingRecords | int | 待处理的记录数(Status=0) | | withBarcodeRecords | int | 成功识别条码的记录数 | | averageParseDurationMs | double | 平均PDF解析耗时(毫秒) | | maxParseDurationMs | int | 最大PDF解析耗时(毫秒) | | minParseDurationMs | int | 最小PDF解析耗时(毫秒) | #### 缓存记录状态说明 | 状态值 | 说明 | |--------|------| | 0 | 待处理 - 刚创建或待重试的记录 | | 1 | 成功 - PDF已缓存且处理成功 | | 2 | 失败 - 处理失败,超过重试次数 | | 3 | 无效 - 缓存已失效或过期 | #### HTTP状态码 - `200` - 请求成功处理 --- ## 数据模型 ### BatchParseLabelRequest 批量解析请求模型 ```typescript { mode: string; // 必需:all | range | customer | single waybillNumber?: string; // 可选:单条模式下的面单号 customerId?: number; // 可选:客户ID startDate?: string; // 可选:开始日期 (YYYY-MM-DD) endDate?: string; // 可选:结束日期 (YYYY-MM-DD) limit?: number; // 可选:最大数量,默认1000 } ``` ### CacheStatistics 缓存统计数据模型 ```typescript { totalRecords: number; // 总记录数 successRecords: number; // 成功记录数 failedRecords: number; // 失败记录数 invalidRecords: number; // 无效记录数 pendingRecords: number; // 待处理记录数 withBarcodeRecords: number; // 包含条码的记录数 averageParseDurationMs: number; // 平均解析时间(毫秒) maxParseDurationMs: number; // 最大解析时间(毫秒) minParseDurationMs: number; // 最小解析时间(毫秒) } ``` --- ## 使用示例 ### JavaScript/TypeScript #### 使用Fetch API ```javascript // 1. 批量解析 - 处理所有有标签的订单 const batchParseAllOrders = async () => { const response = await fetch('http://localhost:8080/api/label/batch-parse', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ mode: 'all', limit: 500 }) }); const data = await response.json(); console.log(data); }; // 2. 批量解析 - 按时间范围 const batchParseByDateRange = async () => { const response = await fetch('http://localhost:8080/api/label/batch-parse', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ mode: 'range', startDate: '2024-01-01', endDate: '2024-01-31', limit: 1000 }) }); const data = await response.json(); console.log(data); }; // 3. 批量解析 - 按客户 const batchParseByCustomer = async () => { const response = await fetch('http://localhost:8080/api/label/batch-parse', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ mode: 'customer', customerId: 123, limit: 500 }) }); const data = await response.json(); console.log(data); }; // 4. 批量解析 - 单条订单 const batchParseSingle = async () => { const response = await fetch('http://localhost:8080/api/label/batch-parse', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ mode: 'single', waybillNumber: '1Z999AA10123456784' }) }); const data = await response.json(); console.log(data); }; // 5. 获取缓存统计 const getCacheStatistics = async () => { const response = await fetch('http://localhost:8080/api/label/cache-statistics'); const data = await response.json(); console.log(data); }; ``` #### 使用Axios ```javascript import axios from 'axios'; const baseURL = 'http://localhost:8080/api/label'; // 1. 批量解析 - 处理所有有标签的订单 const batchParseAll = async () => { try { const response = await axios.post(`${baseURL}/batch-parse`, { mode: 'all', limit: 500 }); console.log(response.data); } catch (error) { console.error('Error:', error); } }; // 2. 获取缓存统计 const getStatistics = async () => { try { const response = await axios.get(`${baseURL}/cache-statistics`); console.log(response.data); } catch (error) { console.error('Error:', error); } }; ``` ### Python ```python import requests import json from datetime import datetime BASE_URL = "http://localhost:8080/api/label" # 1. 批量解析 - 处理所有有标签的订单 def batch_parse_all(): payload = { "mode": "all", "limit": 500 } response = requests.post(f"{BASE_URL}/batch-parse", json=payload) print(json.dumps(response.json(), indent=2)) # 2. 批量解析 - 按时间范围 def batch_parse_by_date_range(): payload = { "mode": "range", "startDate": "2024-01-01", "endDate": "2024-01-31", "limit": 1000 } response = requests.post(f"{BASE_URL}/batch-parse", json=payload) print(json.dumps(response.json(), indent=2)) # 3. 批量解析 - 按客户 def batch_parse_by_customer(): payload = { "mode": "customer", "customerId": 123, "limit": 500 } response = requests.post(f"{BASE_URL}/batch-parse", json=payload) print(json.dumps(response.json(), indent=2)) # 4. 批量解析 - 单条订单 def batch_parse_single(): payload = { "mode": "single", "waybillNumber": "1Z999AA10123456784" } response = requests.post(f"{BASE_URL}/batch-parse", json=payload) print(json.dumps(response.json(), indent=2)) # 5. 获取缓存统计 def get_cache_statistics(): response = requests.get(f"{BASE_URL}/cache-statistics") print(json.dumps(response.json(), indent=2)) # 使用示例 if __name__ == "__main__": # batch_parse_all() # batch_parse_by_date_range() # batch_parse_by_customer() batch_parse_single() # get_cache_statistics() ``` --- ## 错误处理 ### 常见错误及解决方案 | 错误信息 | 原因 | 解决方案 | |---------|------|---------| | 请提供有效的请求参数 | 请求体为空或Mode字段缺失 | 检查请求JSON格式,确保Mode字段存在 | | 时间范围模式需要 StartDate 和 EndDate 参数 | range模式缺少日期参数 | 添加StartDate和EndDate参数 | | 客户模式需要 CustomerId 参数 | customer模式缺少客户ID | 添加CustomerId参数 | | 单条模式需要 WaybillNumber 参数 | single模式缺少面单号 | 添加WaybillNumber参数 | | 无效的处理模式 | Mode值不是允许的四种之一 | 使用 all、range、customer、single 之一 | | 批量解析失败 | 服务器内部错误 | 查看errorDetails字段,检查服务器日志 | | 获取统计信息失败 | 服务器内部错误 | 查看errorDetails字段,检查服务器日志 | --- ## 性能建议 1. **批量大小**: 建议Limit不要超过5000,避免单次请求处理过多数据 2. **日期范围**: 时间范围模式时,建议不要跨越太长的时间跨度(如超过90天) 3. **请求频率**: 避免频繁发送相同的请求,建议间隔至少5秒 4. **缓存更新**: 定时任务会自动处理待处理订单,无需频繁手动调用 --- ## FAQ **Q: 批量解析后多久能看到结果?** A: 批量解析是异步处理的。解析请求返回后,系统会在后台处理。通常需要几秒到几分钟,取决于数据量和系统负载。 **Q: 可以同时发送多个批量解析请求吗?** A: 可以,但建议不要同时发送超过10个请求,避免系统过载。 **Q: 如何判断某个订单是否已被缓存?** A: 调用cache-statistics接口,查看successRecords字段。或者查询订单表中对应订单的缓存状态。 **Q: 缓存数据会被清理吗?** A: 缓存数据会根据业务规则进行清理。无效的缓存会被标记为Status=3,并可能在定期维护时删除。 **Q: 如何处理解析失败的订单?** A: 系统会自动重试失败的订单(最多3次)。重试都失败后会标记为Status=2。可以通过single模式重新尝试解析单个订单。 --- ## 更新历史 | 版本 | 日期 | 说明 | |------|------|------| | 1.0 | 2024-01-01 | 初版发布,包含batch-parse和cache-statistics接口 | --- ## 联系方式 如有任何问题或建议,请联系技术支持团队。