//-------------------------------------------------------------------- // 此代码由T4模板自动生成 byzhouhang 20210918 // 生成时间 2022-10-20 11:52:17 // 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。 //-------------------------------------------------------------------- using IRaCIS.Core.Domain.Models; using Microsoft.AspNetCore.Mvc; using IRaCIS.Core.Application.Interfaces; using IRaCIS.Core.Application.ViewModel; using IRaCIS.Core.Domain.Share; using IRaCIS.Core.Infrastructure; using IRaCIS.Core.Application.Helper; using IRaCIS.Application.Contracts; using IRaCIS.Core.Infra.EFCore.Common; using IRaCIS.Core.Application.Contracts; using IRaCIS.Core.Application.Filter; using MiniSoftware; using IRaCIS.Core.Application.Service.Reading.Dto; using IRaCIS.Core.Domain.Share.Common; using System.IO; using System.Linq; using Spire.Doc; namespace IRaCIS.Core.Application.Service { /// /// TrialEmailNoticeConfigService /// [ApiExplorerSettings(GroupName = "Trial")] public class TrialEmailNoticeConfigService : BaseService, ITrialEmailNoticeConfigService { private readonly IRepository _trialEmailNoticeConfigRepository; private readonly IRepository _trialRepository; private readonly IRepository _taskMedicalReviewRepository; public IRepository _visitTaskRepository { get; } public IRepository _trialUserRepository { get; } public IRepository _subjectRepository { get; } public IRepository _subjectVisitRepository { get; } public TrialEmailNoticeConfigService(IRepository trialEmailNoticeConfigRepository, IRepository visitTaskRepository, IRepository trialRepository, IRepository trialUserRepository, IRepository taskMedicalReviewRepository, IRepository subjectRepository, IRepository subjectVisitRepository) { _trialEmailNoticeConfigRepository = trialEmailNoticeConfigRepository; _visitTaskRepository = visitTaskRepository; this._trialRepository = trialRepository; _trialUserRepository = trialUserRepository; _taskMedicalReviewRepository = taskMedicalReviewRepository; _subjectRepository = subjectRepository; _subjectVisitRepository = subjectVisitRepository; } /// /// 获取项目邮箱 /// /// /// [HttpPost] public async Task GetTrialEmail(GetTrialEmailSetInDto inDto) { return await _trialRepository.Where(x => x.Id == inDto.TrialId).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 }).FirstNotNullAsync(); } /// /// 设置项目邮箱 /// /// /// 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.Value, 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.Value, }); await _trialRepository.SaveChangesAsync(); return ResponseOutput.Ok(); } /// /// 同步系统配置的文档到想项目中 /// /// /// /// private async Task SyncSystemEmainCofigDocListAsync(Guid trialId) { //判断流程配置是否确认 确认了一定确认了标准 可以进行同步 if (_repository.Where(t => t.Id == trialId).Any(t => t.IsTrialProcessConfirmed == true)) { //只要有系统标准的文档 说明同步过了 var trialDocCount = _trialEmailNoticeConfigRepository.Where(t =>/* t.CriterionTypeEnum == criterionTypeEnum &&*/ t.TrialId == trialId && t.TrialReadingCriterionId != null).Count(); if (trialDocCount == 0) { //找到确认的标准 var list = await _repository.Where(t => t.TrialId == trialId && t.IsConfirm).Select(t => new { t.CriterionType, TrialReadingCriterionId = t.Id }).ToListAsync(); var confirmedCriterionTypeList = list.Select(t => (CriterionType?)t.CriterionType).ToList(); var docmentList = _repository.Where(t => confirmedCriterionTypeList.Contains(t.CriterionTypeEnum)).Select(t => new { t.Path, t.Name, t.Code, t.BusinessScenarioEnum, t.CriterionTypeEnum }).ToList(); foreach (var item in docmentList) { await _trialEmailNoticeConfigRepository.AddAsync(new TrialEmailNoticeConfig() { TrialId = trialId, TrialReadingCriterionId = list.Where(t => t.CriterionType == item.CriterionTypeEnum).FirstOrDefault()?.TrialReadingCriterionId, FileName = item.Name, FilePath = item.Path, BusinessScenarioEnum = item.BusinessScenarioEnum, Code = item.Code }); } } } await _trialEmailNoticeConfigRepository.SaveChangesAsync(); } private async Task DealMedicalReviewTasKGenerateAndIsSendAsync(Guid trialId, bool? isHandSend, string pdAnswer, List taskIdList, List minUserIdList) { var isNeedSend = true; //手动发送的时候,也有可能答案是是 此时是 这里不发送,发送已经生成的文件 if (pdAnswer == "是" && 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) { CommonDocumentBusinessScenario? businessScenarioEnum = null; #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.SiteId, 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 = CommonDocumentBusinessScenario.EnrollConfirmed; } //PD确认场景 else if (taskInfo.IsPDProgressView && (taskInfo.PDState == PDStateEnum.PDProgress && taskInfo.SourceSubjectVisitId != null) || (taskInfo.SouceReadModuleId != null && taskInfo.MoudulePDState == PDStateEnum.PDProgress)) { businessScenarioEnum = CommonDocumentBusinessScenario.PDConfirmed; } else { return string.Empty; } } else { throw new BusinessValidationFailedException("进行邮件发送前,该任务必须已签名完成并已经触发完成相应的任务生成"); } #endregion #region 发收件人配置 确保无误 var emailConfig = await _trialEmailNoticeConfigRepository.Where(t => t.TrialId == taskInfo.TrialId && t.TrialReadingCriterionId == taskInfo.TrialReadingCriterionId && t.BusinessScenarioEnum == businessScenarioEnum) .Include(t => t.TrialEmailNoticeUserList).FirstOrDefaultAsync(); if (emailConfig == null || emailConfig.IsAutoSend == false) { //throw new BusinessValidationFailedException("找不到该项目标准场景下邮件的配置"); return string.Empty; } var sendEmailConfig = new SMTPEmailConfig(); //收件人 如果是CRC CRA 要按照中心发送 var toUserTypeEnumList = emailConfig.TrialEmailNoticeUserList.Where(t => t.EmailUserType == EmailUserType.To).Select(c => c.UserType).ToList(); var toUserList = _repository.Where(t => t.TrialId == taskInfo.TrialId && toUserTypeEnumList.Contains(t.User.UserTypeEnum) && t.SiteId == taskInfo.SiteId).Select(t => new { t.User.EMail, t.User.FullName }).ToList(); var copyUserTypeEnumList = emailConfig.TrialEmailNoticeUserList.Where(t => t.EmailUserType == EmailUserType.Copy).Select(c => c.UserType).ToList(); var copyUserList = _repository.Where(t => t.TrialId == taskInfo.TrialId && copyUserTypeEnumList.Contains(t.User.UserTypeEnum)).Select(t => new { t.User.EMail, t.User.FullName }).ToList(); if (toUserList.Count() == 0) { throw new BusinessValidationFailedException("没有收件人,无法发送邮件"); } if (emailConfig.FromEmail.Contains("@") && !string.IsNullOrEmpty(emailConfig.FromEmail)) { sendEmailConfig.FromEmailAddress = new MimeKit.MailboxAddress(emailConfig.FromName, emailConfig.FromEmail); sendEmailConfig.AuthorizationCode = emailConfig.AuthorizationCode; sendEmailConfig.UserName = emailConfig.FromEmail; sendEmailConfig.Host = emailConfig.SMTPServerAddress; sendEmailConfig.Port = emailConfig.SMTPServerPort; //测试 //sendEmailConfig.ToMailAddressList.Add(new MimeKit.MailboxAddress("ddd", "872297557@qq.com")); } else { throw new BusinessValidationFailedException("项目发件邮箱配置有误,请核实"); } foreach (var item in toUserList) { if (item.EMail.Contains("@") && !string.IsNullOrEmpty(item.EMail)) { sendEmailConfig.ToMailAddressList.Add(new MimeKit.MailboxAddress(item.FullName, item.EMail)); } } foreach (var item in copyUserList) { if (item.EMail.Contains("@") && !string.IsNullOrEmpty(item.EMail)) { sendEmailConfig.CopyToMailAddressList.Add(new MimeKit.MailboxAddress(item.FullName, item.EMail)); } } #endregion #region 确保 邮件Html存在 //邮件附件 var path = FileStoreHelper.GetPhysicalFilePath(_hostEnvironment, emailConfig.FilePath); if (!File.Exists(path)) { throw new BusinessValidationFailedException("找不到该项目标准场景下邮件模板"); } var pathToFile = _hostEnvironment.WebRootPath + Path.DirectorySeparatorChar.ToString() + "EmailTemplate" + Path.DirectorySeparatorChar.ToString() + "SubjectEnrollConfirmOrPDProgress.html"; #endregion #region 不同场景 Tile 设置 if (businessScenarioEnum == CommonDocumentBusinessScenario.EnrollConfirmed) { sendEmailConfig.TopicDescription = $"【入组确认报告】关于{taskInfo.ResearchProgramNo}项目{taskInfo.SubjectCode}患者"; using (StreamReader SourceReader = System.IO.File.OpenText(pathToFile)) { var templateInfo = SourceReader.ReadToEnd(); sendEmailConfig.HtmlBodyStr = string.Format(templateInfo, $" 附件为入组确认报告,请查收 " ); } } else if (businessScenarioEnum == CommonDocumentBusinessScenario.PDConfirmed) { sendEmailConfig.TopicDescription = $"【疾病进展确认报告】关于{taskInfo.ResearchProgramNo}项目{taskInfo.SubjectCode}患者"; using (StreamReader SourceReader = System.IO.File.OpenText(pathToFile)) { var templateInfo = SourceReader.ReadToEnd(); sendEmailConfig.HtmlBodyStr = string.Format(templateInfo, $" 附件为疾病进展确认报告,请查收 " ); } } else { // } #endregion #region 不同标准 不同项目配置 发送邮件的时机 处理具体逻辑 var answer = "否"; var isNeedSend = true; var minUserIdList = _trialUserRepository.Where(t => t.User.UserTypeEnum == Domain.Share.UserTypeEnum.MIM && t.TrialId == taskInfo.TrialId).Select(t => t.UserId).ToList(); //入组确认 根据每个标准配置的是否自动发送,发送邮件与否 if (businessScenarioEnum == CommonDocumentBusinessScenario.EnrollConfirmed) { if (await _repository.Where().AnyAsync(x => x.VisitTaskId == visitTaskId && x.Answer == TargetState.Exist.GetEnumInt() && x.ReadingTableQuestionTrial.QuestionMark == QuestionMark.State && x.ReadingQuestionTrial.LesionType == LesionType.TargetLesion)) { answer = "是"; } //如果其他阅片人已经做了,说明发送了入组确认报告,第二个人做完就不发送了 //入组确认一直交给第一个人,如果第一个人重阅 还未做完,第二个人先做完了,此时不发 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 { isNeedSend = await DealMedicalReviewTasKGenerateAndIsSendAsync(taskInfo.TrialId, isHandSend, answer, new List() { visitTaskId }, minUserIdList); if (answer == "是") { //把另外一个人的任务设置为不加急(如果项目加急是否 subject 加急是否) var urgent = _repository.Where(t => t.Id == taskInfo.SourceSubjectVisitId).Select(t => new { IsSubjectUrgent = t.Subject.IsUrgent, t.Trial.IsUrgent }).FirstOrDefault(); if (urgent?.IsUrgent == false || urgent?.IsSubjectUrgent == false) { await _visitTaskRepository.BatchUpdateNoTrackingAsync(t => t.SourceSubjectVisitId == taskInfo.SourceSubjectVisitId && t.TaskState == TaskState.Effect && t.IsAnalysisCreate == false && t.Id != visitTaskId && t.TrialReadingCriterionId == taskInfo.TrialReadingCriterionId, u => new VisitTask() { IsUrgent = false }); } } } } else if (businessScenarioEnum == CommonDocumentBusinessScenario.PDConfirmed) { //有序 if (taskInfo.IsReadingTaskViewInOrder) { //双重 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 { throw new BusinessValidationFailedException("发送PD 进展邮件中发现任务数据有问题!"); } } else { throw new BusinessValidationFailedException("双重有序阅片 没有定义该仲裁规则处理逻辑,请联系业务和后台开发核查!"); } } //屏蔽单重阅片添加 else { isNeedSend = false; return string.Empty; } #region 发邮件屏蔽单重的 ////单重 //else if (taskInfo.ReadingType == ReadingMethod.Single) //{ // //仲裁在检查批次上 或者在阅片期 // if (taskInfo.ArbitrationRule != ArbitrationRule.None) // { // throw new BusinessValidationFailedException("单重有序阅片配置有误(不应该有仲裁对象配置),请核查!"); // } // //要求PD 确认的检查批次 是截止检查批次 还是非截止检查批次(根据该检查批次有没有配置阅片期来判断) // if (taskInfo.ReadingCategory == ReadingCategory.Visit) // { // //存在阅片期 那么就是截止检查批次 // if (await _repository.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("单重有序阅片 该类型的任务不应进入此处逻辑,请联系后台开发核查!"); // } // isNeedSend = await DealMedicalReviewTasKGenerateAndIsSendAsync(taskInfo.TrialId, isHandSend, answer, new List() { visitTaskId }, minUserIdList); //} //else //{ // throw new BusinessValidationFailedException("有序阅片配置有误(应为单重或者双重阅片),请核查!"); //} #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("无序阅片配置有误(应为单重无仲裁对象,双重针对检查批次仲裁),请核查!"); // } //} #endregion } else { isNeedSend = false; } #endregion #region MiniWord 组织字典 发送 if (emailStoreMode == EmailStoreSendMode.NotStoreLocalOnlySentEmail) { var phyPath = FileStoreHelper.GetPhysicalFilePath(_hostEnvironment, sendFileRelativePath); //先预先生成了邮件,发送预先生成的邮件 sendEmailConfig.EmailAttachMentConfigList.Add(new EmailAttachMentConfig() { FileName = $"{taskInfo.SubjectCode}_{Path.GetFileNameWithoutExtension(emailConfig.FileName)}.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 (serverFilePath, relativePath, fileRealName) = FileStoreHelper.GetSubjectEnrollConfirmOrPDEmailPath(_hostEnvironment, Path.GetFileName(path), taskInfo.TrialId, taskInfo.SiteId, taskInfo.SubjectId,true); if (emailStoreMode == EmailStoreSendMode.StoreLocalSend || emailStoreMode == EmailStoreSendMode.OnlyStoreLocalNotSentEmail) { MemoryStream wordMemoryStream = new MemoryStream(); Document document = new Document(); MiniSoftware.MiniWord.SaveAsByTemplate(wordMemoryStream, path, value); document.LoadFromStream(wordMemoryStream,FileFormat.Docx); document.SaveToFile(serverFilePath, FileFormat.PDF); } //手动生成发送的邮件内容,但是并不发送 if (emailStoreMode == EmailStoreSendMode.OnlyStoreLocalNotSentEmail) { isNeedSend = false; return relativePath; } //正常的即时生成邮件 并发送邮件 if (isNeedSend) { MemoryStream memoryStream = new MemoryStream(); MemoryStream pdfMemoryStream = new MemoryStream(); MiniSoftware.MiniWord.SaveAsByTemplate(memoryStream, path, value); Document document = new Document(); document.LoadFromStream(memoryStream, FileFormat.Docx); document.SaveToStream(pdfMemoryStream, FileFormat.PDF); pdfMemoryStream.Seek(0, SeekOrigin.Begin); sendEmailConfig.EmailAttachMentConfigList.Add(new EmailAttachMentConfig() { FileName = $"{taskInfo.SubjectCode}_{Path.GetFileNameWithoutExtension(emailConfig.FileName)}.pdf", FileStream = pdfMemoryStream }); await SendEmailHelper.SendEmailAsync(sendEmailConfig); } return string.Empty; #endregion } /// /// 手动生成入组确认 或者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 == CommonDocumentBusinessScenario.EnrollConfirmed) { if (trialConfig.IsEnrollementQualificationConfirm == false) { return ResponseOutput.NotOk("项目未配置入组确认!"); } var exisitBaseline = subjectVisitList.FirstOrDefault(t => t.IsEnrollmentConfirm); if (exisitBaseline == null) { return ResponseOutput.NotOk("不存在配置了入组确认的并且生成任务的基线检查批次"); } 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("做入组确认的阅片人基线任务没有阅片完!"); } else { var filePath = await BaseBusinessScenarioSendEmailAsync(task.Id, true, EmailStoreSendMode.OnlyStoreLocalNotSentEmail, string.Empty); return ResponseOutput.Ok(new { RelativePath = filePath, TaskName = task.TaskName, VisitTaskId = task.Id }); } } else { return ResponseOutput.NotOk("当前未有阅片人读完基线任务!"); } } } else if (businessScenarioEnum == CommonDocumentBusinessScenario.PDConfirmed) { if (trialConfig.IsPDProgressView == false) { return ResponseOutput.NotOk("项目未配置PD进展!"); } //是否是截止检查批次 截止检查批次在全局发 否则就在当前检查批次发 var pdSubjectVisitIdList = subjectVisitList.Where(t => t.PDState == PDStateEnum.PDProgress).OrderBy(t => t.VisitNum).Select(t => (Guid?)t.Id).ToList(); if (pdSubjectVisitIdList.Count == 0) { return ResponseOutput.NotOk("不存在配置了PD进展的并且生成任务的检查批次"); } var currentLatestPdVisitId = pdSubjectVisitIdList.Last(); //标准配置 var trialReadingCriterionConfig = await _repository.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) { //仲裁在检查批次上面 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 { return ResponseOutput.NotOk("当前患者最新PD检查批次阅片任务完成状态不符合发送条件"); } } //仲裁在阅片期上 else if (trialReadingCriterionConfig.ArbitrationRule == ArbitrationRule.Reading) { var existReadModule = await _repository.Where(t => t.TrialReadingCriterionId == trialReadingCriterionId && t.SubjectVisitId == currentLatestPdVisitId && t.ReadingSetType == ReadingSetType.ImageReading) .FirstOrDefaultAsync(); if (existReadModule == null) { return ResponseOutput.NotOk("项目配置了阅片期仲裁,但是当前患者最新PD检查批次没有影像学阅片期"); } 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 { return ResponseOutput.NotOk("当前患者最新PD检查批次阅片期任务完成状态不符合发送条件"); } } } else { return ResponseOutput.NotOk("未定义该仲裁规则发送业务逻辑!"); } } #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 _repository.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("当前项目配置,不满足双重有序阅片,不满足发送条件!"); } } else { return ResponseOutput.NotOk("当前项目配置,未定义发送业务逻辑!"); } } /// /// 手动发送邮件 /// /// /// /// [HttpPut] public async Task ManualSendEmail(Guid visitTaskId, string sendFileRelativePath) { var filePath = await BaseBusinessScenarioSendEmailAsync(visitTaskId, true, EmailStoreSendMode.NotStoreLocalOnlySentEmail, sendFileRelativePath); return ResponseOutput.Ok(); } /// /// /// /// 任务Id /// 任务类型 /// 标准类型 /// 是否是全局产生(区分裁判任务) /// /// private async Task TranslatePdStateAsync(Guid visitTaskId, ReadingCategory readingCategory, CriterionType criterionType, bool? IsGlobalGenerate = null) { var answer = string.Empty; ReadingTaskQuestionAnswer visitQuestionAnswer = null; ReadingTaskQuestionAnswer globalQuestionAnswer = null; switch (criterionType) { case CriterionType.RECIST1Pointt1: if (readingCategory == ReadingCategory.Visit) { visitQuestionAnswer = await _repository.Where(t => t.VisitTaskId == visitTaskId && t.ReadingQuestionTrial.QuestionType == QuestionType.Tumor).FirstNotNullAsync(); answer = visitQuestionAnswer.Answer; } else if (readingCategory == ReadingCategory.Global) { var questionAnsewer = await _repository.Where(t => t.GlobalTaskId == visitTaskId && t.TrialReadingQuestion.QuestionType == QuestionType.Tumor).OrderByDescending(c => c.VisitTask.VisitTaskNum).FirstNotNullAsync(); answer = questionAnsewer.Answer; if (string.IsNullOrEmpty(questionAnsewer.Answer)) { answer = await _repository.Where(t => questionAnsewer.TaskId == t.VisitTaskId && t.ReadingQuestionTrial.QuestionType == QuestionType.Tumor) .Select(t => t.Answer).FirstOrDefaultAsync(); } } //else if (readingCategory == ReadingCategory.Judge) //{ // var judgeResultTaskId = await _visitTaskRepository.Where(t => t.Id == visitTaskId).Select(t => t.JudgeResultTaskId).FirstNotNullAsync(); // var questionAnsewer = await _repository.Where(t => t.VisitTaskId == judgeResultTaskId && t.ReadingQuestionTrial.QuestionType == QuestionType.Tumor).FirstNotNullAsync(); // answer = questionAnsewer.Answer; //} else { throw new BusinessValidationFailedException("不应有 除检查批次、裁判、全局其他类型的任务进行发送邮件,请核查业务逻辑"); } if (answer == OverallAssessment.PD.GetEnumInt()) { answer = "是"; } else { answer = "否"; } break; case CriterionType.PCWG3: if (readingCategory == ReadingCategory.Visit) { visitQuestionAnswer = await _repository.Where(t => t.VisitTaskId == visitTaskId && t.ReadingQuestionTrial.QuestionType == QuestionType.SiteVisitForTumorEvaluation).FirstNotNullAsync(); answer = visitQuestionAnswer.Answer; } else if (readingCategory == ReadingCategory.Global) { var questionAnsewer = await _repository.Where(t => t.TaskId == visitTaskId && t.TrialReadingQuestion.QuestionType == QuestionType.SiteVisitForTumorEvaluation).FirstNotNullAsync(); answer = questionAnsewer.Answer; } //else if (readingCategory == ReadingCategory.Judge) //{ // //var judgeResultTaskId = await _visitTaskRepository.Where(t => t.Id == visitTaskId).Select(t => t.JudgeResultTaskId).FirstNotNullAsync(); // var questionAnsewer = await _repository.Where(t => t.VisitTaskId == visitTaskId && t.ReadingQuestionTrial.QuestionType == QuestionType.SiteVisitForTumorEvaluation).FirstNotNullAsync(); // answer = questionAnsewer.Answer; //} else { throw new BusinessValidationFailedException("不应有 除检查批次、裁判、全局其他类型的任务进行发送邮件,请核查业务逻辑"); } if (answer == VisitTumorEvaluation.PD.GetEnumInt()) { answer = "是"; } if (answer == VisitTumorEvaluation.ND.GetEnumInt()) { answer = "ND"; } if (answer == VisitTumorEvaluation.NE.GetEnumInt()) { answer = "NE"; } else { 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.Lugano2014: case CriterionType.iRECIST: case CriterionType.RANO_BM: case CriterionType.RANO: case CriterionType.IWCLL2018: case CriterionType.mRECISTHCC: case CriterionType.Cheson2007: case CriterionType.IMWG2016: default: throw new BusinessValidationFailedException("该标准任务还未定义PD获取逻辑,联系业务和后台开发协商后补充"); } return answer; } /// /// 选择人员下拉 /// /// /// public async Task> GetTrialUserTypeSelectList(Guid trialId) { var query = _trialUserRepository.Where(t => t.TrialId == trialId, false, true).IgnoreQueryFilters().Select(t => t.User.UserTypeRole).Distinct() .ProjectTo(_mapper.ConfigurationProvider); return await query.ToListAsync(); } [HttpPost] public async Task> GetTrialEmailNoticeConfigList(TrialEmailNoticeConfigQuery inQuery) { await SyncSystemEmainCofigDocListAsync(inQuery.TrialId); var trialEmailNoticeConfigQueryable = _trialEmailNoticeConfigRepository.Where(t => t.TrialId == inQuery.TrialId) .WhereIf(inQuery.IsDistinguishCriteria == false, t => t.TrialReadingCriterionId == null) .WhereIf(inQuery.TrialReadingCriterionId != null, t => t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId) .WhereIf(inQuery.BusinessScenarioEnum != null, t => t.BusinessScenarioEnum == inQuery.BusinessScenarioEnum) .ProjectTo(_mapper.ConfigurationProvider); return await trialEmailNoticeConfigQueryable.ToListAsync(); } [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "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 }); } await _trialEmailNoticeConfigRepository.AddAsync(entity, true); return ResponseOutput.Ok(entity.Id.ToString()); } else { await _repository.BatchDeleteAsync(t => t.TrialEmailNoticeConfigId == addOrEditTrialEmailNoticeConfig.Id); var entity = (await _trialEmailNoticeConfigRepository.Where(t => t.Id == addOrEditTrialEmailNoticeConfig.Id, true, true).Include(t => t.TrialEmailNoticeUserList).FirstOrDefaultAsync()).IfNullThrowException(); List trialEmailNoticeUsers = new List(); foreach (var item in addOrEditTrialEmailNoticeConfig.ToUserTypeList) { trialEmailNoticeUsers.Add(new TrialEmailNoticeUser() { EmailUserType = EmailUserType.To, UserType = item, TrialEmailNoticeConfigId = entity.Id }); } foreach (var item in addOrEditTrialEmailNoticeConfig.CopyUserTypeList) { trialEmailNoticeUsers.Add(new TrialEmailNoticeUser() { EmailUserType = EmailUserType.Copy, UserType = item, TrialEmailNoticeConfigId = entity.Id }); } await _repository.AddRangeAsync(trialEmailNoticeUsers); await _trialEmailNoticeConfigRepository.UpdateFromDTOAsync(addOrEditTrialEmailNoticeConfig); await _trialEmailNoticeConfigRepository.SaveChangesAsync(); return ResponseOutput.Ok(); } } private async Task TestEmailConfigAsync(TrialEmailNoticeConfigAddOrEdit config) { var toUserList = await _repository.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 (!config.FromEmail.Contains("@") || string.IsNullOrEmpty(config.FromEmail)) { throw new BusinessValidationFailedException("项目发件邮箱配置有误,请核实"); } if (toUserList.Count() == 0 || toUserList.Where(t => t.EMail.Contains("@")).Count() == 0) { throw new BusinessValidationFailedException("项目没有有效的收件人,无法发送邮件"); } 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"; sendEmailConfig.TopicDescription = "项目邮件测试"; using (StreamReader SourceReader = System.IO.File.OpenText(pathToFile)) { var templateInfo = SourceReader.ReadToEnd(); sendEmailConfig.HtmlBodyStr = string.Format(templateInfo, $" 收到此邮件,代表邮件配置正确" ); } try { await SendEmailHelper.SendEmailAsync(sendEmailConfig); } catch (Exception ex) { throw new BusinessValidationFailedException("发件人配置错误,请核对服务器地址或者授权码是否填写有误" + ex.Message); } } [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })] [HttpDelete("{trialEmailNoticeConfigId:guid}")] public async Task DeleteTrialEmailNoticeConfig(Guid trialEmailNoticeConfigId) { var success = await _trialEmailNoticeConfigRepository.DeleteFromQueryAsync(t => t.Id == trialEmailNoticeConfigId, true); return ResponseOutput.Ok(); } } }