7.9 KiB
7.9 KiB
订单指标系统实现总结
完成情况概览
已成功实现订单指标系统的核心模块,包括DTO定义、Repository接口扩展、Service业务逻辑、和Controller API端点。
已实现的文件
1. DTO 层(3个文件)
MetricsCalculationDto.cs
- 存储单个订单的指标计算结果
- 包含:中性面单号、标签率、扫描时间、考核时间、完成状态等
LabelRateMetricsDto.cs
- 存储交接单级别的标签率信息
- 包含:交接单号、总订单数、有标签订单数、标签率百分比、首次扫描时间
Daily24HCompletionRateDto.cs
- 存储每日完整统计数据
- 包含20+个指标字段,全面覆盖日统计需求
2. Repository 层接口扩展
ILabelReplaceRepository
新增3个方法:
GetOrdersByHandoverNumberAsync()- 获取交接单关联的所有订单GetOrdersByHandoverNumbersAsync()- 批量获取交接单关联的订单- (其他已有的标签相关查询方法)
ILabelScanRepository
新增6个方法:
GetScanRecordsByDateRangeAsync()- 按日期范围获取扫描记录(带结果过滤)GetFirstScanRecordByWaybillNumberAsync()- 获取单条订单的首次扫描GetFirstScanRecordsByWaybillNumbersAsync()- 批量获取首次扫描记录HasSuccessScanBeforeAsync()- 检查指定时间前是否有成功扫描GetFirstSuccessScanAsync()- 获取首次成功扫描记录GetByNeutralWaybillNumbersAsync()- 按中性面单号列表获取扫描记录
IArrivalHandoverFormRepository
新增1个方法:
GetArrivalHandoverFormsByDateRangeAsync()- 按日期范围获取到货交接单
3. Service 层
IMetricsCalculationService 接口
定义了26个业务方法,包括:
- 时间转换方法:ConvertUtcToUtc5, ConvertUtc5ToUtc, GetUtc5Today, GetUtc5DateStart, GetUtc5DateEnd
- 标签率计算:GetLabelRateAsync
- 订单考核:GetOrderMetricsAsync
- 日统计指标(12个):
- 当天新增换单数
- 累计要换总单数
- 当日换单完成数
- 当日STOP数
- 当日标签推送数
- 当日未完结失败数
- 当日换单失败数
- 当日换单成功数
- 当天应该换单数
- 16点前/后到仓包裹数
- 16点前/后考核通过包裹数
- 当日扫描数
- 完成率计算:Calculate24HCompletionRateAsync, CalculateDailyCompletionRateAsync
- 完整日统计:GetDailySummaryAsync
- 批量计算:GetBatchOrderMetricsAsync, GetDailySummariesAsync
MetricsCalculationService 实现
实现了所有接口方法,核心特性:
- 完整的时区处理:正确处理UTC-5(到仓时间)和UTC+0(其他时间)的转换
- 标签率两阶段计算:
- 未扫描状态:当前有标签订单数 / 总数
- 已扫描状态:第一扫描时间点前的有标签订单数 / 总数
- 复杂的考核时间计算:
- 高标签率(≥80%):根据收货时间确定次日16:00或23:59
- 低标签率:以首次成功扫描时间作为考核时间
- 完整的业务逻辑:包含所有12项日指标的计算
- 日志记录:完整的业务处理日志便于调试
4. Controller 层
MetricsController
提供8个RESTful API端点:
GET 端点:
/api/metrics/label-rate- 获取交接单标签率/api/metrics/order-assessment- 获取订单考核指标/api/metrics/daily-summary- 获取每日汇总/api/metrics/daily-summaries- 获取日期范围汇总/api/metrics/24h-completion-rate- 获取24小时完成率/api/metrics/daily-completion-rate- 获取每日完成率
POST 端点:
7. /api/metrics/batch-order-metrics - 批量获取订单指标
8. /api/metrics/recalculate-label-rate - 重新计算标签率
所有端点均包含:
- 完整的参数验证
- 标准的错误处理
- 详细的日志记录
- RESTful 返回格式
关键技术实现细节
时区处理
ReceiptTime (UTC-5) ──────────────── ConvertUtc5ToUtc ──> SQL 查询
LabelRetrievedAt (UTC+0) ─────────────────────────────> 直接比较
CreatedAt (UTC+0) ────────────────────────────────────> 直接比较
标签率计算流程
交接单
├─ 检查是否存在扫描记录
│ ├─ 不存在:标签率 = 当前有标签数 / 总数
│ └─ 存在:
│ ├─ 找到首次扫描时间
│ ├─ 统计该时间前有标签的订单
│ └─ 标签率 = 该时间前有标签数 / 总数(固定不变)
考核时间计算
订单
├─ 标签率 >= 80%
│ ├─ 收货时间 <= 16:00 ──> 考核时间 = 次日 16:00
│ └─ 收货时间 > 16:00 ───> 考核时间 = 次日 23:59
└─ 标签率 < 80%
└─ 考核时间 = 首次成功扫描时间
实现清单
- ✅ DTO 定义(3个文件)
- ✅ Repository 接口扩展(12个新方法)
- ✅ Service 接口定义(26个方法)
- ✅ Service 实现类(完整逻辑)
- ✅ Controller API(8个端点)
- ✅ 时间转换辅助方法
- ✅ 标签率计算算法
- ✅ 所有指标计算逻辑
- ✅ 参数验证和错误处理
- ✅ 日志记录
后续需要的工作
Repository 实现层(需要在具体的实现类中完成)
在以下类中实现新添加的接口方法:
LabelReplaceRepository.csLabelScanRepository.csArrivalHandoverFormRepository.cs
依赖注入配置
在 Startup.cs 或 Program.cs 中注册 MetricsCalculationService:
services.AddScoped<IMetricsCalculationService, MetricsCalculationService>();
交接单关联查询
GetOrderMetricsAsync 方法中的交接单查询逻辑需要完善:
- 通过 BillOfLadingNumber 查询交接单
- 通过 MasterPackageNumber 查询交接单
- 需要在 Repository 中添加相应的查询方法
测试建议
-
单元测试:
- 标签率计算(边界情况)
- 考核时间计算
- 时区转换
- 各项指标的数值验证
-
集成测试:
- 完整的订单到指标计算流程
- 使用真实数据验证结果准确性
-
性能测试:
- 大数据量下的计算性能
- 数据库查询优化
文件清单
新创建的文件:
src/MDL/DTOs/MetricsCalculationDto.cssrc/MDL/DTOs/LabelRateMetricsDto.cssrc/MDL/DTOs/Daily24HCompletionRateDto.cssrc/BLL/Interfaces/IMetricsCalculationService.cssrc/BLL/Services/MetricsCalculationService.cssrc/CONTROLLER/Controllers/MetricsController.cs
修改的文件:
src/DAL/interfaces/ILabelReplaceRepository.cssrc/DAL/interfaces/ILabelScanRepository.cssrc/DAL/interfaces/IArrivalHandoverFormRepository.cs
使用示例
获取交接单的标签率
GET /api/metrics/label-rate?handoverNumber=HN20260517001
获取订单的考核信息
GET /api/metrics/order-assessment?neutralWaybillNumber=LR20260517001
获取某日的完整统计
GET /api/metrics/daily-summary?date=2026-05-17
批量获取订单指标
POST /api/metrics/batch-order-metrics
Content-Type: application/json
{
"neutralWaybillNumbers": ["LR20260517001", "LR20260517002"]
}
注意事项
- 时区一致性:所有 UTC-5 时间比较必须先转换为 UTC
- Null 处理:ReceiptTime 可能为 null,需要特殊处理
- 标签率固定性:一旦扫描开始,标签率就固定不变
- 考核时间递推:考核时间与标签率及收货时间有关,不能静态确定
- 数据一致性:复杂计算过程中数据可能变化,生产环境建议加事务保护
维护建议
- 定期审查日志,确保没有异常计算
- 对关键指标的计算结果进行数据验证
- 监控 API 响应时间,必要时进行查询优化
- 保持时区配置与业务需求同步