From 7354ae1641c4dd0a376b016de87959056c55cdca Mon Sep 17 00:00:00 2001
From: haoliang <821644@qq.com>
Date: Sun, 3 May 2026 02:12:25 +0800
Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E4=BB=AA=E8=A1=A8=E7=9B=986?=
=?UTF-8?q?=E4=B8=AA=E6=95=B0=E6=8D=AE=E9=97=AE=E9=A2=98+=E8=A1=A5?=
=?UTF-8?q?=E5=85=85=E6=B5=8B=E8=AF=95=E8=A7=84=E8=8C=83=E5=9B=BE=E8=A1=A8?=
=?UTF-8?q?=E7=BB=B4=E5=BA=A6?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
1. 最新告警:修复createdAt映射(snake_case→PascalCase),补齐alertType/machineName/title/isResolved字段
2. 机床状态分布:从原始group-by改为返回{online,offline,disabled}结构
3. 产量趋势:Controller包装为{items:[]}格式
4. 机床排行:补齐rank/program/status字段
5. 工人排行:补齐rank/machineCount/totalQuantity字段
6. 测试规范:新增维度3.1图表验证,扩展仪表盘速查表维度覆盖(1,2,3,3.1,5,6,9,12,17,20),新增反模式第14条
---
docs/06-测试规范.md | 5 ++-
src/CncModels/Dto/Dashboard/AlertListItem.cs | 11 ++++-
.../Dto/Dashboard/MachineRankResponse.cs | 9 ++++
.../Dto/Dashboard/WorkerRankResponse.cs | 8 +++-
.../Impl/Dashboard/DashboardRepository.cs | 41 +++++++++++++------
.../Interface/IDashboardRepository.cs | 2 +-
.../Controllers/DashboardController.cs | 4 +-
7 files changed, 61 insertions(+), 19 deletions(-)
diff --git a/docs/06-测试规范.md b/docs/06-测试规范.md
index 03eb655..6bdd1a1 100644
--- a/docs/06-测试规范.md
+++ b/docs/06-测试规范.md
@@ -58,6 +58,7 @@
| 1 | 页面加载 | URL正确 + 关键元素可见 | 所有页面 | 只goto不等待 |
| 2 | 默认数据 | 打开即有数据(行数>0 / 卡片有值) | 有数据展示的页面 | 不检查数据 |
| 3 | 汇总卡片数值 | ≠ 空 ≠ `-` ≠ `--` ≠ `undefined` ≠ `null` | 有统计卡片的页面 | 只检查可见 |
+| 3.1 | 图表有数据 | Canvas/SVG已渲染 + 有数据点/色块(非空白) | 有ECharts/Chart组件的页面 | 只检查容器可见 |
| 4 | 表格行数 | `.el-table__row` > 0 | 有表格的页面 | 只检查table可见 |
| 5 | 表格每列有值 | 第一行逐列文本非空 | 有表格的页面 | 只检查前2-3列 |
| 6 | 时间/数值列 | 有具体数值(非空非NULL) | 有时间/数值列的页面 | 跳过 |
@@ -82,7 +83,7 @@
|----------|-------------|
| 列表页(表格+筛选) | 1,2,4,5,8,9,10,13,14,19 |
| 列表页(表格+筛选+卡片) | 1,2,3,4,5,6,7,8,9,10,13,14,17,19 |
-| 仪表盘/概览页 | 1,2,3,20 |
+| 仪表盘/概览页 | 1,2,3,3.1,5,6,9,12,17,20 |
| 详情/表单页 | 1,15,16 |
| 所有页面 | 1,20 |
@@ -104,6 +105,7 @@
| 元素 | 验证标准 |
|------|----------|
| 汇总卡片 | 非空 ∧ ≠ `""` ∧ ≠ `"-"` ∧ ≠ `"--"` ∧ ≠ `"undefined"` ∧ ≠ `"null"` |
+| 图表(ECharts等) | Canvas/SVG存在 + 非空白(有数据点/扇形/柱状) |
| 表格数据列 | 第一行每列有文本值 |
| 状态标签 | 已知中文文案 |
| 时间列 | 有值且格式正确 |
@@ -183,3 +185,4 @@ $headers = @{ Authorization = "Bearer $token" }
| 11 | 测试不按维度表逐项覆盖 | 对照5.0维度总表 |
| 12 | 测试只覆盖部分页面 | 每个改动涉及的页面都要覆盖 |
| 13 | 新增维度后不更新维度总表 | 新发现的问题必须补充为新维度 |
+| 14 | 图表只检查容器DOM存在 | 验证Canvas/SVG有实际渲染内容(数据点/色块) |
diff --git a/src/CncModels/Dto/Dashboard/AlertListItem.cs b/src/CncModels/Dto/Dashboard/AlertListItem.cs
index d7e7a35..99b5c82 100644
--- a/src/CncModels/Dto/Dashboard/AlertListItem.cs
+++ b/src/CncModels/Dto/Dashboard/AlertListItem.cs
@@ -8,8 +8,15 @@ namespace CncModels.Dto.Dashboard
public class AlertListItem
{
public long Id { get; set; }
- public string Message { get; set; }
- public string Severity { get; set; }
+ /// 告警时间
public DateTime CreatedAt { get; set; }
+ /// 告警类型
+ public string AlertType { get; set; }
+ /// 机床名称
+ public string MachineName { get; set; }
+ /// 告警标题
+ public string Title { get; set; }
+ /// 是否已处理
+ public bool IsResolved { get; set; }
}
}
diff --git a/src/CncModels/Dto/Dashboard/MachineRankResponse.cs b/src/CncModels/Dto/Dashboard/MachineRankResponse.cs
index 0e3fda9..3aef658 100644
--- a/src/CncModels/Dto/Dashboard/MachineRankResponse.cs
+++ b/src/CncModels/Dto/Dashboard/MachineRankResponse.cs
@@ -7,8 +7,17 @@ namespace CncModels.Dto.Dashboard
///
public class MachineRankResponse
{
+ /// 排名
+ public int Rank { get; set; }
+ /// 机床ID
public int MachineId { get; set; }
+ /// 机床名称
public string MachineName { get; set; }
+ /// 当前NC程序名
+ public string Program { get; set; }
+ /// 产量
public int Quantity { get; set; }
+ /// 机床状态:1=在线 0=离线
+ public int Status { get; set; }
}
}
diff --git a/src/CncModels/Dto/Dashboard/WorkerRankResponse.cs b/src/CncModels/Dto/Dashboard/WorkerRankResponse.cs
index 5fdbc77..66b23a7 100644
--- a/src/CncModels/Dto/Dashboard/WorkerRankResponse.cs
+++ b/src/CncModels/Dto/Dashboard/WorkerRankResponse.cs
@@ -7,7 +7,13 @@ namespace CncModels.Dto.Dashboard
///
public class WorkerRankResponse
{
+ /// 排名
+ public int Rank { get; set; }
+ /// 工人姓名
public string WorkerName { get; set; }
- public int Quantity { get; set; }
+ /// 绑定机床数
+ public int MachineCount { get; set; }
+ /// 总产量
+ public int TotalQuantity { get; set; }
}
}
diff --git a/src/CncRepository/Impl/Dashboard/DashboardRepository.cs b/src/CncRepository/Impl/Dashboard/DashboardRepository.cs
index a3ecf36..9442d4b 100644
--- a/src/CncRepository/Impl/Dashboard/DashboardRepository.cs
+++ b/src/CncRepository/Impl/Dashboard/DashboardRepository.cs
@@ -137,7 +137,11 @@ namespace CncRepository.Impl.Dashboard
var sql = @"
SELECT m.id AS MachineId,
m.name AS MachineName,
- COALESCE(SUM(ad.day_quantity), 0) AS Quantity
+ COALESCE(SUM(ad.day_quantity), 0) AS Quantity,
+ CAST(m.is_online AS SIGNED) AS Status,
+ (SELECT seg.program_name FROM cnc_production_segment seg
+ WHERE seg.machine_id = m.id AND seg.production_date = CURDATE()
+ ORDER BY seg.id DESC LIMIT 1) AS Program
FROM cnc_machine m
LEFT JOIN (
SELECT machine_id, production_date, day_quantity FROM (
@@ -158,10 +162,13 @@ namespace CncRepository.Impl.Dashboard
)
GROUP BY seg.machine_id, seg.production_date
) ad ON ad.machine_id = m.id
- GROUP BY m.id, m.name
+ GROUP BY m.id, m.name, m.is_online
ORDER BY Quantity DESC
LIMIT @Top";
- return conn.Query(sql, new { StartDate = startDate, EndDate = endDate, Top = top }).ToList();
+ var rows = conn.Query(sql, new { StartDate = startDate, EndDate = endDate, Top = top }).ToList();
+ // 填充排名
+ for (int i = 0; i < rows.Count; i++) rows[i].Rank = i + 1;
+ return rows;
}
}
@@ -172,7 +179,8 @@ namespace CncRepository.Impl.Dashboard
{
var sql = @"
SELECT w.name AS WorkerName,
- COALESCE(SUM(ad.day_quantity), 0) AS Quantity
+ COUNT(DISTINCT wm.machine_id) AS MachineCount,
+ COALESCE(SUM(ad.day_quantity), 0) AS TotalQuantity
FROM cnc_worker w
LEFT JOIN cnc_worker_machine wm ON wm.worker_id = w.id
LEFT JOIN (
@@ -195,9 +203,12 @@ namespace CncRepository.Impl.Dashboard
GROUP BY seg.machine_id, seg.production_date
) ad ON ad.machine_id = wm.machine_id
GROUP BY w.id, w.name
- ORDER BY Quantity DESC
+ ORDER BY TotalQuantity DESC
LIMIT @Top";
- return conn.Query(sql, new { StartDate = startDate, EndDate = endDate, Top = top }).ToList();
+ var rows = conn.Query(sql, new { StartDate = startDate, EndDate = endDate, Top = top }).ToList();
+ // 填充排名
+ for (int i = 0; i < rows.Count; i++) rows[i].Rank = i + 1;
+ return rows;
}
}
@@ -232,13 +243,15 @@ namespace CncRepository.Impl.Dashboard
}
}
- /// 机床状态分布(示意性实现,需要根据实际状态表结构调整)
- public List GetMachineStatusDistribution()
+ /// 机床状态分布
+ public object GetMachineStatusDistribution()
{
using (var conn = CreateConnection())
{
- var sql = @"SELECT last_device_status AS Status, COUNT(1) AS Count FROM cnc_machine GROUP BY last_device_status";
- return conn.Query(sql).ToList();
+ var online = conn.ExecuteScalar("SELECT COUNT(1) FROM cnc_machine WHERE is_enabled = 1 AND is_online = 1");
+ var offline = conn.ExecuteScalar("SELECT COUNT(1) FROM cnc_machine WHERE is_enabled = 1 AND is_online = 0");
+ var disabled = conn.ExecuteScalar("SELECT COUNT(1) FROM cnc_machine WHERE is_enabled = 0");
+ return new { online, offline, disabled };
}
}
@@ -247,8 +260,12 @@ namespace CncRepository.Impl.Dashboard
{
using (var conn = CreateConnection())
{
- var sql = @"SELECT id, title AS Message, alert_type AS Severity, created_at FROM cnc_alert ORDER BY created_at DESC LIMIT @Count";
- // 如果 cnc_alert 不存在 Title/Severity,后续可调整为 Message/Level 等字段
+ var sql = @"SELECT a.id AS Id, a.created_at AS CreatedAt, a.alert_type AS AlertType,
+ COALESCE(m.name, '') AS MachineName, a.title AS Title,
+ CAST(a.is_resolved AS SIGNED) AS IsResolved
+ FROM cnc_alert a
+ LEFT JOIN cnc_machine m ON m.id = a.machine_id
+ ORDER BY a.created_at DESC LIMIT @Count";
return conn.Query(sql, new { Count = count }).ToList();
}
}
diff --git a/src/CncRepository/Interface/IDashboardRepository.cs b/src/CncRepository/Interface/IDashboardRepository.cs
index 5a4b6ab..3609645 100644
--- a/src/CncRepository/Interface/IDashboardRepository.cs
+++ b/src/CncRepository/Interface/IDashboardRepository.cs
@@ -19,7 +19,7 @@ namespace CncRepository.Interface
List GetProductionTrend(int days);
- List GetMachineStatusDistribution();
+ object GetMachineStatusDistribution();
List GetRecentAlerts(int count);
}
diff --git a/src/CncWebApi/Controllers/DashboardController.cs b/src/CncWebApi/Controllers/DashboardController.cs
index 92d5ada..ad784f1 100644
--- a/src/CncWebApi/Controllers/DashboardController.cs
+++ b/src/CncWebApi/Controllers/DashboardController.cs
@@ -85,8 +85,8 @@ namespace CncWebApi.Controllers
[Route("trend")]
public IHttpActionResult GetProductionTrend(int days = 7)
{
- var result = _dashboardService.GetProductionTrend(days);
- return Ok(ApiResponse