人机交互页面
This commit is contained in:
@@ -12,9 +12,12 @@ using ZR.Admin.WebApi.Hubs;
|
|||||||
using ZR.Admin.WebApi.Middleware;
|
using ZR.Admin.WebApi.Middleware;
|
||||||
using ZR.Common.Cache;
|
using ZR.Common.Cache;
|
||||||
using ZR.Common.MqttHelper;
|
using ZR.Common.MqttHelper;
|
||||||
|
using ZR.Service.mes.andon;
|
||||||
using ZR.Service.mqtt;
|
using ZR.Service.mqtt;
|
||||||
|
|
||||||
var builder = WebApplication.CreateBuilder(args);
|
var builder = WebApplication.CreateBuilder(args);
|
||||||
|
//后台定时任务
|
||||||
|
builder.Services.AddHostedService<ScheduledBackgroundService>();
|
||||||
// Add services to the container.
|
// Add services to the container.
|
||||||
builder.Services.AddControllers();
|
builder.Services.AddControllers();
|
||||||
//配置中心
|
//配置中心
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
|
using Aliyun.OSS;
|
||||||
using Infrastructure.Attribute;
|
using Infrastructure.Attribute;
|
||||||
using Infrastructure.Model;
|
using Infrastructure.Model;
|
||||||
using JinianNet.JNTemplate.Parsers;
|
using JinianNet.JNTemplate.Parsers;
|
||||||
using SqlSugar;
|
using SqlSugar;
|
||||||
using SqlSugar.Extensions;
|
using SqlSugar.Extensions;
|
||||||
using System;
|
using System;
|
||||||
|
using System.Linq;
|
||||||
using ZR.Model;
|
using ZR.Model;
|
||||||
using ZR.Model.MES.andon;
|
using ZR.Model.MES.andon;
|
||||||
using ZR.Model.MES.andon.Dto;
|
using ZR.Model.MES.andon.Dto;
|
||||||
@@ -259,6 +261,7 @@ namespace ZR.Service.mes.andon
|
|||||||
andonAlarmRecordProcess.UpdatedName = parm.UserName;
|
andonAlarmRecordProcess.UpdatedName = parm.UserName;
|
||||||
andonAlarmRecordProcess.UpdatedTime = DateTime.Now;
|
andonAlarmRecordProcess.UpdatedTime = DateTime.Now;
|
||||||
int iResult = andonAlarmRecordProcessService.Insert(andonAlarmRecordProcess);
|
int iResult = andonAlarmRecordProcessService.Insert(andonAlarmRecordProcess);
|
||||||
|
//报警给领导
|
||||||
return ApiResult.Success("成功", andonAlarmRecordProcess);
|
return ApiResult.Success("成功", andonAlarmRecordProcess);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -271,5 +274,158 @@ namespace ZR.Service.mes.andon
|
|||||||
return ApiResult.Error(500, ex.Message);
|
return ApiResult.Error(500, ex.Message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 查询一小时内生成的所有未处理报警记录,自动进行超时报警(分批次处理,每批500条)
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>ApiResult</returns>
|
||||||
|
public ApiResult AlarmReportAuto()
|
||||||
|
{
|
||||||
|
// 定义批次大小,可配置化(便于后续调整)
|
||||||
|
const int BatchSize = 500;
|
||||||
|
var currentTime = DateTime.Now;
|
||||||
|
var startTime = currentTime.AddHours(-1);
|
||||||
|
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)
|
||||||
|
);
|
||||||
|
|
||||||
|
var queryData = Queryable()
|
||||||
|
.Where(x =>
|
||||||
|
(x.Status == "待响应" || x.Status == "及时响应" || x.Status == "超时响应")
|
||||||
|
&& x.CreatedTime >= startTime
|
||||||
|
&& x.CreatedTime <= endTime)
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
if (!queryData.Any())
|
||||||
|
{
|
||||||
|
return ApiResult.Success("无需要处理的报警数据");
|
||||||
|
}
|
||||||
|
|
||||||
|
var totalCount = queryData.Count;
|
||||||
|
var batchCount = (int)Math.Ceiling((double)totalCount / BatchSize);
|
||||||
|
var allProcessRecords = new List<AndonAlarmRecordProcess>();
|
||||||
|
var batchUpdateList = new List<AndonAlarmRecord>();
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (timeoutMinutes <= 0) continue;
|
||||||
|
var createdTime = item.CreatedTime.ObjToDate();
|
||||||
|
var timeoutTime = createdTime.AddMinutes(timeoutMinutes);
|
||||||
|
var isTimeout = currentTime > timeoutTime;
|
||||||
|
|
||||||
|
if (isTimeout)
|
||||||
|
{
|
||||||
|
UpdateAlarmItemStatus(item, currentTime);
|
||||||
|
batchUpdateList.Add(item);
|
||||||
|
|
||||||
|
var processRecord = CreateAlarmProcessRecord(item, currentTime);
|
||||||
|
allProcessRecords.Add(processRecord);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (batchUpdateList.Any())
|
||||||
|
{
|
||||||
|
UpdateAndonAlarmRecordBatch(batchUpdateList);
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 报警给领导,手表
|
||||||
|
return ApiResult.Success($"成功处理 {totalCount} 条报警记录,其中超时上报 {allProcessRecords.Count} 条");
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"自动超时报警处理失败:{ex.ToString()}"); // 记录完整异常栈,便于排查
|
||||||
|
return ApiResult.Error(500, "自动超时报警处理异常,请查看日志");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#region 辅助方法
|
||||||
|
/// <summary>
|
||||||
|
/// 更新报警记录的超时状态
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="alarmItem">报警记录</param>
|
||||||
|
/// <param name="operateTime">操作时间</param>
|
||||||
|
private void UpdateAlarmItemStatus(AndonAlarmRecord alarmItem, DateTime operateTime)
|
||||||
|
{
|
||||||
|
alarmItem.Status = "超时上报";
|
||||||
|
alarmItem.UpdatedBy = "admin";
|
||||||
|
alarmItem.UpdatedTime = operateTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 创建报警处理记录
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="alarmItem">报警记录</param>
|
||||||
|
/// <param name="operateTime">操作时间</param>
|
||||||
|
/// <returns>处理记录实体</returns>
|
||||||
|
private AndonAlarmRecordProcess CreateAlarmProcessRecord(AndonAlarmRecord alarmItem, DateTime operateTime)
|
||||||
|
{
|
||||||
|
return new AndonAlarmRecordProcess
|
||||||
|
{
|
||||||
|
AlarmCode = alarmItem.AlarmCode,
|
||||||
|
Operate = "超时上报",
|
||||||
|
CreatedBy = "admin",
|
||||||
|
CreatedName = "admin",
|
||||||
|
CreatedTime = operateTime,
|
||||||
|
UpdatedBy = "admin",
|
||||||
|
UpdatedName = "admin",
|
||||||
|
UpdatedTime = operateTime
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 批量更新报警记录
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="alarmItems">待更新的报警记录列表</param>
|
||||||
|
private void UpdateAndonAlarmRecordBatch(List<AndonAlarmRecord> alarmItems)
|
||||||
|
{
|
||||||
|
if (alarmItems == null || !alarmItems.Any()) return;
|
||||||
|
var alarmRepo = new BaseRepository<AndonAlarmRecord>();
|
||||||
|
alarmRepo.Context.Updateable(alarmItems)
|
||||||
|
.UpdateColumns(t => new { t.Status, t.UpdatedBy, t.UpdatedTime })
|
||||||
|
.ExecuteCommand();
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -7,6 +7,7 @@ using System.Linq;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using ZR.Service.mes.andon.Iservice;
|
||||||
|
|
||||||
namespace ZR.Service.mes.andon
|
namespace ZR.Service.mes.andon
|
||||||
{
|
{
|
||||||
@@ -14,7 +15,7 @@ namespace ZR.Service.mes.andon
|
|||||||
{
|
{
|
||||||
private readonly ILogger<ScheduledBackgroundService> _logger;
|
private readonly ILogger<ScheduledBackgroundService> _logger;
|
||||||
private readonly IServiceScopeFactory _scopeFactory;
|
private readonly IServiceScopeFactory _scopeFactory;
|
||||||
private readonly TimeSpan _interval = TimeSpan.FromMinutes(5);
|
private readonly TimeSpan _interval = TimeSpan.FromMinutes(1);
|
||||||
|
|
||||||
public ScheduledBackgroundService(
|
public ScheduledBackgroundService(
|
||||||
ILogger<ScheduledBackgroundService> logger,
|
ILogger<ScheduledBackgroundService> logger,
|
||||||
@@ -35,15 +36,16 @@ namespace ZR.Service.mes.andon
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_logger.LogInformation($"开始执行定时任务: {DateTime.Now:HH:mm:ss}");
|
_logger.LogInformation($"开始执行安灯超时上报定时任务: {DateTime.Now:HH:mm:ss}");
|
||||||
|
// 核心:创建作用域,获取Scoped服务
|
||||||
//// 使用 Scope 获取 Scoped 服务
|
using (var scope = _scopeFactory.CreateScope())
|
||||||
//using (var scope = _scopeFactory.CreateScope())
|
{
|
||||||
//{
|
// 获取你的报警业务服务(Scoped生命周期)
|
||||||
// var myService = scope.ServiceProvider.GetRequiredService<IMyBusinessService>();
|
var alarmService = scope.ServiceProvider.GetRequiredService<AndonAlarmRecordService>();
|
||||||
// await myService.ProcessDataAsync();
|
// 执行你的自动超时上报逻辑
|
||||||
//}
|
var result = alarmService.AlarmReportAuto();
|
||||||
|
_logger.LogInformation($"定时任务执行完成,结果:{result.Msg}");
|
||||||
|
}
|
||||||
_logger.LogInformation($"定时任务完成");
|
_logger.LogInformation($"定时任务完成");
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
@@ -52,9 +54,12 @@ namespace ZR.Service.mes.andon
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 等待指定间隔
|
// 等待指定间隔
|
||||||
await Task.Delay(_interval, stoppingToken);
|
// Task.Delay增加取消令牌检查,避免任务卡住
|
||||||
|
if (!stoppingToken.IsCancellationRequested)
|
||||||
|
{
|
||||||
|
await Task.Delay(_interval, stoppingToken);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_logger.LogInformation("定时后台服务停止");
|
_logger.LogInformation("定时后台服务停止");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user