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 1/4] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=91=A8=E6=9C=9F?= =?UTF-8?q?=E6=80=A7=E9=82=AE=E4=BB=B6=E9=BB=98=E8=AE=A4Culture,=E5=90=8E?= =?UTF-8?q?=E5=8F=B0=E8=A7=A6=E5=8F=91=E9=82=AE=E4=BB=B6=E6=8A=A5=E9=94=99?= =?UTF-8?q?=E9=80=9A=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}"); + } } } From ea43698ee9ff88803fe1e8df101685b7c50beb58 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Thu, 12 Feb 2026 03:32:26 -0500 Subject: [PATCH 2/4] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E9=80=9A=E7=9F=A5?= =?UTF-8?q?=E5=88=97=E8=A1=A8=E4=BA=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.API/appsettings.json | 4 ++-- .../MassTransit/Extension/ConsumeExceptionFilter.cs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/IRaCIS.Core.API/appsettings.json b/IRaCIS.Core.API/appsettings.json index a39b1b988..08102fb62 100644 --- a/IRaCIS.Core.API/appsettings.json +++ b/IRaCIS.Core.API/appsettings.json @@ -46,8 +46,8 @@ "WeComNoticeConfig": { "IsOpenWeComNotice": true, "WebhookUrl": "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=4355b98e-1e72-4678-8dfb-2fc6ad0bf449", //4355b98e-1e72-4678-8dfb-2fc6ad0bf449 //cdd97aab-d256-4f07-9145-a0a2b1555322 - "APINoticeUserList": [ "ZhouHang" ], - "VueNoticeUserList": [ "wangxiaoshuang" ] + "APINoticeUserList": [ "u","wait..." ], + "VueNoticeUserList": [ "wangxiaoshuang", "6b7717a31647293621697b96f74e6f3d" ] }, "IRaCISImageStore": { "SwitchingMode": "RemainingDiskCapacity", diff --git a/IRaCIS.Core.Application/MassTransit/Extension/ConsumeExceptionFilter.cs b/IRaCIS.Core.Application/MassTransit/Extension/ConsumeExceptionFilter.cs index 3e94451de..95466a916 100644 --- a/IRaCIS.Core.Application/MassTransit/Extension/ConsumeExceptionFilter.cs +++ b/IRaCIS.Core.Application/MassTransit/Extension/ConsumeExceptionFilter.cs @@ -37,7 +37,7 @@ public class ConsumeExceptionFilter(ILogger> _logge var uri = new Uri(_config["SystemEmailSendConfig:SiteUrl"]); var baseUrl = uri.GetLeftPart(UriPartial.Authority); - var userList = _config.GetSection("WeComNoticeConfig:VueNoticeUserList").Get(); + var userList = _config.GetSection("WeComNoticeConfig:APINoticeUserList").Get(); @@ -60,7 +60,7 @@ public class ConsumeExceptionFilter(ILogger> _logge } catch (Exception ex) { - Log.Logger.Error($"模型验证过滤器里发送企业微信出现错误:{ex.Message}"); + Log.Logger.Error($"MassTransit里发送企业微信出现错误:{ex.Message}"); } } } From 010367d018bb31bc1f5e6351672a7286589f66b4 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Thu, 12 Feb 2026 03:57:42 -0500 Subject: [PATCH 3/4] =?UTF-8?q?=E5=AF=BC=E8=A1=A8=E6=A8=A1=E6=9D=BF?= =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../IRaCIS.Core.Application.xml | 546 +++++++++--------- .../Common/{ => Export}/ExcelExportService.cs | 0 .../Service/Visit/VisitPlanService.cs | 20 +- .../_IRaCIS/_Config/_StaticData.cs | 5 + 4 files changed, 290 insertions(+), 281 deletions(-) rename IRaCIS.Core.Application/Service/Common/{ => Export}/ExcelExportService.cs (100%) diff --git a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml index 74d1b453b..61c1555c2 100644 --- a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml +++ b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml @@ -674,6 +674,276 @@ + + + 方案编号 STUDYID + + + + + 域 DOMAIN TU TR RS + + + + + 取值类型 TUSPID TRSPID RSSPID + + + + + 受试者编号 USUBJID 实际展示TrialSiteSubjectCode + + + + + 供应商 TUNAM (Extensive Imaging) + + + + + 阅片人 TUEVAL TREVAL RSEVAL + + + + + 阅片人标识 TUEVALID TREVALID RSEVALID + + + + + 访视编号 VISITNUM + + + + + 访视名称 VISIT + + + + + 拍片日期 TUDTC TRDTC RSDTC + + + + + eCRF标识 TUREFID TRREFID RSREFID + + + + + RSCAT 阅片标准 + + + + + RSACPTFL 裁定标记 TUACPTFL + + + + + 序号 TUSEQ (同一个访视,所有阅片人选择病灶给个顺序号) + + + + + 链接ID TULNKID (阅片人角色_病灶编号)不同访视可以重复 + + + + + 肿瘤识别简称 TUTESTCD + + + + + 肿瘤识别全称 TUTEST + + + + + 肿瘤鉴定结果 TUORRES + + + + + 肿瘤识别结果类型 TUSTRESC + + + + + 部位 TULOC (对应病灶表的部位,需要国际化) + + + + + 鉴定方法 TUMETHOD (Modality?) + + + + + 部位描述 LOCTEXT + + + + + 每个subject 按照顺序编号 TRSEQ + + + + + TRGRPID 组ID 对应TU表肿瘤鉴定结果 TumorIdentificationResult + + + + + TRLNKID 链接ID 对应TU表的链接ID TumorNo(阅片人角色_病灶编号) + + + + + TRLNKGRP 链接组 ARM-任务名(访视名) 对应RS的链接组 + + + + + 肿瘤评估简称 TRTESTCD + + + + + 肿瘤评估全称 TRTEST + + + + + 原始测量 TRORRES + + + + + 原始单位 TRORRESU + + + + + 标准结果(字符) TRSTRESC + + + + + 标准结果(数值) TRORRESU + + + + + 标准单位 TRSTRESU + + + + + 完成状态 TRSTAT + + + + + 完成状态 TRMETHOD + + + + + 无法测量原因 TRREASND + + + + + RSSEQ 按照subject 的数据顺序编号 + + + + + RSLNKGRP 链接组 ARM_任务名(访视名) + + + + + RSTESTCD 疗效评估简称 + + + + + RSTEST 疗效评估全称 + + + + + RSORRES 响应评估原始结果 + + + + + RSSTRESC 标准疗效评估 + + + + + RSSTAT 完成状态 + + + + + RSREASND 无法评估原因 + + + + + REASASM 评估原因 + + + + + REASOVR 重新评估原因 + + + + + REASUPD 更新评估原因 + + + + + 关联域 RS:(访视点备注) 空:裁判选择原因 + + + + + COSEQ 序号 + + + + + IDVAR 标识变量 RSSEQ 空:裁判选择原因 + + + + + 标识 IDVARVAL RSSEQ具体的值 空:裁判选择原因 + + + + + COREF 备注引用 + + + + + 备注 COVAL + + + + + 裁决日期 CODTC + + 质控问题答案导出 @@ -989,276 +1259,6 @@ - - - 方案编号 STUDYID - - - - - 域 DOMAIN TU TR RS - - - - - 取值类型 TUSPID TRSPID RSSPID - - - - - 受试者编号 USUBJID 实际展示TrialSiteSubjectCode - - - - - 供应商 TUNAM (Extensive Imaging) - - - - - 阅片人 TUEVAL TREVAL RSEVAL - - - - - 阅片人标识 TUEVALID TREVALID RSEVALID - - - - - 访视编号 VISITNUM - - - - - 访视名称 VISIT - - - - - 拍片日期 TUDTC TRDTC RSDTC - - - - - eCRF标识 TUREFID TRREFID RSREFID - - - - - RSCAT 阅片标准 - - - - - RSACPTFL 裁定标记 TUACPTFL - - - - - 序号 TUSEQ (同一个访视,所有阅片人选择病灶给个顺序号) - - - - - 链接ID TULNKID (阅片人角色_病灶编号)不同访视可以重复 - - - - - 肿瘤识别简称 TUTESTCD - - - - - 肿瘤识别全称 TUTEST - - - - - 肿瘤鉴定结果 TUORRES - - - - - 肿瘤识别结果类型 TUSTRESC - - - - - 部位 TULOC (对应病灶表的部位,需要国际化) - - - - - 鉴定方法 TUMETHOD (Modality?) - - - - - 部位描述 LOCTEXT - - - - - 每个subject 按照顺序编号 TRSEQ - - - - - TRGRPID 组ID 对应TU表肿瘤鉴定结果 TumorIdentificationResult - - - - - TRLNKID 链接ID 对应TU表的链接ID TumorNo(阅片人角色_病灶编号) - - - - - TRLNKGRP 链接组 ARM-任务名(访视名) 对应RS的链接组 - - - - - 肿瘤评估简称 TRTESTCD - - - - - 肿瘤评估全称 TRTEST - - - - - 原始测量 TRORRES - - - - - 原始单位 TRORRESU - - - - - 标准结果(字符) TRSTRESC - - - - - 标准结果(数值) TRORRESU - - - - - 标准单位 TRSTRESU - - - - - 完成状态 TRSTAT - - - - - 完成状态 TRMETHOD - - - - - 无法测量原因 TRREASND - - - - - RSSEQ 按照subject 的数据顺序编号 - - - - - RSLNKGRP 链接组 ARM_任务名(访视名) - - - - - RSTESTCD 疗效评估简称 - - - - - RSTEST 疗效评估全称 - - - - - RSORRES 响应评估原始结果 - - - - - RSSTRESC 标准疗效评估 - - - - - RSSTAT 完成状态 - - - - - RSREASND 无法评估原因 - - - - - REASASM 评估原因 - - - - - REASOVR 重新评估原因 - - - - - REASUPD 更新评估原因 - - - - - 关联域 RS:(访视点备注) 空:裁判选择原因 - - - - - COSEQ 序号 - - - - - IDVAR 标识变量 RSSEQ 空:裁判选择原因 - - - - - 标识 IDVARVAL RSSEQ具体的值 空:裁判选择原因 - - - - - COREF 备注引用 - - - - - 备注 COVAL - - - - - 裁决日期 CODTC - - 公共影像导表基类(IVUS / OCT 通用) @@ -16790,17 +16790,17 @@ - ���� + 质疑 - һ���Ժ˲� + 一致性核查 - ���� + 复制 diff --git a/IRaCIS.Core.Application/Service/Common/ExcelExportService.cs b/IRaCIS.Core.Application/Service/Common/Export/ExcelExportService.cs similarity index 100% rename from IRaCIS.Core.Application/Service/Common/ExcelExportService.cs rename to IRaCIS.Core.Application/Service/Common/Export/ExcelExportService.cs diff --git a/IRaCIS.Core.Application/Service/Visit/VisitPlanService.cs b/IRaCIS.Core.Application/Service/Visit/VisitPlanService.cs index 8b9c69687..3222e390f 100644 --- a/IRaCIS.Core.Application/Service/Visit/VisitPlanService.cs +++ b/IRaCIS.Core.Application/Service/Visit/VisitPlanService.cs @@ -1,11 +1,16 @@ using DocumentFormat.OpenXml.Office2010.ExcelAc; using IRaCIS.Application.Contracts; using IRaCIS.Application.Interfaces; +using IRaCIS.Core.API._ServiceExtensions.NewtonsoftJson; using IRaCIS.Core.Application.Filter; +using IRaCIS.Core.Application.ViewModel; using IRaCIS.Core.Domain.Share; using IRaCIS.Core.Infrastructure; +using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Hosting; using MiniExcelLibs; +using System.ComponentModel.Design; namespace IRaCIS.Core.Application.Service { @@ -485,22 +490,21 @@ namespace IRaCIS.Core.Application.Service } [HttpGet("{visitPlanInfluenceStatId:guid}")] - public async Task DownloadInflunceStudyList(Guid visitPlanInfluenceStatId) + public async Task DownloadInflunceStudyList(Guid visitPlanInfluenceStatId, + [FromServices] IRepository _commonDocumentRepository, [FromServices] IWebHostEnvironment _hostEnvironment, [FromServices] IRaCIS.Application.Interfaces.IDictionaryService _dictionaryService) { var list = _influnceRepository.Where(t => t.VisitPlanInfluenceStatId == visitPlanInfluenceStatId) .ProjectTo(_mapper.ConfigurationProvider).ToList(); - var memoryStream = new MemoryStream(); - memoryStream.SaveAs(list); - memoryStream.Seek(0, SeekOrigin.Begin); - return new FileStreamResult(memoryStream, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet") - { - FileDownloadName = _localizer["VisitPlan_CheckExport", DateTime.Now.ToString("yyyy-MM-dd:hh:mm:ss")] - }; + var exportInfo = new ExcelExportInfo(); + exportInfo.List = ExportExcelConverterDate.ConvertToClientTimeInObject(list, _userInfo.TimeZoneId); + exportInfo.CurrentTime = ExportExcelConverterDate.DateTimeInternationalToString(DateTime.Now, _userInfo.TimeZoneId); + return await ExcelExportHelper.DataExportAsync(StaticData.Export.TrialVisit_InfluenceStudys_Export, exportInfo, exportInfo.TrialCode, _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(VisitPlanInfluenceSubjectVisitDTO)); + } diff --git a/IRaCIS.Core.Infrastructure/_IRaCIS/_Config/_StaticData.cs b/IRaCIS.Core.Infrastructure/_IRaCIS/_Config/_StaticData.cs index c1f6aa1b4..8e331a5a7 100644 --- a/IRaCIS.Core.Infrastructure/_IRaCIS/_Config/_StaticData.cs +++ b/IRaCIS.Core.Infrastructure/_IRaCIS/_Config/_StaticData.cs @@ -316,6 +316,11 @@ public static class StaticData public const string OCT_CDISC_Export = "OCT_CDISC_Export"; + public const string TrialVisit_InfluenceStudys_Export = "TrialVisit_InfluenceStudys_Export"; + + + + } From bbcab237d41f038e105787746945ff635f5b1478 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Thu, 12 Feb 2026 22:36:36 +0800 Subject: [PATCH 4/4] =?UTF-8?q?=E5=91=A8=E6=9C=9F=E6=80=A7=E4=BB=BB?= =?UTF-8?q?=E5=8A=A1=E4=BA=8B=E4=BB=B6=E6=A0=B9=E6=8D=AE=E7=8E=AF=E5=A2=83?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=EF=BC=8C=E5=A2=9E=E5=8A=A0=E9=BB=98=E8=AE=A4?= =?UTF-8?q?=E8=AF=AD=E8=A8=80=EF=BC=8C=E6=96=B9=E4=BE=BF=E8=A7=A6=E5=8F=91?= =?UTF-8?q?=E7=9A=84=E6=97=B6=E5=80=99=EF=BC=8C=E5=90=8E=E5=8F=B0=E7=9F=A5?= =?UTF-8?q?=E9=81=93=E4=BB=A5=E4=BB=80=E4=B9=88=E8=AF=AD=E8=A8=80=E5=8F=91?= =?UTF-8?q?=E9=80=81=E9=82=AE=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.API/Progranm.cs | 5 +++++ IRaCIS.Core.API/appsettings.Prod_IRC.json | 6 ++++++ IRaCIS.Core.API/appsettings.Test_IRC.json | 6 ++++++ IRaCIS.Core.API/appsettings.US_Prod_IRC.json | 7 ++++++- IRaCIS.Core.API/appsettings.US_Uat_IRC.json | 6 ++++++ IRaCIS.Core.API/appsettings.Uat_IRC.json | 6 ++++++ IRaCIS.Core.API/appsettings.json | 6 ------ .../Helper/OtherTool/WeComNotifier.cs | 4 ++-- .../Extension/ConsumeExceptionFilter.cs | 3 ++- .../Recurring/IRRecurringConsumer.cs | 7 ++++++- .../Recurring/QCRecurringEmailConsumer.cs | 20 ++++++++++++++++--- .../Recurring/SystemDocumentConsumer.cs | 13 ++++++++++-- .../Recurring/TrialDocumentConsumer.cs | 12 +++++++++-- 13 files changed, 83 insertions(+), 18 deletions(-) diff --git a/IRaCIS.Core.API/Progranm.cs b/IRaCIS.Core.API/Progranm.cs index a3b23aa44..e45bd4215 100644 --- a/IRaCIS.Core.API/Progranm.cs +++ b/IRaCIS.Core.API/Progranm.cs @@ -22,6 +22,7 @@ using Newtonsoft.Json; using Serilog; using System; using System.Collections.Generic; +using System.Globalization; using System.IO; using System.Reflection; using System.Runtime.InteropServices; @@ -29,6 +30,10 @@ using System.Runtime.InteropServices; AppContext.SetSwitch("Npgsql.EnableLegacyTimestampBehavior", true); AppContext.SetSwitch("Npgsql.DisableDateTimeInfinityConversions", true); + +Console.WriteLine("Startup Culture: " + CultureInfo.CurrentCulture.Name); +Console.WriteLine("Startup UI Culture: " + CultureInfo.CurrentUICulture.Name); + #region 获取环境变量 //以配置文件为准,否则 从url中取环境值(服务以命令行传递参数启动,配置文件配置了就不需要传递环境参数) var config = new ConfigurationBuilder() diff --git a/IRaCIS.Core.API/appsettings.Prod_IRC.json b/IRaCIS.Core.API/appsettings.Prod_IRC.json index 76a2fcad4..2baac3bf2 100644 --- a/IRaCIS.Core.API/appsettings.Prod_IRC.json +++ b/IRaCIS.Core.API/appsettings.Prod_IRC.json @@ -12,6 +12,12 @@ //"RemoteNew": "Server=prod_mssql_standard,1433;Database=Prod_IRC;User ID=sa;Password=zhanying@2021;TrustServerCertificate=true", //"Hangfire": "Server=prod_mssql_standard,1433;Database=Prod_IRC_Hangfire;User ID=sa;Password=zhanying@2021;TrustServerCertificate=true" }, + "WeComNoticeConfig": { + "IsOpenWeComNotice": true, + "WebhookUrl": "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=4355b98e-1e72-4678-8dfb-2fc6ad0bf449", //4355b98e-1e72-4678-8dfb-2fc6ad0bf449 //cdd97aab-d256-4f07-9145-a0a2b1555322 + "APINoticeUserList": [ "u", "wait..." ], + "VueNoticeUserList": [ "wangxiaoshuang", "6b7717a31647293621697b96f74e6f3d" ] + }, "ObjectStoreService": { "ObjectStoreUse": "AliyunOSS", "AliyunOSS": { diff --git a/IRaCIS.Core.API/appsettings.Test_IRC.json b/IRaCIS.Core.API/appsettings.Test_IRC.json index 41d61542b..d4cce6913 100644 --- a/IRaCIS.Core.API/appsettings.Test_IRC.json +++ b/IRaCIS.Core.API/appsettings.Test_IRC.json @@ -18,6 +18,12 @@ // Hangfire 定时任务数据库链接字符串 "Hangfire": "Server=106.14.89.110,1435;Database=Test_IRC_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true" }, + "WeComNoticeConfig": { + "IsOpenWeComNotice": true, + "WebhookUrl": "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=4355b98e-1e72-4678-8dfb-2fc6ad0bf449", //4355b98e-1e72-4678-8dfb-2fc6ad0bf449 //cdd97aab-d256-4f07-9145-a0a2b1555322 + "APINoticeUserList": [ "u", "wait..." ], + "VueNoticeUserList": [ "wangxiaoshuang", "6b7717a31647293621697b96f74e6f3d" ] + }, // 对象存储服务配置 "ObjectStoreService": { // 使用的对象存储服务类型 diff --git a/IRaCIS.Core.API/appsettings.US_Prod_IRC.json b/IRaCIS.Core.API/appsettings.US_Prod_IRC.json index a2dd4af63..fcc011556 100644 --- a/IRaCIS.Core.API/appsettings.US_Prod_IRC.json +++ b/IRaCIS.Core.API/appsettings.US_Prod_IRC.json @@ -12,7 +12,12 @@ //"RemoteNew": "Server=44.210.231.169,1435;Database=US_IRC;User ID=sa;Password=xc@123456;TrustServerCertificate=true", //"Hangfire": "Server=44.210.231.169,1435;Database=US_IRC_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true", }, - + "WeComNoticeConfig": { + "IsOpenWeComNotice": true, + "WebhookUrl": "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=4355b98e-1e72-4678-8dfb-2fc6ad0bf449", //4355b98e-1e72-4678-8dfb-2fc6ad0bf449 //cdd97aab-d256-4f07-9145-a0a2b1555322 + "APINoticeUserList": [ "u", "wait..." ], + "VueNoticeUserList": [ "wangxiaoshuang", "6b7717a31647293621697b96f74e6f3d" ] + }, "ObjectStoreService": { "ObjectStoreUse": "AWS", "MinIO": { diff --git a/IRaCIS.Core.API/appsettings.US_Uat_IRC.json b/IRaCIS.Core.API/appsettings.US_Uat_IRC.json index 69c063ea0..2300abca3 100644 --- a/IRaCIS.Core.API/appsettings.US_Uat_IRC.json +++ b/IRaCIS.Core.API/appsettings.US_Uat_IRC.json @@ -13,6 +13,12 @@ "RemoteNew": "Server=3.226.182.187,1435;Database=US_Uat_IRC;User ID=sa;Password=xc@123456;TrustServerCertificate=true", "Hangfire": "Server=3.226.182.187,1435;Database=US_Uat_IRC_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true" }, + "WeComNoticeConfig": { + "IsOpenWeComNotice": true, + "WebhookUrl": "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=4355b98e-1e72-4678-8dfb-2fc6ad0bf449", //4355b98e-1e72-4678-8dfb-2fc6ad0bf449 //cdd97aab-d256-4f07-9145-a0a2b1555322 + "APINoticeUserList": [ "u", "wait..." ], + "VueNoticeUserList": [ "wangxiaoshuang", "6b7717a31647293621697b96f74e6f3d" ] + }, "ObjectStoreService": { diff --git a/IRaCIS.Core.API/appsettings.Uat_IRC.json b/IRaCIS.Core.API/appsettings.Uat_IRC.json index e4030836b..06099ad7a 100644 --- a/IRaCIS.Core.API/appsettings.Uat_IRC.json +++ b/IRaCIS.Core.API/appsettings.Uat_IRC.json @@ -10,6 +10,12 @@ "RemoteNew": "Server=101.132.253.119,1435;Database=Uat_IRC;User ID=sa;Password=xc@123456;TrustServerCertificate=true", "Hangfire": "Server=101.132.253.119,1435;Database=Uat_IRC_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true" }, + "WeComNoticeConfig": { + "IsOpenWeComNotice": true, + "WebhookUrl": "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=4355b98e-1e72-4678-8dfb-2fc6ad0bf449", //4355b98e-1e72-4678-8dfb-2fc6ad0bf449 //cdd97aab-d256-4f07-9145-a0a2b1555322 + "APINoticeUserList": [ "u", "wait..." ], + "VueNoticeUserList": [ "wangxiaoshuang", "6b7717a31647293621697b96f74e6f3d" ] + }, "ObjectStoreService": { "ObjectStoreUse": "AliyunOSS", diff --git a/IRaCIS.Core.API/appsettings.json b/IRaCIS.Core.API/appsettings.json index 08102fb62..4889af5de 100644 --- a/IRaCIS.Core.API/appsettings.json +++ b/IRaCIS.Core.API/appsettings.json @@ -43,12 +43,6 @@ } ] }, - "WeComNoticeConfig": { - "IsOpenWeComNotice": true, - "WebhookUrl": "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=4355b98e-1e72-4678-8dfb-2fc6ad0bf449", //4355b98e-1e72-4678-8dfb-2fc6ad0bf449 //cdd97aab-d256-4f07-9145-a0a2b1555322 - "APINoticeUserList": [ "u","wait..." ], - "VueNoticeUserList": [ "wangxiaoshuang", "6b7717a31647293621697b96f74e6f3d" ] - }, "IRaCISImageStore": { "SwitchingMode": "RemainingDiskCapacity", "SwitchingRatio": 80, diff --git a/IRaCIS.Core.Application/Helper/OtherTool/WeComNotifier.cs b/IRaCIS.Core.Application/Helper/OtherTool/WeComNotifier.cs index db100aa68..7af0b625c 100644 --- a/IRaCIS.Core.Application/Helper/OtherTool/WeComNotifier.cs +++ b/IRaCIS.Core.Application/Helper/OtherTool/WeComNotifier.cs @@ -48,8 +48,8 @@ public static class WeComNotifier if (!string.IsNullOrWhiteSpace(stack)) { stack = stack.Replace("\n", "\n> "); - if (stack.Length > 1200) - stack = stack[..1200] + "...(已截断)"; + if (stack.Length > 600) + stack = stack[..600] + "...(已截断)"; } var markdown = $@"## 🚨 系统告警 diff --git a/IRaCIS.Core.Application/MassTransit/Extension/ConsumeExceptionFilter.cs b/IRaCIS.Core.Application/MassTransit/Extension/ConsumeExceptionFilter.cs index 95466a916..6a4aba89c 100644 --- a/IRaCIS.Core.Application/MassTransit/Extension/ConsumeExceptionFilter.cs +++ b/IRaCIS.Core.Application/MassTransit/Extension/ConsumeExceptionFilter.cs @@ -49,7 +49,8 @@ public class ConsumeExceptionFilter(ILogger> _logge Env = baseUrl, UserName = "MassTransit 自动触发邮件", Api = "", - Message = $"异常信息:{exception.Message} 堆栈信息:[{exception.StackTrace}", + Message = $"异常信息:{exception.Message} ", + Stack = exception.StackTrace, AtUsers = userList ?? [] } ); diff --git a/IRaCIS.Core.Application/MassTransit/Recurring/IRRecurringConsumer.cs b/IRaCIS.Core.Application/MassTransit/Recurring/IRRecurringConsumer.cs index 5cd6d0064..791843c2b 100644 --- a/IRaCIS.Core.Application/MassTransit/Recurring/IRRecurringConsumer.cs +++ b/IRaCIS.Core.Application/MassTransit/Recurring/IRRecurringConsumer.cs @@ -37,7 +37,12 @@ namespace IRaCIS.Core.Application.MassTransit.Recurring public async Task Consume(ConsumeContext context) { - var isEn_US = CultureInfo.CurrentCulture.Name == StaticData.CultureInfo.en_US; + var isEn_US = context.Message.CultureInfoName == StaticData.CultureInfo.en_US; + + //设置当前事件传递过来的语言 + var culture = context.Message.CultureInfoName; + CultureInfo.CurrentCulture = new CultureInfo(culture); + var trialId = context.Message.TrialId; var trialInfo = await _trialRepository.FirstOrDefaultAsync(t => t.Id == trialId); diff --git a/IRaCIS.Core.Application/MassTransit/Recurring/QCRecurringEmailConsumer.cs b/IRaCIS.Core.Application/MassTransit/Recurring/QCRecurringEmailConsumer.cs index 1a9e733bf..b3862f003 100644 --- a/IRaCIS.Core.Application/MassTransit/Recurring/QCRecurringEmailConsumer.cs +++ b/IRaCIS.Core.Application/MassTransit/Recurring/QCRecurringEmailConsumer.cs @@ -7,6 +7,7 @@ using MassTransit.Scheduling; using Microsoft.Extensions.Options; using System; using System.Collections.Generic; +using System.Globalization; using System.Linq; using System.Text; using System.Threading.Tasks; @@ -34,7 +35,11 @@ public class QCImageQuestionRecurringEventConsumer(IRepository _trialRepo { var trialId = context.Message.TrialId; - var isEn_us = false; + var isEn_us = context.Message.CultureInfoName == StaticData.CultureInfo.en_US; + + //设置当前事件传递过来的语言 + var culture = context.Message.CultureInfoName; + CultureInfo.CurrentCulture = new CultureInfo(culture); var trialInfo = await _trialRepository.Where(t => t.Id == trialId).Select(t => new { t.ResearchProgramNo, t.ExperimentName, t.TrialCode, t.TrialStatusStr }).FirstNotNullAsync(); @@ -102,7 +107,12 @@ public class CRCImageQuestionRecurringEventConsumer(IRepository _trialRep { var trialId = context.Message.TrialId; - var isEn_us = false; + var isEn_us = context.Message.CultureInfoName == StaticData.CultureInfo.en_US; + + //设置当前事件传递过来的语言 + var culture = context.Message.CultureInfoName; + CultureInfo.CurrentCulture = new CultureInfo(culture); + var trialInfo = await _trialRepository.Where(t => t.Id == trialId).Select(t => new { t.ResearchProgramNo, t.ExperimentName, t.TrialCode, t.TrialStatusStr, t.DeclarationTypeEnumList }).FirstNotNullAsync(); //找到 该项目的IQC 用户Id @@ -173,7 +183,11 @@ public class ImageQCRecurringEventConsumer(IRepository _trialRepository, { var trialId=context.Message.TrialId; - var isEn_us = false; + var isEn_us = context.Message.CultureInfoName == StaticData.CultureInfo.en_US; + + //设置当前事件传递过来的语言 + var culture = context.Message.CultureInfoName; + CultureInfo.CurrentCulture = new CultureInfo(culture); var trialInfo = await _trialRepository.Where(t => t.Id == trialId).Select(t => new { t.ResearchProgramNo, t.ExperimentName, t.TrialCode, t.TrialStatusStr }).FirstNotNullAsync(); diff --git a/IRaCIS.Core.Application/MassTransit/Recurring/SystemDocumentConsumer.cs b/IRaCIS.Core.Application/MassTransit/Recurring/SystemDocumentConsumer.cs index 678b63e54..4497bf8f6 100644 --- a/IRaCIS.Core.Application/MassTransit/Recurring/SystemDocumentConsumer.cs +++ b/IRaCIS.Core.Application/MassTransit/Recurring/SystemDocumentConsumer.cs @@ -42,7 +42,12 @@ namespace IRaCIS.Core.Application.MassTransit.Recurring DateTime now = DateTime.Now; Console.WriteLine("发送定时过期提醒"); - var isEn_US = CultureInfo.CurrentCulture.Name == StaticData.CultureInfo.en_US; + var isEn_US = context.Message.CultureInfoName == StaticData.CultureInfo.en_US; + + //设置当前事件传递过来的语言 + var culture = context.Message.CultureInfoName; + CultureInfo.CurrentCulture = new CultureInfo(culture); + var systemDocQuery = from sysDoc in _systemDocumentRepository.AsQueryable(false) from identityUser in _identityUserRepository.AsQueryable(false).Where(t => t.UserRoleList.Where(t => t.IsUserRoleDisabled == false).Any(t => sysDoc.NeedConfirmedUserTypeList.AsQueryable().Any(c => c.NeedConfirmUserTypeId == t.UserTypeId))) @@ -150,7 +155,11 @@ namespace IRaCIS.Core.Application.MassTransit.Recurring public async Task Consume(ConsumeContext context) { - var isEn_US = CultureInfo.CurrentCulture.Name == StaticData.CultureInfo.en_US; + var isEn_US = context.Message.CultureInfoName == StaticData.CultureInfo.en_US; + + //设置当前事件传递过来的语言 + var culture = context.Message.CultureInfoName; + CultureInfo.CurrentCulture = new CultureInfo(culture); // 记录是否只发送给新增角色的日志 if (context.Message.NewUserTypeIds != null && context.Message.NewUserTypeIds.Any()) diff --git a/IRaCIS.Core.Application/MassTransit/Recurring/TrialDocumentConsumer.cs b/IRaCIS.Core.Application/MassTransit/Recurring/TrialDocumentConsumer.cs index 68978d9de..a0e2607c7 100644 --- a/IRaCIS.Core.Application/MassTransit/Recurring/TrialDocumentConsumer.cs +++ b/IRaCIS.Core.Application/MassTransit/Recurring/TrialDocumentConsumer.cs @@ -53,7 +53,11 @@ namespace IRaCIS.Core.Application.MassTransit.Recurring DateTime now = DateTime.Now; Console.WriteLine("发送定时项目过期提醒"); - var isEn_US = CultureInfo.CurrentCulture.Name == StaticData.CultureInfo.en_US; + var isEn_US = context.Message.CultureInfoName == StaticData.CultureInfo.en_US; + //设置当前事件传递过来的语言 + var culture = context.Message.CultureInfoName; + CultureInfo.CurrentCulture = new CultureInfo(culture); + var trialDocQuery = from trialDoc in _trialDocumentRepository.AsQueryable(true) @@ -177,7 +181,11 @@ namespace IRaCIS.Core.Application.MassTransit.Recurring public async Task Consume(ConsumeContext context) { - var isEn_US = CultureInfo.CurrentCulture.Name == StaticData.CultureInfo.en_US; + var isEn_US = context.Message.CultureInfoName == StaticData.CultureInfo.en_US; + + //设置当前事件传递过来的语言 + var culture = context.Message.CultureInfoName; + CultureInfo.CurrentCulture = new CultureInfo(culture); // 记录是否只发送给新增角色的日志 if (context.Message.NewUserTypeIds != null && context.Message.NewUserTypeIds.Any())