Files
LabelChange-server/.trae/documents/batch_webhook_plan.md
2026-06-01 16:30:29 +08:00

5.9 KiB
Raw Blame History

批量推送扫描记录接口开发计划

需求分析

用户需要开发一个接口,支持:

  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

// 请求DTO
public class BatchPushRequestDto
{
    public List<string> 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<PushResultDetail> 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 接口中添加:

/// <summary>
/// 获取指定条件的最新扫描记录(按订单号分组,取最新的一条)
/// </summary>
Task<List<LabelScanEntity>> GetLatestScanRecordsAsync(
    List<string> waybillNumbers = null, 
    DateTime? startTime = null, 
    DateTime? endTime = null,
    int? customerId = null);

3. 新增Controller接口

LabelController 中添加:

/// <summary>
/// 批量推送扫描记录到客户系统
/// </summary>
[HttpPost("webhook/batch-push")]
public async Task<IActionResult> 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 修改 添加批量推送接口

数据库查询逻辑

获取每个订单的最新扫描记录:

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. 幂等性:相同订单重复推送时应考虑是否需要重复发送

接口调用示例

请求

POST /api/label/webhook/batch-push
{
    "waybillNumbers": ["WB001", "WB002", "WB003"],
    "customerCode": "XT_JX"
}

响应

{
    "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
        }
    ]
}