From 61c0f909791499ed89efa6e9fa99e9b71e3bfce1 Mon Sep 17 00:00:00 2001 From: dev02 Date: Fri, 12 May 2023 18:42:22 +0800 Subject: [PATCH] =?UTF-8?q?[=E5=BE=8C=E7=AB=AF]=20=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E6=B0=B4=E9=9B=BB=E8=A1=A8sql=E8=AA=9E=E6=B3=95,=20=E6=96=B0?= =?UTF-8?q?=E5=A2=9E=E6=B0=B4=E9=9B=BB=E8=A1=A8=E8=B2=BB=E7=94=A8api,=20?= =?UTF-8?q?=E6=96=B0=E5=A2=9E=E6=9C=83=E5=87=BAexcel=E6=B0=B4=E9=9B=BB?= =?UTF-8?q?=E8=A1=A8,=20=E4=BF=AE=E6=94=B9hinet=E8=B3=AC=E5=AF=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ApiControllers/HiNetController.cs | 18 +- .../ApiControllers/HydroMeterController.cs | 290 ++++++++++++++++-- FrontendWebApi/Models/HydroMeter.cs | 5 + 3 files changed, 284 insertions(+), 29 deletions(-) diff --git a/FrontendWebApi/ApiControllers/HiNetController.cs b/FrontendWebApi/ApiControllers/HiNetController.cs index 92ceeb4..30b901a 100644 --- a/FrontendWebApi/ApiControllers/HiNetController.cs +++ b/FrontendWebApi/ApiControllers/HiNetController.cs @@ -765,25 +765,23 @@ namespace FrontendWebApi.ApiControllers public ActionResult> HiNetMsg(HiNetInput input) { ApiResult apiResult = new ApiResult(jwt_str); - if (!jwtlife) - { - apiResult.Code = "5000"; - return BadRequest(apiResult); - } + //if (!jwtlife) + //{ + // apiResult.Code = "5000"; + // return BadRequest(apiResult); + //} try { var hiair = new HiNetController(); - int retCode = this.StartCon("202.39.54.130", 8000, "test", "test123"); + int retCode = hiair.StartCon("202.39.54.130", 8000, "airtest6", "95929ALz"); string retContent = string.Empty; if (retCode == 0) { //發送文字簡訊並回傳狀態碼 - retCode = this.SendMsg(input.Number, input.Msg); - //retCode = hiair.SendMsg(input.Number, input.Msg); + retCode = hiair.SendMsg(input.Number, input.Msg); //取得messageID或文字描述 - retContent = this.Get_Message(); - //retContent = hiair.Get_Message(); + retContent = hiair.Get_Message(); apiResult.Data = retCode + " : " + retContent; } else diff --git a/FrontendWebApi/ApiControllers/HydroMeterController.cs b/FrontendWebApi/ApiControllers/HydroMeterController.cs index d818568..7369e71 100644 --- a/FrontendWebApi/ApiControllers/HydroMeterController.cs +++ b/FrontendWebApi/ApiControllers/HydroMeterController.cs @@ -1,6 +1,8 @@ using FrontendWebApi.Models; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Logging; +using NPOI.SS.UserModel; +using NPOI.XSSF.UserModel; using Repository.BackendRepository.Interface; using Repository.FrontendRepository.Interface; using System; @@ -28,8 +30,8 @@ namespace FrontendWebApi.ApiControllers /// /// [HttpPost] - [Route("api/MeterList")] - public async Task>>> MeterList([FromBody] HydroMeterInput input) + [Route("api/ElectricList")] + public async Task>>> ElectricList([FromBody] HydroMeterInput input) { ApiResult> apiResult = new ApiResult>(jwt_str); if (!jwtlife) @@ -37,6 +39,7 @@ namespace FrontendWebApi.ApiControllers apiResult.Code = "5000"; return BadRequest(apiResult); } + string tableType = "day week month year"; if (input.building_tag == null) { @@ -63,15 +66,47 @@ namespace FrontendWebApi.ApiControllers : input.tableType == "year" ? input.endTime + "-01-01" : null; string sqlWhere = ""; + string sqlGroup = ""; + string sqlAvgRawData = ""; if (input.floor_tag.Count > 0) - sqlWhere = $@" and substring_index(substring_index(device_number, '_', 3), '_', -1) in @floor_tag"; + sqlWhere = $@" and substring_index(substring_index(device_number, '_', 3), '_', -1) in @floor_tag "; + + if (input.tableType == "year") + { + sqlGroup = $@" group by DATE_FORMAT(start_timestamp, @dateFormat), DATE_FORMAT(end_timestamp, @dateFormat), device_number "; + sqlAvgRawData = " round(avg(avg_rawdata), 2) as avg_rawdata"; + } + else + sqlAvgRawData = " round(avg_rawdata, 2) as avg_rawdata"; + var table = input.tableType == "year" ? "archive_electric_meter_day" : "archive_electric_meter_" + input.tableType; var dateFormat = input.tableType == "day" || input.tableType == "week" ? "%Y-%m-%d" : input.tableType == "month" ? "%Y-%m" : input.tableType == "year" ? "%Y" : null; - var sql = $@"select device_number, avg_rawdata, DATE_FORMAT(start_timestamp, @dateFormat) as timeStamp - from {table} - where start_timestamp >= @startTime and end_timestamp < @endTime and point = 'KWH' and substring_index(device_number, '_', 1) = @building_tag - {sqlWhere} - order by created_at desc;"; + var sql = $@"set @i = -1; + select fd.device_number, aemm.avg_rawdata, DATE_FORMAT(fd.date, @dateFormat) as timestamp + from ( + select * + from ( + ( + SELECT DATE(ADDDATE(@startTime, INTERVAL @i:=@i+1 {input.tableType})) AS date + FROM {table} + HAVING @i < TIMESTAMPDIFF({input.tableType}, @startTime, ADDDATE(@endTime, INTERVAL -1 DAY)) + ) d, + ( + select device_number + from {table} + where start_timestamp >= @startTime and end_timestamp < @endTime and point = 'KWH' and SUBSTRING_INDEX(device_number, '_', 1) = @building_tag + {sqlWhere} + group by device_number + ) dn + ) + ) fd + left join ( + select device_number, {sqlAvgRawData}, start_timestamp, end_timestamp + from {table} + where start_timestamp >= @startTime and end_timestamp < @endTime and point = 'KWH' and SUBSTRING_INDEX(device_number, '_', 1) = @building_tag + {sqlWhere} {sqlGroup} + ) aemm on aemm.start_timestamp >= fd.date and aemm.end_timestamp < DATE_ADD(fd.date, INTERVAL +1 {input.tableType}) and aemm.device_number = fd.device_number + order by fd.device_number, fd.date"; var rawData = await backendRepository.GetAllAsync(sql, new { startTime = startTime, endtime = endTime, building_tag = input.building_tag, floor_tag = input.floor_tag, dateFormat = dateFormat }); var list = rawData @@ -87,11 +122,11 @@ namespace FrontendWebApi.ApiControllers ); l.building_name = await backendRepository.GetOneAsync("select full_name from building where building_tag = @building_tag and deleted = 0", new { building_tag = l.building_tag }); - l.total = l.rawData.Count.ToString(); + l.total = l.rawData.Sum(x => x.avg_rawdata).ToString(); l.price = input.price.HasValue ? (Math.Round(input.price.Value, 2)).ToString() - : Math.Round((await backendRepository.GetOneAsync("select system_value from variable where system_type = 'MeterPrice' and deleted = 0")), 2).ToString(); - l.total_price = (l.rawData.Count * Decimal.Parse(l.price)).ToString(); + : Math.Round((await backendRepository.GetOneAsync("select system_value from variable where system_type = 'ElectricPrice' and deleted = 0")), 2).ToString(); + l.total_price = Math.Round((Decimal.Parse(l.total) * Decimal.Parse(l.price)), 2).ToString(); } apiResult.Code = "0000"; @@ -150,15 +185,48 @@ namespace FrontendWebApi.ApiControllers : input.tableType == "year" ? input.endTime + "-01-01" : null; string sqlWhere = ""; + string sqlGroup = ""; + string sqlAvgRawData = ""; if (input.floor_tag.Count > 0) - sqlWhere = $@" and substring_index(substring_index(device_number, '_', 3), '_', -1) in @floor_tag"; + sqlWhere = $@" and substring_index(substring_index(device_number, '_', 3), '_', -1) in @floor_tag "; + + if (input.tableType == "year") + { + sqlGroup = $@" group by DATE_FORMAT(start_timestamp, @dateFormat), DATE_FORMAT(end_timestamp, @dateFormat), device_number "; + sqlAvgRawData = " round(avg(avg_rawdata), 2) as avg_rawdata"; + } + else + sqlAvgRawData = " round(avg_rawdata, 2) as avg_rawdata"; + var table = input.tableType == "year" ? "archive_water_meter_day" : "archive_water_meter_" + input.tableType; var dateFormat = input.tableType == "day" || input.tableType == "week" ? "%Y-%m-%d" : input.tableType == "month" ? "%Y-%m" : input.tableType == "year" ? "%Y" : null; - var sql = $@"select device_number, avg_rawdata, DATE_FORMAT(start_timestamp, @dateFormat) as timeStamp - from @table - where start_timestamp >= @startTime and end_timestamp < @endTime and point = 'RCV' and substring_index(device_number, '_', 1) = @building_tag - {sqlWhere} - order by created_at desc;"; + var sql = $@"set @i = -1; + select fd.device_number, aemm.avg_rawdata, DATE_FORMAT(fd.date, @dateFormat) as timestamp + from ( + select * + from ( + ( + SELECT DATE(ADDDATE(@startTime, INTERVAL @i:=@i+1 {input.tableType})) AS date + FROM {table} + HAVING @i < TIMESTAMPDIFF({input.tableType}, @startTime, ADDDATE(@endTime, INTERVAL -1 DAY)) + ) d, + ( + select device_number + from {table} + where start_timestamp >= @startTime and end_timestamp < @endTime and point = 'RCV' and SUBSTRING_INDEX(device_number, '_', 1) = @building_tag + {sqlWhere} + group by device_number + ) dn + ) + ) fd + left join ( + select device_number, {sqlAvgRawData}, start_timestamp, end_timestamp + from {table} + where start_timestamp >= @startTime and end_timestamp < @endTime and point = 'RCV' and SUBSTRING_INDEX(device_number, '_', 1) = @building_tag + {sqlWhere} {sqlGroup} + ) aemm on aemm.start_timestamp >= fd.date and aemm.end_timestamp < DATE_ADD(fd.date, INTERVAL +1 {input.tableType}) and aemm.device_number = fd.device_number + order by fd.device_number, fd.date"; + var rawData = await backendRepository.GetAllAsync(sql, new { startTime = startTime, endTime = endTime, building_tag = input.building_tag, floor_tag = input.floor_tag, dateFormat = dateFormat }); var list = rawData @@ -174,11 +242,11 @@ namespace FrontendWebApi.ApiControllers ); l.building_name = await backendRepository.GetOneAsync("select full_name from building where building_tag = @building_tag and deleted = 0", new { building_tag = l.building_tag }); - l.total = l.rawData.Count.ToString(); + l.total = l.rawData.Sum(x => x.avg_rawdata).ToString(); l.price = input.price.HasValue ? (Math.Round(input.price.Value, 2)).ToString() : Math.Round((await backendRepository.GetOneAsync("select system_value from variable where system_type = 'WaterPrice' and deleted = 0")), 2).ToString(); - l.total_price = (l.rawData.Count * Int32.Parse(l.price)).ToString(); + l.total_price = Math.Round((Decimal.Parse(l.total) * Decimal.Parse(l.price)), 2).ToString(); } apiResult.Code = "0000"; @@ -194,5 +262,189 @@ namespace FrontendWebApi.ApiControllers } return apiResult; } + + /// + /// 水電表費用 + /// + /// + /// + [HttpPost] + [Route("api/HydroMeterPrice")] + public async Task>> Price([FromBody] HydroMeterPriceInput input) + { + ApiResult apiResult = new ApiResult(jwt_str); + if (!jwtlife) + { + apiResult.Code = "5000"; + return BadRequest(apiResult); + } + + try + { + apiResult.Code = "0000"; + apiResult.Data = await backendRepository.GetOneAsync($@"select system_value from variable where system_type = {input.type}Price and deleted = 0"); + } + catch (Exception exception) + { + apiResult.Code = "9999"; + apiResult.Msg = "系統內部錯誤,請聯絡管理者。"; + string json = System.Text.Json.JsonSerializer.Serialize(input); + Logger.LogError("【" + controllerName + "/" + actionName + "】" + json); + Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message); + } + return apiResult; + } + + [HttpPost] + [Route("api/ExportElectricList")] + public FileResult OpeExportExcel([FromBody] HydroMeterInput input) + { + var result = this.ElectricList(input).Result.Value.Data.ToList(); + + var workbook = new XSSFWorkbook(); + #region excel設定 + IFont font12 = workbook.CreateFont(); + font12.FontName = "新細明體"; + font12.FontHeightInPoints = 12; + ICellStyle style12 = workbook.CreateCellStyle(); + style12.SetFont(font12); + style12.Alignment = HorizontalAlignment.Center; + style12.VerticalAlignment = VerticalAlignment.Center; + IFont font12Times = workbook.CreateFont(); + font12Times.FontName = "Times New Roman"; + font12Times.FontHeightInPoints = 12; + IFont font18 = workbook.CreateFont(); + font18.FontName = "新細明體"; + font18.FontHeightInPoints = 18; + font18.IsBold = true; + ICellStyle styleTitle18 = workbook.CreateCellStyle(); + styleTitle18.SetFont(font18); + styleTitle18.Alignment = HorizontalAlignment.Center; + styleTitle18.VerticalAlignment = VerticalAlignment.Center; + ICellStyle styleLeft12 = workbook.CreateCellStyle(); + styleLeft12.SetFont(font12); + styleLeft12.Alignment = HorizontalAlignment.Left; + styleLeft12.VerticalAlignment = VerticalAlignment.Center; + ICellStyle styleLine12 = workbook.CreateCellStyle(); + styleLine12.SetFont(font12); + styleLine12.Alignment = NPOI.SS.UserModel.HorizontalAlignment.Center; + styleLine12.VerticalAlignment = VerticalAlignment.Center; + styleLine12.BorderTop = NPOI.SS.UserModel.BorderStyle.Thin; + styleLine12.BorderBottom = NPOI.SS.UserModel.BorderStyle.Thin; + styleLine12.BorderRight = NPOI.SS.UserModel.BorderStyle.Thin; + styleLine12.BorderLeft = NPOI.SS.UserModel.BorderStyle.Thin; + ICellStyle stylein12 = workbook.CreateCellStyle(); + stylein12.SetFont(font12Times); + stylein12.Alignment = NPOI.SS.UserModel.HorizontalAlignment.Left; + stylein12.VerticalAlignment = VerticalAlignment.Center; + stylein12.BorderTop = NPOI.SS.UserModel.BorderStyle.Thin; + stylein12.BorderBottom = NPOI.SS.UserModel.BorderStyle.Thin; + stylein12.BorderRight = NPOI.SS.UserModel.BorderStyle.Thin; + stylein12.BorderLeft = NPOI.SS.UserModel.BorderStyle.Thin; + stylein12.WrapText = true; + #endregion + + var sheet = workbook.CreateSheet("電表報表"); + int RowPosition = 0; + if (result.Count > 0) + { + #region set cell + IRow row = sheet.CreateRow(RowPosition); + sheet.SetColumnWidth(0, 4 * 160 * 12); + sheet.SetColumnWidth(1, 4 * 160 * 12); + sheet.SetColumnWidth(2, 4 * 160 * 12); + + int i = 0; + ICell cell = row.CreateCell(i++); + cell.SetCellValue("東別"); + cell.CellStyle = styleLine12; + cell = row.CreateCell(i++); + cell.SetCellValue("樓層"); + cell.CellStyle = styleLine12; + cell = row.CreateCell(i++); + cell.SetCellValue("設備"); + cell.CellStyle = styleLine12; + + foreach (var r in result) + { + foreach (var rr in r.rawData) + { + cell = row.CreateCell(i++); + cell.SetCellValue(rr.timeStamp); + cell.CellStyle = styleLine12; + } + } + + cell = row.CreateCell(i++); + cell.SetCellValue("小計"); + cell.CellStyle = styleLine12; + cell = row.CreateCell(i++); + cell.SetCellValue("單價"); + cell.CellStyle = styleLine12; + cell = row.CreateCell(i++); + cell.SetCellValue("金額總計"); + cell.CellStyle = styleLine12; + #endregion + + foreach (var r in result) + { + RowPosition += 1; + row = sheet.CreateRow(RowPosition); + for (int j = 0; j <= i; j++) + { + cell = row.CreateCell(j); + if (j == 0) + { + cell.SetCellValue(r.building_name); + } + if (j == 1) + { + cell.SetCellValue(r.floor_tag); + } + if (j == 2) + { + cell.SetCellValue(r.device_serial_tag); + } + + int k = 3; + if (j == 3) + { + foreach (var rr in r.rawData) + { + if (j++ == k++) + { + cell.SetCellValue(rr.avg_rawdata.ToString()); + } + } + } + + if (j == k++) + { + cell.SetCellValue(r.total); + } + if (j == k++) + { + cell.SetCellValue(r.price); + } + if (j == k++) + { + cell.SetCellValue(r.total_price); + } + + cell.CellStyle = style12; + } + } + } + + var ms = new NpoiMemoryStream + { + AllowClose = false + }; + workbook.Write(ms); + ms.Flush(); + ms.Seek(0, SeekOrigin.Begin); + + return File(ms, "application/vnd.ms-excel", "電表報表.xlsx"); + } } } diff --git a/FrontendWebApi/Models/HydroMeter.cs b/FrontendWebApi/Models/HydroMeter.cs index 564e311..774d0c9 100644 --- a/FrontendWebApi/Models/HydroMeter.cs +++ b/FrontendWebApi/Models/HydroMeter.cs @@ -36,4 +36,9 @@ namespace FrontendWebApi.Models public string device_number { get; set; } public decimal avg_rawdata { get; set; } } + + public class HydroMeterPriceInput + { + public string type { get; set; } + } }