552 lines
24 KiB
C#
552 lines
24 KiB
C#
using Aliyun.OSS;
|
||
using DOAN.ServiceCore.MyMatchPush;
|
||
using Infrastructure;
|
||
using Infrastructure.Attribute;
|
||
using Infrastructure.Model;
|
||
using JinianNet.JNTemplate.Parsers;
|
||
using SqlSugar;
|
||
using SqlSugar.Extensions;
|
||
using System;
|
||
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;
|
||
|
||
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;
|
||
|
||
public AndonAlarmRecordService(SocketGatewayServer socketGateway)
|
||
{
|
||
_socketGateway = socketGateway;
|
||
}
|
||
/// <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);
|
||
}
|
||
}
|
||
var response = Queryable()
|
||
.Where(predicate.ToExpression())
|
||
.ToPage<AndonAlarmRecord, AndonAlarmRecordDto>(parm);
|
||
|
||
return response;
|
||
}
|
||
|
||
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)
|
||
// {
|
||
// if (record.AlarmLevel != null && record.AlarmLevel.Length > 0)
|
||
// {
|
||
// int minute = 0;
|
||
// var levelInfo = andonAlarmLevelService.Queryable()
|
||
// .Where(x => x.LevelName == record.AlarmLevel).First();
|
||
// if (levelInfo != null && levelInfo.HandleTimeout != null)
|
||
// {
|
||
// minute = (int)levelInfo.HandleTimeout;
|
||
// }
|
||
// // 提前计算超时时间,提高可读性
|
||
// var createdTime = record.CreatedTime.ObjToDate();
|
||
// var timeoutTime = createdTime.AddMinutes(minute);
|
||
// var isTimeout = DateTime.Now > timeoutTime;
|
||
// record.Status = isTimeout ? "超时响应" : "及时响应";
|
||
// }
|
||
// else
|
||
// {
|
||
// 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
|
||
// {
|
||
// response.Code = 500;
|
||
// response.Msg = "参数不能为空";
|
||
// }
|
||
// return response;
|
||
//}
|
||
//catch (Exception ex)
|
||
//{
|
||
// return ApiResult.Error(500, ex.Message);
|
||
//}
|
||
|
||
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);
|
||
return ApiResult.Success("成功", andonAlarmRecordProcess);
|
||
}
|
||
}
|
||
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();
|
||
//if(parm.Status == "及时响应")
|
||
//{
|
||
// record.Status = "及时处理";
|
||
//}
|
||
//else
|
||
//{
|
||
// record.Status = "超时处理";
|
||
//}
|
||
record.Status = "已处理";
|
||
record.HandleResult = parm.HandleResult;
|
||
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);
|
||
}
|
||
}
|
||
|
||
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);
|
||
|
||
//报警给领导
|
||
//Watchup.StartPush("123456789", _socketGateway);
|
||
return ApiResult.Success("成功", andonAlarmRecordProcess);
|
||
}
|
||
else
|
||
{
|
||
return ApiResult.Error(500, "只能处理响应状态数据");
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
return ApiResult.Error(500, ex.Message);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 创建报警记录
|
||
/// </summary>
|
||
/// <param name="model"></param>
|
||
/// <returns></returns>
|
||
public AndonAlarmRecord CreateAndonAlarmRecord(AndonAlarmRecord model)
|
||
{
|
||
string strDay = DateTime.Now.ToString("yyyyMMdd");
|
||
int Sequence = 1;
|
||
AndonAlarmRecord item = Queryable()
|
||
.Where(it => it.AlarmCode.Contains(strDay)).OrderByDescending(it => it.Sequence).First();
|
||
if (item != null)
|
||
{
|
||
Sequence = (int)item.Sequence;
|
||
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();
|
||
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;
|
||
//Watchup.StartPush(strMessage, _socketGateway);
|
||
Watchup.StartPush("000234", _socketGateway);
|
||
return Context.Insertable(model).ExecuteReturnEntity();
|
||
}
|
||
|
||
/// <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;
|
||
//超时未响应,接收人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 (isTimeout)
|
||
{
|
||
|
||
item.AutoCount += 1;
|
||
item.UpdatedBy = "admin";
|
||
item.UpdatedTime = DateTime.Now;
|
||
batchUpdateList.Add(item);
|
||
|
||
var processRecord = CreateAlarmProcessRecord(item, strOperate);
|
||
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>
|
||
/// <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();
|
||
}
|
||
#endregion
|
||
}
|
||
} |