# 批量推送扫描记录接口开发计划 ## 需求分析 用户需要开发一个接口,支持: 1. 按批量订单号查询扫描记录 2. 按时间范围查询扫描记录 3. 对每个客户推送其订单最新的扫描记录 4. 有最新记录则推送,没有则不推送 ## 现有代码结构 ### 核心组件 - **LabelController** (`src/CONTROLLER/Controllers/LabelController.cs`): 控制器,包含webhook推送方法 - **ILabelScanService** (`src/BLL/Interfaces/ILabelScanService.cs`): 扫描服务接口 - **LabelScanService** (`src/BLL/Services/LabelScanService.cs`): 扫描服务实现 - **LabelScanEntity** (`src/MDL/Models/LabelScanEntity.cs`): 扫描记录实体 - **CustomerEntity** (`src/MDL/Models/CustomerEntity.cs`): 客户实体 ### 现有Webhook方法 | 客户代码 | 推送方法 | 参数 | |---------|---------|------| | PT_GZ | `SendWebhookToPatuen` | waybillNumber, scanTime, printTime | | XT_JX | `SendWebhookToXunTong` | waybillNumber, scanTime, printTime, scanResult, scanDescription | | ZY_SH | `SendWebhookToZunYou` | waybillNumber, scanTime, printTime, scanResult, finalMileTrackingNumber | | IDI_ZJ | `SendWebhookToIDI` | waybillNumber, scanTime, printTime, scanResult, scanDescription | | WEM_ZJ | `SendWebhookToWEM` | waybillNumber, scanTime, printTime, scanResult, scanDescription | ## 实现方案 ### 1. 新增DTO定义 创建批量推送请求和响应DTO: ```csharp // 请求DTO public class BatchPushRequestDto { public List WaybillNumbers { get; set; } // 批量订单号(可选) public string StartTime { get; set; } // 开始时间(可选,格式:yyyy-MM-dd HH:mm:ss) public string EndTime { get; set; } // 结束时间(可选,格式:yyyy-MM-dd HH:mm:ss) public string CustomerCode { get; set; } // 客户代码(可选,指定推送特定客户) } // 响应DTO public class BatchPushResponseDto { public string Status { get; set; } public string Message { get; set; } public int TotalOrders { get; set; } public int PushedCount { get; set; } public int SkippedCount { get; set; } public List Details { get; set; } } public class PushResultDetail { public string WaybillNumber { get; set; } public string CustomerCode { get; set; } public bool Success { get; set; } public string Message { get; set; } public DateTime? ScanTime { get; set; } } ``` ### 2. 新增服务方法 在 `ILabelScanService` 接口中添加: ```csharp /// /// 获取指定条件的最新扫描记录(按订单号分组,取最新的一条) /// Task> GetLatestScanRecordsAsync( List waybillNumbers = null, DateTime? startTime = null, DateTime? endTime = null, int? customerId = null); ``` ### 3. 新增Controller接口 在 `LabelController` 中添加: ```csharp /// /// 批量推送扫描记录到客户系统 /// [HttpPost("webhook/batch-push")] public async Task BatchPushWebhook([FromBody] BatchPushRequestDto request) ``` ### 4. 核心业务逻辑 1. **参数校验**:验证请求参数,至少提供订单号列表或时间范围 2. **数据查询**:根据条件查询扫描记录,按订单号分组取最新记录 3. **客户匹配**:根据订单关联的客户ID获取客户信息 4. **条件过滤**:如果指定了客户代码,只处理该客户的订单 5. **推送执行**:根据客户代码调用对应的webhook方法 6. **结果汇总**:返回推送结果统计 ## 文件修改清单 | 文件 | 修改类型 | 说明 | |-----|---------|------| | `src/MDL/DTOs/BatchPushDto.cs` | 新建 | 批量推送请求/响应DTO | | `src/BLL/Interfaces/ILabelScanService.cs` | 修改 | 添加获取最新扫描记录方法 | | `src/BLL/Services/LabelScanService.cs` | 修改 | 实现获取最新扫描记录方法 | | `src/DAL/Interfaces/ILabelScanRepository.cs` | 修改 | 添加仓储方法 | | `src/DAL/Repositories/LabelScanRepository.cs` | 修改 | 实现仓储方法 | | `src/CONTROLLER/Controllers/LabelController.cs` | 修改 | 添加批量推送接口 | ## 数据库查询逻辑 获取每个订单的最新扫描记录: ```sql SELECT * FROM label_scan_history WHERE (NeutralWaybillNumber IN (@waybillNumbers) OR @waybillNumbers IS NULL) AND (CreatedAt >= @startTime OR @startTime IS NULL) AND (CreatedAt <= @endTime OR @endTime IS NULL) AND (CustomerId = @customerId OR @customerId IS NULL) ORDER BY NeutralWaybillNumber, CreatedAt DESC ``` 然后按订单号分组,取每组第一条(最新的)记录。 ## 注意事项 1. **性能考虑**:批量查询时限制单次最大订单数量(建议2000条以内) 2. **异步处理**:推送操作应异步执行,不阻塞接口响应 3. **日志记录**:记录每条推送的详细结果,便于问题排查 4. **异常处理**:单个订单推送失败不应影响其他订单 5. **幂等性**:相同订单重复推送时应考虑是否需要重复发送 ## 接口调用示例 ### 请求 ```json POST /api/label/webhook/batch-push { "waybillNumbers": ["WB001", "WB002", "WB003"], "customerCode": "XT_JX" } ``` ### 响应 ```json { "status": "ok", "message": "批量推送完成", "totalOrders": 3, "pushedCount": 2, "skippedCount": 1, "details": [ { "waybillNumber": "WB001", "customerCode": "XT_JX", "success": true, "message": "推送成功", "scanTime": "2024-01-15 10:30:00" }, { "waybillNumber": "WB002", "customerCode": "XT_JX", "success": true, "message": "推送成功", "scanTime": "2024-01-15 10:35:00" }, { "waybillNumber": "WB003", "customerCode": "XT_JX", "success": false, "message": "无扫描记录", "scanTime": null } ] } ```