# 数据库视图逻辑修复 - 执行说明

## 📋 执行步骤

### 步骤1：在数据库中创建存储过程

#### 1.1 打开MySQL客户端或MySQL Workbench

连接到您的数据库服务器（lr01mainusa）。

#### 1.2 执行存储过程创建脚本

打开文件 `d:\EPproject\LabelReplaceServer\database\migrations\002_create_sp_daily_metrics_summary.sql`

将整个文件内容复制粘贴到MySQL客户端中并执行。

⚠️ **重要**: 确保在正确的数据库（lr01mainusa）中执行此脚本。

#### 1.3 验证存储过程创建成功

执行以下命令验证存储过程是否创建成功：

```sql
SHOW PROCEDURE STATUS WHERE Db = 'lr01mainusa' AND Name = 'sp_GetDailyMetricsSummary';
```

应该返回一行结果，显示存储过程的信息。

### 步骤2：测试存储过程

#### 2.1 执行测试查询

在MySQL客户端中执行以下命令来测试存储过程：

```sql
CALL sp_GetDailyMetricsSummary('2026-05-15');
```

#### 2.2 验证查询结果

✅ **预期结果**：应该返回一行数据，包含以下列：

| 列名 | 预期值 | 说明 |
|------|--------|------|
| MetricsDate | 2026-05-15 | 查询日期 |
| DailyNewReplaceCount | > 0 | 当天新增换单数 |
| DailyShouldReplaceCount | 3592 | 应该换单数（与之前查询结果一致） |
| DailySuccessCount | > 0 | 当天完成数 |
| CumulativeTotalReplaceCount | 3315 | 累计未完成数（与之前查询结果一致） |
| DailyStopCount | > 0 或 0 | 冻结数 |
| DailyLabelPushCount | > 0 | 标签推送数 |
| DailyScanCount | > 0 | 扫描总数 |
| BeforeNoonArrivedCount | > 0 | 16点前到仓数 |
| AfternoonArrivedCount | > 0 或 0 | 16点后到仓数 |
| BeforeNoonPassedCount | > 0 | 16点前完成数 |
| AfternoonPassedCount | > 0 或 0 | 16点后完成数 |
| DailyFailureCount | >= 0 | 失败数 |
| DataFetchTime | 当前时间 | 数据获取时间 |

❌ **如果仍然看到大多数值为0**：

可能的原因：
1. 数据库中没有2026-05-15的实际数据
2. 时区转换逻辑仍然有问题
3. 交接单与订单的关联逻辑不正确

**解决方案**：
- 检查实际数据：`SELECT COUNT(*) FROM arrival_handover_forms WHERE DATE(CONVERT_TZ(ReceiptTime, '+00:00', '-05:00')) = '2026-05-15'`
- 检查订单数据：`SELECT COUNT(*) FROM label_replace_requests WHERE DATE(CONVERT_TZ(CreatedAt, '+00:00', '-05:00')) = '2026-05-15' AND Label IS NOT NULL`
- 检查扫描数据：`SELECT COUNT(*) FROM label_scan_history WHERE DATE(CONVERT_TZ(CreatedAt, '+00:00', '-05:00')) = '2026-05-15'`

### 步骤3：应用层验证

应用层代码已经修改为调用存储过程：

文件：`d:\EPproject\LabelReplaceServer\src\BLL\Services\MetricsCalculationService.cs`

修改内容：
- 第463行：从 `SELECT * FROM v_DailyMetricsSummary` 改为 `CALL sp_GetDailyMetricsSummary()`
- 支持参数化日期查询，可以查询任意历史日期

### 步骤4：前端集成测试

1. 启动后端应用程序
2. 打开前端仪表盘：`http://localhost:5002/metrics-dashboard-summary.html`（或您的实际URL）
3. 选择日期 2026-05-15 进行查询
4. 验证显示的指标是否正确：
   - 应该换单数 ≈ 3592
   - 累计未完成数 ≈ 3315
   - 其他指标应该 > 0（如标签推送数、扫描总数等）

### 步骤5：性能验证

查询应该在 **< 1 秒内完成**（相比原来的15-30秒）。

如果性能仍未达到目标：
- 检查数据库连接状态
- 查看MySQL慢查询日志
- 考虑添加额外的索引

## 🔧 故障排除

### 问题1：存储过程创建失败

**错误信息**：`1064 - You have an error in your SQL syntax`

**解决方案**：
1. 检查SQL语法，尤其是DELIMITER语句
2. 确保复制了完整的SQL文件内容
3. 检查数据库连接权限

### 问题2：存储过程执行超时

**错误信息**：`Timeout expired`

**解决方案**：
1. 增加查询超时时间（在应用层）
2. 优化数据库索引
3. 检查是否有表锁定

### 问题3：结果仍然全是0

**解决方案**：
1. 验证数据库中实际存在2026-05-15的数据
2. 检查时区转换：
   ```sql
   SELECT CONVERT_TZ(NOW(), '+00:00', '-05:00');  -- 应该返回UTC-5时间
   ```
3. 检查表关联是否正确

## 📝 关键指标定义

### DailyShouldReplaceCount（应该换单数）
- **定义**：当日到仓的交接单中，标签率≥80%的订单总数
- **计算方式**：
  1. 找出当日到仓的交接单（ReceiptTime在UTC-5时区的当天）
  2. 对每个交接单计算标签率（有标签订单数 / 总订单数）
  3. 只统计标签率≥80%的交接单中的订单

### DailySuccessCount（当天完成数）
- **定义**：当日扫描成功的不同中性面单数
- **计算方式**：扫描结果 Result = 0 且扫描时间在当日

### BeforeNoonArrivedCount（16点前到仓数）
- **定义**：当日16点前到仓的订单数（标签率≥80%）
- **时间判断**：HOUR(ReceiptTime UTC-5) < 16

### BeforeNoonPassedCount（16点前完成数）
- **定义**：16点前到仓的订单中，在次日16点前扫描成功的订单数

### CumulativeTotalReplaceCount（累计未完成数）
- **定义**：截至前一天的所有到仓记录中，未扫描成功的订单数

## ✅ 验收标准

1. ✅ 存储过程创建成功
2. ✅ 执行 `CALL sp_GetDailyMetricsSummary('2026-05-15')` 返回非空结果
3. ✅ DailyShouldReplaceCount = 3592（或接近值）
4. ✅ CumulativeTotalReplaceCount = 3315（或接近值）
5. ✅ 其他关键指标 > 0（如DailyLabelPushCount、DailyScanCount）
6. ✅ 前端仪表盘正确显示数据
7. ✅ 查询性能 < 1 秒

## 🚀 后续优化

如果需要进一步优化性能，可以考虑：

1. **添加缓存层**：缓存已查询的日期数据，避免重复查询
2. **并发优化**：优化存储过程中的并发执行
3. **索引优化**：根据实际查询模式添加更多索引
4. **分区表**：将大表按日期分区

