diff --git a/ZR.Admin.WebApi/Controllers/MES/andon/AndonDataAnalysisController .cs b/ZR.Admin.WebApi/Controllers/MES/andon/AndonDataAnalysisController .cs index c78f07d..0d4ad9e 100644 --- a/ZR.Admin.WebApi/Controllers/MES/andon/AndonDataAnalysisController .cs +++ b/ZR.Admin.WebApi/Controllers/MES/andon/AndonDataAnalysisController .cs @@ -2,6 +2,8 @@ using Microsoft.AspNetCore.Mvc; using ZR.Service.MES.andon.IService; using ZR.Model.MES.andon.Dto; +using ZR.Model.Dto; +using ZR.Service.MES.andon; namespace DOAN.WebApi.Controllers.MES.andon { @@ -17,7 +19,19 @@ namespace DOAN.WebApi.Controllers.MES.andon _andonDataAnalysisServcie= andonDataAnalysisServcie; } + /// + /// 查询故障记录表列表 + /// + /// + /// + [HttpPost("list")] + [ActionPermissionFilter(Permission = "andonManagement:andonfaultrecord:list")] + public IActionResult QueryAndonFaultRecord([FromBody] AndonFaultRecordQueryDto parm) + { + var response = _andonDataAnalysisServcie.GetList(parm); + return SUCCESS(response); + } /// /// 获取故障类型 /// diff --git a/ZR.Admin.WebApi/appsettings.Development.json b/ZR.Admin.WebApi/appsettings.Development.json index e179d1d..f9e7d4d 100644 --- a/ZR.Admin.WebApi/appsettings.Development.json +++ b/ZR.Admin.WebApi/appsettings.Development.json @@ -87,19 +87,45 @@ } }, //邮箱配置信息 + //"MailOptions": { + // //发件人名称 + // "FromName": "3143976203", + // //发送人邮箱 + // "FromEmail": "3143976203@qq.com", //eg:xxxx@qq.com + // //发送人邮箱密码 + // "Password": "wwxcrgvbotxxdcfg", + // //协议 + // "Smtp": "smtp.qq.com", + // "Port": 465, + // "Signature": "系统邮件,请勿回复! ", + // "UseSsl": true + //}, "MailOptions": { //发件人名称 - "FromName": "system", + "FromName": "gx.andon@gam.com.cn", //发送人邮箱 - "FromEmail": "", //eg:xxxx@qq.com + "FromEmail": "gx.andon@gam.com.cn ", //eg:xxxx@qq.com //发送人邮箱密码 - "Password": "", + "Password": "chejinggx", //协议 - "Smtp": "smtp.qq.com", - "Port": 587, - "Signature": "系统邮件,请勿回复!", + "Smtp": "smtp.gam.com.cn", + "Port": 25, + "Signature": "上海干巷Andon系统邮件,请勿回复! ", "UseSsl": true }, + //"MailOptions": { + // //发件人名称 + // "FromName": "gx.andon@gam.com.cn", + // //发送人邮箱 + // "FromEmail": "gx.andon@gam.com.cn", //eg:xxxx@qq.com + // //发送人邮箱密码 + // "Password": "chejinggx", + // //协议 + // "Smtp": "mai.gam.com.cn", + // "Port": 25, + // "Signature": "系统邮件,请勿回复! ", + // "UseSsl": false + //}, //redis服务配置 "RedisServer": { "open": 0, //是否启用redis diff --git a/ZR.Admin.WebApi/appsettings.Production.json b/ZR.Admin.WebApi/appsettings.Production.json index 1ff644e..24893ac 100644 --- a/ZR.Admin.WebApi/appsettings.Production.json +++ b/ZR.Admin.WebApi/appsettings.Production.json @@ -89,16 +89,16 @@ //邮箱配置信息 "MailOptions": { //发件人名称 - "FromName": "system", + "FromName": "gx.andon@gam.com.cn", //发送人邮箱 - "FromEmail": "", //eg:xxxx@qq.com + "FromEmail": "gx.andon@gam.com.cn", //eg:xxxx@qq.com //发送人邮箱密码 - "Password": "", + "Password": "chejinggx", //协议 - "Smtp": "smtp.qq.com", - "Port": 587, - "Signature": "系统邮件,请勿回复!", - "UseSsl": true + "Smtp": "mai.gam.com.cn", + "Port": 25, + "Signature": "上海干巷Andon系统邮件,请勿回复! ", + "UseSsl": false }, //redis服务配置 "RedisServer": { diff --git a/ZR.Model/MES/andon/AndonFaultDict.cs b/ZR.Model/MES/andon/AndonFaultDict.cs index 6bc8831..89580d2 100644 --- a/ZR.Model/MES/andon/AndonFaultDict.cs +++ b/ZR.Model/MES/andon/AndonFaultDict.cs @@ -27,6 +27,17 @@ namespace ZR.Model.MES.andon /// public string color { get; set; } + + /// + /// 邮箱 + /// + public string Email { get; set; } + + /// + /// 主管 + /// + public string Director { get; set; } + /// /// 状态 /// diff --git a/ZR.Service/MES/andon/AndonDataAnalysisServcie.cs b/ZR.Service/MES/andon/AndonDataAnalysisServcie.cs index 2149a6e..bc6dfac 100644 --- a/ZR.Service/MES/andon/AndonDataAnalysisServcie.cs +++ b/ZR.Service/MES/andon/AndonDataAnalysisServcie.cs @@ -7,9 +7,12 @@ using System.Linq; using System.Text; using System.Threading.Tasks; using System.Xml.Linq; +using ZR.Model.Dto; +using ZR.Model; using ZR.Model.MES.andon; using ZR.Model.MES.andon.Dto; using ZR.Model.MES.dev; +using ZR.Repository; using ZR.Service.MES.andon.IService; using static System.Runtime.InteropServices.JavaScript.JSType; @@ -18,6 +21,25 @@ namespace ZR.Service.MES.andon [AppService(ServiceType = typeof(IAndonDataAnalysisServcie), ServiceLifetime = LifeTime.Transient)] public class AndonDataAnalysisServcie : BaseService, IAndonDataAnalysisServcie { + /// + /// 查询故障记录表列表 今日全部 和以前未签到异常 + /// + /// + /// + public PagedInfo GetList(AndonFaultRecordQueryDto parm) + { + var predicate = Expressionable.Create() + .AndIF(parm.DateTimeRange.Count() == 2 && parm.DateTimeRange[0] > DateTime.MinValue, it => it.StartTime >= parm.DateTimeRange[0]) + .AndIF(parm.DateTimeRange.Count() == 2 && parm.DateTimeRange[1] > DateTime.MinValue, it => it.StartTime <= parm.DateTimeRange[1]) + .OrIF(parm.DateTimeRange.Count() == 2 , it => it.StartTime < parm.DateTimeRange[0] && it.Status == 1) + ; + + var response = Queryable() + .Where(predicate.ToExpression()) + .ToPage(parm); + + return response; + } /// /// 1.获取安灯报警类型字典 /// diff --git a/ZR.Service/MES/andon/AndonInteractionService.cs b/ZR.Service/MES/andon/AndonInteractionService.cs index f370e63..f9adce9 100644 --- a/ZR.Service/MES/andon/AndonInteractionService.cs +++ b/ZR.Service/MES/andon/AndonInteractionService.cs @@ -1,9 +1,15 @@ using Infrastructure.Attribute; +using Infrastructure.Model; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Options; +using Microsoft.Extensions.Primitives; +using SqlSugar.IOC; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using ZR.Common; using ZR.Model.Dto; using ZR.Model.MES.andon; using ZR.Service.MES.andon.IService; @@ -13,6 +19,10 @@ namespace ZR.Service.MES.andon [AppService(ServiceType = typeof(IAndonInteractionService), ServiceLifetime = LifeTime.Transient)] public class AndonInteractionService : BaseService, IAndonInteractionService { + private NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger(); + private OptionsSetting OptionsSetting; + + public AndonInteractionService(IOptions options) { OptionsSetting = options.Value; } /// /// 呼叫请求 /// @@ -35,19 +45,113 @@ namespace ZR.Service.MES.andon } else { - + } record.Status = 2; return Update(record, true); } - + /// /// 获取待响应的 记录 /// /// public List WaitingResponse() { - return Context.Queryable().Where(it=>it.Status == 1).ToList(); + return Context.Queryable().Where(it => it.Status == 1).ToList(); + } + + + private static List GetFaultDicts() + { + return DbScoped.SugarScope.CopyNew().Queryable().ToList(); + } + /// + /// 监测超时发送邮件 + /// + /// + public string[] MonitoringMails() + { + string[] result =null; + // 获取异常字典 + List andonFaults = GetFaultDicts(); + // 获取超时记录 + DateTime Overtime = DateTime.Now.AddHours(-1); + List AlarmRecord = Context.Queryable().Where(it => it.Status == 1).Where(it => it.StartTime <= Overtime).ToList(); + + if (AlarmRecord.Count > 0 && andonFaults.Count > 0) + { + result = new string[AlarmRecord.Count]; + foreach (var alarm in AlarmRecord) + { + + foreach (var fault in andonFaults) + { + + if (alarm.FaultDict == fault.Name) + { + double overSpan =Math.Round((DateTime.Now - alarm.StartTime.Value).TotalHours,2) ; + SendEmailDto sendEmailVo = new SendEmailDto(); + sendEmailVo.Subject = "上海干巷总装车间 Andon [报警升级]通知"; + // 邮箱责任 + sendEmailVo.ToUser=fault.Email?? "qianhao.xu@doan-tech.com"; + StringBuilder msg=new StringBuilder(); + msg.Append($"Dear [{fault.Director}]经理:"); + msg.Append("\n"); + msg.Append("\n"); + msg.Append($"[{alarm.LineCode}]产线发生[{alarm.FaultDict}]类型异常, [{alarm.AskPerson}]报警人 在{alarm.StartTime.Value.ToString("yyyy-MM-dd HH:mm:ss")}时间发起报警,已经超过{overSpan}小时未处理,请立刻到现场扫码签到并处理异常,报警内容如下:\n"); + msg.Append("\n"); + msg.Append($"{alarm.FaultContext??"[无报警内容]"}。"); + msg.Append("\n"); + msg.Append("\n"); + msg.Append("\n"); + msg.Append($"Andon系统将每10分钟发送一次邮件,直至[{alarm.FaultDict}]类型异常,被签到并处理!"); + msg.Append("\n"); + msg.Append("\n"); + msg.Append("\n"); + msg.Append("如果邮件中有任务不清楚的地方或者需要我们提供任何帮助,请联系苏州道安自动化有限公司IT部门,邮件地址为qianhao.xu@doan-tech.com"); + + sendEmailVo.Content = msg.ToString(); + sendEmailVo.SendMe = true; + sendEmailVo.AddTime = DateTime.Now; + result[AlarmRecord.IndexOf(alarm)] = SendEmail(sendEmailVo); + continue; + } + } + + } + + } + return result; + + } + /// + /// 发送邮件任务 + /// + /// + /// + private string SendEmail(SendEmailDto sendEmailVo) + { + if (sendEmailVo == null) + { + return "请求参数不完整"; + } + if (string.IsNullOrEmpty(OptionsSetting.MailOptions.FromEmail) || string.IsNullOrEmpty(OptionsSetting.MailOptions.Password)) + { + return "请配置邮箱信息"; + } + + MailHelper mailHelper = new(); + + string[] toUsers = sendEmailVo.ToUser.Split(",", StringSplitOptions.RemoveEmptyEntries); + if (sendEmailVo.SendMe) + { + toUsers.Append(mailHelper.FromEmail); + } + string result = mailHelper.SendMail(toUsers, sendEmailVo.Subject, sendEmailVo.Content, sendEmailVo.FileUrl, sendEmailVo.HtmlContent); + + logger.Info($"发送邮件{JsonConvert.SerializeObject(sendEmailVo)}, 结果{result}"); + + return result; } } } diff --git a/ZR.Service/MES/andon/IService/IAndonDataAnalysisServcie.cs b/ZR.Service/MES/andon/IService/IAndonDataAnalysisServcie.cs index b3ad79a..7862c58 100644 --- a/ZR.Service/MES/andon/IService/IAndonDataAnalysisServcie.cs +++ b/ZR.Service/MES/andon/IService/IAndonDataAnalysisServcie.cs @@ -4,6 +4,8 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using ZR.Model.Dto; +using ZR.Model; using ZR.Model.MES.andon; using ZR.Model.MES.andon.Dto; @@ -11,6 +13,7 @@ namespace ZR.Service.MES.andon.IService { public interface IAndonDataAnalysisServcie { + PagedInfo GetList(AndonFaultRecordQueryDto parm); List GetListFault(); List AbnormalDurationRatio(AndonAnalysisQueryDto query); List AbnormalNumDurationRatio(AndonAnalysisQueryDto query); diff --git a/ZR.Service/MES/andon/IService/IAndonInteractionService.cs b/ZR.Service/MES/andon/IService/IAndonInteractionService.cs index 330902b..2a31497 100644 --- a/ZR.Service/MES/andon/IService/IAndonInteractionService.cs +++ b/ZR.Service/MES/andon/IService/IAndonInteractionService.cs @@ -15,5 +15,10 @@ namespace ZR.Service.MES.andon.IService int CallHandle(AndonFaultRecord query); int SignIn(AndonFaultRecord response); List WaitingResponse(); + /// + /// 监测超时发送邮件 + /// + /// + string[] MonitoringMails(); } } diff --git a/ZR.Tasks/TaskScheduler/Job_Email_send.cs b/ZR.Tasks/TaskScheduler/Job_Email_send.cs new file mode 100644 index 0000000..df9b026 --- /dev/null +++ b/ZR.Tasks/TaskScheduler/Job_Email_send.cs @@ -0,0 +1,64 @@ +using Infrastructure; +using Infrastructure.Attribute; +using Quartz; +using Quartz.Impl.Triggers; +using Quartz.Impl; +using SqlSugar.IOC; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using ZR.Model.MES.dev; +using ZR.Model.System; +using ZR.Service.MES.andon.IService; + +namespace ZR.Tasks.TaskScheduler +{ + /// + /// 超过一个小时就发送邮箱 + /// + [AppService(ServiceType = typeof(Job_Email_send), ServiceLifetime = LifeTime.Scoped)] + public class Job_Email_send : JobBase, IJob + { + private readonly NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger(); + private readonly IAndonInteractionService _andonInteractionService; + public Job_Email_send(IAndonInteractionService andonInteractionService) + { + _andonInteractionService= andonInteractionService; + } + public async Task Execute(IJobExecutionContext context) + { + await ExecuteJob(context, async () => await Run(context)); + } + public async Task Run(IJobExecutionContext context) + { + AbstractTrigger trigger = (context as JobExecutionContextImpl).Trigger as AbstractTrigger; + //var info = await tasksQzService.CopyNew().GetByIdAsync(trigger.JobName); + var info = await DbScoped.SugarScope.CopyNew().Queryable().FirstAsync(f => f.ID == trigger.JobName); + if (info == null) + { + throw new CustomException($"任务{trigger?.JobName}_邮件发送定时调度请求执行失败,任务不存在"); + } + + string[] result = _andonInteractionService.MonitoringMails(); + if (result.Length > 0) + { + foreach (string s in result) + { + logger.Info($"任务【{info.Name}】_邮件发送定时调度请求执行结果={s}\n"); + } + + + } + else + { + logger.Info($"任务【{info.Name}】_邮件发送定时调度请求执行结果 没有数据\n"); + } + + + } + + } + +}