From 4c7ef6c7415760f72d8f0b8d10ed78c3f801e6f4 Mon Sep 17 00:00:00 2001 From: quowingwang Date: Sun, 21 Dec 2025 14:25:17 +0800 Subject: [PATCH] andon --- ZR.Admin.WebApi/Program.cs | 4 +- ZR.Model/MES/andon/AndonAlarmLevel.cs | 2 +- ZR.Model/MES/andon/AndonAlarmRecord.cs | 3 + ZR.Model/MES/andon/Dto/AndonAlarmLevelDto.cs | 2 +- ZR.Model/MES/andon/Dto/AndonAlarmRecordDto.cs | 2 + .../mes/andon/AndonAlarmRecordService.cs | 213 +++++++++--------- .../IService/IAndonAlarmRecordService.cs | 2 + .../mes/andon/ScheduledBackgroundService.cs | 2 +- 8 files changed, 118 insertions(+), 112 deletions(-) diff --git a/ZR.Admin.WebApi/Program.cs b/ZR.Admin.WebApi/Program.cs index c9df7e6e..b07df0ab 100644 --- a/ZR.Admin.WebApi/Program.cs +++ b/ZR.Admin.WebApi/Program.cs @@ -17,7 +17,7 @@ using ZR.Service.mqtt; var builder = WebApplication.CreateBuilder(args); //后台定时任务 -//builder.Services.AddHostedService(); +builder.Services.AddHostedService(); // Add services to the container. builder.Services.AddControllers(); @@ -115,7 +115,7 @@ builder.Services.Configure((o) => // 注册 SocketGatewayServer 为 Singleton(单例,整个应用生命周期一个实例) builder.Services.AddSingleton(provider => { - var server = new SocketGatewayServer("192.168.1.48", 2325); // 你可以按需修改 IP 和端口 + var server = new SocketGatewayServer("192.168.1.210", 2325); // 你可以按需修改 IP 和端口 server.Start(); // 项目启动时立即启动监听 //server.StartReceiving(); diff --git a/ZR.Model/MES/andon/AndonAlarmLevel.cs b/ZR.Model/MES/andon/AndonAlarmLevel.cs index 191f1176..49b6bc19 100644 --- a/ZR.Model/MES/andon/AndonAlarmLevel.cs +++ b/ZR.Model/MES/andon/AndonAlarmLevel.cs @@ -23,7 +23,7 @@ namespace ZR.Model.MES.andon /// 报警时间 /// [SugarColumn(ColumnName = "level_time")] - public string LevelTime { get; set; } + public int LevelTime { get; set; } /// diff --git a/ZR.Model/MES/andon/AndonAlarmRecord.cs b/ZR.Model/MES/andon/AndonAlarmRecord.cs index da512900..815f8474 100644 --- a/ZR.Model/MES/andon/AndonAlarmRecord.cs +++ b/ZR.Model/MES/andon/AndonAlarmRecord.cs @@ -146,5 +146,8 @@ namespace ZR.Model.MES.andon [SugarColumn(ColumnName = "area2")] public string Area2 { get; set; } + [SugarColumn(ColumnName = "autocount")] + public int AutoCount { get; set; } + } } \ No newline at end of file diff --git a/ZR.Model/MES/andon/Dto/AndonAlarmLevelDto.cs b/ZR.Model/MES/andon/Dto/AndonAlarmLevelDto.cs index d2b583bb..bf6705c3 100644 --- a/ZR.Model/MES/andon/Dto/AndonAlarmLevelDto.cs +++ b/ZR.Model/MES/andon/Dto/AndonAlarmLevelDto.cs @@ -20,7 +20,7 @@ namespace ZR.Model.MES.andon.Dto public string LevelName { get; set; } - public string LevelTime { get; set; } + public int LevelTime { get; set; } public string CreatedBy { get; set; } diff --git a/ZR.Model/MES/andon/Dto/AndonAlarmRecordDto.cs b/ZR.Model/MES/andon/Dto/AndonAlarmRecordDto.cs index 9e90a113..6b70763f 100644 --- a/ZR.Model/MES/andon/Dto/AndonAlarmRecordDto.cs +++ b/ZR.Model/MES/andon/Dto/AndonAlarmRecordDto.cs @@ -67,5 +67,7 @@ namespace ZR.Model.MES.andon.Dto public string Area1 { get; set; } public string Area2 { get; set; } public string[] Area { get; set; } + + public int AutoCount { get; set; } } } \ No newline at end of file diff --git a/ZR.Service/mes/andon/AndonAlarmRecordService.cs b/ZR.Service/mes/andon/AndonAlarmRecordService.cs index 93f25fff..2a2dae28 100644 --- a/ZR.Service/mes/andon/AndonAlarmRecordService.cs +++ b/ZR.Service/mes/andon/AndonAlarmRecordService.cs @@ -25,13 +25,7 @@ namespace ZR.Service.mes.andon private AndonAlarmLevelService andonAlarmLevelService = new AndonAlarmLevelService(); private AndonAlarmRecordProcessService andonAlarmRecordProcessService = new AndonAlarmRecordProcessService(); private AndonAlarmTypeDictService andonAlarmTypeDictService = new AndonAlarmTypeDictService(); - private SocketGatewayServer _socketGateway = null; - public AndonAlarmRecordService(SocketGatewayServer socketGateway) - { - - _socketGateway= socketGateway; - } - + private SocketGatewayServer _socketGateway = new SocketGatewayServer(); /// /// 查询报警记录列表 @@ -376,122 +370,127 @@ namespace ZR.Service.mes.andon } /// - /// 查询一小时内生成的所有未处理报警记录,自动进行超时报警(分批次处理,每批500条) + /// 查询三小时内生成的所有未处理报警记录,自动进行超时报警(分批次处理,每批500条) /// /// ApiResult public ApiResult AlarmReportAuto() { - return null; - //// 定义批次大小,可配置化(便于后续调整) - //const int BatchSize = 500; - //var currentTime = DateTime.Now; - //var startTime = currentTime.AddHours(-1); - //var endTime = currentTime; + // 定义批次大小,可配置化(便于后续调整) + const int BatchSize = 500; + var currentTime = DateTime.Now; + var startTime = currentTime.AddHours(-3); + var endTime = currentTime; - //try - //{ - // var alarmLevelMap = andonAlarmLevelService.Queryable() - // .Where(level => !string.IsNullOrWhiteSpace(level.LevelName) && level.HandleTimeout.HasValue) - // .ToDictionary( - // level => (object)level.LevelName.Trim(), - // level => (object)Convert.ToInt32(level.HandleTimeout.Value) - // ); + try + { + var alarmLevelMap = andonAlarmLevelService.Queryable() + .Where(level => !string.IsNullOrWhiteSpace(level.LevelName) && level.LevelTime > 0) + .ToDictionary( + level => (object)level.LevelName.Trim(), + level => (object)level.LevelTime + ); + var predicate = Expressionable.Create(); + predicate.And(x => x.Status == "待响应"); + predicate.And(x => x.CreatedTime >= startTime); + predicate.And(x => x.CreatedTime <= endTime); + predicate.And(x => x.AutoCount < 3); - // var queryData = Queryable() - // .Where(x => - // (x.Status == "待响应" || x.Status == "及时响应" || x.Status == "超时响应") - // && x.CreatedTime >= startTime - // && x.CreatedTime <= endTime) - // .ToList(); + var queryData = Queryable() + .Where(predicate.ToExpression()) + .ToList(); - // if (!queryData.Any()) - // { - // return ApiResult.Success("无需要处理的报警数据"); - // } + if (!queryData.Any()) + { + return ApiResult.Success("无需要处理的报警数据"); + } - // var totalCount = queryData.Count; - // var batchCount = (int)Math.Ceiling((double)totalCount / BatchSize); - // var allProcessRecords = new List(); - // var batchUpdateList = new List(); + var totalCount = queryData.Count; + var batchCount = (int)Math.Ceiling((double)totalCount / BatchSize); + var allProcessRecords = new List(); + var batchUpdateList = new List(); - // for (int batchIndex = 0; batchIndex < batchCount; batchIndex++) - // { - // try - // { - // var currentBatch = queryData.Skip(batchIndex * BatchSize).Take(BatchSize).ToList(); - // batchUpdateList.Clear(); + for (int batchIndex = 0; batchIndex < batchCount; batchIndex++) + { + try + { + var currentBatch = queryData.Skip(batchIndex * BatchSize).Take(BatchSize).ToList(); + batchUpdateList.Clear(); - // foreach (var item in currentBatch) - // { - // if (string.IsNullOrWhiteSpace(item.AlarmLevel)) continue; - // var alarmLevelKey = item.AlarmLevel?.Trim() ?? ""; - // int timeoutMinutes = 0; - // if (alarmLevelMap.TryGetValue(alarmLevelKey, out object value)) - // { - // timeoutMinutes = (int)value; - // } + foreach (var item in currentBatch) + { + string strOperate = "超时上报"; + int timeoutMinutes = 0; + //超时未响应,接收人1向接收人2上报 + if (item.AutoCount == 0 && item.Receiver2Name != null) + { + timeoutMinutes = (int) alarmLevelMap.GetValueOrDefault("一级", 0); + strOperate += ","+item.Receiver1Name+"到"+item.Receiver2Name; + } + //超时未响应,接收人2向接收人3上报 + else if (item.AutoCount == 1 && item.Receiver3Name != null) + { + timeoutMinutes = (int)alarmLevelMap.GetValueOrDefault("二级", 0); + strOperate += ","+item.Receiver2Name+"到"+item.Receiver3Name; + } + //超时未响应,接收人3向接收人4上报 + else if (item.AutoCount == 2 && item.Receiver4Name != null) + { + timeoutMinutes = (int)alarmLevelMap.GetValueOrDefault("三级", 0); + strOperate += ","+item.Receiver3Name+"到"+item.Receiver4Name; + } + if (timeoutMinutes == 0) continue; + var createdTime = item.CreatedTime.ObjToDate(); + var timeoutTime = createdTime.AddMinutes(timeoutMinutes); + var isTimeout = currentTime > timeoutTime; - // if (timeoutMinutes <= 0) continue; - // var createdTime = item.CreatedTime.ObjToDate(); - // var timeoutTime = createdTime.AddMinutes(timeoutMinutes); - // var isTimeout = currentTime > timeoutTime; + if (isTimeout) + { - // if (isTimeout) - // { - // UpdateAlarmItemStatus(item, currentTime); - // batchUpdateList.Add(item); + item.AutoCount += 1; + item.UpdatedBy = "admin"; + item.UpdatedTime = DateTime.Now; + batchUpdateList.Add(item); - // var processRecord = CreateAlarmProcessRecord(item, currentTime); - // allProcessRecords.Add(processRecord); - // } - // } + var processRecord = CreateAlarmProcessRecord(item, strOperate); + allProcessRecords.Add(processRecord); + } + } - // if (batchUpdateList.Any()) - // { - // UpdateAndonAlarmRecordBatch(batchUpdateList); - // } + if (batchUpdateList.Any()) + { + UpdateAndonAlarmRecordBatch(batchUpdateList); + } - // Console.WriteLine($"批次 {batchIndex + 1}/{batchCount} 处理完成,本批更新 {batchUpdateList.Count} 条报警记录"); - // } - // catch (Exception batchEx) - // { - // Console.WriteLine($"批次 {batchIndex + 1} 处理失败:{batchEx.Message}"); - // continue; - // } - // } + Console.WriteLine($"批次 {batchIndex + 1}/{batchCount} 处理完成,本批更新 {batchUpdateList.Count} 条报警记录"); + } + catch (Exception batchEx) + { + Console.WriteLine($"批次 {batchIndex + 1} 处理失败:{batchEx.Message}"); + continue; + } + } - // if (allProcessRecords.Any()) - // { - // var processBatchCount = (int)Math.Ceiling((double)allProcessRecords.Count / BatchSize); - // for (int pBatchIndex = 0; pBatchIndex < processBatchCount; pBatchIndex++) - // { - // var processBatch = allProcessRecords.Skip(pBatchIndex * BatchSize).Take(BatchSize).ToList(); - // andonAlarmRecordProcessService.Insert(processBatch); - // } - // } + if (allProcessRecords.Any()) + { + var processBatchCount = (int)Math.Ceiling((double)allProcessRecords.Count / BatchSize); + for (int pBatchIndex = 0; pBatchIndex < processBatchCount; pBatchIndex++) + { + var processBatch = allProcessRecords.Skip(pBatchIndex * BatchSize).Take(BatchSize).ToList(); + andonAlarmRecordProcessService.Insert(processBatch); + } + } - // // 报警给领导,手表 - // return ApiResult.Success($"成功处理 {totalCount} 条报警记录,其中超时上报 {allProcessRecords.Count} 条"); - //} - //catch (Exception ex) - //{ - // Console.WriteLine($"自动超时报警处理失败:{ex.ToString()}"); // 记录完整异常栈,便于排查 - // return ApiResult.Error(500, "自动超时报警处理异常,请查看日志"); - //} + // 报警给领导,手表 + return ApiResult.Success($"成功处理 {totalCount} 条报警记录,其中超时上报 {allProcessRecords.Count} 条"); + } + catch (Exception ex) + { + Console.WriteLine($"自动超时报警处理失败:{ex.ToString()}"); // 记录完整异常栈,便于排查 + return ApiResult.Error(500, "自动超时报警处理异常,请查看日志"); + } } #region 辅助方法 - /// - /// 更新报警记录的超时状态 - /// - /// 报警记录 - /// 操作时间 - private void UpdateAlarmItemStatus(AndonAlarmRecord alarmItem, DateTime operateTime) - { - alarmItem.Status = "超时上报"; - alarmItem.UpdatedBy = "admin"; - alarmItem.UpdatedTime = operateTime; - } /// /// 创建报警处理记录 @@ -499,18 +498,18 @@ namespace ZR.Service.mes.andon /// 报警记录 /// 操作时间 /// 处理记录实体 - private AndonAlarmRecordProcess CreateAlarmProcessRecord(AndonAlarmRecord alarmItem, DateTime operateTime) + private AndonAlarmRecordProcess CreateAlarmProcessRecord(AndonAlarmRecord alarmItem,string strOperate) { return new AndonAlarmRecordProcess { AlarmCode = alarmItem.AlarmCode, - Operate = "超时上报", + Operate = strOperate, CreatedBy = "admin", CreatedName = "admin", - CreatedTime = operateTime, + CreatedTime = DateTime.Now, UpdatedBy = "admin", UpdatedName = "admin", - UpdatedTime = operateTime + UpdatedTime = DateTime.Now, }; } diff --git a/ZR.Service/mes/andon/IService/IAndonAlarmRecordService.cs b/ZR.Service/mes/andon/IService/IAndonAlarmRecordService.cs index 849a4599..322e0598 100644 --- a/ZR.Service/mes/andon/IService/IAndonAlarmRecordService.cs +++ b/ZR.Service/mes/andon/IService/IAndonAlarmRecordService.cs @@ -25,5 +25,7 @@ namespace ZR.Service.mes.andon.Iservice ApiResult AlarmHandle(AndonAlarmRecordDto parm); ApiResult AlarmReportHand(AndonAlarmRecordDto parm); + + ApiResult AlarmReportAuto(); } } diff --git a/ZR.Service/mes/andon/ScheduledBackgroundService.cs b/ZR.Service/mes/andon/ScheduledBackgroundService.cs index 9f477df4..53b96d55 100644 --- a/ZR.Service/mes/andon/ScheduledBackgroundService.cs +++ b/ZR.Service/mes/andon/ScheduledBackgroundService.cs @@ -41,7 +41,7 @@ namespace ZR.Service.mes.andon using (var scope = _scopeFactory.CreateScope()) { // 获取你的报警业务服务(Scoped生命周期) - var alarmService = scope.ServiceProvider.GetRequiredService(); + var alarmService = scope.ServiceProvider.GetRequiredService(); // 执行你的自动超时上报逻辑 var result = alarmService.AlarmReportAuto(); _logger.LogInformation($"定时任务执行完成,结果:{result.Msg}");