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(); } }