//-------------------------------------------------------------------- // 此代码由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; namespace IRaCIS.Core.Application.Service { /// /// TrialEmailNoticeConfigService /// [ApiExplorerSettings(GroupName = "Trial")] public class TrialEmailNoticeConfigService : BaseService, ITrialEmailNoticeConfigService { private readonly IRepository _trialEmailNoticeConfigRepository; public IRepository _visitTaskRepository { get; } public IRepository _trialUserRepository { get; } public TrialEmailNoticeConfigService(IRepository trialEmailNoticeConfigRepository, IRepository visitTaskRepository, IRepository trialUserRepository) { _trialEmailNoticeConfigRepository = trialEmailNoticeConfigRepository; _visitTaskRepository = visitTaskRepository; _trialUserRepository = trialUserRepository; } /// /// 同步系统配置的文档到想项目中 /// /// /// /// /// private async Task SyncSystemEmainCofigDocListAsync(Guid trialId, CriterionType? criterionTypeEnum) { if (criterionTypeEnum != null) { var docmentList = _repository.Where(t => t.CriterionTypeEnum == criterionTypeEnum).Select(t => new { t.Path, t.Name, t.Code, t.BusinessScenarioEnum }).ToList(); var trialDocCount = _trialEmailNoticeConfigRepository.Where(t => t.CriterionTypeEnum == criterionTypeEnum && t.TrialId == trialId).Count(); if (trialDocCount == 0) { foreach (var item in docmentList) { await _trialEmailNoticeConfigRepository.AddAsync(new TrialEmailNoticeConfig() { FileName = item.Name, FilePath = item.Path, BusinessScenarioEnum = item.BusinessScenarioEnum, Code = item.Code }); } } } await _trialEmailNoticeConfigRepository.SaveChangesAsync(); } /// /// 测试邮件 带附件 填充word --前端不需要用 /// /// /// /// public async Task BaseBusinessScenarioSendEmailAsync(Guid visitTaskId) { 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 = t.SourceSubjectVisit.VisitName, t.SourceSubjectVisit.IsFinalVisit, t.SourceSubjectVisit.PDState, t.SourceSubjectVisit.IsEnrollmentConfirm, ModuleEarliestScanDate = t.ReadModule.SubjectVisit.EarliestScanDate, ModuleVisitName = t.ReadModule.SubjectVisit.VisitName, t.SourceSubjectVisitId, t.SouceReadModuleId, t.SubjectId, t.ReadingTaskState, t.ReadingCategory, t.SignTime, //仲裁规则 t.TrialReadingCriterion.ArbitrationRule, //单双中 t.TrialReadingCriterion.ReadingType, //有序与否 t.TrialReadingCriterion.IsReadingTaskViewInOrder, MoudulePDState = t.ReadModule.SubjectVisit.PDState, t.TrialId, IsBaseline = t.SourceSubjectVisit.IsBaseLine, t.TrialReadingCriterion.CriterionType, t.TrialReadingCriterionId, }).FirstNotNullAsync(); #endregion #region 任务 -邮件场景区分 if (taskInfo.ReadingTaskState == ReadingTaskState.HaveSigned) { //入组确认场景 if (taskInfo.IsEnrollmentConfirm && taskInfo.IsEnrollementQualificationConfirm && taskInfo.IsBaseline) { 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; } } else { throw new BusinessValidationFailedException("进行邮件发送前,该任务必须已签名完成并已经触发完成相应的任务生成"); } var emailConfig = await _trialEmailNoticeConfigRepository.Where(t => t.TrialId == taskInfo.TrialId && t.CriterionTypeEnum == taskInfo.CriterionType && t.BusinessScenarioEnum == businessScenarioEnum) .Include(t => t.TrialEmailNoticeUserList).FirstOrDefaultAsync(); if (emailConfig == null) { throw new BusinessValidationFailedException("找不到该项目标准场景下邮件的配置"); } #endregion #region 发收件人配置 var sendEmailConfig = new SMTPEmailConfig(); var toUserList = _repository.Where(t => t.TrialId == taskInfo.TrialId && emailConfig.TrialEmailNoticeUserList.Where(t => t.EmailUserType == EmailUserType.To).Select(c => c.UserType).Contains(t.User.UserTypeEnum)).Select(t => new { t.User.EMail, t.User.FullName }); var copyUserList = _repository.Where(t => t.TrialId == taskInfo.TrialId && emailConfig.TrialEmailNoticeUserList.Where(t => t.EmailUserType == EmailUserType.Copy).Select(c => c.UserType).Contains(t.User.UserTypeEnum)).Select(t => new { t.User.EMail, t.User.FullName }); if (emailConfig.FromEmail.Contains("@") && !string.IsNullOrEmpty(emailConfig.FromEmail)) { sendEmailConfig.FromEmailAddress = new MimeKit.MailboxAddress(emailConfig.FromName, emailConfig.FromEmail); //测试 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 //邮件附件 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"; var answer = "否"; var isNeedSend = true; if (businessScenarioEnum == CommonDocumentBusinessScenario.EnrollConfirmed) { //如果其他阅片人已经做了,说明发送了入组确认报告,第二个人做完就不发送了 if (await _visitTaskRepository.AnyAsync(t => t.SourceSubjectVisitId == taskInfo.SourceSubjectVisitId && t.TaskState == TaskState.Effect && t.IsAnalysisCreate == false && t.Id != visitTaskId && t.ReadingTaskState == ReadingTaskState.HaveSigned)) { isNeedSend = false; } else { sendEmailConfig.TopicDescription = "入组确认"; using (StreamReader SourceReader = System.IO.File.OpenText(pathToFile)) { var templateInfo = SourceReader.ReadToEnd(); sendEmailConfig.HtmlBodyStr = string.Format(templateInfo, $" 附件为入组确认报告,请查收 " ); } 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 = "是"; } } } else if (businessScenarioEnum == CommonDocumentBusinessScenario.PDConfirmed) { sendEmailConfig.TopicDescription = "疾病进展"; using (StreamReader SourceReader = System.IO.File.OpenText(pathToFile)) { var templateInfo = SourceReader.ReadToEnd(); sendEmailConfig.HtmlBodyStr = string.Format(templateInfo, $" 附件为疾病进展确认报告,请查收 " ); } //有序 if (taskInfo.IsReadingTaskViewInOrder) { //单重 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); } } else if (taskInfo.ReadingCategory == ReadingCategory.Global) { answer = await TranslatePdStateAsync(visitTaskId, ReadingCategory.Global); } else { throw new BusinessValidationFailedException("单重有序阅片 该类型的任务不应进入此处逻辑,请联系后台开发核查!"); } } //双重 else if (taskInfo.ReadingType == ReadingMethod.Double) { //仲裁在访视上 就没有全局阅片 没有阅片期 if (taskInfo.ArbitrationRule == ArbitrationRule.Visit) { //找到 访视,裁判 所有有效任务(不可能有全局的) 访视和裁判任务的SourceSubjectVisitId 一样 var taskList = await _visitTaskRepository.Where(t => t.SourceSubjectVisitId == taskInfo.SourceSubjectVisitId && 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); } //双人 产生裁判,并且裁判完成 发 else if (taskList.Count == 3 && taskList.Count(t => t.ReadingTaskState == ReadingTaskState.HaveSigned) == 3 && taskList.Where(t => t.ReadingCategory == ReadingCategory.Judge).Count() == 1) { answer = await TranslatePdStateAsync(taskList.Where(t => t.ReadingCategory == ReadingCategory.Judge).First().Id, ReadingCategory.Judge); } else { isNeedSend = false; } } //在阅片期 仲裁在全局阅片,不会在访视上 else if (taskInfo.ArbitrationRule == ArbitrationRule.Reading) { //是访视任务 不可能是裁判任务(访视上不会生成裁判),也不会是全局任务(全局任务 SourceSubjectVisitId=null ) if (taskInfo.SourceSubjectVisitId != null) { #region MyRegion ////看该访视是否是截止访视 //var moduleIdList = await _repository.Where(t => t.TrialReadingCriterionId == taskInfo.TrialReadingCriterionId && t.SubjectVisitId == taskInfo.SourceSubjectVisitId && t.ReadingSetType == ReadingSetType.ImageReading) // .Select(t => (Guid?) t.Id).ToListAsync(); ////截止访视 //if (moduleIdList.Count > 0) //{ // //截止访视,需要等待生成全局,完成全局再发 // isNeedSend = false; //} ////非截止访视 CRC在该访视设置PD后,在提交的时候,生成了阅片期,一定会生成全局任务 //else //{ // isNeedSend = false; //} #endregion //访视类型的任务 根本就不需要发送邮件 isNeedSend = false; } //是全局任务 或者全局的裁判任务 (如果是全局任务,那么此时裁判任务已经生成,如果是全局裁判) else if (taskInfo.SouceReadModuleId != null) { var taskList = await _visitTaskRepository.Where(t => 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); } //双人全局产生裁判 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) { answer = await TranslatePdStateAsync(taskList.Where(t => t.ReadingCategory == ReadingCategory.Judge).First().Id, ReadingCategory.Judge); } else { isNeedSend = false; } } } else { throw new BusinessValidationFailedException("双重有序阅片 没有定义该仲裁规则处理逻辑,请联系业务和后台开发核查!"); } } else { throw new BusinessValidationFailedException("有序阅片配置有误(应为单重或者双重阅片),请核查!"); } } //无序 else { //单重 if (taskInfo.ReadingType == ReadingMethod.Single && taskInfo.ArbitrationRule == ArbitrationRule.None) { answer = await TranslatePdStateAsync(visitTaskId, taskInfo.ReadingCategory); } //双重 截止访视只在阅片期的时候存在 要求PD确认的访视 肯定是非截止访视 else if (taskInfo.ReadingType == ReadingMethod.Double && taskInfo.ArbitrationRule == ArbitrationRule.Visit) { //在两位阅片人读完访视后,如果有裁判者等裁判读完,如果无裁判则等第二个人的读完 var taskList = await _visitTaskRepository.Where(t => t.SourceSubjectVisitId == taskInfo.SourceSubjectVisitId && 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); } else if (taskList.Count == 3 && taskList.Count(t => t.ReadingTaskState == ReadingTaskState.HaveSigned) == 3 && taskList.Where(t => t.ReadingCategory == ReadingCategory.Judge).Count() == 1) { answer = await TranslatePdStateAsync(taskList.Where(t => t.ReadingCategory == ReadingCategory.Judge).First().Id, ReadingCategory.Judge); } else { isNeedSend = false; } } else { throw new BusinessValidationFailedException("无序阅片配置有误(应为单重无仲裁对象,双重针对访视仲裁),请核查!"); } } } else { isNeedSend=false; } if (isNeedSend) { var value = new Dictionary() { ["SponsorName"] = taskInfo.SponsorName, ["ResearchProgramNo"] = taskInfo.ResearchProgramNo, ["TrialSiteCode"] = taskInfo.TrialSiteCode, ["SubjectCode"] = taskInfo.SubjectCode, ["VisitName"] = taskInfo.VisitName, ["EarliestScanDate"] = taskInfo.SourceSubjectVisitId != null ? taskInfo.VisitEarliestScanDate : taskInfo.ModuleEarliestScanDate, ["SignTime"] = taskInfo.SignTime, ["Result"] = answer }; MemoryStream memoryStream = new MemoryStream(); MiniSoftware.MiniWord.SaveAsByTemplate(memoryStream, path, value); memoryStream.Seek(0, SeekOrigin.Begin); sendEmailConfig.EmailAttachMentConfigList.Add(new EmailAttachMentConfig() { FileName = emailConfig.FileName, FileStream = memoryStream }); await SendEmailHelper.SendEmailAsync(sendEmailConfig); } } private async Task TranslatePdStateAsync(Guid visitTaskId, ReadingCategory readingCategory) { var answer = string.Empty; if (readingCategory == ReadingCategory.Visit) { var questionAnsewer = await _repository.Where(t => t.VisitTaskId == visitTaskId && t.ReadingQuestionTrial.QuestionType == QuestionType.Tumor).FirstNotNullAsync(); answer = questionAnsewer.Answer; } else if (readingCategory == ReadingCategory.Global) { var questionAnsewer = await _repository.Where(t => t.TaskId == visitTaskId && t.TrialReadingQuestion.QuestionType == QuestionType.Tumor).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 == judgeResultTaskId && t.ReadingQuestionTrial.QuestionType == QuestionType.Tumor).FirstNotNullAsync(); answer = questionAnsewer.Answer; } else { throw new BusinessValidationFailedException("不应有 除访视、裁判、全局其他类型的任务进行发送邮件,请核查业务逻辑"); } if (answer == OverallAssessment.PD.GetEnumInt()) { return "是"; } if (answer == OverallAssessment.NA.GetEnumInt()) { return "NA"; } else { return "否"; } } /// /// 选择人员下拉 /// /// /// public async Task> GetTrialUserTypeSelectList(Guid trialId) { var query = _trialUserRepository.Where(t => t.TrialId == trialId && t.IsDeleted == false, false, true).IgnoreQueryFilters().Select(t => t.User.UserTypeRole) .ProjectTo(_mapper.ConfigurationProvider); return await query.ToListAsync(); } [HttpPost] public async Task> GetTrialEmailNoticeConfigList(TrialEmailNoticeConfigQuery inQuery) { await SyncSystemEmainCofigDocListAsync(inQuery.TrialId, inQuery.CriterionTypeEnum); var trialEmailNoticeConfigQueryable = _trialEmailNoticeConfigRepository.Where(t => t.TrialId == inQuery.TrialId) .WhereIf(inQuery.CriterionTypeEnum != null, t => t.CriterionTypeEnum == inQuery.CriterionTypeEnum) .WhereIf(inQuery.BusinessScenarioEnum != null, t => t.BusinessScenarioEnum == inQuery.BusinessScenarioEnum) .ProjectTo(_mapper.ConfigurationProvider); return await trialEmailNoticeConfigQueryable.ToListAsync(); } public async Task AddOrUpdateTrialEmailNoticeConfig(TrialEmailNoticeConfigAddOrEdit addOrEditTrialEmailNoticeConfig) { //var entity = await _trialEmailNoticeConfigRepository.InsertOrUpdateAsync(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(); } } [HttpDelete("{trialEmailNoticeConfigId:guid}")] public async Task DeleteTrialEmailNoticeConfig(Guid trialEmailNoticeConfigId) { var success = await _trialEmailNoticeConfigRepository.DeleteFromQueryAsync(t => t.Id == trialEmailNoticeConfigId, true); return ResponseOutput.Ok(); } } }