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

344 lines
10 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.

# 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<AutoPackFailedItem>)
- [ ] 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<AutoPackFailedItem>)
- [ ] 创建 `AutoPackResultResponse`
- [ ] TaskId (string)
- [ ] TagNumber (string)
- [ ] Status (string)
- [ ] TotalCount (int)
- [ ] SuccessCount (int)
- [ ] FailedCount (int)
- [ ] StartTime (DateTime)
- [ ] EndTime (DateTime?)
- [ ] Duration (int)
- [ ] FailedItems (List<AutoPackFailedItem>)
- [ ] 编译通过
---
## 阶段二:数据访问层
### 任务 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<string>
- [ ] 实现 `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 前端正常调用
- [ ] 接口响应格式符合规范
- [ ] 错误码定义清晰