shgx_tz_mom/ZR.Service/mes/andon/AndonAlarmRecordService.cs
2026-01-07 09:11:30 +08:00

857 lines
36 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using Aliyun.OSS;
using DOAN.ServiceCore.MyMatchPush;
using Infrastructure;
using Infrastructure.Attribute;
using Infrastructure.Helper;
using Infrastructure.Model;
using JinianNet.JNTemplate.Parsers;
using Microsoft.AspNetCore.Server.Kestrel.Core;
using SqlSugar;
using SqlSugar.Extensions;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using ZR.Model;
using ZR.Model.MES.andon;
using ZR.Model.MES.andon.Dto;
using ZR.Repository;
using ZR.Service.mes.andon.Iservice;
using ZR.Service.Utils.MyAlarmLigth;
namespace ZR.Service.mes.andon
{
/// <summary>
/// 报警记录Service业务层处理
/// </summary>
[AppService(ServiceType = typeof(IAndonAlarmRecordService), ServiceLifetime = LifeTime.Transient)]
public class AndonAlarmRecordService : BaseService<AndonAlarmRecord>, IAndonAlarmRecordService
{
private AndonAlarmLevelService andonAlarmLevelService = new AndonAlarmLevelService();
private AndonAlarmRecordProcessService andonAlarmRecordProcessService = new AndonAlarmRecordProcessService();
private AndonAlarmTypeDictService andonAlarmTypeDictService = new AndonAlarmTypeDictService();
private SocketGatewayServer _socketGateway = null;
//private readonly ModbusTcpClientHelper _modbusClient;
private readonly ThreeColorLightModbus _modbusClient;
private AndonAlarmAreaLightDicService andonAlarmAreaLightDicService = new AndonAlarmAreaLightDicService();
private AndonAlarmReceiverWatchDicService andonAlarmReceiverWatchDicService = new AndonAlarmReceiverWatchDicService();
//public AndonAlarmRecordService(SocketGatewayServer socketGateway, ModbusTcpClientHelper modbusClient)
//{
// _socketGateway = socketGateway;
// _modbusClient = modbusClient;
//}
public AndonAlarmRecordService(SocketGatewayServer socketGateway, ThreeColorLightModbus modbusClient)
{
_socketGateway = socketGateway;
_modbusClient = modbusClient;
}
/// <summary>
/// 查询报警记录列表
/// </summary>
/// <param name="parm"></param>
/// <returns></returns>
public PagedInfo<AndonAlarmRecordDto> GetList(AndonAlarmRecordQueryDto parm)
{
var predicate = Expressionable.Create<AndonAlarmRecord>();
if (parm != null)
{
if (parm.startTime != null && parm.startTime > DateTime.MinValue)
{
predicate = predicate.And(it => it.CreatedTime >= parm.startTime);
}
if (parm.endTime != null && parm.endTime > DateTime.MaxValue)
{
predicate = predicate.And(it => it.CreatedTime <= parm.endTime);
}
if (!string.IsNullOrEmpty(parm.AlarmCode))
{
predicate = predicate.And(it => it.AlarmCode.Contains(parm.AlarmCode));
}
if (!string.IsNullOrEmpty(parm.AlarmTypeCode))
{
predicate = predicate.And(it => it.AlarmTypeCode == parm.AlarmTypeCode);
}
if (!string.IsNullOrEmpty(parm.Area1))
{
predicate = predicate.And(it => it.Area1 == parm.Area1);
}
}
var response = Queryable()
.Where(predicate.ToExpression())
.ToPage<AndonAlarmRecord, AndonAlarmRecordDto>(parm);
return response;
}
public List<AndonAlarmRecordDto> GetListToWeek()
{
DateTime now = DateTime.Now;
DateTime endTime = now;
Calendar calendar = CultureInfo.CurrentCulture.Calendar;
// 获取当天是本周的第几天WeekOfDay1=周一7=周日)
int dayOfWeek = (int)calendar.GetDayOfWeek(now);
DateTime startTime = now.AddDays(-(dayOfWeek - 1)).Date; // 截断时分秒为00:00:00
var queryList = Queryable()
.LeftJoin<AndonAlarmRecordProcess>((a, b) =>
a.AlarmCode == b.AlarmCode && b.Operate == "已响应")
.LeftJoin<AndonAlarmRecordProcess>((a, b, c) =>
a.AlarmCode == c.AlarmCode && c.Operate == "已处理")
.Where(a => a.CreatedTime >= startTime && a.CreatedTime <= endTime)
.Select((a, b, c) => new AndonAlarmRecordDto
{
Id = a.Id,
AlarmCode = a.AlarmCode,
AlarmTypeCode = a.AlarmTypeCode,
AlarmType = a.AlarmType,
AlarmInfo = a.AlarmInfo,
Receiver1 = a.Receiver1,
Receiver1Name = a.Receiver1Name,
Receiver2 = a.Receiver2,
Receiver2Name = a.Receiver2Name,
Receiver3 = a.Receiver3,
Receiver3Name = a.Receiver3Name,
Receiver4 = a.Receiver4,
Receiver4Name = a.Receiver4Name,
Sequence = a.Sequence,
DurationTime = a.DurationTime,
Status = a.Status,
HandleResult = a.HandleResult,
Remarks = a.Remarks,
CreatedBy = a.CreatedBy,
CreatedTime = a.CreatedTime,
UpdatedBy = a.UpdatedBy,
UpdatedTime = a.UpdatedTime,
Area1 = a.Area1,
Area2 = a.Area2,
AutoCount = a.AutoCount,
ResponseTime = b == null ? null : b.CreatedTime, // 已响应时间
HandleTime = c == null ? null : c.CreatedTime // 已处理时间
})
.ToList();
return queryList;
}
public ApiResult QueryMonthAlarmCountByType()
{
//查询本月的报警信息
DateTime now = DateTime.Now;
DateTime endTime = now;
DateTime startTime = new DateTime(now.Year, now.Month, 1).Date; // 截断时分秒为00:00:00
var predicate = Expressionable.Create<AndonAlarmRecord>();
predicate.And(a => a.CreatedTime >= startTime && a.CreatedTime <= endTime);
var queryList = Queryable()
.Where(predicate.ToExpression())
.GroupBy(a => a.AlarmType)
.Having(a => a.AlarmType != null)
.Select(a => new SelectOption
{
label = a.AlarmType,
value = SqlFunc.AggregateCount(1).ToString()
})
.ToList();
return new ApiResult(200,"",queryList);
}
public ApiResult QueryWeekAlarmLineChart()
{
DateTime now = DateTime.Now;
DateTime endTime = now;
DateTime startTime = now.AddDays(-14).Date;
// 方法1使用 ToDate 函数(确保按日期分组)
var dbStats = Queryable()
.Where(a => a.CreatedTime >= startTime && a.CreatedTime <= endTime)
.LeftJoin<AndonAlarmRecordProcess>((a, p) =>
a.AlarmCode == p.AlarmCode && p.Operate == "已处理")
.GroupBy((a, p) => SqlFunc.ToDate(a.CreatedTime).ToString("yyyy/MM/dd")) // 直接使用 Date 属性
.Select((a, p) => new
{
DayDate = SqlFunc.ToDate(a.CreatedTime).ToString("yyyy/MM/dd"), // 存储为 DateTime
TotalCount = SqlFunc.AggregateCount(1),
HandledCount = SqlFunc.AggregateCount(p.Id) // 更简洁的写法
})
.ToList();
// 生成完整的14天日期序列包含开始日期
var allDates = Enumerable.Range(0, 14)
.Select(days => startTime.AddDays(days+1))
.ToList();
// 转换为字典,使用 ToString("yyyy/MM/dd") 作为 Key
var statDict = dbStats.ToDictionary(
x => x.DayDate,
x => x
);
var chartData = new
{
// X轴日期格式统一为 yyyy/MM/dd
xAxisData = allDates.Select(d => d.ToString("yyyy/MM/dd")).ToList(),
// Y轴1总报警数量
yAxisData1 = allDates.Select(date =>
{
var dateStr = date.ToString("yyyy/MM/dd");
return statDict.ContainsKey(dateStr) ? statDict[dateStr].TotalCount : 0;
}).ToList(),
// Y轴2已处理报警数量
yAxisData2 = allDates.Select(date =>
{
var dateStr = date.ToString("yyyy/MM/dd");
return statDict.ContainsKey(dateStr) ? statDict[dateStr].HandledCount : 0;
}).ToList(),
};
return new ApiResult(200, "查询成功", chartData);
}
public ApiResult QueryWeekAlarmTJChart()
{
DateTime now = DateTime.Now;
DateTime endTime = now;
DateTime startTime = now.AddDays(-7).Date;
// 方法1使用 ToDate 函数(确保按日期分组)
var dbStats = Queryable()
.Where(a => a.CreatedTime >= startTime && a.CreatedTime <= endTime)
.Where(a => a.Area1 != null && a.Area1 != "")
.GroupBy(a => a.Area1)
.Select(a => new
{
Area1 = a.Area1,
Hours = SqlFunc.Round(
SqlFunc.IIF(
a.Status == "已处理",
a.DurationTime / 60.0, // 已处理:分钟转小时
SqlFunc.DateDiff(DateType.Minute, SqlFunc.ToDate(a.CreatedTime), DateTime.Now) / 60.0 // 未处理:计算等待时间转小时
), 2),
AlarmCount = SqlFunc.AggregateCount(1)
})
.OrderBy(a => a.Area1)
.ToList();
var chartData = new
{
// X轴区域名称
xAxisData = dbStats.Select(a => a.Area1).ToList(),
// Y轴1停机时长小时
yAxisData1 = dbStats.Select(a => a.Hours).ToList(),
// Y轴2报警数量
yAxisData2 = dbStats.Select(a => a.AlarmCount).ToList(),
};
return new ApiResult(200, "查询成功", chartData);
}
public PagedInfo<AndonAlarmRecordDto> GetListToday(AndonAlarmRecordQueryDto parm)
{
var predicate = Expressionable.Create<AndonAlarmRecord>();
DateTime dtNow = DateTime.Now;
DateTime startTime = new DateTime(dtNow.Year, dtNow.Month, dtNow.Day, 0, 0, 0);
DateTime endTime = new DateTime(dtNow.Year, dtNow.Month, dtNow.Day, 23, 59, 59);
predicate = predicate.And(it => it.CreatedTime >= startTime);
predicate = predicate.And(it => it.CreatedTime <= endTime);
var response = Queryable()
.Where(predicate.ToExpression())
.ToPage<AndonAlarmRecord, AndonAlarmRecordDto>(parm);
return response;
}
/// <summary>
/// 获取详情
/// </summary>
/// <param name="Id"></param>
/// <returns></returns>
public AndonAlarmRecord GetInfo(int Id)
{
var response = Queryable()
.Where(x => x.Id == Id)
.First();
return response;
}
/// <summary>
/// 添加报警记录
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public AndonAlarmRecord AddAndonAlarmRecord(AndonAlarmRecord model)
{
return Context.Insertable(model).ExecuteReturnEntity();
}
/// <summary>
/// 修改报警记录
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public int UpdateAndonAlarmRecord(AndonAlarmRecord model)
{
if (model != null && !string.IsNullOrEmpty(model.AlarmTypeCode))
{
var typeDic = andonAlarmTypeDictService.Queryable()
.Where(k => k.TypeCode == model.AlarmTypeCode)
.ToList().FirstOrDefault();
if (typeDic != null)
{
model.Receiver1 = typeDic.Receiver1;
model.Receiver1Name = typeDic.Receiver1Name;
model.Receiver2 = typeDic.Receiver2;
model.Receiver2Name = typeDic.Receiver2Name;
model.Receiver3 = typeDic.Receiver3;
model.Receiver3Name = typeDic.Receiver3Name;
model.Receiver4 = typeDic.Receiver4;
model.Receiver4Name = typeDic.Receiver4Name;
}
else
{
model.Receiver1 = null;
model.Receiver1Name = string.Empty;
model.Receiver2 = null;
model.Receiver2Name = string.Empty;
model.Receiver3 = null;
model.Receiver3Name = string.Empty;
model.Receiver4 = null;
model.Receiver4Name = string.Empty;
}
}
else
{
model.Receiver1 = null;
model.Receiver1Name = string.Empty;
model.Receiver2 = null;
model.Receiver2Name = string.Empty;
model.Receiver3 = null;
model.Receiver3Name = string.Empty;
model.Receiver4 = null;
model.Receiver4Name = string.Empty;
}
return Update(model, true);
}
public ApiResult AlarmResponse(AndonAlarmRecordDto parm)
{
try
{
var response = new ApiResult();
if (parm != null)
{
var record = Queryable()
.Where(x => x.Id == parm.Id)
.First();
if (record != null)
{
record.Status = "已响应";
record.Remarks = parm.Remarks;
record.UpdatedBy = parm.UserId;
record.UpdatedTime = DateTime.Now;
UpdateAndonAlarmRecord(record);
AndonAlarmRecordProcess andonAlarmRecordProcess = new AndonAlarmRecordProcess();
andonAlarmRecordProcess.AlarmCode = record.AlarmCode;
andonAlarmRecordProcess.Operate = record.Status;
andonAlarmRecordProcess.CreatedBy = parm.UserId;
andonAlarmRecordProcess.CreatedName = parm.UserName;
andonAlarmRecordProcess.CreatedTime = DateTime.Now;
andonAlarmRecordProcess.UpdatedBy = parm.UserId;
andonAlarmRecordProcess.UpdatedName = parm.UserName;
andonAlarmRecordProcess.UpdatedTime = DateTime.Now;
int iResult = andonAlarmRecordProcessService.Insert(andonAlarmRecordProcess);
try
{
//三色灯变黄
byte bLightIp = GetLightIp(parm.Area1, parm.Area2);
if (bLightIp != 0)
{
LightUp.WriteAlarmLightCommand_Yellow(_modbusClient, bLightIp);
}
}
catch (Exception ex)
{
}
AndonAlarmRecordProcessQueryDto parmP = new AndonAlarmRecordProcessQueryDto();
parmP.AlarmCode = andonAlarmRecordProcess.AlarmCode;
var processList = andonAlarmRecordProcessService.GetList(parmP);
return ApiResult.Success("成功", processList);
}
}
else
{
response.Code = 500;
response.Msg = "参数不能为空";
}
return response;
}
catch (Exception ex)
{
return ApiResult.Error(500, ex.Message);
}
}
public ApiResult AlarmHandle(AndonAlarmRecordDto parm)
{
try
{
if (parm == null)
{
return ApiResult.Error(500, "参数不能为空");
}
if (parm.Status == "已响应")
{
var record = Queryable()
.Where(x => x.Id == parm.Id)
.First();
record.Status = "已处理";
record.HandleResult = parm.HandleResult;
record.Remarks = parm.Remarks;
record.UpdatedBy = parm.UserId;
record.UpdatedTime = DateTime.Now;
//获取设备停机持续时间
if (record.CreatedTime != null)
{
record.DurationTime = getDurationTime((DateTime)record.CreatedTime);
}
else
{
record.DurationTime = 0;
}
UpdateAndonAlarmRecord(record);
AndonAlarmRecordProcess andonAlarmRecordProcess = new AndonAlarmRecordProcess();
andonAlarmRecordProcess.AlarmCode = record.AlarmCode;
andonAlarmRecordProcess.Operate = record.Status;
andonAlarmRecordProcess.CreatedBy = parm.UserId;
andonAlarmRecordProcess.CreatedName = parm.UserName;
andonAlarmRecordProcess.CreatedTime = DateTime.Now;
andonAlarmRecordProcess.UpdatedBy = parm.UserId;
andonAlarmRecordProcess.UpdatedName = parm.UserName;
andonAlarmRecordProcess.UpdatedTime = DateTime.Now;
int iResult = andonAlarmRecordProcessService.Insert(andonAlarmRecordProcess);
try
{
//三色灯变绿
byte bLightIp = GetLightIp(parm.Area1, parm.Area2);
if (bLightIp != 0)
{
LightUp.WriteAlarmLightCommand_Normal(_modbusClient, bLightIp);
}
}
catch (Exception ex)
{
}
AndonAlarmRecordProcessQueryDto parmP = new AndonAlarmRecordProcessQueryDto();
parmP.AlarmCode = andonAlarmRecordProcess.AlarmCode;
var processList = andonAlarmRecordProcessService.GetList(parmP);
return ApiResult.Success("成功", processList);
}
else
{
return ApiResult.Error(500, "只能处理响应状态数据");
}
}
catch (Exception ex)
{
return ApiResult.Error(500, ex.Message);
}
}
private int getDurationTime(DateTime alarmStartTime)
{
try
{
int duration = 0;
// 假设 MinDateValue 是 DateTime.MinValue 或某个最小日期
DateTime MinDateValue = DateTime.MinValue;
if (alarmStartTime > MinDateValue && alarmStartTime < DateTime.Now)
{
// 将当前时间减去创建时间,作为报警持续时间(返回分钟数)
TimeSpan timeSpan = DateTime.Now - alarmStartTime;
duration = (int)timeSpan.TotalMinutes;
}
return duration;
}
catch (Exception ex)
{
return 0;
}
}
public ApiResult AlarmReportHand(AndonAlarmRecordDto parm)
{
try
{
if (parm == null)
{
return ApiResult.Error(500, "参数不能为空");
}
if (parm.Status == "待响应" || parm.Status == "已响应")
{
var record = Queryable()
.Where(x => x.Id == parm.Id)
.First();
record.Status = "已上报";
record.Remarks = parm.Remarks;
record.UpdatedBy = parm.UserId;
record.UpdatedTime = DateTime.Now;
UpdateAndonAlarmRecord(record);
AndonAlarmRecordProcess andonAlarmRecordProcess = new AndonAlarmRecordProcess();
andonAlarmRecordProcess.AlarmCode = record.AlarmCode;
andonAlarmRecordProcess.Operate = record.Status;
andonAlarmRecordProcess.CreatedBy = parm.UserId;
andonAlarmRecordProcess.CreatedName = parm.UserName;
andonAlarmRecordProcess.CreatedTime = DateTime.Now;
andonAlarmRecordProcess.UpdatedBy = parm.UserId;
andonAlarmRecordProcess.UpdatedName = parm.UserName;
andonAlarmRecordProcess.UpdatedTime = DateTime.Now;
int iResult = andonAlarmRecordProcessService.Insert(andonAlarmRecordProcess);
return ApiResult.Success("成功", andonAlarmRecordProcess);
}
else
{
return ApiResult.Error(500, "只能处理响应状态数据");
}
}
catch (Exception ex)
{
return ApiResult.Error(500, ex.Message);
}
}
private byte GetLightIp(string area1, string area2)
{
byte bLightIp = 0;
if (area2 == null || area2 == "")
{
area2 = "NA";
}
var query = andonAlarmAreaLightDicService.Queryable()
.Where(x => x.Area1 == area1 && x.Area2 == area2)
.ToList().FirstOrDefault();
if (query != null)
{
string lightIp = query.Lightip;
bLightIp = Convert.ToByte(lightIp);
}
return bLightIp;
}
/// <summary>
/// 创建报警记录(优化版:通讯失败不影响核心数据新增)
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public AndonAlarmRecord CreateAndonAlarmRecord(AndonAlarmRecord model)
{
// 1. 核心业务逻辑(新增报警记录)- 优先执行,不受通讯影响
string strDay = DateTime.Now.ToString("yyyyMMdd");
int Sequence = 1;
// 兼容无历史记录的情况避免First()空指针)
var lastItem = Queryable()
.Where(it => it.AlarmCode.Contains(strDay))
.OrderByDescending(it => it.Sequence)
.ToList()
.FirstOrDefault(); // 替换First()为FirstOrDefault(),避免无数据时抛异常
if (lastItem != null)
{
Sequence = (int)lastItem.Sequence + 1;
}
string formattedSequence = Sequence.ToString("D4");
string strAlarmCode = "Alarm" + strDay + formattedSequence;
model.AlarmCode = strAlarmCode;
model.Sequence = Sequence;
model.Status = "待响应";
// 获取报警类型配置
var typeDic = andonAlarmTypeDictService.Queryable()
.Where(k => k.TypeCode == model.AlarmTypeCode)
.ToList()
.FirstOrDefault(); // 替换ToList().FirstOrDefault(),减少内存占用
if (typeDic != null)
{
model.Receiver1 = typeDic.Receiver1;
model.Receiver1Name = typeDic.Receiver1Name;
model.Receiver2 = typeDic.Receiver2;
model.Receiver2Name = typeDic.Receiver2Name;
model.Receiver3 = typeDic.Receiver3;
model.Receiver3Name = typeDic.Receiver3Name;
model.Receiver4 = typeDic.Receiver4;
model.Receiver4Name = typeDic.Receiver4Name;
}
string strMessage = $"{model.Area1}{model.Area2}{model.AlarmType}{model.AlarmInfo}";
// 2. 执行核心数据插入(先落库,确保数据不丢失)
var resultEntity = Context.Insertable(model).ExecuteReturnEntity();
// 3. 通讯相关操作(手表推送+三色灯)- 独立try-catch
try
{
// 3.1 手表呼叫报警(注释保留,仅做异常隔离)
if (!string.IsNullOrEmpty(model.Receiver1))
{
List<string> WatchAddressList = GetReceiverWatchAddress(model.Receiver1);
if (WatchAddressList.Any())
{
foreach (string strWatchAddress in WatchAddressList)
{
Watchup.StartPush(strMessage, _socketGateway, strWatchAddress);
}
}
}
}
catch (Exception ex)
{
}
try
{
// 3.2 三色灯鸣叫报警(核心通讯操作,单独异常捕获)
byte bLightIp = GetLightIp(model.Area1, model.Area2);
if (bLightIp != 0)
{
LightUp.WriteAlarmLightCommand_Red(_modbusClient, bLightIp);
}
}
catch (Exception ex)
{
}
// 4. 返回新增的实体(核心业务结果不受通讯影响)
return resultEntity;
}
//根据报警联系人获取对应人的手表地址
private List<string> GetReceiverWatchAddress(string receiverIds)
{
string[] receiverIdArr = receiverIds.Split(',');
List<string> watchAddressList = new List<string>();
foreach (string receiverId in receiverIdArr)
{
var query = andonAlarmReceiverWatchDicService.Queryable()
.Where(a => a.Receiverid == receiverId)
.ToList().FirstOrDefault();
if (query != null)
{
watchAddressList.Add(query.Watchip);
}
}
return watchAddressList;
}
/// <summary>
/// 查询三小时内生成的所有未处理报警记录自动进行超时报警分批次处理每批500条
/// </summary>
/// <returns>ApiResult</returns>
public ApiResult AlarmReportAuto()
{
// 定义批次大小,可配置化(便于后续调整)
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.LevelTime > 0)
.ToDictionary(
level => (object)level.LevelName.Trim(),
level => (object)level.LevelTime
);
var predicate = Expressionable.Create<AndonAlarmRecord>();
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(predicate.ToExpression())
.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)
{
string strOperate = "超时上报";
int timeoutMinutes = 0;
string ReceiveId = "";
string strWatchMessage = item.Area1 + item.Area2 + item.AlarmType + item.AlarmInfo;
//超时未响应接收人1向接收人2上报
if (item.AutoCount == 0 && item.Receiver2Name != null)
{
timeoutMinutes = (int) alarmLevelMap.GetValueOrDefault("一级", 0);
strOperate += ","+item.Receiver1Name+"到"+item.Receiver2Name;
ReceiveId = item.Receiver2;
}
//超时未响应接收人2向接收人3上报
else if (item.AutoCount == 1 && item.Receiver3Name != null)
{
timeoutMinutes = (int)alarmLevelMap.GetValueOrDefault("二级", 0);
strOperate += ","+item.Receiver2Name+"到"+item.Receiver3Name;
ReceiveId = item.Receiver3;
}
//超时未响应接收人3向接收人4上报
else if (item.AutoCount == 2 && item.Receiver4Name != null)
{
timeoutMinutes = (int)alarmLevelMap.GetValueOrDefault("三级", 0);
strOperate += ","+item.Receiver3Name+"到"+item.Receiver4Name;
ReceiveId = item.Receiver4;
}
if (timeoutMinutes == 0) continue;
var createdTime = item.CreatedTime.ObjToDate();
var timeoutTime = createdTime.AddMinutes(timeoutMinutes);
var isTimeout = currentTime > timeoutTime;
if (isTimeout)
{
item.AutoCount += 1;
item.UpdatedBy = "admin";
item.UpdatedTime = DateTime.Now;
batchUpdateList.Add(item);
var processRecord = CreateAlarmProcessRecord(item, strOperate);
allProcessRecords.Add(processRecord);
try
{
//手表发送提醒上报领导
if (!string.IsNullOrEmpty(ReceiveId))
{
List<string> WatchAddressList = GetReceiverWatchAddress(ReceiveId);
if (WatchAddressList.Any())
{
foreach (string strWatchAddress in WatchAddressList)
{
Watchup.StartPush(strWatchMessage, _socketGateway, strWatchAddress);
}
}
}
}
catch (Exception ex)
{
}
}
}
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, "自动超时报警处理异常,请查看日志");
}
}
/// <summary>
/// 创建报警处理记录
/// </summary>
/// <param name="alarmItem">报警记录</param>
/// <param name="operateTime">操作时间</param>
/// <returns>处理记录实体</returns>
private AndonAlarmRecordProcess CreateAlarmProcessRecord(AndonAlarmRecord alarmItem,string strOperate)
{
return new AndonAlarmRecordProcess
{
AlarmCode = alarmItem.AlarmCode,
Operate = strOperate,
CreatedBy = "admin",
CreatedName = "admin",
CreatedTime = DateTime.Now,
UpdatedBy = "admin",
UpdatedName = "admin",
UpdatedTime = DateTime.Now,
};
}
/// <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.AutoCount, t.UpdatedBy, t.UpdatedTime })
.ExecuteCommand();
}
public ApiResult InitAlarmLightStates()
{
//var lights = andonAlarmAreaLightDicService.GetList();
//if (lights.Any())
//{
// foreach (var item in lights)
// {
// if (!string.IsNullOrEmpty(item.Lightip))
// {
// byte bLightIp = Convert.ToByte(item.Lightip);
// if (bLightIp != 0)
// {
// LightUp.CheckLightOnStatusAndTurnOn(_modbusClient, bLightIp);
// }
// }
// }
//}
LightUp.CheckLightOnStatusAndTurnOn(_modbusClient, Convert.ToByte(14));
LightUp.CheckLightOnStatusAndTurnOn(_modbusClient, Convert.ToByte(08));
LightUp.CheckLightOnStatusAndTurnOn(_modbusClient, Convert.ToByte(07));
LightUp.CheckLightOnStatusAndTurnOn(_modbusClient, Convert.ToByte(13));
LightUp.CheckLightOnStatusAndTurnOn(_modbusClient, Convert.ToByte(04));
LightUp.CheckLightOnStatusAndTurnOn(_modbusClient, Convert.ToByte(15));
return ApiResult.Success("处理成功");
}
}
}