From 1c1698f9ddaaaa6ac7af9189cea68e5742d0a9ca Mon Sep 17 00:00:00 2001 From: haoliang <821644@qq.com> Date: Sat, 2 May 2026 22:04:36 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BB=AA=E8=A1=A8=E7=9B=98=E6=9F=A5=E8=AF=A2?= =?UTF-8?q?=E4=BC=98=E5=8C=96=EF=BC=9A=E5=B7=B2=E6=B1=87=E6=80=BB=E6=97=A5?= =?UTF-8?q?=E6=9C=9F=E7=94=A8daily=5Fproduction=EF=BC=8C=E6=9C=AA=E6=B1=87?= =?UTF-8?q?=E6=80=BB=E6=97=A5=E6=9C=9F=E5=AE=9E=E6=97=B6=E8=AE=A1=E7=AE=97?= =?UTF-8?q?segment=EF=BC=8C=E8=BD=A6=E9=97=B4=E4=BA=A7=E9=87=8F/=E6=9C=BA?= =?UTF-8?q?=E5=BA=8A=E6=8E=92=E8=A1=8C/=E5=B7=A5=E4=BA=BA=E6=8E=92?= =?UTF-8?q?=E8=A1=8C/=E4=BA=A7=E9=87=8F=E8=B6=8B=E5=8A=BF=E5=9D=87?= =?UTF-8?q?=E9=87=87=E7=94=A8=E6=B7=B7=E5=90=88=E6=9F=A5=E8=AF=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Impl/Dashboard/DashboardRepository.cs | 141 ++++++++++++++---- 1 file changed, 112 insertions(+), 29 deletions(-) diff --git a/src/CncRepository/Impl/Dashboard/DashboardRepository.cs b/src/CncRepository/Impl/Dashboard/DashboardRepository.cs index b82a8f4..a3ecf36 100644 --- a/src/CncRepository/Impl/Dashboard/DashboardRepository.cs +++ b/src/CncRepository/Impl/Dashboard/DashboardRepository.cs @@ -17,6 +17,32 @@ namespace CncRepository.Impl.Dashboard { public DashboardRepository(string connectionString) : base(connectionString) { } + /// + /// 通用产量计算SQL片段:已汇总日期用cnc_daily_production,未汇总日期用cnc_production_segment实时计算。 + /// 与machine表JOIN时,需在外层提供 machine_id 列。 + /// 参数:@StartDate, @EndDate + /// 返回列:machine_id, production_date, day_quantity + /// + private const string DailyQuantityUnionSql = @" + SELECT machine_id, production_date, day_quantity FROM ( + SELECT dp.machine_id, dp.production_date, SUM(dp.total_quantity) AS day_quantity + FROM cnc_daily_production dp + WHERE dp.production_date BETWEEN @StartDate AND @EndDate + GROUP BY dp.machine_id, dp.production_date + ) summarized + UNION ALL + SELECT seg.machine_id, seg.production_date, + SUM(CASE WHEN seg.is_settled=1 THEN seg.quantity + ELSE COALESCE(seg.end_part_count, seg.start_part_count) - seg.start_part_count END) AS day_quantity + FROM cnc_production_segment seg + WHERE seg.production_date BETWEEN @StartDate AND @EndDate + AND NOT EXISTS ( + SELECT 1 FROM cnc_daily_production dp + WHERE dp.machine_id = seg.machine_id AND dp.production_date = seg.production_date + ) + GROUP BY seg.machine_id, seg.production_date + ) all_days"; + /// 汇总卡片数据 public DashboardSummaryResponse GetSummary() { @@ -24,7 +50,7 @@ namespace CncRepository.Impl.Dashboard { var onlineCount = conn.ExecuteScalar(@"SELECT COUNT(1) FROM cnc_machine WHERE is_online = 1"); var totalMachines = conn.ExecuteScalar(@"SELECT COUNT(1) FROM cnc_machine"); - // 今日总产量:直接从产量分段实时计算 + // 今日总产量:直接从产量分段实时计算(今日一定没有日终汇总) var todayProduction = conn.ExecuteScalar(@" SELECT COALESCE(SUM(CASE WHEN is_settled=1 THEN quantity ELSE COALESCE(end_part_count,start_part_count) - start_part_count END), 0) @@ -68,26 +94,36 @@ namespace CncRepository.Impl.Dashboard { using (var conn = CreateConnection()) { - // 当查询范围包含今天时,使用产量分段实时数据;历史日期使用日终汇总 - var today = DateTime.Today; - bool includeToday = endDate >= today; - DateTime histEnd = includeToday ? today.AddDays(-1) : endDate; - var sql = @" SELECT w.Name AS WorkshopName, - COALESCE(SUM(CASE WHEN is_settled=1 THEN dp.quantity - ELSE COALESCE(dp.end_part_count,dp.start_part_count) - dp.start_part_count END), 0) AS Quantity, + COALESCE(SUM(ad.day_quantity), 0) AS Quantity, COUNT(DISTINCT m.id) AS MachineCount, CASE - WHEN DATEDIFF(@EndDate, @StartDate) = 0 THEN COALESCE(SUM(CASE WHEN is_settled=1 THEN dp.quantity - ELSE COALESCE(dp.end_part_count,dp.start_part_count) - dp.start_part_count END), 0) / NULLIF(COUNT(DISTINCT m.id),0) - ELSE COALESCE(SUM(CASE WHEN is_settled=1 THEN dp.quantity - ELSE COALESCE(dp.end_part_count,dp.start_part_count) - dp.start_part_count END), 0) / (DATEDIFF(@EndDate, @StartDate) + 1) / NULLIF(COUNT(DISTINCT m.id),0) + WHEN DATEDIFF(@EndDate, @StartDate) = 0 + THEN COALESCE(SUM(ad.day_quantity), 0) / NULLIF(COUNT(DISTINCT m.id), 0) + ELSE COALESCE(SUM(ad.day_quantity), 0) / (DATEDIFF(@EndDate, @StartDate) + 1) / NULLIF(COUNT(DISTINCT m.id), 0) END AS AvgQuantity FROM cnc_workshop w LEFT JOIN cnc_machine m ON m.workshop_id = w.id - LEFT JOIN cnc_production_segment dp ON dp.machine_id = m.id - AND dp.production_date BETWEEN @StartDate AND @EndDate + LEFT JOIN ( + SELECT machine_id, production_date, day_quantity FROM ( + SELECT dp.machine_id, dp.production_date, SUM(dp.total_quantity) AS day_quantity + FROM cnc_daily_production dp + WHERE dp.production_date BETWEEN @StartDate AND @EndDate + GROUP BY dp.machine_id, dp.production_date + ) summarized + UNION ALL + SELECT seg.machine_id, seg.production_date, + SUM(CASE WHEN seg.is_settled=1 THEN seg.quantity + ELSE COALESCE(seg.end_part_count, seg.start_part_count) - seg.start_part_count END) AS day_quantity + FROM cnc_production_segment seg + WHERE seg.production_date BETWEEN @StartDate AND @EndDate + AND NOT EXISTS ( + SELECT 1 FROM cnc_daily_production dp + WHERE dp.machine_id = seg.machine_id AND dp.production_date = seg.production_date + ) + GROUP BY seg.machine_id, seg.production_date + ) ad ON ad.machine_id = m.id GROUP BY w.id, w.name"; return conn.Query(sql, new { StartDate = startDate, EndDate = endDate }).ToList(); } @@ -101,11 +137,27 @@ namespace CncRepository.Impl.Dashboard var sql = @" SELECT m.id AS MachineId, m.name AS MachineName, - COALESCE(SUM(CASE WHEN dp.is_settled=1 THEN dp.quantity - ELSE COALESCE(dp.end_part_count,dp.start_part_count) - dp.start_part_count END), 0) AS Quantity + COALESCE(SUM(ad.day_quantity), 0) AS Quantity FROM cnc_machine m - LEFT JOIN cnc_production_segment dp ON dp.machine_id = m.id - AND dp.production_date BETWEEN @StartDate AND @EndDate + LEFT JOIN ( + SELECT machine_id, production_date, day_quantity FROM ( + SELECT dp.machine_id, dp.production_date, SUM(dp.total_quantity) AS day_quantity + FROM cnc_daily_production dp + WHERE dp.production_date BETWEEN @StartDate AND @EndDate + GROUP BY dp.machine_id, dp.production_date + ) summarized + UNION ALL + SELECT seg.machine_id, seg.production_date, + SUM(CASE WHEN seg.is_settled=1 THEN seg.quantity + ELSE COALESCE(seg.end_part_count, seg.start_part_count) - seg.start_part_count END) AS day_quantity + FROM cnc_production_segment seg + WHERE seg.production_date BETWEEN @StartDate AND @EndDate + AND NOT EXISTS ( + SELECT 1 FROM cnc_daily_production dp + WHERE dp.machine_id = seg.machine_id AND dp.production_date = seg.production_date + ) + GROUP BY seg.machine_id, seg.production_date + ) ad ON ad.machine_id = m.id GROUP BY m.id, m.name ORDER BY Quantity DESC LIMIT @Top"; @@ -120,12 +172,28 @@ namespace CncRepository.Impl.Dashboard { var sql = @" SELECT w.name AS WorkerName, - COALESCE(SUM(CASE WHEN dp.is_settled=1 THEN dp.quantity - ELSE COALESCE(dp.end_part_count,dp.start_part_count) - dp.start_part_count END), 0) AS Quantity + COALESCE(SUM(ad.day_quantity), 0) AS Quantity FROM cnc_worker w LEFT JOIN cnc_worker_machine wm ON wm.worker_id = w.id - LEFT JOIN cnc_production_segment dp ON dp.machine_id = wm.machine_id - AND dp.production_date BETWEEN @StartDate AND @EndDate + LEFT JOIN ( + SELECT machine_id, production_date, day_quantity FROM ( + SELECT dp.machine_id, dp.production_date, SUM(dp.total_quantity) AS day_quantity + FROM cnc_daily_production dp + WHERE dp.production_date BETWEEN @StartDate AND @EndDate + GROUP BY dp.machine_id, dp.production_date + ) summarized + UNION ALL + SELECT seg.machine_id, seg.production_date, + SUM(CASE WHEN seg.is_settled=1 THEN seg.quantity + ELSE COALESCE(seg.end_part_count, seg.start_part_count) - seg.start_part_count END) AS day_quantity + FROM cnc_production_segment seg + WHERE seg.production_date BETWEEN @StartDate AND @EndDate + AND NOT EXISTS ( + SELECT 1 FROM cnc_daily_production dp + WHERE dp.machine_id = seg.machine_id AND dp.production_date = seg.production_date + ) + 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 LIMIT @Top"; @@ -138,13 +206,28 @@ namespace CncRepository.Impl.Dashboard { using (var conn = CreateConnection()) { - var sql = @"SELECT production_date AS Date, - COALESCE(SUM(CASE WHEN is_settled=1 THEN quantity - ELSE COALESCE(end_part_count,start_part_count) - start_part_count END), 0) AS Quantity - FROM cnc_production_segment - WHERE production_date >= DATE_SUB(CURDATE(), INTERVAL @Days DAY) - GROUP BY production_date - ORDER BY production_date ASC"; + // 已汇总日期用daily_production,未汇总日期用segment实时计算 + var sql = @" + SELECT production_date AS Date, COALESCE(SUM(day_quantity), 0) AS Quantity + FROM ( + SELECT dp.production_date, SUM(dp.total_quantity) AS day_quantity + FROM cnc_daily_production dp + WHERE dp.production_date >= DATE_SUB(CURDATE(), INTERVAL @Days DAY) + GROUP BY dp.production_date + UNION ALL + SELECT seg.production_date, + SUM(CASE WHEN seg.is_settled=1 THEN seg.quantity + ELSE COALESCE(seg.end_part_count, seg.start_part_count) - seg.start_part_count END) AS day_quantity + FROM cnc_production_segment seg + WHERE seg.production_date >= DATE_SUB(CURDATE(), INTERVAL @Days DAY) + AND NOT EXISTS ( + SELECT 1 FROM cnc_daily_production dp + WHERE dp.production_date = seg.production_date + ) + GROUP BY seg.production_date + ) all_days + GROUP BY production_date + ORDER BY production_date ASC"; return conn.Query(sql, new { Days = days }).ToList(); } }