From 34a8995f150432a583bf251c3838bb3e17c534f1 Mon Sep 17 00:00:00 2001 From: tq <1916474859@qq,com> Date: Wed, 3 Jul 2024 11:59:05 +0800 Subject: [PATCH] =?UTF-8?q?=E7=94=B5=E8=A1=A8=E6=9F=A5=E8=A1=A8=E6=9B=B4?= =?UTF-8?q?=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Entity/Ammeter/EmeterDayEnergy.cs | 18 +++ Entity/Ammeter/EmeterHourEnergy.cs | 19 +++ Entity/Ammeter/EmeterMinutesEnergy.cs | 19 +++ Service/Ammeter/EmeterDayEnergyService.cs | 88 +++++++++++++ Service/Ammeter/EmeterHourEnergyService.cs | 103 +++++++++++++++ Service/Ammeter/EmeterMinutesEnergyService.cs | 50 ++++++++ .../Controllers/Ammeter/AmmeterController.cs | 119 ++++++++++++------ 7 files changed, 377 insertions(+), 39 deletions(-) diff --git a/Entity/Ammeter/EmeterDayEnergy.cs b/Entity/Ammeter/EmeterDayEnergy.cs index 4778796..4a7b110 100644 --- a/Entity/Ammeter/EmeterDayEnergy.cs +++ b/Entity/Ammeter/EmeterDayEnergy.cs @@ -48,5 +48,23 @@ namespace Entity.Ammeter [SugarColumn(ColumnName = "upload_flag")] public int UploadFlag { get; set; } + + /// + /// 统计sql时间接收 + /// + [SugarColumn(IsIgnore = true)] + public virtual DateTime UploadTime { get; set; } + + /// + /// 统计sql小时接收 + /// + [SugarColumn(IsIgnore = true)] + public virtual string Hour { get; set; } + + /// + /// 统计sql分钟接收 + /// + [SugarColumn(IsIgnore = true)] + public virtual string Minute { get; set; } } } \ No newline at end of file diff --git a/Entity/Ammeter/EmeterHourEnergy.cs b/Entity/Ammeter/EmeterHourEnergy.cs index dd36f3a..92d3129 100644 --- a/Entity/Ammeter/EmeterHourEnergy.cs +++ b/Entity/Ammeter/EmeterHourEnergy.cs @@ -47,5 +47,24 @@ namespace Entity.Ammeter [SugarColumn(ColumnName = "upload_flag")] public int UploadFlag { get; set; } + + /// + /// 统计sql时间接收 + /// + [SugarColumn(IsIgnore = true)] + public virtual DateTime UploadTime { get; set; } + + /// + /// 统计sql小时接收 + /// + [SugarColumn(IsIgnore = true)] + public virtual string Hour { get; set; } + + /// + /// 统计sql分钟接收 + /// + [SugarColumn(IsIgnore = true)] + public virtual string Minute { get; set; } + } } diff --git a/Entity/Ammeter/EmeterMinutesEnergy.cs b/Entity/Ammeter/EmeterMinutesEnergy.cs index 5c4223d..fee6853 100644 --- a/Entity/Ammeter/EmeterMinutesEnergy.cs +++ b/Entity/Ammeter/EmeterMinutesEnergy.cs @@ -48,7 +48,26 @@ namespace Entity.Ammeter [SugarColumn(ColumnName = "upload_flag")] public int UploadFlag { get; set; } + + + + /// + /// 统计sql时间接收 + /// + [SugarColumn(IsIgnore = true)] + public virtual DateTime UploadTime { get; set; } + /// + /// 统计sql小时接收 + /// + [SugarColumn(IsIgnore = true)] + public virtual string Hour { get; set; } + + /// + /// 统计sql分钟接收 + /// + [SugarColumn(IsIgnore = true)] + public virtual string Minute { get; set; } } } diff --git a/Service/Ammeter/EmeterDayEnergyService.cs b/Service/Ammeter/EmeterDayEnergyService.cs index aca3677..adca2cb 100644 --- a/Service/Ammeter/EmeterDayEnergyService.cs +++ b/Service/Ammeter/EmeterDayEnergyService.cs @@ -29,5 +29,93 @@ namespace Service.Ammeter else return PageResult.ConvertPage(this.BaseDal.QueryIPageByCause(queryPageModel1, null)); } + + + /// + /// 获取七天用电量 + /// + /// + public async Task> SevenDaysElectrical(int type) + { + // 根据code分组,取最近7天数据,每天最大值-最小值=当日用电量,如果当天目前只有一条数据,取当天最大值-前一天最大值=当天耗电量 + string sql = $@" + WITH daily_max_min AS ( + SELECT + `code`, + DATE(`time`) AS `UploadTime`, + MAX(`real_time_value`) AS `MaxValue`, + MIN(`real_time_value`) AS `MinValue`, + COUNT(*) AS `Count` + FROM + `emeter_day_energy` + WHERE + `time` >= NOW() - INTERVAL 8 DAY + AND `type` = {type} + GROUP BY + `code`, DATE(`time`) +), previous_day_max AS ( + SELECT + `code`, + `UploadTime`, + `MaxValue`, + `MinValue`, + `Count`, + LAG(`MaxValue`) OVER (PARTITION BY `code` ORDER BY `UploadTime`) AS `PreviousMaxValue` + FROM + daily_max_min +), daily_consumption AS ( + SELECT + d.`code`, + d.`UploadTime`, + CASE + WHEN d.`Count` > 1 THEN d.`MaxValue` - d.`MinValue` + WHEN d.`Count` = 1 AND d.`PreviousMaxValue` IS NOT NULL THEN d.`MaxValue` - d.`PreviousMaxValue` + ELSE 0 + END AS `DailyValue` + FROM + previous_day_max d + WHERE + d.`UploadTime` >= NOW() - INTERVAL 7 DAY +) +SELECT + `UploadTime`, + SUM(`DailyValue`) AS `Value` +FROM + daily_consumption +GROUP BY + `UploadTime` +ORDER BY + `UploadTime`; +"; + + List emeterEnergies = await this.BaseDal.SqlQueryable(sql); + return emeterEnergies; + } + + + /// + /// 获取全部用电量 + /// + /// + public async Task> GetAllElectricalData(int type) + { + string sql = $@" + SELECT + code, + MAX(real_time_value) - MIN(real_time_value) AS Value + FROM + emeter_day_energy + WHERE + time >= DATE_SUB(NOW(), INTERVAL 1 MONTH) + AND type = {type} + GROUP BY + code + ORDER BY + code; + "; + + List emeterEnergies = await this.BaseDal.SqlQueryable(sql); + return emeterEnergies; + } } } diff --git a/Service/Ammeter/EmeterHourEnergyService.cs b/Service/Ammeter/EmeterHourEnergyService.cs index 57aed24..95054ce 100644 --- a/Service/Ammeter/EmeterHourEnergyService.cs +++ b/Service/Ammeter/EmeterHourEnergyService.cs @@ -4,6 +4,7 @@ using HybirdFrameworkCore.Autofac.Attribute; using HybirdFrameworkCore.Entity; using Microsoft.AspNetCore.Mvc.RazorPages; using Repository.Ammeter; +using SqlSugar; namespace Service.Ammeter { @@ -30,5 +31,107 @@ namespace Service.Ammeter else return Result>.Success(PageResult.ConvertPage(this.BaseDal.QueryIPageByCause(queryPageModel1, null))); } + + /// + /// 根据小时统计电量 + /// + /// + public async Task> GetTodayHourlyElectricalData(int type) + { + string sql = $@" + WITH hourly_max_min AS ( + SELECT + `code`, + DATE_FORMAT(`time`, '%Y-%m-%d %H:00:00') AS `Hour`, + MAX(`real_time_value`) AS `MaxValue`, + MIN(`real_time_value`) AS `MinValue`, + COUNT(*) AS `record_count` + FROM + `emeter_hour_energy` + WHERE + DATE(`time`) = CURDATE() + AND `type` = {type} + GROUP BY + `code`, DATE_FORMAT(`time`, '%Y-%m-%d %H:00:00') + ), previous_hour_max AS ( + SELECT + `code`, + `Hour`, + LAG(`MaxValue`) OVER (PARTITION BY `code` ORDER BY `Hour`) AS `PreviousMaxValue` + FROM + hourly_max_min + ) + SELECT + h.`code`, + h.`Hour`, + CASE + WHEN h.`record_count` > 1 THEN h.`MaxValue` - h.`MinValue` + ELSE h.`MaxValue` - COALESCE(p.`PreviousMaxValue`, 0) + END AS `Value` + FROM + hourly_max_min h + LEFT JOIN + previous_hour_max p ON h.`code` = p.`code` AND h.`Hour` = p.`Hour` + ORDER BY + h.`code`, h.`Hour`; + "; + + List emeterEnergies = await this.BaseDal.SqlQueryable(sql); + return emeterEnergies; + } + + + /// + /// 获取直流电表实时数据 + /// + /// + public async Task> GetEnergyMeterRealTime(string endTime, int type) + { + // 将传入的时间参数转换为 DateTime 类型 + DateTime endDateTime = DateTime.Parse(endTime); + + // 根据传入的时间参数计算 1 天前的时间 + DateTime startDateTime = endDateTime.AddDays(-1); + + // 构建 SQL 查询字符串并包含参数 + string sql = @" + WITH latest_data AS ( + SELECT + code, + MAX(time) AS latest_upload_time + FROM emeter_hour_energy + WHERE time >= @StartDateTime AND time <= @EndDateTime + AND type = @Type + GROUP BY code + ), + max_value_data AS ( + SELECT + e.*, + ROW_NUMBER() OVER (PARTITION BY e.code ORDER BY e.real_time_value DESC) AS rn + FROM emeter_hour_energy e + JOIN latest_data ld ON e.code = ld.code AND e.time = ld.latest_upload_time + WHERE e.type = @Type + ) + SELECT + * + FROM max_value_data + WHERE rn = 1; + "; + + // 使用参数化查询防止 SQL 注入 + var parameters = new List + { + new SugarParameter("@StartDateTime", startDateTime), + new SugarParameter("@EndDateTime", endDateTime), + new SugarParameter("@Type", type) + }; + + // 调用现有的 SqlQuery 方法 + List emeterEnergyChanges = this.BaseDal.SqlQuery(sql, parameters); + return emeterEnergyChanges; + } + + + } } diff --git a/Service/Ammeter/EmeterMinutesEnergyService.cs b/Service/Ammeter/EmeterMinutesEnergyService.cs index feb7c34..0cbd296 100644 --- a/Service/Ammeter/EmeterMinutesEnergyService.cs +++ b/Service/Ammeter/EmeterMinutesEnergyService.cs @@ -31,5 +31,55 @@ namespace Service.Ammeter else return PageResult.ConvertPage(_emeterMinutesEnergyRepository1.QueryIPageByCause(queryPageModel1, null)); } + + + /// + /// 根据分钟统计电量 + /// + /// + public async Task> GetTodayMinutelyElectricalData(int type) + { + string sql = $@" + WITH minute_max_min AS ( + SELECT + `code`, + DATE_FORMAT(`time`, '%Y-%m-%d %H:%i:00') AS `Minute`, + MAX(`real_time_value`) AS `MaxValue`, + MIN(`real_time_value`) AS `MinValue`, + COUNT(*) AS `record_count` + FROM + `emeter_minutes_energy` + WHERE + `time` >= NOW() - INTERVAL 1 HOUR + AND `type` = {type} + GROUP BY + `code`, DATE_FORMAT(`time`, '%Y-%m-%d %H:%i:00') + ), previous_minute_max AS ( + SELECT + `code`, + `Minute`, + LAG(`MaxValue`) OVER (PARTITION BY `code` ORDER BY `Minute`) AS `PreviousMaxValue` + FROM + minute_max_min + ) + SELECT + m.`code`, + m.`Minute`, + CASE + WHEN m.`record_count` > 1 THEN m.`MaxValue` - m.`MinValue` + WHEN p.`PreviousMaxValue` IS NULL THEN 0 + ELSE m.`MaxValue` - p.`PreviousMaxValue` + END AS `Value` + FROM + minute_max_min m + LEFT JOIN + previous_minute_max p ON m.`code` = p.`code` AND m.`Minute` = p.`Minute` + ORDER BY + m.`code`, m.`Minute`; +"; + + List emeterEnergies = await this.BaseDal.SqlQueryable(sql); + return emeterEnergies; + } } } diff --git a/WebStarter/Controllers/Ammeter/AmmeterController.cs b/WebStarter/Controllers/Ammeter/AmmeterController.cs index 1e9fd7c..e47b2b8 100644 --- a/WebStarter/Controllers/Ammeter/AmmeterController.cs +++ b/WebStarter/Controllers/Ammeter/AmmeterController.cs @@ -58,19 +58,19 @@ namespace WebStarter.Controllers.Ammeter [HttpGet("SevenDaysElectrical")] public async Task> SevenDaysElectrical() { - // 获取直流和交流表数据 - List sevenDaysElectrical = await _emeterEnergyService.SevenDaysElectrical(); - List emeterEnergyChanges = await _emeterEnergyChangeService.SevenDaysElectrical(); + + List sevenDaysElectrical = await _emeterDayEnergyService.SevenDaysElectrical(1); + List emeterEnergyChanges = await _emeterDayEnergyService.SevenDaysElectrical(2); EmeterEnergyResp resp = new EmeterEnergyResp(); - - - ChargeAssignment(sevenDaysElectrical, emeterEnergyChanges, resp); - + + ElectricEnergyDay(sevenDaysElectrical, emeterEnergyChanges, resp); return Result.Success(resp, "成功"); } + + /// /// 30天累计能耗 @@ -79,13 +79,13 @@ namespace WebStarter.Controllers.Ammeter [HttpGet("GetAllElectricalData")] public async Task> GetAllElectricalData() { - List emeterEnergy = await _emeterEnergyService.GetAllElectricalData(); - List emeterEnergyChanges = await _emeterEnergyChangeService.GetAllElectricalData(); + + List emeterEnergy = await _emeterDayEnergyService.GetAllElectricalData(1); + List emeterEnergyChanges = await _emeterDayEnergyService.GetAllElectricalData(2); + EmeterEnergyResp resp = new EmeterEnergyResp(); - - ChargeAssignment(emeterEnergy, emeterEnergyChanges, resp); - + ElectricEnergyDay(emeterEnergy, emeterEnergyChanges, resp); return Result.Success(resp, "成功"); } @@ -98,15 +98,29 @@ namespace WebStarter.Controllers.Ammeter public async Task> GetLastDayMeterData() { // 获取最近一天直流和交流表数据 - List daysElectrical = await _emeterEnergyService.GetTodayHourlyElectricalData(); - List daysElectricalChange = - await _emeterEnergyChangeService.GetTodayHourlyElectricalData(); + List daysElectrical = await _emeterHourEnergyService.GetTodayHourlyElectricalData(1); + List daysElectricalChange = + await _emeterHourEnergyService.GetTodayHourlyElectricalData(2); EmeterEnergyResp resp = new EmeterEnergyResp(); + + var config = new MapperConfiguration(cfg => + { + cfg.CreateMap().ReverseMap(); + }); + IMapper mapper = config.CreateMapper(); - ChargeAssignment(daysElectrical, daysElectricalChange, resp); + List EnergyList = mapper.Map>(daysElectrical); + // 类型赋值直流 + EnergyList?.ForEach(emeterResp => emeterResp.Type = 0); + List EnergyChangeList = mapper.Map>(daysElectricalChange); + // 类型赋值交流 + EnergyChangeList?.ForEach(emeterResp => emeterResp.Type = 1); + resp.emeterEnergy = EnergyList.OrderBy(i => i.Code).ToList(); + resp.emeterEnergyChange = EnergyChangeList.OrderBy(i => i.Code).ToList(); + return Result.Success(resp, "成功"); } @@ -115,10 +129,10 @@ namespace WebStarter.Controllers.Ammeter /// /// [HttpGet("GetTodayHourlyEnergy")] - public async Task>> GetTodayHourlyElectricalData() + public async Task>> GetTodayHourlyElectricalData() { // 直流表数据 - return Result>.Success(await _emeterEnergyService.GetTodayHourlyElectricalData(), "成功"); + return Result>.Success(await _emeterHourEnergyService.GetTodayHourlyElectricalData(1), "成功"); } @@ -127,11 +141,11 @@ namespace WebStarter.Controllers.Ammeter /// /// [HttpGet("GetTodayHourlyEnergyChange")] - public async Task>> GetTodayHourlyElectricalChangeData() + public async Task>> GetTodayHourlyElectricalChangeData() { // 交流表数据 - return Result>.Success( - await _emeterEnergyChangeService.GetTodayHourlyElectricalData(), "成功"); + return Result>.Success( + await _emeterHourEnergyService.GetTodayHourlyElectricalData(2), "成功"); } /// @@ -142,13 +156,28 @@ namespace WebStarter.Controllers.Ammeter public async Task> GetTodayMinutelyElectricalData() { // 获取最近一个小时直流和交流表数据 - List minutesElectrical = await _emeterEnergyService.GetTodayMinutelyElectricalData(); - List minutesElectricalChange = - await _emeterEnergyChangeService.GetTodayMinutelyElectricalData(); + List minutesElectrical = await _emeterMinutesEnergyService.GetTodayMinutelyElectricalData(1); + List minutesElectricalChange = + await _emeterMinutesEnergyService.GetTodayMinutelyElectricalData(2); EmeterEnergyResp resp = new EmeterEnergyResp(); - ChargeAssignment(minutesElectrical, minutesElectricalChange, resp); + var config = new MapperConfiguration(cfg => + { + cfg.CreateMap().ReverseMap(); + }); + IMapper mapper = config.CreateMapper(); + + List EnergyList = mapper.Map>(minutesElectrical); + // 类型赋值直流 + EnergyList?.ForEach(emeterResp => emeterResp.Type = 0); + + List EnergyChangeList = mapper.Map>(minutesElectricalChange); + // 类型赋值交流 + EnergyChangeList?.ForEach(emeterResp => emeterResp.Type = 1); + + resp.emeterEnergy = EnergyList.OrderBy(i => i.Code).ToList(); + resp.emeterEnergyChange = EnergyChangeList.OrderBy(i => i.Code).ToList(); return Result.Success(resp, "成功"); @@ -170,30 +199,42 @@ namespace WebStarter.Controllers.Ammeter endTime = parsedEndTime.ToString("yyyy-MM-dd HH:mm:ss"); // 获取实时直流和交流表数据 - List minutesElectrical = await _emeterEnergyService.GetEnergyMeterRealTime(endTime); - List minutesElectricalChange = - await _emeterEnergyChangeService.GetEnergyMeterRealTime(endTime); - - EmeterEnergyResp resp = new EmeterEnergyResp(); - - ChargeAssignment(minutesElectrical, minutesElectricalChange, resp); + List minutesElectrical = await _emeterHourEnergyService.GetEnergyMeterRealTime(endTime, 1); + List minutesElectricalChange = await _emeterHourEnergyService.GetEnergyMeterRealTime(endTime, 2); + EmeterEnergyResp resp = new EmeterEnergyResp + { + emeterEnergy = TransformEnergyData(minutesElectrical, 0), + emeterEnergyChange = TransformEnergyData(minutesElectricalChange, 1) + }; return Result.Success(resp, "成功"); } - - - private static void ChargeAssignment(List emeterEnergy, - List emeterEnergyChanges, EmeterEnergyResp resp) + private List TransformEnergyData(List energyData, int type) + { + return energyData.Select(hourEnergy => + { + DateTime? uploadTime = DateTime.TryParse(hourEnergy.Time, out DateTime parsedTime) ? parsedTime : (DateTime?)null; + + return new EmeterResp + { + Code = hourEnergy.Code, + Value = hourEnergy.RealTimeValue, + UploadTime = uploadTime, + Type = type + }; + }).OrderBy(e => e.Code).ToList(); + } + + private static void ElectricEnergyDay(List daysElectrical, List emeterEnergyChanges, EmeterEnergyResp resp) { var config = new MapperConfiguration(cfg => { - cfg.CreateMap().ReverseMap(); - cfg.CreateMap().ReverseMap(); + cfg.CreateMap().ReverseMap(); }); IMapper mapper = config.CreateMapper(); - List EnergyList = mapper.Map>(emeterEnergy); + List EnergyList = mapper.Map>(daysElectrical); // 类型赋值直流 EnergyList?.ForEach(emeterResp => emeterResp.Type = 0);