From 3bdba355018ad9ad212598996d0dc53ad2998657 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Thu, 12 Feb 2026 03:24:58 -0500 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=91=A8=E6=9C=9F=E6=80=A7?= =?UTF-8?q?=E9=82=AE=E4=BB=B6=E9=BB=98=E8=AE=A4Culture,=E5=90=8E=E5=8F=B0?= =?UTF-8?q?=E8=A7=A6=E5=8F=91=E9=82=AE=E4=BB=B6=E6=8A=A5=E9=94=99=E9=80=9A?= =?UTF-8?q?=E7=9F=A5=E4=BC=81=E4=B8=9A=E5=BE=AE=E4=BF=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../HostService/HangfireHostService.cs | 11 ++-- IRaCIS.Core.API/appsettings.Prod_IRC.json | 1 + IRaCIS.Core.API/appsettings.Test_IRC.json | 1 + IRaCIS.Core.API/appsettings.US_Prod_IRC.json | 1 + IRaCIS.Core.API/appsettings.US_Uat_IRC.json | 1 + IRaCIS.Core.API/appsettings.Uat_IRC.json | 1 + .../Helper/HangfireJobHelper.cs | 26 +++++++--- .../Extension/ConsumeExceptionFilter.cs | 51 ++++++++++++++++--- 8 files changed, 75 insertions(+), 18 deletions(-) diff --git a/IRaCIS.Core.API/HostService/HangfireHostService.cs b/IRaCIS.Core.API/HostService/HangfireHostService.cs index c522c2eb4..b811d935e 100644 --- a/IRaCIS.Core.API/HostService/HangfireHostService.cs +++ b/IRaCIS.Core.API/HostService/HangfireHostService.cs @@ -15,12 +15,13 @@ using Hangfire.Storage; using System.Linq; using Microsoft.EntityFrameworkCore; using MassTransit.Mediator; +using Microsoft.Extensions.Configuration; namespace IRaCIS.Core.API.HostService; public class HangfireHostService(IRecurringMessageScheduler _recurringMessageScheduler, IRepository _trialEmailNoticeConfigRepository, - + IConfiguration _config, IRepository _emailNoticeConfigrepository, IMediator _mediator, ILogger _logger) : IHostedService @@ -56,6 +57,8 @@ public class HangfireHostService(IRecurringMessageScheduler _recurringMessageSch } } + string defaultCulture = _config.GetValue("SystemEmailSendConfig:CronEmailDefaultCulture"); + // 项目手动选择,周期性邮件 var taskInfoList = await _trialEmailNoticeConfigRepository.Where(t => t.Trial.TrialStatusStr == StaticData.TrialState.TrialOngoing && t.EmailCron != string.Empty && t.IsAutoSend) .Select(t => new { t.Id, t.Code, TrialCode = t.Trial.TrialCode, t.EmailCron, t.BusinessScenarioEnum, t.TrialId }) @@ -68,11 +71,11 @@ public class HangfireHostService(IRecurringMessageScheduler _recurringMessageSch var trialId = task.TrialId; - HangfireJobHelper.AddOrUpdateTrialCronJob(jobId, trialId, task.BusinessScenarioEnum, task.EmailCron); + HangfireJobHelper.AddOrUpdateTrialCronJob(jobId, trialId, task.BusinessScenarioEnum, task.EmailCron, defaultCulture); } - // 系统邮件定时任务 + // 系统邮件定时任务 要设置默认语言 var systemTaskInfoList = await _emailNoticeConfigrepository.Where(t => t.EmailCron != string.Empty && t.IsAutoSend) .Select(t => new { t.Id, t.Code, t.EmailCron, t.BusinessScenarioEnum, }) .ToListAsync(); @@ -82,7 +85,7 @@ public class HangfireHostService(IRecurringMessageScheduler _recurringMessageSch //利用主键作为任务Id var jobId = $"{task.Id}_({task.BusinessScenarioEnum})"; - HangfireJobHelper.AddOrUpdateTimingCronJob(jobId, task.BusinessScenarioEnum, task.EmailCron); + HangfireJobHelper.AddOrUpdateTimingCronJob(jobId, task.BusinessScenarioEnum, task.EmailCron, defaultCulture); } diff --git a/IRaCIS.Core.API/appsettings.Prod_IRC.json b/IRaCIS.Core.API/appsettings.Prod_IRC.json index 1f48f2e19..76a2fcad4 100644 --- a/IRaCIS.Core.API/appsettings.Prod_IRC.json +++ b/IRaCIS.Core.API/appsettings.Prod_IRC.json @@ -81,6 +81,7 @@ "IsEnv_US": false, "IsOpenErrorNoticeEmail": false, "EmailRegexStr": "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$", + "CronEmailDefaultCulture": "zh-CN", "ErrorNoticeEmailList": [ "872297557@qq.com" ] }, "SystemPacsConfig": { diff --git a/IRaCIS.Core.API/appsettings.Test_IRC.json b/IRaCIS.Core.API/appsettings.Test_IRC.json index a7e6e4bda..41d61542b 100644 --- a/IRaCIS.Core.API/appsettings.Test_IRC.json +++ b/IRaCIS.Core.API/appsettings.Test_IRC.json @@ -162,6 +162,7 @@ "IsOpenErrorNoticeEmail": false, // 邮箱格式校验正则表达式 "EmailRegexStr": "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$", + "CronEmailDefaultCulture": "zh-CN", // 接收系统异常报警的邮箱列表 "ErrorNoticeEmailList": [ "872297557@qq.com" ] }, diff --git a/IRaCIS.Core.API/appsettings.US_Prod_IRC.json b/IRaCIS.Core.API/appsettings.US_Prod_IRC.json index 3e89ee8a8..a2dd4af63 100644 --- a/IRaCIS.Core.API/appsettings.US_Prod_IRC.json +++ b/IRaCIS.Core.API/appsettings.US_Prod_IRC.json @@ -87,6 +87,7 @@ "IsEnv_US": true, "IsOpenErrorNoticeEmail": false, "EmailRegexStr": "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$", + "CronEmailDefaultCulture": "en-US", "ErrorNoticeEmailList": [ "872297557@qq.com" ] }, diff --git a/IRaCIS.Core.API/appsettings.US_Uat_IRC.json b/IRaCIS.Core.API/appsettings.US_Uat_IRC.json index a4da7f8b2..69c063ea0 100644 --- a/IRaCIS.Core.API/appsettings.US_Uat_IRC.json +++ b/IRaCIS.Core.API/appsettings.US_Uat_IRC.json @@ -93,6 +93,7 @@ "IsEnv_US": true, "IsOpenErrorNoticeEmail": false, "EmailRegexStr": "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$", + "CronEmailDefaultCulture": "en-US", "ErrorNoticeEmailList": [ "872297557@qq.com" ] }, diff --git a/IRaCIS.Core.API/appsettings.Uat_IRC.json b/IRaCIS.Core.API/appsettings.Uat_IRC.json index a26e5d6b1..e4030836b 100644 --- a/IRaCIS.Core.API/appsettings.Uat_IRC.json +++ b/IRaCIS.Core.API/appsettings.Uat_IRC.json @@ -100,6 +100,7 @@ "IsEnv_US": false, "IsOpenErrorNoticeEmail": false, "EmailRegexStr": "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$", + "CronEmailDefaultCulture": "zh-CN", "ErrorNoticeEmailList": [ "872297557@qq.com" ] }, diff --git a/IRaCIS.Core.Application/Helper/HangfireJobHelper.cs b/IRaCIS.Core.Application/Helper/HangfireJobHelper.cs index dfd485ecb..110644f91 100644 --- a/IRaCIS.Core.Application/Helper/HangfireJobHelper.cs +++ b/IRaCIS.Core.Application/Helper/HangfireJobHelper.cs @@ -2,6 +2,7 @@ using IRaCIS.Core.Application.MassTransit.Consumer; using IRaCIS.Core.Domain.Share; using MassTransit.Mediator; +using System.Globalization; namespace IRaCIS.Core.Application.Helper { @@ -57,25 +58,29 @@ namespace IRaCIS.Core.Application.Helper } - public static void AddOrUpdateTrialCronJob(string jobId, Guid trialId, EmailBusinessScenario businessScenario, string emailCron) + public static void AddOrUpdateTrialCronJob(string jobId, Guid trialId, EmailBusinessScenario businessScenario, string emailCron,string defaultCulture="") { + if (defaultCulture == "") + { + defaultCulture = CultureInfo.CurrentCulture.Name; + } switch (businessScenario) { case EmailBusinessScenario.QCTask: - HangfireJobHelper.AddOrUpdateCronJob(jobId, t => t.Send(new ImageQCRecurringEvent() { TrialId = trialId }, default), emailCron); + HangfireJobHelper.AddOrUpdateCronJob(jobId, t => t.Send(new ImageQCRecurringEvent() { TrialId = trialId,CultureInfoName= defaultCulture }, default), emailCron); break; case EmailBusinessScenario.CRCToQCQuestion: - HangfireJobHelper.AddOrUpdateCronJob(jobId, t => t.Send(new CRCImageQuestionRecurringEvent() { TrialId = trialId }, default), emailCron); + HangfireJobHelper.AddOrUpdateCronJob(jobId, t => t.Send(new CRCImageQuestionRecurringEvent() { TrialId = trialId, CultureInfoName = defaultCulture }, default), emailCron); break; case EmailBusinessScenario.QCToCRCImageQuestion: - HangfireJobHelper.AddOrUpdateCronJob(jobId, t => t.Send(new QCImageQuestionRecurringEvent() { TrialId = trialId }, default), emailCron); + HangfireJobHelper.AddOrUpdateCronJob(jobId, t => t.Send(new QCImageQuestionRecurringEvent() { TrialId = trialId, CultureInfoName = defaultCulture }, default), emailCron); break; //加急阅片 10分钟 case EmailBusinessScenario.ExpeditedReading: - HangfireJobHelper.AddOrUpdateCronJob(jobId, t => t.Send(new UrgentIRUnReadTaskRecurringEvent() { TrialId = trialId }, default), emailCron); + HangfireJobHelper.AddOrUpdateCronJob(jobId, t => t.Send(new UrgentIRUnReadTaskRecurringEvent() { TrialId = trialId, CultureInfoName = defaultCulture }, default), emailCron); break; default: break; @@ -83,20 +88,25 @@ namespace IRaCIS.Core.Application.Helper } - public static void AddOrUpdateTimingCronJob(string jobId, EmailBusinessScenario businessScenario, string emailCron) + public static void AddOrUpdateTimingCronJob(string jobId, EmailBusinessScenario businessScenario, string emailCron, string defaultCulture="") { + if (defaultCulture == "") + { + defaultCulture = CultureInfo.CurrentCulture.Name; + } + switch (businessScenario) { case EmailBusinessScenario.GeneralTraining_ExpirationNotification: - HangfireJobHelper.AddOrUpdateCronJob(jobId, t => t.Send(new SystemDocumentErverDayEvent() { }, default), emailCron); + HangfireJobHelper.AddOrUpdateCronJob(jobId, t => t.Send(new SystemDocumentErverDayEvent() { CultureInfoName = defaultCulture }, default), emailCron); break; case EmailBusinessScenario.TrialTraining_ExpirationNotification: Console.WriteLine("更新项目到期job"); - HangfireJobHelper.AddOrUpdateCronJob(jobId, t => t.Send(new TrialDocumentErverDayEvent() { }, default), emailCron); + HangfireJobHelper.AddOrUpdateCronJob(jobId, t => t.Send(new TrialDocumentErverDayEvent() { CultureInfoName = defaultCulture }, default), emailCron); break; default: diff --git a/IRaCIS.Core.Application/MassTransit/Extension/ConsumeExceptionFilter.cs b/IRaCIS.Core.Application/MassTransit/Extension/ConsumeExceptionFilter.cs index 8bdf23368..3e94451de 100644 --- a/IRaCIS.Core.Application/MassTransit/Extension/ConsumeExceptionFilter.cs +++ b/IRaCIS.Core.Application/MassTransit/Extension/ConsumeExceptionFilter.cs @@ -1,14 +1,16 @@ -using System; -using System.Globalization; -using System.Threading; -using System.Threading.Tasks; +using IRaCIS.Core.Application.Helper.OtherTool; using IRaCIS.Core.Domain.BaseModel; using IRaCIS.Core.Domain.Share; using MassTransit; +using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Logging; -using NPOI.SS.Formula.Functions; +using Newtonsoft.Json; +using System; +using System.Globalization; +using System.Threading; +using System.Threading.Tasks; -public class ConsumeExceptionFilter(ILogger> _logger) : IFilter> where T : DomainEvent +public class ConsumeExceptionFilter(ILogger> _logger, IConfiguration _config) : IFilter> where T : DomainEvent { public async Task Send(ConsumeContext context, IPipe> next) @@ -23,6 +25,43 @@ public class ConsumeExceptionFilter(ILogger> _logge { var errorInfo = $"Exception: {exception.Message}[{exception.StackTrace}]" + (exception.InnerException != null ? $" InnerException: {exception.InnerException.Message}[{exception.InnerException.StackTrace}]" : ""); _logger.LogError(errorInfo); + + try + { + bool isOpenWeComNotice = _config.GetValue("WeComNoticeConfig:IsOpenWeComNotice"); + + if (isOpenWeComNotice) + { + string webhook = _config["WeComNoticeConfig:WebhookUrl"] ?? string.Empty; + + var uri = new Uri(_config["SystemEmailSendConfig:SiteUrl"]); + var baseUrl = uri.GetLeftPart(UriPartial.Authority); + + var userList = _config.GetSection("WeComNoticeConfig:VueNoticeUserList").Get(); + + + + // 🔔 异步告警(不要阻塞请求) + _ = WeComNotifier.SendAlertAsync( + webhook: webhook, + alert: new WeComAlert + { + Env = baseUrl, + UserName = "MassTransit 自动触发邮件", + Api = "", + Message = $"异常信息:{exception.Message} 堆栈信息:[{exception.StackTrace}", + AtUsers = userList ?? [] + } + ); + + } + + + } + catch (Exception ex) + { + Log.Logger.Error($"模型验证过滤器里发送企业微信出现错误:{ex.Message}"); + } } }