From 0be30a75706198fdcc77060bccbe449aef533bdc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=BD=98=E5=BB=BA=E4=B8=9C?= <617601767@qq.com> Date: Wed, 3 Jan 2024 22:02:01 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=A4=9A=E7=BA=BF=E7=A8=8B?= =?UTF-8?q?=E8=BF=9B=E8=A1=8C=E4=BD=9C=E4=B8=9A=EF=BC=8C=E5=B9=B6=E4=B8=94?= =?UTF-8?q?=E5=88=86=E5=9D=97=E6=97=A5=E6=9C=9F=E8=8C=83=E5=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Controllers/DeviceController.cs | 14 + LanSheng/LanShengInterface/IDeviceService.cs | 2 + LanSheng/LanShengModel/DeviceError.cs | 17 +- LanSheng/LanShengModel/DeviceErrorReport.cs | 21 +- LanSheng/LanShengService/DeviceService.cs | 313 +++++++++++------- .../LanShengService/LanShengService.csproj | 1 + ZhongLian/ZhongLianModel/DeviceDO.cs | 31 ++ 7 files changed, 272 insertions(+), 127 deletions(-) diff --git a/LanSheng/LanShengAPI/Controllers/DeviceController.cs b/LanSheng/LanShengAPI/Controllers/DeviceController.cs index d21e5e1..3c1f7b4 100644 --- a/LanSheng/LanShengAPI/Controllers/DeviceController.cs +++ b/LanSheng/LanShengAPI/Controllers/DeviceController.cs @@ -100,5 +100,19 @@ namespace LanShengAPI.Controllers return BadRequest(ex.Message); } } + + [HttpGet("DeviceErrorList")] + + public async Task DeviceErrorList() + { + try + { + return Ok(await DeviceService.GetErrorList()); + } + catch (BadRequestException ex) + { + return BadRequest(ex.Message); + } + } } } diff --git a/LanSheng/LanShengInterface/IDeviceService.cs b/LanSheng/LanShengInterface/IDeviceService.cs index 33e7a2a..3cd8a4f 100644 --- a/LanSheng/LanShengInterface/IDeviceService.cs +++ b/LanSheng/LanShengInterface/IDeviceService.cs @@ -38,5 +38,7 @@ namespace LanShengInterface /// 报表筛选 /// Task GetDeviceErrorReport(DeviceErrorReport report); + + Task> GetErrorList(); } } diff --git a/LanSheng/LanShengModel/DeviceError.cs b/LanSheng/LanShengModel/DeviceError.cs index e9a7ad7..6e81db0 100644 --- a/LanSheng/LanShengModel/DeviceError.cs +++ b/LanSheng/LanShengModel/DeviceError.cs @@ -8,37 +8,37 @@ using System.Threading.Tasks; namespace LanShengModel { [SugarTable("LS_DeviceError_{year}{month}{day}")] - [SplitTable(SplitType.Year)] + [SplitTable(SplitType.Week)] public class DeviceError { /// /// 编号 /// - [SugarColumn(IsPrimaryKey = true,Length = 50,ColumnDescription = "编号")] + [SugarColumn(IsPrimaryKey = true, Length = 50, ColumnDescription = "编号")] public string? Id { get; set; } /// /// 设备编号 /// - [SugarColumn(IsPrimaryKey = true,Length = 50,ColumnDescription = "设备编号")] + [SugarColumn(IsPrimaryKey = true, Length = 50, ColumnDescription = "设备编号")] public string? DeviceId { get; set; } /// /// 错误代码 /// - [SugarColumn(IsNullable = true,ColumnDescription = "错误代码",Length = 20)] + [SugarColumn(IsNullable = true, ColumnDescription = "错误代码", Length = 20)] public string? ErrCode { get; set; } /// /// 错误信息 /// - [SugarColumn(IsNullable = true,ColumnDescription = "错误信息",Length = 200)] + [SugarColumn(IsNullable = true, ColumnDescription = "错误信息", Length = 200)] public string? ErrMsg { get; set; } /// /// 结束日期 /// - [SugarColumn(IsNullable = true,ColumnDescription = "结束日期")] + [SugarColumn(IsNullable = true, ColumnDescription = "结束日期")] public DateTime? EndDate { get; set; } [SplitField] @@ -46,6 +46,9 @@ namespace LanShengModel public DateTime? CreateDate { get; set; } [SugarColumn(IsIgnore = true)] - public int? Count{get;set;} + public string? CountDate { get; set; } + + [SugarColumn(IsIgnore = true)] + public int? Count { get; set; } } } diff --git a/LanSheng/LanShengModel/DeviceErrorReport.cs b/LanSheng/LanShengModel/DeviceErrorReport.cs index 7c3ff59..42b55b0 100644 --- a/LanSheng/LanShengModel/DeviceErrorReport.cs +++ b/LanSheng/LanShengModel/DeviceErrorReport.cs @@ -25,6 +25,9 @@ public class DeviceErrorReport /// public IEnumerable? DeviceIds { get; set; } + + public IEnumerable? GpsIds { get; set; } + /// /// 开始日期 /// @@ -43,5 +46,21 @@ public class DeviceErrorReport /// /// 数据集 /// - public IEnumerable? Items { get; set; } + public IEnumerable? Items { get; set; } +} + +public class DeviceErrorReportItem { + public DeviceErrorReportItem() { + Code = ""; + Msg = ""; + Counts = new Dictionary(); + } + + public string Code { get; set; } + + public string Msg { get; set; } + + public Dictionary Counts { get; set; } + + public int Count { get; set; } } \ No newline at end of file diff --git a/LanSheng/LanShengService/DeviceService.cs b/LanSheng/LanShengService/DeviceService.cs index 7d52d05..65e5dc1 100644 --- a/LanSheng/LanShengService/DeviceService.cs +++ b/LanSheng/LanShengService/DeviceService.cs @@ -6,6 +6,7 @@ using Microsoft.Data.SqlClient; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using NewLife.Reflection; +using Newtonsoft.Json.Linq; using SqlSugar; using System; using System.Collections.Generic; @@ -13,7 +14,9 @@ using System.Data; using System.Linq; using System.Text; using System.Text.Json; +using System.Text.Json.Serialization; using System.Threading.Tasks; +using ZhongLianModel; namespace LanShengService { @@ -906,124 +909,124 @@ namespace LanShengService switch (deviceData.Data17) { case 2: - deviceData.ErrCode = "门机故障"; - deviceData.ErrMsg = "加速过电流"; + deviceData.ErrCode = "MJ0002"; + deviceData.ErrMsg = "门机故障-加速过电流"; break; case 3: - deviceData.ErrCode = "门机故障"; - deviceData.ErrMsg = "减速过电流"; + deviceData.ErrCode = "MJ0003"; + deviceData.ErrMsg = "门机故障-减速过电流"; break; case 4: - deviceData.ErrCode = "门机故障"; - deviceData.ErrMsg = "恒速过电流"; + deviceData.ErrCode = "MJ0004"; + deviceData.ErrMsg = "门机故障-恒速过电流"; break; case 5: - deviceData.ErrCode = "门机故障"; - deviceData.ErrMsg = "加速过电压"; + deviceData.ErrCode = "MJ0005"; + deviceData.ErrMsg = "门机故障-加速过电压"; break; case 6: - deviceData.ErrCode = "门机故障"; - deviceData.ErrMsg = "减速过电压"; + deviceData.ErrCode = "MJ0006"; + deviceData.ErrMsg = "门机故障-减速过电压"; break; case 7: - deviceData.ErrCode = "门机故障"; - deviceData.ErrMsg = "恒速过电压"; + deviceData.ErrCode = "MJ0007"; + deviceData.ErrMsg = "门机故障-恒速过电压"; break; case 8: - deviceData.ErrCode = "门机故障"; - deviceData.ErrMsg = "控制电源异常"; + deviceData.ErrCode = "MJ0008"; + deviceData.ErrMsg = "门机故障-控制电源异常"; break; case 9: - deviceData.ErrCode = "门机故障"; - deviceData.ErrMsg = "欠电压"; + deviceData.ErrCode = "MJ0009"; + deviceData.ErrMsg = "门机故障-欠电压"; break; case 10: - deviceData.ErrCode = "门机故障"; - deviceData.ErrMsg = "变频器过载"; + deviceData.ErrCode = "MJ0010"; + deviceData.ErrMsg = "门机故障-变频器过载"; break; case 11: - deviceData.ErrCode = "门机故障"; - deviceData.ErrMsg = "电机过载"; + deviceData.ErrCode = "MJ0011"; + deviceData.ErrMsg = "门机故障-电机过载"; break; case 12: - deviceData.ErrCode = "门机故障"; - deviceData.ErrMsg = "输入缺相"; + deviceData.ErrCode = "MJ0012"; + deviceData.ErrMsg = "门机故障-输入缺相"; break; case 13: - deviceData.ErrCode = "门机故障"; - deviceData.ErrMsg = "输出缺相"; + deviceData.ErrCode = "MJ0013"; + deviceData.ErrMsg = "门机故障-输出缺相"; break; case 14: - deviceData.ErrCode = "门机故障"; - deviceData.ErrMsg = "模块过热"; + deviceData.ErrCode = "MJ0014"; + deviceData.ErrMsg = "门机故障-模块过热"; break; case 15: - deviceData.ErrCode = "门机故障"; - deviceData.ErrMsg = "外部故障"; + deviceData.ErrCode = "MJ0015"; + deviceData.ErrMsg = "门机故障-外部故障"; break; case 16: - deviceData.ErrCode = "门机故障"; - deviceData.ErrMsg = "通讯异常"; + deviceData.ErrCode = "MJ0016"; + deviceData.ErrMsg = "门机故障-通讯异常"; break; case 17: - deviceData.ErrCode = "门机故障"; - deviceData.ErrMsg = "接触器异常"; + deviceData.ErrCode = "MJ0017"; + deviceData.ErrMsg = "门机故障-接触器异常"; break; case 18: - deviceData.ErrCode = "门机故障"; - deviceData.ErrMsg = "电流检测异常"; + deviceData.ErrCode = "MJ0018"; + deviceData.ErrMsg = "门机故障-电流检测异常"; break; case 19: - deviceData.ErrCode = "门机故障"; - deviceData.ErrMsg = "电机调谐异常"; + deviceData.ErrCode = "MJ0019"; + deviceData.ErrMsg = "门机故障-电机调谐异常"; break; case 20: - deviceData.ErrCode = "门机故障"; - deviceData.ErrMsg = "编码器/PG卡异常"; + deviceData.ErrCode = "MJ0020"; + deviceData.ErrMsg = "门机故障-编码器/PG卡异常"; break; case 21: - deviceData.ErrCode = "门机故障"; - deviceData.ErrMsg = "EPPROM读写异常"; + deviceData.ErrCode = "MJ0021"; + deviceData.ErrMsg = "门机故障-EPPROM读写异常"; break; case 22: - deviceData.ErrCode = "门机故障"; - deviceData.ErrMsg = "变频器硬件故障"; + deviceData.ErrCode = "MJ0022"; + deviceData.ErrMsg = "门机故障-变频器硬件故障"; break; case 23: - deviceData.ErrCode = "门机故障"; - deviceData.ErrMsg = "电机对地短路"; + deviceData.ErrCode = "MJ0023"; + deviceData.ErrMsg = "门机故障-电机对地短路"; break; case 26: - deviceData.ErrCode = "门机故障"; - deviceData.ErrMsg = "累计运行时间到达"; + deviceData.ErrCode = "MJ0026"; + deviceData.ErrMsg = "门机故障-累计运行时间到达"; break; case 29: - deviceData.ErrCode = "门机故障"; - deviceData.ErrMsg = "累计上电时间到达"; + deviceData.ErrCode = "MJ0029"; + deviceData.ErrMsg = "门机故障-累计上电时间到达"; break; case 30: - deviceData.ErrCode = "门机故障"; - deviceData.ErrMsg = "掉载"; + deviceData.ErrCode = "MJ0030"; + deviceData.ErrMsg = "门机故障-掉载"; break; case 31: - deviceData.ErrCode = "门机故障"; - deviceData.ErrMsg = "运行时PID反馈丢失"; + deviceData.ErrCode = "MJ0031"; + deviceData.ErrMsg = "门机故障-运行时PID反馈丢失"; break; case 40: - deviceData.ErrCode = "门机故障"; - deviceData.ErrMsg = "CBC限流保护"; + deviceData.ErrCode = "MJ0040"; + deviceData.ErrMsg = "门机故障-CBC限流保护"; break; case 42: - deviceData.ErrCode = "门机故障"; - deviceData.ErrMsg = "速度偏差过大"; + deviceData.ErrCode = "MJ0040"; + deviceData.ErrMsg = "门机故障-速度偏差过大"; break; case 43: - deviceData.ErrCode = "门机故障"; - deviceData.ErrMsg = "过速度"; + deviceData.ErrCode = "MJ0043"; + deviceData.ErrMsg = "门机故障-过速度"; break; case 45: - deviceData.ErrCode = "门机故障"; - deviceData.ErrMsg = "电机过热"; + deviceData.ErrCode = "MJ0045"; + deviceData.ErrMsg = "门机故障-电机过热"; break; default: break; @@ -1283,81 +1286,153 @@ namespace LanShengService throw new BadRequestException("单元无效"); } #endregion - var TempQuery = Db.Queryable() - .WhereIF(report.ErrCodes != null, x => report.ErrCodes!.Any(q => q == x.ErrCode)) - .WhereIF(report.DeviceIds != null, x => report.DeviceIds!.Any(q => q == x.DeviceId)) - .Where(x => x.CreateDate >= report.StartDate && x.CreateDate <= report.EndDate); - DateTime TempStart = (DateTime)report.StartDate!; - DateTime TempEnd = (DateTime)report.EndDate!; + if ((report.CompanyIds != null && report.CompanyIds.Count() > 0) || (report.ProjectIds != null && report.ProjectIds.Count() > 0) || (report.DeviceIds != null && report.DeviceIds.Count() > 0)) { + var TempCompanyIds = report.CompanyIds; + var TempProjectIds = report.ProjectIds; + var TempDeviceIds = report.DeviceIds; + var TempGpss = Db.Queryable() + .LeftJoin((x, y) => x.ProjectId == y.Id) + .WhereIF(TempCompanyIds != null, (x, y) => TempCompanyIds!.Contains(y.CompanyId)) + .WhereIF(TempProjectIds != null, (x, y) => TempProjectIds!.Contains(x.ProjectId)) + .WhereIF(TempDeviceIds != null, (x, y) => TempDeviceIds!.Contains(x.Id)) + .Where((x, y) => x.Deleted == 0) + .Select((x,y)=> x.Gps!.ToString()) + .ToList(); + var TempGpsIds = new List(); + TempGpss.ForEach(v => { + try + { + var tempGps = JsonSerializer.Deserialize>(v!); + TempGpsIds.AddRange(tempGps!.Select(x => x.Id!)); + } + catch { + + } + }); + report.GpsIds = TempGpsIds!; + } + var TempErrors = await GetDayError(report); + var TempErrorGroup = TempErrors.Select(x => x.ErrCode).Distinct(); + var TempItems = new List(); if (string.IsNullOrEmpty(report.Unit)) { - report.Items = await TempQuery - .GroupBy(x => new { x.ErrCode, x.ErrMsg }) - .Select(x => new DeviceError + foreach (var group in TempErrorGroup) { - ErrCode = x.ErrCode, - ErrMsg = x.ErrMsg, - Count = SqlFunc.AggregateCount(x.ErrCode) - }) - .SplitTable(TempStart, TempEnd) - .ToListAsync(); + TempItems.Add(new DeviceErrorReportItem + { + Code = group!, + Msg = TempErrors.First(x => x.ErrCode == group).ErrMsg!, + Count = TempErrors.Where(x => x.ErrCode == group).Select(x => x.Count).Sum().ToInt() + }); + } } else if (report.Unit.ToLower() == "year") { - var TempYears = TempEnd.Year - TempStart.Year + 1; - var TempYearArray = Enumerable.Range(0, TempYears).Select(x => Convert.ToDateTime(TempStart.AddYears(x).ToString("yyyy-MM-dd"))).ToList(); - var TempQueryYear = Db.Reportable(TempYearArray).ToQueryable(); - report.Items = TempQueryYear - .LeftJoin(TempQuery.SplitTable(TempStart, TempEnd), (x, y) => x.ColumnName.ToString("yyyy") == ((DateTime)y.CreateDate!).ToString("yyyy")) - .GroupBy((x, y) => new { x.ColumnName, y.ErrCode, y.ErrMsg }) - .Select((x, y) => new DeviceError + var TempErrorDate = TempErrors.Select(x => x.Id!.Substring(0, 4)).Distinct(); + foreach (var group in TempErrorGroup) { - ErrCode = y.ErrCode, - ErrMsg = y.ErrMsg, - Count = SqlFunc.AggregateCount(y.ErrCode), - Id = x.ColumnName.ToString("yyyy"), - CreateDate = x.ColumnName - }) - .ToList().OrderBy(x => x.Id); + var item = new DeviceErrorReportItem + { + Code = group!, + Msg = TempErrors.First(x => x.ErrCode == group).ErrMsg!, + Count = TempErrors.Where(x => x.ErrCode == group).Select(x => x.Count).Sum().ToInt() + }; + + foreach (var date in TempErrorDate) + { + item.Counts.Add(date, TempErrors.Where(x => x.ErrCode == group && x.Id!.IndexOf(date) == 0).Select(x => x.Count).Sum().ToInt()); + } + TempItems.Add(item); + } } - else if (report.Unit.ToLower() == "month") - { - var TempMonths = (TempEnd.Year - TempStart.Year) * 12 + (TempEnd.Month - TempStart.Month + 1); - var TempMonthArray = Enumerable.Range(0, TempMonths).Select(x => Convert.ToDateTime(TempStart.AddMonths(x).ToString("yyyy-MM-dd"))).ToList(); - var TempQueryMonth = Db.Reportable(TempMonthArray).ToQueryable(); - report.Items = TempQueryMonth - .LeftJoin(TempQuery.SplitTable(TempStart, TempEnd), (x, y) => x.ColumnName.ToString("yyyy-MM") == ((DateTime)y.CreateDate!).ToString("yyyy-MM")) - .GroupBy((x, y) => new { x.ColumnName, y.ErrCode, y.ErrMsg }) - .Select((x, y) => new DeviceError + else if (report.Unit.ToLower() == "month") { + var TempErrorDate = TempErrors.Select(x => x.Id!.Substring(0, 7)).Distinct(); + foreach (var group in TempErrorGroup) { - ErrCode = y.ErrCode, - ErrMsg = y.ErrMsg, - Count = SqlFunc.AggregateCount(y.ErrCode), - Id = x.ColumnName.ToString("yyyy-MM"), - CreateDate = x.ColumnName - }) - .ToList().OrderBy(x => x.Id); + var item = new DeviceErrorReportItem + { + Code = group!, + Msg = TempErrors.First(x => x.ErrCode == group).ErrMsg!, + Count = TempErrors.Where(x => x.ErrCode == group).Select(x => x.Count).Sum().ToInt() + }; + + foreach (var date in TempErrorDate) + { + item.Counts.Add(date, TempErrors.Where(x => x.ErrCode == group && x.Id!.IndexOf(date) == 0).Select(x => x.Count).Sum().ToInt()); + } + TempItems.Add(item); + } } else if (report.Unit.ToLower() == "day") { - var TempDays = (TempEnd - TempStart).TotalDays.ToInt(); - var TempDayArray = Enumerable.Range(0, TempDays).Select(x => Convert.ToDateTime(TempStart.AddDays(x).ToString("yyyy-MM-dd"))).ToList(); - var TempQueryDay = Db.Reportable(TempDayArray).ToQueryable(); - report.Items = TempQueryDay - .LeftJoin(TempQuery.SplitTable(TempStart, TempEnd), (x, y) => x.ColumnName.ToString("yyyy-MM-dd") == ((DateTime)y.CreateDate!).ToString("yyyy-MM-dd")) - .GroupBy((x, y) => new { x.ColumnName, y.ErrCode, y.ErrMsg }) - .Select((x, y) => new DeviceError + var TempErrorDate = TempErrors.Select(x => x.Id).Distinct(); + foreach (var group in TempErrorGroup) { - ErrCode = y.ErrCode, - ErrMsg = y.ErrMsg, - Count = SqlFunc.AggregateCount(y.ErrCode), - Id = x.ColumnName.ToString("yyyy-MM-dd"), - CreateDate = x.ColumnName - }) - .ToList().OrderBy(x => x.Id); + var item = new DeviceErrorReportItem + { + Code = group!, + Msg = TempErrors.First(x => x.ErrCode == group).ErrMsg!, + Count = TempErrors.Where(x => x.ErrCode == group).Select(x => x.Count).Sum().ToInt() + }; + + foreach (var date in TempErrorDate) + { + item.Counts.Add(date, TempErrors.Where(x => x.ErrCode == group && x.Id!.IndexOf(date) == 0).Select(x => x.Count).Sum().ToInt()); + } + TempItems.Add(item); + } } + report.Items = TempItems; + report.GpsIds = null; return report; } + + private Task> GetDayError(DeviceErrorReport report) + { + var TempStart = (DateTime)report.StartDate!; + var TempEnd = (DateTime)report.EndDate!; + var TempSpan = TempEnd - TempStart; + var TempDayCount = (int)TempSpan.TotalDays; + var TempDaySpan = 5; + + var TempTasks = new Task>[TempDayCount % TempDaySpan > 0 ? TempDayCount / TempDaySpan + 1 : TempDayCount / TempDaySpan]; + for (var i = 0; i < TempTasks.Length; i++) + { + SqlSugarClient client = new SqlSugarClient(Db.CurrentConnectionConfig); + TempTasks[i] = client.Queryable() + .WhereIF(report.ErrCodes != null && report.ErrCodes.Count() > 0, x => report.ErrCodes!.Contains(x.ErrCode)) + .WhereIF(report.GpsIds != null && report.GpsIds.Count() > 0, x => report.GpsIds!.Contains(x.DeviceId!)) + .Select(x => new DeviceError + { + ErrCode = x.ErrCode, + ErrMsg = x.ErrMsg, + Id = ((DateTime)x.CreateDate!).ToString("yyyy-MM-dd"), + Count = SqlFunc.AggregateCount(x.ErrCode) + }) + .GroupBy(x => new { x.ErrCode, x.ErrMsg, Date = ((DateTime)x.CreateDate!).ToString("yyyy-MM-dd") }) + .SplitTable(TempStart.AddDays(i * TempDaySpan), TempStart.AddDays((i + 1) * TempDaySpan)) + .OrderBy(x => x.Id) + .ToListAsync(); + } + Task.WaitAll(TempTasks); + List result = new List(); + foreach (var task in TempTasks) + { + result.AddRange(task.Result); + } + return Task.FromResult(result); + } + + public async Task> GetErrorList() { + return await Db.Queryable() + .Select(x => new DeviceError + { + ErrCode = x.ErrCode, + ErrMsg = x.ErrMsg + }).Distinct() + .SplitTable(DateTime.Now.AddYears(-1), DateTime.Now) + .ToListAsync(); + } #endregion } } diff --git a/LanSheng/LanShengService/LanShengService.csproj b/LanSheng/LanShengService/LanShengService.csproj index 860fae2..dd555cd 100644 --- a/LanSheng/LanShengService/LanShengService.csproj +++ b/LanSheng/LanShengService/LanShengService.csproj @@ -26,6 +26,7 @@ + diff --git a/ZhongLian/ZhongLianModel/DeviceDO.cs b/ZhongLian/ZhongLianModel/DeviceDO.cs index 63efdf6..cf3fc5e 100644 --- a/ZhongLian/ZhongLianModel/DeviceDO.cs +++ b/ZhongLian/ZhongLianModel/DeviceDO.cs @@ -25,10 +25,41 @@ namespace ZhongLianModel [SugarColumn(Length = 64, IsNullable = true)] public string? ProjectId { get; set; } + /// + /// GPS数组 + /// + [SugarColumn(Length = 500, IsNullable = true, IsJson = true)] + public IEnumerable? Gps { get; set; } + /// /// 删除标识 /// [SugarColumn(Length = 1, IsNullable = true)] public int? Deleted { get; set; } } + + public class DeviceGpsDO + { + /// + /// GPS编号 + /// + public string? Id { get; set; } + + /// + /// GPS名称 + /// + public string? Name { get; set; } + + /// + /// 设备编号 + /// + public string? DeviceId { get; set; } + + /// + /// 博瓦监控设备编号 + /// + public string? Bw { get; set; } + + public string? Bw1 { get; set; } + } }