//-------------------------------------------------------------------- // 此代码由T4模板自动生成 byzhouhang 20210918 // 生成时间 2022-10-20 11:52:17 // 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。 //-------------------------------------------------------------------- using Amazon.Runtime; using IRaCIS.Core.Application.Contracts; using IRaCIS.Core.Application.Filter; using IRaCIS.Core.Application.Helper; using IRaCIS.Core.Application.Interfaces; using IRaCIS.Core.Application.MassTransit.Consumer; using IRaCIS.Core.Application.Service.Reading.Dto; using IRaCIS.Core.Application.ViewModel; using IRaCIS.Core.Domain.Share; using IRaCIS.Core.Domain.Share.Common; using IRaCIS.Core.Infra.EFCore.Common; using IRaCIS.Core.Infrastructure; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Options; using Spire.Doc; using System.Linq.Dynamic.Core; using System.Runtime.InteropServices; namespace IRaCIS.Core.Application.Service { /// /// TrialEmailNoticeConfigService /// [ApiExplorerSettings(GroupName = "Trial")] public class TrialEmailNoticeConfigService(IRepository _trialEmailNoticeConfigRepository, IRepository _trialEmailBlackUserRepository, IRepository _emailNoticeConfigRepository, IRepository _trialRepository, IRepository _taskMedicalReviewRepository, IRepository _readingGlobalTaskInfoRepository, IRepository _visitTaskRepository, IRepository _trialUserRoleRepository, IRepository _trialEmailNoticeUserRepository, IRepository _subjectRepository, IRepository _readModuleRepository, IRepository _readingTableQuestionAnswerRepository, IRepository _subjectVisitRepository, IRepository _readingTaskQuestionAnswerRepository, IRepository _readingQuestionCriterionTrialRepository, IOptionsMonitor _systemEmailSendConfig, IEmailSendService _emailSendService, IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer, IWebHostEnvironment _hostEnvironment) : BaseService, ITrialEmailNoticeConfigService { /// /// 获取项目邮箱 /// /// /// [HttpPost] public async Task GetTrialEmail(GetTrialEmailSetInDto inDto) { return await _trialRepository.Where(x => x.Id == inDto.TrialId, ignoreQueryFilters: true).Select(x => new GetTrialEmailSetOutDto() { TrialId = inDto.TrialId, EmailAuthorizationCode = x.EmailAuthorizationCode, EmailSMTPServerAddress = x.EmailSMTPServerAddress, EmailFromEmail = x.EmailFromEmail, EmailFromName = x.EmailFromName, IsConfigureEmail = x.IsConfigureEmail, EmailSMTPServerPort = x.EmailSMTPServerPort }).FirstAsync(); } /// /// 设置项目邮箱 /// /// /// public async Task SetTrialEmail(SetTrialEmailInDto inDto) { await TestEmailConfigAsync(new TrialEmailNoticeConfigAddOrEdit() { AuthorizationCode = inDto.EmailAuthorizationCode, FromEmail = inDto.EmailFromEmail, FromName = inDto.EmailFromName, SMTPServerAddress = inDto.EmailSMTPServerAddress, SMTPServerPort = inDto.EmailSMTPServerPort, TrialId = inDto.TrialId, }); await _trialRepository.UpdatePartialFromQueryAsync(inDto.TrialId, x => new Trial() { EmailFromEmail = inDto.EmailFromEmail, EmailFromName = inDto.EmailFromName, EmailAuthorizationCode = inDto.EmailAuthorizationCode, EmailSMTPServerAddress = inDto.EmailSMTPServerAddress, EmailSMTPServerPort = inDto.EmailSMTPServerPort, IsConfigureEmail = true, }); await _trialEmailNoticeConfigRepository.BatchUpdateNoTrackingAsync(x => x.TrialId == inDto.TrialId, x => new TrialEmailNoticeConfig() { AuthorizationCode = inDto.EmailAuthorizationCode, FromEmail = inDto.EmailFromEmail, FromName = inDto.EmailFromName, SMTPServerAddress = inDto.EmailSMTPServerAddress, SMTPServerPort = inDto.EmailSMTPServerPort, }); await _trialRepository.SaveChangesAsync(); return ResponseOutput.Ok(); } /// /// /// /// /// 为空 代表 正常任务自动发送,为true 代表医学审核手动发送 为false 代表医学审核自动发送 /// /// /// /// private async Task DealMedicalReviewTasKGenerateAndIsSendAsync(Guid trialId, bool? isHandSend, string answer, List taskIdList, List minUserIdList) { var isNeedSend = true; //手动发送的时候,也有可能答案是是 此时是 这里不发送,发送已经生成的文件 if (answer == "是" && isHandSend == null) { isNeedSend = true; } else { //正常阅片自动发送,阅片为否的产生医学审核 if (isHandSend == null) { isNeedSend = false; //生成任务 foreach (var taskId in taskIdList) { await _taskMedicalReviewRepository.AddAsync(new TaskMedicalReview() { TrialId = trialId, VisitTaskId = taskId, MedicalManagerUserId = minUserIdList.FirstOrDefault(), AllocateTime = DateTime.Now , IsAutoGenerate = true, PDRelationTaskIdListStr = string.Join('|', taskIdList.Distinct()) }, true); } } else if (isHandSend == true) { //医学审核手动发送 isNeedSend = false; } else { // 医学审核自动发送 isNeedSend = true; } } return isNeedSend; } /// /// 测试邮件 带附件 填充word /// /// /// 为空 代表 正常任务自动发送,为true 代表医学审核手动发送 为false 代表医学审核自动发送 /// /// /// /// public async Task BaseBusinessScenarioSendEmailAsync(Guid visitTaskId, bool? isHandSend, EmailStoreSendMode emailStoreMode, string sendFileRelativePath) { var isEn_us = _userInfo.IsEn_Us; EmailBusinessScenario businessScenarioEnum = EmailBusinessScenario.None; #region 任务关联的项目配置 标准信息及配置,subject 信息 var taskInfo = await _visitTaskRepository.Where(t => t.Id == visitTaskId).Select(t => new { t.Trial.ResearchProgramNo, t.Subject.TrialSite.TrialSiteCode, SubjectCode = t.Subject.Code, t.Trial.Sponsor.SponsorName, t.Trial.IsEnrollementQualificationConfirm, t.Trial.IsPDProgressView, VisitEarliestScanDate = t.SourceSubjectVisit.EarliestScanDate, VisitName = (string?)t.SourceSubjectVisit.VisitName, IsFinalVisit = (bool?)t.SourceSubjectVisit.IsFinalVisit, PDState = (PDStateEnum?)t.SourceSubjectVisit.PDState, IsEnrollmentConfirm = (bool?)t.SourceSubjectVisit.IsEnrollmentConfirm, IsBaseline = (bool?)t.SourceSubjectVisit.IsBaseLine, ModuleEarliestScanDate = t.ReadModule.SubjectVisit.EarliestScanDate, ModuleVisitName = (string?)t.ReadModule.SubjectVisit.VisitName, MoudulePDState = (PDStateEnum?)t.ReadModule.SubjectVisit.PDState, t.SourceSubjectVisitId, t.SouceReadModuleId, t.SubjectId, t.Subject.TrialSiteId, t.DoctorUserId, t.ReadingTaskState, t.ReadingCategory, t.SignTime, //仲裁规则 t.TrialReadingCriterion.ArbitrationRule, //单双中 t.TrialReadingCriterion.ReadingType, t.TrialReadingCriterion.CriterionType, //有序与否 t.TrialReadingCriterion.IsReadingTaskViewInOrder, t.TrialId, t.IsAnalysisCreate, t.TrialReadingCriterionId, }).FirstNotNullAsync(); if (taskInfo.IsAnalysisCreate) { return string.Empty; } #endregion #region 任务 -邮件场景区分 if (taskInfo.ReadingTaskState == ReadingTaskState.HaveSigned) { //入组确认场景 if (taskInfo.IsEnrollmentConfirm == true && taskInfo.IsEnrollementQualificationConfirm == true && taskInfo.IsBaseline == true) { businessScenarioEnum = EmailBusinessScenario.EnrollConfirmed; } //PD确认场景 else if (taskInfo.IsPDProgressView && (taskInfo.PDState == PDStateEnum.PDProgress && taskInfo.SourceSubjectVisitId != null) || (taskInfo.SouceReadModuleId != null && taskInfo.MoudulePDState == PDStateEnum.PDProgress)) { businessScenarioEnum = EmailBusinessScenario.PDConfirmed; } else { return string.Empty; } } else { //---进行邮件发送前,该任务必须已签名完成并已经触发完成相应的任务生成 throw new BusinessValidationFailedException(_localizer["TrialEmailN_TaskNotSigned"]); } #endregion #region 邮件内容装配 Func topicAndHtmlFunc = trialEmailConfig => { var topicStr = string.Format(isEn_us ? trialEmailConfig.EmailTopic : trialEmailConfig.EmailTopicCN, taskInfo.ResearchProgramNo, taskInfo.SubjectCode); var htmlBodyStr = isEn_us ? trialEmailConfig.EmailHtmlContent : trialEmailConfig.EmailHtmlContentCN; return (topicStr, htmlBodyStr, isEn_us, null); }; var (trialEmailConfig, sendEmailConfig) = await _emailSendService.BuildEmailConfig(taskInfo.TrialId, businessScenarioEnum, topicAndHtmlFunc, taskInfo.TrialSiteId); #endregion //自动发送 if (sendEmailConfig != null && trialEmailConfig != null) { #region 不同标准 不同项目配置 发送邮件的时机 处理具体逻辑 var answer = string.Empty; var isNeedSend = true; var minUserIdList = _trialUserRoleRepository.Where(t => t.UserRole.UserTypeEnum == Domain.Share.UserTypeEnum.MIM && t.TrialId == taskInfo.TrialId).Select(t => t.UserId).ToList(); //入组确认 根据每个标准配置的是否自动发送,发送邮件与否 if (businessScenarioEnum == EmailBusinessScenario.EnrollConfirmed) { //如果其他阅片人已经做了,说明发送了入组确认报告,第二个人做完就不发送了 //入组确认一直交给第一个人,如果第一个人重阅 还未做完,第二个人先做完了,此时不发 var existFirstEnrollTask = await _visitTaskRepository.Where(t => t.SourceSubjectVisitId == taskInfo.SourceSubjectVisitId && t.IsAnalysisCreate == false && t.ReadingTaskState == ReadingTaskState.HaveSigned && t.TrialReadingCriterionId == taskInfo.TrialReadingCriterionId).OrderBy(t => t.SignTime).FirstOrDefaultAsync(); //入组确认的医生已确定 if ((existFirstEnrollTask != null) && (taskInfo.DoctorUserId != existFirstEnrollTask.DoctorUserId)) { isNeedSend = false; } else { bool isEnroll = false; (answer, isEnroll) = await DealEnrollAnswer(visitTaskId, (Guid)taskInfo.SourceSubjectVisitId, taskInfo.CriterionType, taskInfo.TrialReadingCriterionId); isNeedSend = await DealMedicalReviewTasKGenerateAndIsSendAsync(taskInfo.TrialId, isHandSend, answer, new List() { visitTaskId }, minUserIdList); } } else if (businessScenarioEnum == EmailBusinessScenario.PDConfirmed) { //有序 if (taskInfo.IsReadingTaskViewInOrder == ReadingOrder.InOrder) { //双重 if (taskInfo.ReadingType == ReadingMethod.Double) { //仲裁在访视上 就没有全局阅片 没有阅片期 if (taskInfo.ArbitrationRule == ArbitrationRule.Visit) { //找到 访视,裁判 所有有效任务(不可能有全局的) 访视和裁判任务的SourceSubjectVisitId 一样 var taskList = await _visitTaskRepository.Where(t => t.SourceSubjectVisitId == taskInfo.SourceSubjectVisitId && t.TrialReadingCriterionId == taskInfo.TrialReadingCriterionId && t.IsAnalysisCreate == false && t.TaskState == TaskState.Effect && (t.ReadingCategory == ReadingCategory.Visit || t.ReadingCategory == ReadingCategory.Judge)).ToListAsync(); //这里要求 到这里已经如果有裁判 已经生成裁判了保存数据库 //双人阅片,没有产生裁判 第二个人读完发 if (taskList.Count == 2 && taskList.Count(t => t.ReadingTaskState == ReadingTaskState.HaveSigned && t.ReadingCategory == ReadingCategory.Visit) == 2) { answer = await TranslatePdStateAsync(visitTaskId, taskInfo.ReadingCategory, taskInfo.CriterionType); isNeedSend = await DealMedicalReviewTasKGenerateAndIsSendAsync(taskInfo.TrialId, isHandSend, answer, taskList.Select(t => t.Id).ToList(), minUserIdList); } //双人 产生裁判,并且裁判完成 发 else if (taskList.Count == 3 && taskList.Count(t => t.ReadingTaskState == ReadingTaskState.HaveSigned) == 3 && taskList.Where(t => t.ReadingCategory == ReadingCategory.Judge).Count() == 1) { var judgeResultId = taskList.Where(t => t.ReadingCategory == ReadingCategory.Judge).First()!.JudgeResultTaskId!.Value; answer = await TranslatePdStateAsync(judgeResultId, ReadingCategory.Visit, taskInfo.CriterionType); isNeedSend = await DealMedicalReviewTasKGenerateAndIsSendAsync(taskInfo.TrialId, isHandSend, answer, taskList.Where(t => t.ReadingCategory == ReadingCategory.Judge).Select(t => t.Id).ToList(), minUserIdList); } else { isNeedSend = false; } } //仲裁在阅片期 else if (taskInfo.ArbitrationRule == ArbitrationRule.Reading) { //是访视任务 不可能是裁判任务(访视上不会生成裁判),也不会是全局任务(全局任务 SourceSubjectVisitId=null ) if (taskInfo.SourceSubjectVisitId != null) { //访视类型的任务 根本就不需要发送邮件 isNeedSend = false; } //是全局任务 或者全局的裁判任务 (如果是全局任务,那么此时裁判任务已经生成) else if (taskInfo.SouceReadModuleId != null) { var taskList = await _visitTaskRepository.Where(t => t.TrialReadingCriterionId == taskInfo.TrialReadingCriterionId && t.IsAnalysisCreate == false && t.TaskState == TaskState.Effect && t.SouceReadModuleId == taskInfo.SouceReadModuleId && (t.ReadingCategory == ReadingCategory.Global || t.ReadingCategory == ReadingCategory.Judge)).ToListAsync(); //两个全局没有裁判 if (taskList.Count == 2 && taskList.Count(t => t.ReadingTaskState == ReadingTaskState.HaveSigned && t.ReadingCategory == ReadingCategory.Global) == 2) { answer = await TranslatePdStateAsync(visitTaskId, taskInfo.ReadingCategory, taskInfo.CriterionType); isNeedSend = await DealMedicalReviewTasKGenerateAndIsSendAsync(taskInfo.TrialId, isHandSend, answer, taskList.Select(t => t.Id).ToList(), minUserIdList); } //双人全局产生裁判 else if (taskList.Count == 3 && taskList.Count(t => t.ReadingTaskState == ReadingTaskState.HaveSigned) == 3 && taskList.Where(t => t.ReadingCategory == ReadingCategory.Judge).Count() == 1 && taskList.Where(t => t.ReadingCategory == ReadingCategory.Global).Count() == 2) { var judgeResultId = taskList.Where(t => t.ReadingCategory == ReadingCategory.Judge).First().JudgeResultTaskId!.Value; answer = await TranslatePdStateAsync(judgeResultId, ReadingCategory.Global, taskInfo.CriterionType); isNeedSend = await DealMedicalReviewTasKGenerateAndIsSendAsync(taskInfo.TrialId, isHandSend, answer, taskList.Where(t => t.ReadingCategory == ReadingCategory.Judge).Select(t => t.Id).ToList(), minUserIdList); } else { isNeedSend = false; } } else { //---发送PD 进展邮件中发现任务数据有问题! throw new BusinessValidationFailedException(_localizer["TrialEmailN_PDProgressEmailTask"]); } } else { //---双重有序阅片 没有定义该仲裁规则处理逻辑,请联系业务和后台开发核查! throw new BusinessValidationFailedException(_localizer["TrialEmailN_DoubleBlindedError"]); } } //屏蔽单重阅片添加 else { isNeedSend = false; return string.Empty; } #region 发邮件屏蔽单重的 ////单重 //else if (taskInfo.ReadingType == ReadingMethod.Single) //{ // //仲裁在访视上 或者在阅片期 // if (taskInfo.ArbitrationRule != ArbitrationRule.None) // { //---单重有序阅片配置有误(不应该有仲裁对象配置),请核查! // throw new BusinessValidationFailedException(_localizer["TrialEmailN_SingleBlindedSet"]); // } // //要求PD 确认的访视 是截止访视 还是非截止访视(根据该访视有没有配置阅片期来判断) // if (taskInfo.ReadingCategory == ReadingCategory.Visit) // { // //存在阅片期 那么就是截止访视 // if (await _readModuleRepository.Where(t => t.TrialReadingCriterionId == taskInfo.TrialReadingCriterionId && t.SubjectVisitId == taskInfo.SourceSubjectVisitId && t.ReadingSetType == ReadingSetType.ImageReading).AnyAsync()) // { // isNeedSend = false; // } // else//非截止访视 在访视读完后,发送 // { // answer = await TranslatePdStateAsync(visitTaskId, ReadingCategory.Visit, taskInfo.CriterionType); // } // } // //截止访视 在访视读完,并完成全局阅片后发送全局的结果 // else if (taskInfo.ReadingCategory == ReadingCategory.Global) // { // answer = await TranslatePdStateAsync(visitTaskId, ReadingCategory.Global, taskInfo.CriterionType); // } // else // { //---单重有序阅片 该类型的任务不应进入此处逻辑,请联系后台开发核查! // throw new BusinessValidationFailedException(_localizer["TrialEmailN_SingleBlindedSequenced"]); // } // isNeedSend = await DealMedicalReviewTasKGenerateAndIsSendAsync(taskInfo.TrialId, isHandSend, answer, new List() { visitTaskId }, minUserIdList); //} //else //{ //---有序阅片配置有误(应为单重或者双重阅片),请核查! // throw new BusinessValidationFailedException(_localizer["TrialEmailN_BlindedSequencedReading"]); //} #endregion } //屏蔽无序阅片添加 else { isNeedSend = false; return string.Empty; } #region 发送邮件屏蔽无序的 // //无序 //else //{ // //单重 // if (taskInfo.ReadingType == ReadingMethod.Single && taskInfo.ArbitrationRule == ArbitrationRule.None) // { // answer = await TranslatePdStateAsync(visitTaskId, taskInfo.ReadingCategory, taskInfo.CriterionType); // isNeedSend = await DealMedicalReviewTasKGenerateAndIsSendAsync(taskInfo.TrialId, isHandSend, answer, new List() { visitTaskId }, minUserIdList); // } // //双重 截止访视只在阅片期的时候存在 要求PD确认的访视 肯定是非截止访视 // else if (taskInfo.ReadingType == ReadingMethod.Double && taskInfo.ArbitrationRule == ArbitrationRule.Visit) // { // //在两位阅片人读完访视后,如果有裁判者等裁判读完,如果无裁判则等第二个人的读完 // var taskList = await _visitTaskRepository.Where(t => t.SourceSubjectVisitId == taskInfo.SourceSubjectVisitId && t.TrialReadingCriterionId == taskInfo.TrialReadingCriterionId && t.IsAnalysisCreate == false && t.TaskState == TaskState.Effect // && (t.ReadingCategory == ReadingCategory.Visit || t.ReadingCategory == ReadingCategory.Judge)).ToListAsync(); // //这里要求 到这里已经如果有裁判 已经生成裁判了保存数据库 // if (taskList.Count == 2 && taskList.Count(t => t.ReadingTaskState == ReadingTaskState.HaveSigned && t.ReadingCategory == ReadingCategory.Visit) == 2) // { // answer = await TranslatePdStateAsync(visitTaskId, taskInfo.ReadingCategory, taskInfo.CriterionType); // isNeedSend = await DealMedicalReviewTasKGenerateAndIsSendAsync(taskInfo.TrialId, isHandSend, answer, taskList.Select(t => t.Id).ToList(), minUserIdList); // } // else if (taskList.Count == 3 && taskList.Count(t => t.ReadingTaskState == ReadingTaskState.HaveSigned) == 3 && taskList.Where(t => t.ReadingCategory == ReadingCategory.Judge).Count() == 1) // { // var judgeResultId = taskList.Where(t => t.ReadingCategory == ReadingCategory.Judge).First().JudgeResultTaskId.Value; // answer = await TranslatePdStateAsync(judgeResultId, ReadingCategory.Visit, taskInfo.CriterionType); // isNeedSend = await DealMedicalReviewTasKGenerateAndIsSendAsync(taskInfo.TrialId, isHandSend, answer, taskList.Where(t => t.ReadingCategory == ReadingCategory.Judge).Select(t => t.Id).ToList(), minUserIdList); // } // else // { // isNeedSend = false; // } // } // else // { //---无序阅片配置有误(应为单重无仲裁对象,双重针对访视仲裁),请核查! // throw new BusinessValidationFailedException(_localizer["TrialEmailN_UnblindedSequencedReading"]); // } //} #endregion } else { isNeedSend = false; } #endregion #region MiniWord 组织字典 发送 if (emailStoreMode == EmailStoreSendMode.NotStoreLocalOnlySentEmail) { var phyPath = FileStoreHelper.GetPhysicalFilePath(_hostEnvironment, sendFileRelativePath); var attachPrefix = $"{taskInfo.SubjectCode}"; //先预先生成了邮件,发送预先生成的邮件 sendEmailConfig.EmailAttachMentConfigList.Add(new EmailAttachMentConfig() { FileName = $"{attachPrefix}_{Path.GetFileNameWithoutExtension(_userInfo.IsEn_Us ? trialEmailConfig.AttachName : trialEmailConfig!.AttachNameCN)}.pdf", FileStream = File.OpenRead(phyPath), }); await SendEmailHelper.SendEmailAsync(sendEmailConfig); return string.Empty; } var value = new Dictionary() { ["SponsorName"] = taskInfo.SponsorName, ["ResearchProgramNo"] = taskInfo.ResearchProgramNo, ["TrialSiteCode"] = taskInfo.TrialSiteCode, ["SubjectCode"] = taskInfo.SubjectCode, ["VisitName"] = taskInfo.SourceSubjectVisitId != null ? taskInfo.VisitName : taskInfo.ModuleVisitName, ["EarliestScanDate"] = taskInfo.SourceSubjectVisitId != null ? taskInfo.VisitEarliestScanDate?.ToString("yyyy-MM-dd") : taskInfo.ModuleEarliestScanDate?.ToString("yyyy-MM-dd"), ["SignTime"] = taskInfo.SignTime?.ToString("yyyy-MM-dd"), ["Result"] = answer }; var path = FileStoreHelper.GetPhysicalFilePath(_hostEnvironment, _userInfo.IsEn_Us ? trialEmailConfig.AttachPath : trialEmailConfig.AttachCNPath); //获取从word 到 PDF的路径 var (serverFilePath, relativePath, fileRealName) = FileStoreHelper.GetSubjectEnrollConfirmOrPDEmailPath(_hostEnvironment, Path.GetFileName(path), taskInfo.TrialId, taskInfo.TrialSiteId, taskInfo.SubjectId, true); if (emailStoreMode == EmailStoreSendMode.StoreLocalSend || emailStoreMode == EmailStoreSendMode.OnlyStoreLocalNotSentEmail) { MemoryStream wordMemoryStream = new MemoryStream(); MiniSoftware.MiniWord.SaveAsByTemplate(wordMemoryStream, path, value); if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { Document document = new Document(); document.LoadFromStream(wordMemoryStream, FileFormat.Docx); document.SaveToFile(serverFilePath, FileFormat.PDF); } else { var wordStoreServerPath = Path.Combine(Path.GetDirectoryName(serverFilePath), Path.GetFileNameWithoutExtension(serverFilePath) + ".docx"); //using (FileStream fileStream = new FileStream(wordStoreServerPath, FileMode.Create, FileAccess.Write)) //{ // wordMemoryStream.WriteTo(fileStream); //} FileConvertHelper.ConvertWordToPdf(wordStoreServerPath, Path.GetDirectoryName(serverFilePath)); File.Delete(wordStoreServerPath); } } //手动生成发送的邮件内容,但是并不发送 if (emailStoreMode == EmailStoreSendMode.OnlyStoreLocalNotSentEmail) { isNeedSend = false; return relativePath; } //正常的即时生成邮件 并发送邮件 if (isNeedSend) { MemoryStream wordMemoryStream = new MemoryStream(); MemoryStream pdfMemoryStream = new MemoryStream(); MiniSoftware.MiniWord.SaveAsByTemplate(wordMemoryStream, path, value); if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { Document document = new Document(); document.LoadFromStream(wordMemoryStream, FileFormat.Docx); document.SaveToStream(pdfMemoryStream, FileFormat.PDF); } else { var wordStoreServerPath = Path.Combine(Path.GetDirectoryName(serverFilePath), Path.GetFileNameWithoutExtension(serverFilePath) + ".docx"); //using (FileStream fileStream = new FileStream(wordStoreServerPath, FileMode.Create, FileAccess.Write)) //{ // wordMemoryStream.WriteTo(fileStream); //} FileConvertHelper.ConvertWordToPdf(wordStoreServerPath, Path.GetDirectoryName(serverFilePath)); File.Delete(wordStoreServerPath); using (FileStream fileStream = new FileStream(serverFilePath, FileMode.Open, FileAccess.Read)) { fileStream.CopyTo(pdfMemoryStream); } } pdfMemoryStream.Seek(0, SeekOrigin.Begin); sendEmailConfig.EmailAttachMentConfigList.Add(new EmailAttachMentConfig() { FileName = $"{taskInfo.SubjectCode}_{Path.GetFileNameWithoutExtension(_userInfo.IsEn_Us ? trialEmailConfig.AttachName : trialEmailConfig.AttachNameCN)}.pdf", FileStream = pdfMemoryStream }); await SendEmailHelper.SendEmailAsync(sendEmailConfig); } return string.Empty; #endregion } else { return string.Empty; } } /// /// 手动生成入组确认 或者PD 进展的邮件 如果能发送,会返回文件的路径,否则会给出提示 /// /// /// [HttpPost] public async Task ManualGenerateEmailFile(GenerateEmailCommand generateEmailCommand) { var subjectId = generateEmailCommand.SubjectId; var businessScenarioEnum = generateEmailCommand.BusinessScenarioEnum; var trialReadingCriterionId = generateEmailCommand.TrialReadingCriterionId; var trialConfig = await _subjectRepository.Where(t => t.Id == subjectId).Select(t => new { t.Trial.IsEnrollementQualificationConfirm, t.Trial.IsPDProgressView }).FirstNotNullAsync(); //找到入组确认 或者Pd 进展 已生成任务的 访视 var subjectVisitList = await _subjectVisitRepository.Where(t => t.SubjectId == subjectId & t.CheckState == CheckStateEnum.CVPassed && (t.IsEnrollmentConfirm == true || t.PDState == PDStateEnum.PDProgress)).ToListAsync(); if (businessScenarioEnum == EmailBusinessScenario.EnrollConfirmed) { if (trialConfig.IsEnrollementQualificationConfirm == false) { //---项目未配置入组确认! return ResponseOutput.NotOk(_localizer["TrialEmailN_InCons"]); } var exisitBaseline = subjectVisitList.FirstOrDefault(t => t.IsEnrollmentConfirm); if (exisitBaseline == null) { //---不存在配置了入组确认的并且生成任务的基线访视 return ResponseOutput.NotOk(_localizer["TrialEmailN_NoBaseLine"]); } else { //入组确认不用管项目的 有序 无序 单重 双重 阅片 //找到最早签名的 var firstSignTask = await _visitTaskRepository.Where(t => t.SourceSubjectVisitId == exisitBaseline.Id /*&& t.TaskState == TaskState.Effect*/ && t.IsAnalysisCreate == false && t.ReadingTaskState == ReadingTaskState.HaveSigned && t.TrialReadingCriterionId == trialReadingCriterionId).OrderBy(t => t.SignTime).FirstOrDefaultAsync(); if (firstSignTask != null) { var task = await _visitTaskRepository.Where(t => t.SourceSubjectVisitId == exisitBaseline.Id && t.TaskState == TaskState.Effect && t.DoctorUserId == firstSignTask.DoctorUserId && t.IsAnalysisCreate == false && t.ReadingTaskState == ReadingTaskState.HaveSigned && t.TrialReadingCriterionId == trialReadingCriterionId).OrderBy(t => t.SignTime).FirstOrDefaultAsync(); //如果存在做完的该任务 if (task == null) { //---做入组确认的阅片人基线任务没有阅片完! return ResponseOutput.NotOk(_localizer["TrialEmailN_IncompBase"]); } else { var filePath = await BaseBusinessScenarioSendEmailAsync(task.Id, true, EmailStoreSendMode.OnlyStoreLocalNotSentEmail, string.Empty); if (string.IsNullOrEmpty(filePath)) { //---邮件手动生成失败,请联系开发核实该场景失败原因 return ResponseOutput.NotOk(_localizer["TrialEmailN_EmailFail"]); } else { return ResponseOutput.Ok(new { RelativePath = filePath, TaskName = task.TaskName, VisitTaskId = task.Id }); } } } else { //---当前未有阅片人读完基线任务! return ResponseOutput.NotOk(_localizer["TrialEmailN_NoReader"]); } } } else if (businessScenarioEnum == EmailBusinessScenario.PDConfirmed) { if (trialConfig.IsPDProgressView == false) { //---项目未配置PD进展! return ResponseOutput.NotOk(_localizer["TrialEmailN_NoPDConfig"]); } //是否是截止访视 截止访视在全局发 否则就在当前访视发 var pdSubjectVisitIdList = subjectVisitList.Where(t => t.PDState == PDStateEnum.PDProgress).OrderBy(t => t.VisitNum).Select(t => (Guid?)t.Id).ToList(); if (pdSubjectVisitIdList.Count == 0) { //---不存在配置了PD进展的并且生成任务的访视 return ResponseOutput.NotOk(_localizer["TrialEmailN_NoPDTasks"]); } var currentLatestPdVisitId = pdSubjectVisitIdList.Last(); //标准配置 var trialReadingCriterionConfig = await _readingQuestionCriterionTrialRepository.Where(t => t.Id == trialReadingCriterionId).Select(t => new { TrialReadingCriterionId = t.Id, t.ReadingType, t.IsReadingTaskViewInOrder, t.CriterionType, t.ArbitrationRule }).FirstNotNullAsync(); // 项目双重 if (trialReadingCriterionConfig.ReadingType == ReadingMethod.Double && trialReadingCriterionConfig.IsReadingTaskViewInOrder == ReadingOrder.InOrder) { //仲裁在访视上面 if (trialReadingCriterionConfig.ArbitrationRule == ArbitrationRule.Visit) { //在两位阅片人读完访视后,如果有裁判者等裁判读完,如果无裁判则等第二个人的读完 var taskList = await _visitTaskRepository.Where(t => t.SourceSubjectVisitId == currentLatestPdVisitId && t.TrialReadingCriterionId == trialReadingCriterionId && t.IsAnalysisCreate == false && t.TaskState == TaskState.Effect && (t.ReadingCategory == ReadingCategory.Visit || t.ReadingCategory == ReadingCategory.Judge)).ToListAsync(); var totalTaskCount = taskList.Count; var finishedCount = taskList.Where(t => t.ReadingTaskState == ReadingTaskState.HaveSigned).Count(); //发送随访的 if (totalTaskCount == 2 && totalTaskCount == finishedCount) { var task = taskList.FirstOrDefault(t => t.ReadingCategory == ReadingCategory.Visit); var filePath = await BaseBusinessScenarioSendEmailAsync(task!.Id, true, EmailStoreSendMode.OnlyStoreLocalNotSentEmail, string.Empty); return ResponseOutput.Ok(new { RelativePath = filePath, TaskName = task.TaskName, VisitTaskId = task.Id }); } //发送全局 else if (totalTaskCount == 3 && totalTaskCount == finishedCount) { var task = taskList.FirstOrDefault(t => t.ReadingCategory == ReadingCategory.Judge); var filePath = await BaseBusinessScenarioSendEmailAsync(task!.Id, true, EmailStoreSendMode.OnlyStoreLocalNotSentEmail, string.Empty); return ResponseOutput.Ok(new { RelativePath = filePath, TaskName = task.TaskName, VisitTaskId = task.Id }); } else { //---当前受试者最新PD访视阅片任务完成状态不符合发送条件 return ResponseOutput.NotOk(_localizer["TrialEmailN_PDNotFinished"]); } } //仲裁在阅片期上 else if (trialReadingCriterionConfig.ArbitrationRule == ArbitrationRule.Reading) { var existReadModule = await _readModuleRepository.Where(t => t.TrialReadingCriterionId == trialReadingCriterionId && t.SubjectVisitId == currentLatestPdVisitId && t.ReadingSetType == ReadingSetType.ImageReading) .FirstOrDefaultAsync(); if (existReadModule == null) { //---项目配置了阅片期仲裁,但是当前受试者最新PD访视没有影像学阅片期 return ResponseOutput.NotOk(_localizer["TrialEmailN_PDNoImaging"]); } else { var taskList = await _visitTaskRepository.Where(t => t.TrialReadingCriterionId == trialReadingCriterionId && t.IsAnalysisCreate == false && t.TaskState == TaskState.Effect && t.SouceReadModuleId == existReadModule.Id && (t.ReadingCategory == ReadingCategory.Global || t.ReadingCategory == ReadingCategory.Judge)).ToListAsync(); var totalTaskCount = taskList.Count; var finishedCount = taskList.Where(t => t.ReadingTaskState == ReadingTaskState.HaveSigned).Count(); //发送全局的 if (totalTaskCount == 2 && totalTaskCount == finishedCount) { var task = taskList.FirstOrDefault(t => t.ReadingCategory == ReadingCategory.Global); var filePath = await BaseBusinessScenarioSendEmailAsync(task!.Id, true, EmailStoreSendMode.OnlyStoreLocalNotSentEmail, string.Empty); return ResponseOutput.Ok(new { RelativePath = filePath, TaskName = task.TaskName, VisitTaskId = task.Id }); } //发送全局裁判的 else if (totalTaskCount == 3 && totalTaskCount == finishedCount) { var task = taskList.FirstOrDefault(t => t.ReadingCategory == ReadingCategory.Judge); var filePath = await BaseBusinessScenarioSendEmailAsync(task!.Id, true, EmailStoreSendMode.OnlyStoreLocalNotSentEmail, string.Empty); return ResponseOutput.Ok(new { RelativePath = filePath, TaskName = task.TaskName, VisitTaskId = task.Id }); } else { //---当前受试者最新PD访视阅片期任务完成状态不符合发送条件 return ResponseOutput.NotOk(_localizer["TrialEmailN_PDPhaseNotFinished"]); } } } else { //---未定义该仲裁规则发送业务逻辑! return ResponseOutput.NotOk(_localizer["TrialEmailN_NoRuleDefined"]); } } #region 发送邮件屏蔽单重阅片情况 //// 项目单重 判断最新的Pd 访视是否完成 是否有阅片期即可 //else if (trialReadingCriterionConfig.ReadingType == ReadingMethod.Single) //{ // var task = await _visitTaskRepository.Where(t => t.SourceSubjectVisitId == currentLatestPdVisitId && t.TaskState == TaskState.Effect && t.IsAnalysisCreate == false // && t.ReadingTaskState == ReadingTaskState.HaveSigned && t.TrialReadingCriterionId == trialReadingCriterionId).FirstOrDefaultAsync(); // if (task == null) // { // return ResponseOutput.NotOk("当前受试者最新PD访视任务未阅片完成"); // } // else // { // //存在阅片期 那么就是截止访视 // var existReadModule = await _readModuleRepository.Where(t => t.TrialReadingCriterionId == trialReadingCriterionId && t.SubjectVisitId == currentLatestPdVisitId && t.ReadingSetType == ReadingSetType.ImageReading) // .FirstOrDefaultAsync(); // if (existReadModule != null) // { // var global = await _visitTaskRepository.Where(t => t.SouceReadModuleId == currentLatestPdVisitId && t.TaskState == TaskState.Effect && t.IsAnalysisCreate == false // && t.ReadingTaskState == ReadingTaskState.HaveSigned && t.TrialReadingCriterionId == trialReadingCriterionId).FirstOrDefaultAsync(); // if (global != null) // { // var filePath = await BaseBusinessScenarioSendEmailAsync(global.Id, true, EmailStoreSendMode.OnlyStoreLocalNotSentEmail, string.Empty); // return ResponseOutput.Ok(new { RelativePath = filePath, TaskName = task.TaskName, VisitTaskId = task.Id }); // } // else // { // return ResponseOutput.NotOk("当前受试者阅片期任务未阅片完成"); // } // } // else//非截止访视 在访视读完后,发送 // { // var filePath = await BaseBusinessScenarioSendEmailAsync(task.Id, true, EmailStoreSendMode.OnlyStoreLocalNotSentEmail, string.Empty); // return ResponseOutput.Ok(new { RelativePath = filePath, TaskName = task.TaskName, VisitTaskId = task.Id }); // } // } //} #endregion else { //---当前项目配置,不满足双重有序阅片,不满足发送条件! return ResponseOutput.NotOk(_localizer["TrialEmailN_NoDoubleOrder"]); } } else { //---当前项目配置,未定义发送业务逻辑! return ResponseOutput.NotOk(_localizer["TrialEmailN_NoSendLogicDefined"]); } } /// /// 手动发送邮件 /// /// /// /// [HttpPut] public async Task ManualSendEmail(Guid visitTaskId, string sendFileRelativePath) { var filePath = await BaseBusinessScenarioSendEmailAsync(visitTaskId, true, EmailStoreSendMode.NotStoreLocalOnlySentEmail, sendFileRelativePath); return ResponseOutput.Ok(); } /// /// 获取入组结果 /// /// /// /// /// /// private async Task<(string enrollAnswer, bool isEnroll)> DealEnrollAnswer(Guid visitTaskId, Guid subjectVisitId, CriterionType criterionType, Guid trialReadingCriterionId) { var enrollAnswer = string.Empty; var isEnroll = false; switch (criterionType) { case CriterionType.RECIST1Point1: case CriterionType.RECIST1Pointt1_MB: case CriterionType.IRECIST1Point1: case CriterionType.mRECISTHCC: case CriterionType.Lugano2014: case CriterionType.Lugano2014WithoutPET: if (await _readingTableQuestionAnswerRepository.Where().AnyAsync(x => x.VisitTaskId == visitTaskId && x.Answer == TargetState.Exist.GetEnumInt() && x.ReadingTableQuestionTrial.QuestionMark == QuestionMark.State && x.ReadingQuestionTrial.LesionType == LesionType.TargetLesion)) { enrollAnswer = _userInfo.IsEn_Us ? "Yes" : "是"; } break; case CriterionType.PCWG3: break; case CriterionType.RANO_BM: break; case CriterionType.RANO: break; case CriterionType.IWCLL2018: break; case CriterionType.Cheson2007: break; case CriterionType.IMWG2016: break; case CriterionType.mRECISTMesothelioma: break; case CriterionType.RECIL: break; case CriterionType.RECIST1Point0: break; case CriterionType.WHO: break; case CriterionType.PERCIST: break; case CriterionType.Forrest: break; case CriterionType.IVUS: break; case CriterionType.OCT: break; case CriterionType.MRIPDFF: break; case CriterionType.NoCriterion: break; case CriterionType.SelfDefine: break; default: break; } if (enrollAnswer == "是" || enrollAnswer == "Yes") { //把另外一个人的任务设置为不加急(如果项目加急是否 subject 加急是否) var urgent = _subjectVisitRepository.Where(t => t.Id == subjectVisitId).Select(t => new { IsSubjectUrgent = t.Subject.IsUrgent, t.Trial.IsUrgent }).FirstOrDefault(); if (urgent?.IsUrgent == false || urgent?.IsSubjectUrgent == false) { await _visitTaskRepository.BatchUpdateNoTrackingAsync(t => t.SourceSubjectVisitId == subjectVisitId && t.TaskState == TaskState.Effect && t.IsAnalysisCreate == false && t.Id != visitTaskId && t.TrialReadingCriterionId == trialReadingCriterionId, u => new VisitTask() { IsUrgent = false }); } } return (enrollAnswer, isEnroll); } /// /// 获取PD 结果 /// /// 任务Id /// 任务类型 /// 标准类型 /// 是否是全局产生(区分裁判任务) /// /// private async Task TranslatePdStateAsync(Guid visitTaskId, ReadingCategory readingCategory, CriterionType criterionType, bool? IsGlobalGenerate = null) { var answer = string.Empty; ReadingTaskQuestionAnswer visitQuestionAnswer = null; ReadingGlobalTaskInfo readingGlobalTaskInfo = null; if (readingCategory == ReadingCategory.Visit) { switch (criterionType) { case CriterionType.RECIST1Point1: case CriterionType.RECIST1Pointt1_MB: case CriterionType.IRECIST1Point1: case CriterionType.mRECISTHCC: visitQuestionAnswer = await _readingTaskQuestionAnswerRepository.Where(t => t.VisitTaskId == visitTaskId && t.ReadingQuestionTrial.QuestionType == QuestionType.Tumor).FirstNotNullAsync(); answer = visitQuestionAnswer.Answer; break; case CriterionType.Lugano2014: visitQuestionAnswer = await _readingTaskQuestionAnswerRepository.Where(t => t.VisitTaskId == visitTaskId && t.ReadingQuestionTrial.QuestionType == QuestionType.ImgOncology).FirstNotNullAsync(); answer = visitQuestionAnswer.Answer; break; case CriterionType.Lugano2014WithoutPET: visitQuestionAnswer = await _readingTaskQuestionAnswerRepository.Where(t => t.VisitTaskId == visitTaskId && t.ReadingQuestionTrial.QuestionType == QuestionType.CTandMRI).FirstNotNullAsync(); answer = visitQuestionAnswer.Answer; break; case CriterionType.PCWG3: visitQuestionAnswer = await _readingTaskQuestionAnswerRepository.Where(t => t.VisitTaskId == visitTaskId && t.ReadingQuestionTrial.QuestionType == QuestionType.SiteVisitForTumorEvaluation).FirstNotNullAsync(); answer = visitQuestionAnswer.Answer; break; case CriterionType.SelfDefine: case CriterionType.mRECISTMesothelioma: case CriterionType.RECIL: case CriterionType.RECIST1Point0: case CriterionType.WHO: case CriterionType.PERCIST: case CriterionType.Forrest: case CriterionType.RANO_BM: case CriterionType.RANO: case CriterionType.IWCLL2018: case CriterionType.Cheson2007: case CriterionType.IMWG2016: default: //---该标准任务还未定义PD获取逻辑,联系业务和后台开发协商后补充 throw new BusinessValidationFailedException(_localizer["TrialEmailN_PDLogicNotDefined"]); } } else if (readingCategory == ReadingCategory.Global) { switch (criterionType) { case CriterionType.RECIST1Point1: case CriterionType.RECIST1Pointt1_MB: case CriterionType.IRECIST1Point1: case CriterionType.mRECISTHCC: readingGlobalTaskInfo = await _readingGlobalTaskInfoRepository.Where(t => t.GlobalTaskId == visitTaskId && t.TrialReadingQuestion.QuestionType == QuestionType.Tumor).OrderByDescending(c => c.VisitTask.VisitTaskNum).FirstNotNullAsync(); answer = readingGlobalTaskInfo.Answer; if (string.IsNullOrEmpty(readingGlobalTaskInfo.Answer)) { answer = await _readingTaskQuestionAnswerRepository.Where(t => readingGlobalTaskInfo.TaskId == t.VisitTaskId && t.ReadingQuestionTrial.QuestionType == QuestionType.Tumor) .Select(t => t.Answer).FirstOrDefaultAsync(); } break; case CriterionType.Lugano2014: readingGlobalTaskInfo = await _readingGlobalTaskInfoRepository.Where(t => t.GlobalTaskId == visitTaskId && t.TrialReadingQuestion.QuestionType == QuestionType.ImgOncology).OrderByDescending(c => c.VisitTask.VisitTaskNum).FirstNotNullAsync(); answer = readingGlobalTaskInfo.Answer; if (string.IsNullOrEmpty(readingGlobalTaskInfo.Answer)) { answer = await _readingTaskQuestionAnswerRepository.Where(t => readingGlobalTaskInfo.TaskId == t.VisitTaskId && t.ReadingQuestionTrial.QuestionType == QuestionType.ImgOncology) .Select(t => t.Answer).FirstOrDefaultAsync(); } break; case CriterionType.Lugano2014WithoutPET: readingGlobalTaskInfo = await _readingGlobalTaskInfoRepository.Where(t => t.GlobalTaskId == visitTaskId && t.TrialReadingQuestion.QuestionType == QuestionType.CTandMRI).OrderByDescending(c => c.VisitTask.VisitTaskNum).FirstNotNullAsync(); answer = readingGlobalTaskInfo.Answer; if (string.IsNullOrEmpty(readingGlobalTaskInfo.Answer)) { answer = await _readingTaskQuestionAnswerRepository.Where(t => readingGlobalTaskInfo.TaskId == t.VisitTaskId && t.ReadingQuestionTrial.QuestionType == QuestionType.CTandMRI) .Select(t => t.Answer).FirstOrDefaultAsync(); } break; case CriterionType.PCWG3: var questionAnsewer = await _readingGlobalTaskInfoRepository.Where(t => t.TaskId == visitTaskId && t.TrialReadingQuestion.QuestionType == QuestionType.SiteVisitForTumorEvaluation).FirstNotNullAsync(); answer = questionAnsewer.Answer; break; case CriterionType.RANO_BM: break; case CriterionType.RANO: break; case CriterionType.IWCLL2018: break; case CriterionType.Cheson2007: break; case CriterionType.IMWG2016: break; case CriterionType.mRECISTMesothelioma: break; case CriterionType.RECIL: break; case CriterionType.RECIST1Point0: break; case CriterionType.WHO: break; case CriterionType.PERCIST: break; case CriterionType.Forrest: break; case CriterionType.IVUS: break; case CriterionType.OCT: break; case CriterionType.MRIPDFF: break; case CriterionType.NoCriterion: break; case CriterionType.SelfDefine: break; default: break; } } else { //---不应有 除访视、裁判、全局其他类型的任务进行发送邮件,请核查业务逻辑 throw new BusinessValidationFailedException(_localizer["TrialEmailN_InvalidTaskTypeForEmailSending"]); } switch (criterionType) { case CriterionType.RECIST1Point1: case CriterionType.RECIST1Pointt1_MB: case CriterionType.mRECISTHCC: if (answer == OverallAssessment.PD.GetEnumInt()) { answer = _userInfo.IsEn_Us ? "Yes" : "是"; } else if (answer == OverallAssessment.ND.GetEnumInt()) { answer = "ND"; } else if (answer == OverallAssessment.NE.GetEnumInt()) { answer = "NE"; } else { answer = _userInfo.IsEn_Us ? "No" : "否"; } break; case CriterionType.IRECIST1Point1: if (answer == OverallAssessment.iCPD.GetEnumInt()) { answer = _userInfo.IsEn_Us ? "Yes" : "是"; } else if (answer == OverallAssessment.ND.GetEnumInt()) { answer = "ND"; } else if (answer == OverallAssessment.NE.GetEnumInt()) { answer = "NE"; } else { answer = _userInfo.IsEn_Us ? "No" : "否"; } break; case CriterionType.Lugano2014WithoutPET: if (answer == CTMRIOverallAssessment.PD.GetEnumInt()) { answer = _userInfo.IsEn_Us ? "Yes" : "是"; } else if (answer == CTMRIOverallAssessment.ND.GetEnumInt()) { answer = "ND"; } else if (answer == CTMRIOverallAssessment.NE.GetEnumInt()) { answer = "NE"; } else { answer = _userInfo.IsEn_Us ? "No" : "否"; } break; case CriterionType.Lugano2014: if (answer == ImagingOverallAssessment_Lugano.PMDPD.GetEnumInt()) { answer = _userInfo.IsEn_Us ? "Yes" : "是"; } else if (answer == ImagingOverallAssessment_Lugano.ND.GetEnumInt()) { answer = "ND"; } else if (answer == ImagingOverallAssessment_Lugano.NE.GetEnumInt()) { answer = "NE"; } else { answer = _userInfo.IsEn_Us ? "No" : "否"; } break; case CriterionType.PCWG3: if (answer == VisitTumorEvaluation.PD.GetEnumInt()) { answer = _userInfo.IsEn_Us ? "Yes" : "是"; } else if (answer == VisitTumorEvaluation.ND.GetEnumInt()) { answer = "ND"; } else if (answer == VisitTumorEvaluation.NE.GetEnumInt()) { answer = "NE"; } else { answer = _userInfo.IsEn_Us ? "No" : "否"; } break; case CriterionType.RANO_BM: break; case CriterionType.RANO: break; case CriterionType.IWCLL2018: break; case CriterionType.Cheson2007: break; case CriterionType.IMWG2016: break; case CriterionType.mRECISTMesothelioma: break; case CriterionType.RECIL: break; case CriterionType.RECIST1Point0: break; case CriterionType.WHO: break; case CriterionType.PERCIST: break; case CriterionType.Forrest: break; case CriterionType.IVUS: break; case CriterionType.OCT: break; case CriterionType.MRIPDFF: break; case CriterionType.NoCriterion: break; case CriterionType.SelfDefine: break; default: break; } return answer; } /// /// 选择人员下拉 /// /// /// public async Task> GetTrialUserTypeSelectList(Guid trialId) { var query = _trialUserRoleRepository.Where(t => t.TrialId == trialId, false, true).IgnoreQueryFilters().Select(t => t.UserRole.UserTypeRole).Distinct() .ProjectTo(_mapper.ConfigurationProvider); return await query.ToListAsync(); } /// /// 黑名单用户Id 列表 /// /// /// public async Task> GetTrialUserIdSelectList(Guid trialEmailNoticeConfigId) { var trialEmailNoticeConfig = await _trialEmailNoticeConfigRepository.Where(t => t.Id == trialEmailNoticeConfigId).Include(t => t.TrialEmailNoticeUserList).FirstNotNullAsync(); var trialId = trialEmailNoticeConfig.TrialId; var userTypeList = trialEmailNoticeConfig.TrialEmailNoticeUserList.Select(t => t.UserType).ToList(); var query = _trialUserRoleRepository.Where(t => t.TrialId == trialId && userTypeList.Contains(t.UserRole.UserTypeEnum), false, true).IgnoreQueryFilters() .Select(t => new TrialSelectUser() { UserId = t.UserId, UserName = t.UserRole.IdentityUser.UserName, RealName = t.UserRole.FullName, UserTypeEnum = t.UserRole.UserTypeEnum }).Distinct(); return await query.ToListAsync(); } /// /// 获取系统 邮件配置 勾选列表 /// /// /// [HttpPost] public async Task> GetSysEmailNoticeConfigList(EmailNoticeConfigQuery inQuery) { var trialConfig = _trialRepository.Where(t => t.Id == inQuery.TrialId).Select(t => new { t.IsEnrollementQualificationConfirm, t.IsPDProgressView }).First(); var emailNoticeConfigQueryable = _emailNoticeConfigRepository.Where(t => t.BusinessLevelEnum == BusinessLevel.Trial) .WhereIf(inQuery.BusinessScenarioEnum != null, t => t.BusinessScenarioEnum == inQuery.BusinessScenarioEnum) .WhereIf(inQuery.IsReturnRequired != null, t => t.IsReturnRequired == inQuery.IsReturnRequired) .WhereIf(inQuery.IsEnable != null, t => t.IsEnable == inQuery.IsEnable) .WhereIf(inQuery.IsDistinguishCriteria != null, t => t.IsDistinguishCriteria == inQuery.IsDistinguishCriteria) .WhereIf(inQuery.BusinessModuleEnum != null, t => t.BusinessModuleEnum == inQuery.BusinessModuleEnum) .WhereIf(inQuery.EmailUrgentEnum != null, t => t.EmailUrgentEnum == inQuery.EmailUrgentEnum) .WhereIf(inQuery.ToUserType != null, t => t.EmailNoticeUserTypeList.Any(t => t.UserType == inQuery.ToUserType && t.EmailUserType == EmailUserType.To)) .WhereIf(inQuery.CopyUserType != null, t => t.EmailNoticeUserTypeList.Any(t => t.UserType == inQuery.CopyUserType && t.EmailUserType == EmailUserType.Copy)) .WhereIf(trialConfig.IsEnrollementQualificationConfirm == false, t => t.BusinessModuleEnum != BusinessModule.EligibilityVerification) .WhereIf(trialConfig.IsPDProgressView == false, t => t.BusinessModuleEnum != BusinessModule.PDVerification) .WhereIf(trialConfig.IsPDProgressView == false && trialConfig.IsEnrollementQualificationConfirm == false, t => t.BusinessModuleEnum != BusinessModule.PDVerification && t.BusinessModuleEnum != BusinessModule.EligibilityVerification) .ProjectTo(_mapper.ConfigurationProvider, new { trialId = inQuery.TrialId }); return await emailNoticeConfigQueryable.ToPagedListAsync(inQuery); } public async Task BatchAddEnrollOrPdEmailConfig(Guid trialId) { var trialConfig = _trialRepository.Where(t => t.Id == trialId).Select(t => new { t.IsEnrollementQualificationConfirm, t.IsPDProgressView }).First(); var emailNoticeConfigQueryable = _emailNoticeConfigRepository .WhereIf(trialConfig.IsEnrollementQualificationConfirm == true && trialConfig.IsPDProgressView == false, t => t.BusinessModuleEnum == BusinessModule.EligibilityVerification || t.BusinessModuleEnum == BusinessModule.Eligibility_PDVerification) .WhereIf(trialConfig.IsEnrollementQualificationConfirm == false && trialConfig.IsPDProgressView == true, t => t.BusinessModuleEnum == BusinessModule.PDVerification || t.BusinessModuleEnum == BusinessModule.Eligibility_PDVerification) .WhereIf(trialConfig.IsPDProgressView == true && trialConfig.IsEnrollementQualificationConfirm == true, t => t.BusinessModuleEnum == BusinessModule.PDVerification || t.BusinessModuleEnum == BusinessModule.EligibilityVerification || t.BusinessModuleEnum == BusinessModule.Eligibility_PDVerification) .ProjectTo(_mapper.ConfigurationProvider, new { trialId = trialId }); var list = await emailNoticeConfigQueryable.ToListAsync(); var addList = _mapper.Map>(list.Where(t => t.IsHaveSelected == false).ToList()); foreach (var item in addList) { item.TrialId = trialId; } return await BatchAddSysEmailConfig(addList); } /// /// 批量勾选 传递列表每行数据,后台进行处理转换,建立关联关系 /// /// /// public async Task BatchAddSysEmailConfig(List batchAddList) { if (!batchAddList.Any()) { return ResponseOutput.Ok(); } var first = batchAddList.First(); var trialId = first.TrialId; var emailConfig = await _trialRepository.Where(t => t.Id == trialId).Select(x => new { TrialId = x.Id, EmailAuthorizationCode = x.EmailAuthorizationCode, EmailSMTPServerAddress = x.EmailSMTPServerAddress, EmailFromEmail = x.EmailFromEmail, EmailFromName = x.EmailFromName, IsConfigureEmail = x.IsConfigureEmail, EmailSMTPServerPort = x.EmailSMTPServerPort }).FirstNotNullAsync(); //var list = await _readingQuestionCriterionTrialRepository.Where(t => t.TrialId == trialId && t.IsConfirm).Select(t => new { t.CriterionType, TrialReadingCriterionId = t.Id }).ToListAsync(); var addList = _mapper.Map>(batchAddList); foreach (var item in addList) { item.SysEmailNoticeConfigId = item.Id; item.Id = Guid.Empty; item.AuthorizationCode = emailConfig.EmailAuthorizationCode; item.FromEmail = emailConfig.EmailFromEmail; item.SMTPServerAddress = emailConfig.EmailSMTPServerAddress; item.FromName = emailConfig.EmailFromName; item.SMTPServerPort = emailConfig.EmailSMTPServerPort; item.IsAutoSend = true; item.IsEnable = true; //item.TrialReadingCriterionId = list.FirstOrDefault(t => t.CriterionType == item.CriterionTypeEnum)?.TrialReadingCriterionId; item.TrialEmailNoticeUserList.AddRange(batchAddList.Where(t => t.Id == item.SysEmailNoticeConfigId) .SelectMany(t => t.ToUserTypeList).Select(t => new TrialEmailNoticeUser() { EmailUserType = EmailUserType.To, UserType = t })); item.TrialEmailNoticeUserList.AddRange(batchAddList.Where(t => t.Id == item.SysEmailNoticeConfigId) .SelectMany(t => t.CopyUserTypeList).Select(t => new TrialEmailNoticeUser() { EmailUserType = EmailUserType.Copy, UserType = t })); await _trialEmailNoticeConfigRepository.AddAsync(item); } await _trialEmailNoticeConfigRepository.SaveChangesAsync(); //处理定时任务 var taskInfoList = await _trialEmailNoticeConfigRepository.Where(t => t.TrialId == trialId && t.EmailCron != string.Empty && t.IsAutoSend) .Select(t => new { t.Id, t.Code, TrialCode = t.Trial.TrialCode, t.EmailCron, t.BusinessScenarioEnum, t.TrialId }) .ToListAsync(); foreach (var task in taskInfoList) { //利用主键作为任务Id var jobId = $"{task.TrialId}({task.TrialCode})_({task.BusinessScenarioEnum})"; HangfireJobHelper.AddOrUpdateTrialCronJob(jobId, trialId, task.BusinessScenarioEnum, task.EmailCron); } return ResponseOutput.Ok(); } [HttpPost] public async Task>> GetTrialEmailNoticeConfigList(TrialEmailNoticeConfigQuery inQuery) { //await SyncSystemEmainCofigDocListAsync(inQuery.TrialId); var trialConfig = _trialRepository.Where(t => t.Id == inQuery.TrialId).Select(t => new { t.IsEnrollementQualificationConfirm, t.IsPDProgressView }).First(); var trialEmailNoticeConfigQueryable = _trialEmailNoticeConfigRepository.Where(t => t.TrialId == inQuery.TrialId) .WhereIf(inQuery.IsDistinguishCriteria == false, t => t.IsDistinguishCriteria == false) .WhereIf(inQuery.IsDistinguishCriteria == true, t => t.IsDistinguishCriteria == true) .WhereIf(inQuery.CriterionTypeEnum != null, t => t.CriterionTypeList.Any(c => c == inQuery.CriterionTypeEnum)) .WhereIf(inQuery.BusinessScenarioEnum != null, t => t.BusinessScenarioEnum == inQuery.BusinessScenarioEnum) .WhereIf(inQuery.EmailUrgentEnum != null, t => t.EmailUrgentEnum == inQuery.EmailUrgentEnum) .WhereIf(inQuery.IsEnable != null, t => t.IsEnable == inQuery.IsEnable) .WhereIf(inQuery.ToUserType != null, t => t.TrialEmailNoticeUserList.Any(t => t.UserType == inQuery.ToUserType && t.EmailUserType == EmailUserType.To)) .WhereIf(inQuery.CopyUserType != null, t => t.TrialEmailNoticeUserList.Any(t => t.UserType == inQuery.CopyUserType && t.EmailUserType == EmailUserType.Copy)) .WhereIf(inQuery.BusinessModuleEnum != null, t => t.BusinessModuleEnum == inQuery.BusinessModuleEnum) .ProjectTo(_mapper.ConfigurationProvider); var sortField = string.IsNullOrWhiteSpace(inQuery.SortField) ? nameof(TrialEmailNoticeConfigView.Code) : inQuery.SortField; var orderQuery = inQuery.Asc ? trialEmailNoticeConfigQueryable.OrderBy(sortField) : trialEmailNoticeConfigQueryable.OrderBy(sortField + " desc"); var list = await orderQuery.ToListAsync(); return ResponseOutput.Ok(list, trialConfig); } [TrialGlobalLimit("AfterStopCannNotOpt")] public async Task AddOrUpdateTrialEmailNoticeConfig(TrialEmailNoticeConfigAddOrEdit addOrEditTrialEmailNoticeConfig) { await TestEmailConfigAsync(addOrEditTrialEmailNoticeConfig); if (addOrEditTrialEmailNoticeConfig.Id == null) { var entity = _mapper.Map(addOrEditTrialEmailNoticeConfig); foreach (var item in addOrEditTrialEmailNoticeConfig.ToUserTypeList) { entity.TrialEmailNoticeUserList.Add(new TrialEmailNoticeUser() { EmailUserType = EmailUserType.To, UserType = item }); } foreach (var item in addOrEditTrialEmailNoticeConfig.CopyUserTypeList) { entity.TrialEmailNoticeUserList.Add(new TrialEmailNoticeUser() { EmailUserType = EmailUserType.Copy, UserType = item }); } foreach (var userid in addOrEditTrialEmailNoticeConfig.BlackUserIdList) { entity.TrialEmailBlackUserList.Add(new TrialEmailBlackUser() { UserId = userid }); } await _trialEmailNoticeConfigRepository.AddAsync(entity, true); return ResponseOutput.Ok(entity.Id.ToString()); } else { var id = (Guid)addOrEditTrialEmailNoticeConfig.Id; await _trialEmailNoticeUserRepository.BatchDeleteNoTrackingAsync(t => t.TrialEmailNoticeConfigId == addOrEditTrialEmailNoticeConfig.Id); await _trialEmailBlackUserRepository.BatchDeleteNoTrackingAsync(t => t.TrialEmailNoticeConfigId == addOrEditTrialEmailNoticeConfig.Id); List trialEmailNoticeUsers = new List(); foreach (var item in addOrEditTrialEmailNoticeConfig.ToUserTypeList) { trialEmailNoticeUsers.Add(new TrialEmailNoticeUser() { EmailUserType = EmailUserType.To, UserType = item, TrialEmailNoticeConfigId = id }); } foreach (var item in addOrEditTrialEmailNoticeConfig.CopyUserTypeList) { trialEmailNoticeUsers.Add(new TrialEmailNoticeUser() { EmailUserType = EmailUserType.Copy, UserType = item, TrialEmailNoticeConfigId = id }); } await _trialEmailNoticeUserRepository.AddRangeAsync(trialEmailNoticeUsers); foreach (var userid in addOrEditTrialEmailNoticeConfig.BlackUserIdList) { await _trialEmailBlackUserRepository.AddAsync(new TrialEmailBlackUser() { UserId = userid, TrialEmailNoticeConfigId = id }); } await _trialEmailNoticeConfigRepository.UpdateFromDTOAsync(addOrEditTrialEmailNoticeConfig); await _trialEmailNoticeConfigRepository.SaveChangesAsync(); var cronInfo = await _trialEmailNoticeConfigRepository.Where(t => t.Id == addOrEditTrialEmailNoticeConfig.Id) .Select(t => new { t.Id, t.Code, TrialCode = t.Trial.TrialCode, t.EmailCron, t.BusinessScenarioEnum, t.TrialId }) .FirstAsync(); var jobId = $"{cronInfo.TrialId}({cronInfo.TrialCode})_({cronInfo.BusinessScenarioEnum})"; if (addOrEditTrialEmailNoticeConfig.IsAutoSend) { HangfireJobHelper.AddOrUpdateTrialCronJob(jobId, addOrEditTrialEmailNoticeConfig.TrialId, addOrEditTrialEmailNoticeConfig.BusinessScenarioEnum, addOrEditTrialEmailNoticeConfig.EmailCron); } else { HangfireJobHelper.RemoveCronJob(jobId); } return ResponseOutput.Ok(); } } private async Task TestEmailConfigAsync(TrialEmailNoticeConfigAddOrEdit config) { if (!config.FromEmail.Contains("@") || string.IsNullOrEmpty(config.FromEmail)) { //---项目发件邮箱配置有误,请核实 throw new BusinessValidationFailedException(_localizer["TrialEmailN_InvalidEmailConfig"]); } try { await SendEmailHelper.TestEmailConfigAsync(new SystemEmailSendConfig() { AuthorizationCode = config.AuthorizationCode, FromEmail = config.FromEmail, FromName = config.FromName, Host = config.SMTPServerAddress, Port = config.SMTPServerPort }); } catch (Exception ex) { //---发件人配置错误,请核对服务器地址或者授权码是否填写有误 throw new BusinessValidationFailedException(_localizer["TrialEmailN_InvalidSenderEmailConfig"]); } #region 人员还未加入,可以先配置邮件 历史废弃 //var toUserList = await _trialUserRoleRepository.Where(t => t.TrialId == config.TrialId) // .WhereIf(config.ToUserTypeList != null, t => config.ToUserTypeList.Contains(t.User.UserTypeEnum)) // .Select(t => new { t.User.EMail, t.User.FullName }).ToListAsync(); //if (toUserList.Count() == 0 || toUserList.Where(t => t.EMail.Contains("@")).Count() == 0) //{ // //---项目没有有效的收件人,无法发送邮件 // throw new BusinessValidationFailedException(_localizer["TrialEmailN_InvalidRecipient"]); //} //var sendEmailConfig = new SMTPEmailConfig(); //sendEmailConfig.FromEmailAddress = new MimeKit.MailboxAddress(config.FromName, config.FromEmail); //sendEmailConfig.AuthorizationCode = config.AuthorizationCode; //sendEmailConfig.UserName = config.FromEmail; //sendEmailConfig.Host = config.SMTPServerAddress; //sendEmailConfig.Port = config.SMTPServerPort; //sendEmailConfig.ToMailAddressList.Add(new MimeKit.MailboxAddress(config.FromName, config.FromEmail)); //var pathToFile = _hostEnvironment.WebRootPath // + Path.DirectorySeparatorChar.ToString() // + "EmailTemplate" // + Path.DirectorySeparatorChar.ToString() // //+ "EmailConfigTest.html"; // + (_userInfo.IsEn_Us ? "EmailConfigTest_US.html" : "EmailConfigTest.html"); ////---项目邮件测试 //sendEmailConfig.TopicDescription = _localizer["TrialEmailN_EmailTestMessage"]; //using (StreamReader SourceReader = System.IO.File.OpenText(pathToFile)) //{ // var templateInfo = SourceReader.ReadToEnd(); // sendEmailConfig.HtmlBodyStr = string.Format(templateInfo, // //--- 收到此邮件,代表邮件配置正确 // _localizer["TrialEmailN_ConfigurationCorrect"] // ); //} //try //{ // await SendEmailHelper.SendEmailAsync(sendEmailConfig); //} //catch (Exception ex) //{ // //---发件人配置错误,请核对服务器地址或者授权码是否填写有误 // throw new BusinessValidationFailedException(_localizer["TrialEmailN_InvalidSenderEmailConfig"] + ex.Message); //} #endregion } [TrialGlobalLimit("AfterStopCannNotOpt")] [HttpDelete("{trialEmailNoticeConfigId:guid}")] public async Task DeleteTrialEmailNoticeConfig(Guid trialEmailNoticeConfigId) { var cronInfo = await _trialEmailNoticeConfigRepository.Where(t => t.Id == trialEmailNoticeConfigId) .Select(t => new { t.Id, t.Code, TrialCode = t.Trial.TrialCode, t.EmailCron, t.BusinessScenarioEnum, t.TrialId }) .FirstAsync(); var jobId = $"{cronInfo.TrialId}({cronInfo.TrialCode})_({cronInfo.BusinessScenarioEnum})"; HangfireJobHelper.RemoveCronJob(jobId); var success = await _trialEmailNoticeConfigRepository.DeleteFromQueryAsync(t => t.Id == trialEmailNoticeConfigId, true); return ResponseOutput.Ok(); } } }