220 lines
6.2 KiB
Markdown
220 lines
6.2 KiB
Markdown
# 前端数据处理错误修复计划
|
||
|
||
## 问题分析
|
||
|
||
用户反馈:后端返回JSON数据成功,但前端显示error
|
||
|
||
### 用户收到的JSON数据:
|
||
```json
|
||
{
|
||
"data": {
|
||
"date": "2026-05-17",
|
||
"summary": {
|
||
"dailyNewReplaceCount": 0,
|
||
"dailyShouldReplaceCount": 0,
|
||
"dailySuccessCount": 0,
|
||
"dailyCompletionRate": "0.00%",
|
||
"rate24Hour": "0.00%"
|
||
},
|
||
"breakdown": {
|
||
"beforeNoon": {
|
||
"arrived": 0,
|
||
"passed": 0,
|
||
"rate": "0%"
|
||
},
|
||
"afternoon": {
|
||
"arrived": 0,
|
||
"passed": 0,
|
||
"rate": "0%"
|
||
}
|
||
},
|
||
"details": {
|
||
"cumulativeTotal": 106,
|
||
"dailyStop": 0,
|
||
"dailyLabelPush": 0,
|
||
"dailyScanCount": 0,
|
||
"dailyFailure": 0
|
||
}
|
||
},
|
||
"success": true
|
||
}
|
||
```
|
||
|
||
### 问题根源
|
||
|
||
查看 `metrics-dashboard-summary.html` 第525-628行的 `displayDashboard` 函数:
|
||
|
||
```javascript
|
||
function displayDashboard(data) {
|
||
const date = data.date;
|
||
const summary = data.summary || {};
|
||
const breakdown = data.breakdown || {};
|
||
const details = data.details || {};
|
||
|
||
// ... 生成HTML ...
|
||
}
|
||
```
|
||
|
||
**问题识别**:
|
||
1. 前端代码期望的数据结构与后端返回的结构不一致
|
||
2. `data.summary` 应该包含 `dailyNewReplaceCount` 等字段
|
||
3. 但后端可能返回的是不同的结构
|
||
|
||
### 数据不匹配的具体原因
|
||
|
||
后端 API:`/api/metrics/daily-dashboard?date=2026-05-17`
|
||
|
||
后端返回的JSON结构中 `success: true`,说明后端代码执行成功。
|
||
|
||
但根据数据内容:
|
||
- `daily NewReplaceCount: 0` - 应为大于0
|
||
- `dailyShouldReplaceCount: 0` - 应该与之前查询的3592接近
|
||
- 仅有 `cumulativeTotal: 106` 有合理的值
|
||
|
||
### 真实原因
|
||
|
||
这不是前端代码问题,而是**后端返回的数据本身是全0**。
|
||
|
||
前端代码正确地处理了接收到的数据:
|
||
- 第493行:检查 `response.success`
|
||
- 第507行:调用 `displayDashboard(response.data)`
|
||
- 第525-628行:遍历 `data.summary` 和 `data.breakdown` 显示
|
||
|
||
**关键问题**:用户说"显示error",但我们看到的JSON显示 `success: true`。
|
||
|
||
这可能意味着:
|
||
1. 存储过程未执行或返回空结果
|
||
2. 后端的 `GetDailySummaryAsync` 返回的是默认值(全0)
|
||
3. 查询的日期 2026-05-17 在数据库中没有实际数据
|
||
|
||
## 修复计划
|
||
|
||
### 步骤1:验证后端API实际返回的数据
|
||
|
||
在浏览器开发者工具中:
|
||
1. 打开 Chrome DevTools (F12)
|
||
2. 切换到 Network 标签
|
||
3. 选择日期 2026-05-17 并点击"查询汇总"
|
||
4. 找到 `/api/metrics/daily-dashboard` 请求
|
||
5. 在 Response 标签查看实际返回的JSON
|
||
|
||
**检查项**:
|
||
- `success` 字段值
|
||
- `data.summary` 中各字段的实际值
|
||
- 是否有错误信息
|
||
|
||
### 步骤2:检查后端的 MetricsController.GetDailyDashboard 方法
|
||
|
||
**问题**:需要确认后端是否正确调用了存储过程并映射了数据
|
||
|
||
**检查文件**:`src/CONTROLLER/Controllers/MetricsController.cs`
|
||
|
||
**关键问题**:
|
||
- 是否正确传递了日期参数?
|
||
- `GetDailySummaryAsync(date)` 返回的是什么?
|
||
- DTO映射是否正确?
|
||
|
||
### 步骤3:检查存储过程是否真的被创建和调用
|
||
|
||
在数据库中验证:
|
||
|
||
```sql
|
||
-- 1. 验证存储过程存在
|
||
SHOW PROCEDURE STATUS WHERE Db = 'lr01mainusa' AND Name = 'sp_GetDailyMetricsSummary';
|
||
|
||
-- 2. 直接测试存储过程
|
||
CALL sp_GetDailyMetricsSummary('2026-05-17');
|
||
|
||
-- 3. 检查该日期是否有实际数据
|
||
SELECT COUNT(*) FROM arrival_handover_forms
|
||
WHERE DATE(CONVERT_TZ(ReceiptTime, '+00:00', '-05:00')) = '2026-05-17';
|
||
|
||
SELECT COUNT(*) FROM label_replace_requests
|
||
WHERE DATE(CONVERT_TZ(CreatedAt, '+00:00', '-05:00')) = '2026-05-17'
|
||
AND Label IS NOT NULL;
|
||
```
|
||
|
||
### 步骤4:在不同日期上测试
|
||
|
||
尝试查询其他日期(如2026-05-16、2026-05-15等),确认:
|
||
- 是否某个特定日期返回0
|
||
- 还是所有日期都返回0
|
||
|
||
### 步骤5:添加前端调试日志
|
||
|
||
在前端 `handleDashboardResponse` 函数中添加详细日志:
|
||
|
||
```javascript
|
||
function handleDashboardResponse(response) {
|
||
console.log('响应内容:', JSON.stringify(response, null, 2));
|
||
|
||
if (response && response.success) {
|
||
console.log('数据验证:成功');
|
||
console.log('summary:', response.data?.summary);
|
||
console.log('breakdown:', response.data?.breakdown);
|
||
console.log('details:', response.data?.details);
|
||
displayDashboard(response.data);
|
||
} else {
|
||
console.error('响应失败:', response?.error);
|
||
showError(response?.error || '查询失败');
|
||
}
|
||
}
|
||
```
|
||
|
||
### 步骤6:后端添加详细日志
|
||
|
||
在 `MetricsCalculationService.GetDailySummaryAsync` 中添加日志:
|
||
|
||
```csharp
|
||
public async Task<Daily24HCompletionRateDto> GetDailySummaryAsync(DateTime date)
|
||
{
|
||
_logger.LogInformation("=== GetDailySummaryAsync START ===");
|
||
_logger.LogInformation("查询日期:{date:yyyy-MM-dd}", date);
|
||
|
||
try
|
||
{
|
||
var db = _provider.GetClient();
|
||
string sql = $"CALL sp_GetDailyMetricsSummary('{date:yyyy-MM-dd}')";
|
||
_logger.LogInformation("执行SQL:{sql}", sql);
|
||
|
||
var summaryList = await db.SqlQueryable<dynamic>(sql).ToListAsync();
|
||
_logger.LogInformation("查询结果行数:{count}", summaryList?.Count ?? 0);
|
||
|
||
if (summaryList?.Count > 0)
|
||
{
|
||
var firstRow = summaryList[0];
|
||
_logger.LogInformation("第一行数据:DailyShouldReplaceCount={count}", firstRow.DailyShouldReplaceCount);
|
||
}
|
||
|
||
// ... 后续处理 ...
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
_logger.LogError(ex, "=== GetDailySummaryAsync ERROR ===");
|
||
// ... 降级处理 ...
|
||
}
|
||
}
|
||
```
|
||
|
||
## 关键发现
|
||
|
||
用户提供的JSON显示 `success: true` 和数据存在,所以前端的问题不在于处理null或异常。
|
||
|
||
真实问题是**后端返回的数据本身全是0**(除了 `cumulativeTotal: 106`)。
|
||
|
||
这说明:
|
||
1. ✅ API端点工作正常
|
||
2. ✅ 数据库连接成功
|
||
3. ✅ 没有异常导致降级
|
||
4. ❌ 存储过程返回了错误的数据(全0)或者
|
||
5. ❌ 查询的日期在数据库中确实没有相关数据
|
||
|
||
## 验收标准
|
||
|
||
1. ✅ 通过浏览器DevTools查看实际API返回
|
||
2. ✅ 验证存储过程是否存在并可执行
|
||
3. ✅ 检查查询日期的实际源数据
|
||
4. ✅ 修改日期后验证不同日期的数据
|
||
5. ✅ 查看后端日志确认实际调用情况
|
||
|