Files
2026-06-01 16:30:29 +08:00

10 KiB
Raw Permalink Blame History

USPS 自动集包开发检查清单

开发前准备

  • 已阅读 USPS自动集包需求文档.md
  • 已阅读 spec.md 接口规范
  • 已阅读 tasks.md 任务分解
  • 已确认数据库表结构label_replace_requests, bag_tag_waybills
  • 已确认 USPS 运单号识别规则

阶段一:模型定义

任务 1.1:创建任务状态模型

文件src/MDL/Models/AutoPackTaskStatus.cs

  • 创建 AutoPackTaskStatus
    • TaskId (string)
    • TagNumber (string)
    • Status (string)
    • TotalCount (int)
    • ProcessedCount (int)
    • SuccessCount (int)
    • FailedCount (int)
    • CurrentWaybill (string)
    • StartTime (DateTime)
    • EndTime (DateTime?)
    • FailedItems (List)
    • CancellationTokenSource (CancellationTokenSource)
  • 创建 AutoPackFailedItem
    • WaybillNumber (string)
    • ErrorCode (int)
    • ErrorMessage (string)
  • 添加必要的 using 语句
  • 编译通过

任务 1.2:创建请求/响应 DTO

文件src/MDL/Models/AutoPackRequest.cs

  • 创建 StartAutoPackRequest
    • TagNumber (string)
    • Creator (string, 默认 "system")
  • 创建 StartAutoPackResponse
    • TaskId (string)
    • TagNumber (string)
    • Status (string)
    • TotalCount (int)
    • Message (string)
  • 创建 AutoPackProgressResponse
    • TaskId (string)
    • TagNumber (string)
    • Status (string)
    • TotalCount (int)
    • ProcessedCount (int)
    • SuccessCount (int)
    • FailedCount (int)
    • CurrentWaybill (string)
    • Progress (int)
    • Message (string)
    • StartTime (DateTime)
    • EstimatedEndTime (DateTime?)
    • FailedItems (List)
  • 创建 AutoPackResultResponse
    • TaskId (string)
    • TagNumber (string)
    • Status (string)
    • TotalCount (int)
    • SuccessCount (int)
    • FailedCount (int)
    • StartTime (DateTime)
    • EndTime (DateTime?)
    • Duration (int)
    • FailedItems (List)
  • 编译通过

阶段二:数据访问层

任务 2.1:扩展 Repository 接口

文件src/DAL/Interfaces/IBagTagRepository.cs

  • 添加 GetEligibleUspsWaybillsAsync(DateTime cutoffTime) 方法声明
  • 添加 GetEligibleUspsWaybillCountAsync(DateTime cutoffTime) 方法声明
  • 添加 XML 注释
  • 编译通过

任务 2.2:实现 Repository 方法

文件src/DAL/Repositories/BagTagRepository.cs

  • 实现 GetEligibleUspsWaybillsAsync 方法
    • 使用 SqlSugar 执行 SQL 查询
    • 查询条件ReplaceStatus = 'Y'
    • 查询条件CreatedAt >= cutoffTime
    • 查询条件FinalMileTrackingNumber IS NOT NULL AND != ''
    • 查询条件:未关联到 bag_tag_waybillsLEFT JOIN + IS NULL
    • 查询条件USPS 格式REGEXP '^(92|93|94|95)'
    • 查询条件USPS 格式REGEXP '^420[0-9]{5}(92|93|94|95)'
    • 查询条件USPS 格式REGEXP '^420[0-9]{9}(92|93|94|95)'
    • ORDER BY CreatedAt ASC
    • 返回 List
  • 实现 GetEligibleUspsWaybillCountAsync 方法
    • 使用 COUNT(*) 查询
    • 相同的 WHERE 条件
    • 返回 int
  • 添加异常处理
  • 编译通过

阶段三:业务逻辑层

任务 3.1:扩展 Service 接口

文件src/BLL/Interfaces/IBagTagService.cs

  • 添加 StartAutoPackAsync(string tagNumber, string creator) 方法声明
  • 添加 GetAutoPackProgressAsync(string taskId) 方法声明
  • 添加 CancelAutoPackAsync(string taskId) 方法声明
  • 添加 GetAutoPackResultAsync(string taskId) 方法声明
  • 添加 XML 注释
  • 编译通过

任务 3.2:实现任务启动逻辑

文件src/BLL/Services/BagTagService.cs

  • 注入 ICacheService如未注入
  • 实现 StartAutoPackAsync 方法
    • 验证袋牌存在GetByTagNumberAsync
    • 验证袋牌状态为 "Opened"
    • 计算 cutoffTimeDateTime.UtcNow.AddHours(-84)
    • 调用 GetEligibleUspsWaybillsAsync 获取包裹列表
    • 检查包裹数量 > 0
    • 生成唯一 TaskId格式task_{timestamp}_{guid}
    • 创建 AutoPackTaskStatus 对象
    • 存入缓存key: "autopack:{taskId}", 过期时间 60 分钟)
    • 启动后台任务Task.Run
    • 返回 StartAutoPackResponse
  • 添加异常处理
  • 编译通过

任务 3.3:实现自动集包执行逻辑

文件src/BLL/Services/BagTagService.cs

  • 创建 ExecuteAutoPackAsync 私有方法
    • 参数taskId, tagNumber, waybills, creator
    • 创建 Random 对象
    • 遍历 waybills
      • 从缓存获取任务状态
      • 检查 CancellationTokenSource.IsCancellationRequested
      • 更新 CurrentWaybill
      • 调用 AssociateWaybillAsync 进行关联
      • 更新 SuccessCount 或 FailedCount
      • 记录失败信息到 FailedItems
      • 更新 ProcessedCount
      • 保存任务状态到缓存
      • 随机延迟 2-4 秒(最后一个不延迟)
    • 任务完成处理
      • 设置 Statuscompleted/cancelled
      • 设置 EndTime
      • 清空 CurrentWaybill
      • 保存最终状态到缓存
  • 实现 GetAutoPackProgressAsync 方法
    • 从缓存获取任务状态
    • 计算 Progress 百分比
    • 计算 EstimatedEndTime
    • 映射到 AutoPackProgressResponse
    • 返回响应
  • 实现 CancelAutoPackAsync 方法
    • 从缓存获取任务状态
    • 检查任务是否存在且状态为 processing
    • 调用 CancellationTokenSource.Cancel()
    • 更新状态为 cancelled
    • 保存到缓存
    • 返回 bool
  • 实现 GetAutoPackResultAsync 方法
    • 从缓存获取任务状态
    • 映射到 AutoPackResultResponse
    • 计算 Duration
    • 返回响应
  • 添加异常处理
  • 编译通过

阶段四:接口层

任务 4.1:实现控制器方法

文件src/CONTROLLER/Controllers/BagTagController.cs

  • 添加 StartAutoPack 方法
    • HTTP POST 路由:"auto-pack/start"
    • 参数:[FromBody] StartAutoPackRequest
    • 调用 _bagTagService.StartAutoPackAsync
    • 返回统一响应格式 { code, message, data }
    • 异常处理
  • 添加 GetAutoPackProgress 方法
    • HTTP GET 路由:"auto-pack/progress/{taskId}"
    • 参数string taskId
    • 调用 _bagTagService.GetAutoPackProgressAsync
    • 处理任务不存在的情况
    • 返回统一响应格式
    • 异常处理
  • 添加 CancelAutoPack 方法
    • HTTP POST 路由:"auto-pack/cancel/{taskId}"
    • 参数string taskId
    • 调用 _bagTagService.CancelAutoPackAsync
    • 处理取消失败的情况
    • 返回统一响应格式
    • 异常处理
  • 添加 GetAutoPackResult 方法
    • HTTP GET 路由:"auto-pack/result/{taskId}"
    • 参数string taskId
    • 调用 _bagTagService.GetAutoPackResultAsync
    • 处理任务不存在的情况
    • 返回统一响应格式
    • 异常处理
  • 编译通过

任务 4.2:注册依赖注入

文件src/CONTROLLER/Program.cs

  • 检查 ICacheService 是否已注册
  • 检查 IBagTagService 是否已注册
  • 确认无需额外注册

阶段五:测试与优化

任务 5.1:编写单元测试

  • 测试启动任务 - 袋牌不存在
  • 测试启动任务 - 袋牌未打开
  • 测试启动任务 - 无符合条件的包裹
  • 测试启动任务 - 成功启动
  • 测试查询进度 - 任务不存在
  • 测试查询进度 - 正常查询
  • 测试取消任务 - 任务不存在
  • 测试取消任务 - 任务已完成
  • 测试取消任务 - 正常取消
  • 测试自动集包执行 - 全部成功
  • 测试自动集包执行 - 部分失败
  • 测试自动集包执行 - 取消操作
  • 所有测试通过

任务 5.2:性能优化与联调

  • SQL 查询性能优化
    • 检查 label_replace_requests 表索引CreatedAt, ReplaceStatus, FinalMileTrackingNumber
    • 检查 bag_tag_waybills 表索引FinalMileTrackingNumber
  • 缓存配置优化
    • 确认缓存过期时间合理60分钟
  • 并发控制
    • 确认同时只能有一个自动集包任务在运行(可选)
  • 异常处理完善
    • 数据库连接异常
    • 缓存访问异常
    • 关联操作异常
  • WinForm 联调
    • 前端能正常调用启动接口
    • 前端能正常轮询进度
    • 进度条实时更新
    • 取消功能正常
    • 大数据量测试100+ 包裹)

代码审查清单

代码规范

  • 命名规范符合项目标准
  • 方法添加 XML 注释
  • 复杂逻辑添加行内注释
  • 无死代码
  • 无 Console.WriteLine使用 ILogger

异常处理

  • 所有异步方法有 try-catch
  • 异常信息不暴露敏感信息
  • 异常正确记录日志

性能

  • 数据库查询使用参数化 SQL
  • 避免 N+1 查询问题
  • 缓存使用合理

安全

  • 输入参数验证
  • 防止 SQL 注入
  • 权限检查(如需要)

部署检查清单

  • 代码编译通过
  • 单元测试全部通过
  • 数据库迁移脚本(如需要)
  • 配置文件更新(如需要)
  • API 文档更新
  • 部署到测试环境
  • 测试环境验证通过
  • 部署到生产环境
  • 生产环境验证通过

文档检查清单

  • spec.md 已更新(如有变更)
  • tasks.md 已更新(如有变更)
  • 接口文档已更新
  • 前端联调文档已提供

验收标准

功能验收

  • 创建 USPS 袋牌后能自动触发集包(或手动触发接口)
  • 正确筛选符合条件的 USPS 包裹84小时内、未集包、已换单
  • 逐个关联包裹,间隔 2-4 秒
  • 实时反馈进度(总数、已处理数、成功数、失败数)
  • 支持取消操作
  • 记录操作日志

性能验收

  • 100 个包裹处理时间 < 10 分钟
  • 前端轮询响应时间 < 100ms
  • 内存占用稳定,无内存泄漏

兼容性验收

  • WinForm 前端正常调用
  • 接口响应格式符合规范
  • 错误码定义清晰