irc-netcore-api/IRaCIS.Core.Application/Service/Document/TrialEmailNoticeConfigServi...

1817 lines
80 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

//--------------------------------------------------------------------
// 此代码由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
{
/// <summary>
/// TrialEmailNoticeConfigService
/// </summary>
[ApiExplorerSettings(GroupName = "Trial")]
public class TrialEmailNoticeConfigService : BaseService, ITrialEmailNoticeConfigService
{
private readonly IRepository<TrialEmailNoticeConfig> _trialEmailNoticeConfigRepository;
private readonly IRepository<TrialEmailBlackUser> _trialEmailBlackUserRepository;
private readonly IRepository<EmailNoticeConfig> _emailNoticeConfigRepository;
private readonly IRepository<Trial> _trialRepository;
private readonly IRepository<TaskMedicalReview> _taskMedicalReviewRepository;
private readonly IRepository<VisitTask> _visitTaskRepository;
private readonly IRepository<TrialUser> _trialUserRepository;
private readonly IRepository<Subject> _subjectRepository;
private readonly IRepository<SubjectVisit> _subjectVisitRepository;
public TrialEmailNoticeConfigService(
IRepository<TrialEmailNoticeConfig> trialEmailNoticeConfigRepository,
IRepository<VisitTask> visitTaskRepository,
IRepository<Trial> trialRepository,
IRepository<TrialUser> trialUserRepository,
IRepository<TaskMedicalReview> taskMedicalReviewRepository,
IRepository<Subject> subjectRepository,
IRepository<SubjectVisit> subjectVisitRepository,
IRepository<TrialEmailBlackUser> trialEmailBlackUserRepository,
IRepository<EmailNoticeConfig> emailNoticeConfigRepository
)
{
_trialEmailNoticeConfigRepository = trialEmailNoticeConfigRepository;
_visitTaskRepository = visitTaskRepository;
_trialRepository = trialRepository;
_trialUserRepository = trialUserRepository;
_taskMedicalReviewRepository = taskMedicalReviewRepository;
_subjectRepository = subjectRepository;
_subjectVisitRepository = subjectVisitRepository;
_trialEmailBlackUserRepository = trialEmailBlackUserRepository;
_emailNoticeConfigRepository = emailNoticeConfigRepository;
}
/// <summary>
/// 获取项目邮箱
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
[HttpPost]
public async Task<GetTrialEmailSetOutDto> 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
}).FirstOrDefaultAsync();
}
/// <summary>
/// 设置项目邮箱
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
public async Task<IResponseOutput> 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();
}
/// <summary>
/// 同步系统配置的文档到想项目中 ---废弃
/// </summary>
/// <param name="trialId"></param>
/// <returns></returns>
///
private async Task SyncSystemEmainCofigDocListAsync(Guid trialId)
{
//判断流程配置是否确认 确认了一定确认了标准 可以进行同步
if (_repository.Where<Trial>(t => t.Id == trialId).Any(t => t.IsTrialProcessConfirmed == true))
{
//只要有系统标准的文档 说明同步过了
var trialDocCount = _trialEmailNoticeConfigRepository.Where(t => t.TrialId == trialId).Count();
if (trialDocCount == 0)
{
//找到确认的标准
var list = await _repository.Where<ReadingQuestionCriterionTrial>(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<CommonDocument>(t => t.BusinessScenarioEnum == CommonDocumentBusinessScenario.EnrollConfirmed || t.BusinessScenarioEnum == CommonDocumentBusinessScenario.PDConfirmed)
.Where(t => (confirmedCriterionTypeList.Contains(t.CriterionTypeEnum)) || t.CriterionTypeEnum == null).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();
}
public async Task CommonBusinessScenarioSendEmailAsync(Guid visitTaskId, bool? isEnrollment, bool? isPDConfirm)
{
#region 区分场景
CommonDocumentBusinessScenario businessScenarioEnum;
if (isEnrollment != null && isPDConfirm == null)
{
businessScenarioEnum = CommonDocumentBusinessScenario.EnrollConfirmed;
}
else /*if (isEnrollment == null && isPDConfirm != null)*/
{
businessScenarioEnum = CommonDocumentBusinessScenario.PDConfirmed;
}
#endregion
#region 任务 基本信息,邮件需要
var taskInfo = await _visitTaskRepository.Where(t => t.Id == visitTaskId).Select(t => new
{
t.Subject.SiteId,
t.Trial.ResearchProgramNo,
t.Subject.TrialSite.TrialSiteCode,
SubjectCode = t.Subject.Code,
t.Trial.Sponsor.SponsorName,
t.TrialId,
}).FirstNotNullAsync();
var trialId = taskInfo.TrialId;
#endregion
#region 发收件人配置 确保无误
var emailConfig = await _trialEmailNoticeConfigRepository.Where(t => t.TrialId == trialId && t.TrialReadingCriterionId == null && t.BusinessScenarioEnum == businessScenarioEnum)
.Include(t => t.TrialEmailNoticeUserList).FirstOrDefaultAsync();
if (emailConfig == null || emailConfig.IsAutoSend == false)
{
return;
}
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<TrialSiteUser>(t => t.TrialId == 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<TrialUser>(t => t.TrialId == trialId && copyUserTypeEnumList.Contains(t.User.UserTypeEnum)).Select(t => new { t.User.EMail, t.User.FullName }).ToList();
if (toUserList.Count() == 0)
{
//---没有收件人,无法发送邮件
throw new BusinessValidationFailedException(_localizer["TrialEmailN_NoRecipient"]);
}
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;
}
else
{
//---项目发件邮箱配置有误,请核实
throw new BusinessValidationFailedException(_localizer["TrialEmailN_InvalidEmailConfig"]);
}
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 确保 设置邮件Tile
var pathToFile = _hostEnvironment.WebRootPath
+ Path.DirectorySeparatorChar.ToString()
+ "EmailTemplate"
+ Path.DirectorySeparatorChar.ToString()
//+ "SubjectEnrollConfirmOrPDProgress.html";
+ (_userInfo.IsEn_Us ? "SubjectEnrollConfirmOrPDProgress_US.html" : "SubjectEnrollConfirmOrPDProgress.html");
if (businessScenarioEnum == CommonDocumentBusinessScenario.EnrollConfirmed)
{
sendEmailConfig.TopicDescription = _localizer["TrialEmailN_EnrollmentConfirmation", taskInfo.ResearchProgramNo, taskInfo.SubjectCode];
using (StreamReader SourceReader = System.IO.File.OpenText(pathToFile))
{
var templateInfo = SourceReader.ReadToEnd();
sendEmailConfig.HtmlBodyStr = string.Format(templateInfo,
//--- 附件为疾病进展确认报告,
//_localizer["TrialEmailN_SubjectDiseaseProgression"]
$"请查收 关于{taskInfo.ResearchProgramNo}项目{taskInfo.SubjectCode}受试者入组确认已完成 PI / MM入组确认{(isEnrollment == true ? "" : "")}"
);
}
}
else /*if (businessScenarioEnum == CommonDocumentBusinessScenario.PDConfirmed)*/
{
sendEmailConfig.TopicDescription = _localizer["TrialEmailN_PDReport", taskInfo.ResearchProgramNo, taskInfo.SubjectCode];
using (StreamReader SourceReader = System.IO.File.OpenText(pathToFile))
{
var templateInfo = SourceReader.ReadToEnd();
sendEmailConfig.HtmlBodyStr = string.Format(templateInfo,
//--- 附件为疾病进展确认报告,请查收
//_localizer["TrialEmailN_SubjectDiseaseProgression"]
$"请查收 关于{taskInfo.ResearchProgramNo}项目{taskInfo.SubjectCode}受试者PD确认已完成 PI / MM PD确认{(isPDConfirm == true ? "" : "")}"
);
}
}
#endregion
await SendEmailHelper.SendEmailAsync(sendEmailConfig);
}
private async Task<bool> DealMedicalReviewTasKGenerateAndIsSendAsync(Guid trialId, bool? isHandSend, string pdAnswer, List<Guid> taskIdList, List<Guid> 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;
}
/// <summary>
/// 测试邮件 带附件 填充word --前端不需
/// </summary>
/// <param name="visitTaskId"></param>
/// <param name="isHandSend"> 为空 代表 正常任务自动发送为true 代表医学审核手动发送 为false 代表医学审核自动发送 </param>
/// <param name="emailStoreMode"></param>
/// <param name="sendFileRelativePath"></param>
/// <returns></returns>
/// <exception cref="BusinessValidationFailedException"></exception>
public async Task<string> 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(_localizer["TrialEmailN_TaskNotSigned"]);
}
#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 && isHandSend == null))
{
//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<TrialSiteUser>(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<TrialUser>(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(_localizer["TrialEmailN_NoRecipient"]);
}
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(_localizer["TrialEmailN_InvalidEmailConfig"]);
}
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, _userInfo.IsEn_Us ? emailConfig.AttachPath : emailConfig.AttachCNPath);
if (!File.Exists(path))
{
//---找不到该项目标准场景下邮件模板
throw new BusinessValidationFailedException(_localizer["TrialEmailN_EmailTemplateNotFound"]);
}
var pathToFile = _hostEnvironment.WebRootPath
+ Path.DirectorySeparatorChar.ToString()
+ "EmailTemplate"
+ Path.DirectorySeparatorChar.ToString()
//+ "SubjectEnrollConfirmOrPDProgress.html";
+ (_userInfo.IsEn_Us ? "SubjectEnrollConfirmOrPDProgress_US.html" : "SubjectEnrollConfirmOrPDProgress.html");
#endregion
#region 不同场景 Tile 设置
if (businessScenarioEnum == CommonDocumentBusinessScenario.EnrollConfirmed)
{
sendEmailConfig.TopicDescription = _localizer["TrialEmailN_EnrollmentConfirmation", taskInfo.ResearchProgramNo, taskInfo.SubjectCode];
using (StreamReader SourceReader = System.IO.File.OpenText(pathToFile))
{
var templateInfo = SourceReader.ReadToEnd();
sendEmailConfig.HtmlBodyStr = string.Format(templateInfo,
//--- 附件为疾病进展确认报告,请查收
_localizer["TrialEmailN_SubjectDiseaseProgression"]
);
}
}
else if (businessScenarioEnum == CommonDocumentBusinessScenario.PDConfirmed)
{
sendEmailConfig.TopicDescription = _localizer["TrialEmailN_PDReport", taskInfo.ResearchProgramNo, taskInfo.SubjectCode];
using (StreamReader SourceReader = System.IO.File.OpenText(pathToFile))
{
var templateInfo = SourceReader.ReadToEnd();
sendEmailConfig.HtmlBodyStr = string.Format(templateInfo,
//--- 附件为疾病进展确认报告,请查收
_localizer["TrialEmailN_SubjectDiseaseProgression"]
);
}
}
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<ReadingTableQuestionAnswer>().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<Guid>() { visitTaskId }, minUserIdList);
if (answer == "是")
{
//把另外一个人的任务设置为不加急(如果项目加急是否 subject 加急是否)
var urgent = _repository.Where<SubjectVisit>(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
{
//---发送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 _repository.Where<ReadModule>(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<Guid>() { 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<Guid>() { 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);
//先预先生成了邮件,发送预先生成的邮件
sendEmailConfig.EmailAttachMentConfigList.Add(new EmailAttachMentConfig()
{
FileName = $"{taskInfo.SubjectCode}_{Path.GetFileNameWithoutExtension(_userInfo.IsEn_Us ? emailConfig.AttachName : emailConfig.AttachNameCN)}.pdf",
FileStream = File.OpenRead(phyPath),
});
await SendEmailHelper.SendEmailAsync(sendEmailConfig);
return string.Empty;
}
var value = new Dictionary<string, object>()
{
["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(_userInfo.IsEn_Us ? emailConfig.AttachName : emailConfig.AttachNameCN)}.pdf",
FileStream = pdfMemoryStream
});
await SendEmailHelper.SendEmailAsync(sendEmailConfig);
}
return string.Empty;
#endregion
}
/// <summary>
/// 手动生成入组确认 或者PD 进展的邮件 如果能发送,会返回文件的路径,否则会给出提示
/// </summary>
/// <param name="generateEmailCommand"></param>
/// <returns></returns>
[HttpPost]
public async Task<IResponseOutput> 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(_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 == CommonDocumentBusinessScenario.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 _repository.Where<ReadingQuestionCriterionTrial>(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
{
//---当前受试者最新PD访视阅片任务完成状态不符合发送条件
return ResponseOutput.NotOk(_localizer["TrialEmailN_PDNotFinished"]);
}
}
//仲裁在阅片期上
else if (trialReadingCriterionConfig.ArbitrationRule == ArbitrationRule.Reading)
{
var existReadModule = await _repository.Where<ReadModule>(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 _repository.Where<ReadModule>(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"]);
}
}
/// <summary>
/// 手动发送邮件
/// </summary>
/// <param name="visitTaskId"></param>
/// <param name="sendFileRelativePath"></param>
/// <returns></returns>
[HttpPut]
public async Task<IResponseOutput> ManualSendEmail(Guid visitTaskId, string sendFileRelativePath)
{
var filePath = await BaseBusinessScenarioSendEmailAsync(visitTaskId, true, EmailStoreSendMode.NotStoreLocalOnlySentEmail, sendFileRelativePath);
return ResponseOutput.Ok();
}
/// <summary>
///
/// </summary>
/// <param name="visitTaskId"> 任务Id</param>
/// <param name="readingCategory"> 任务类型</param>
/// <param name="criterionType">标准类型</param>
/// <param name="IsGlobalGenerate"> 是否是全局产生(区分裁判任务)</param>
/// <returns></returns>
/// <exception cref="BusinessValidationFailedException"></exception>
private async Task<string> TranslatePdStateAsync(Guid visitTaskId, ReadingCategory readingCategory, CriterionType criterionType, bool? IsGlobalGenerate = null)
{
var answer = string.Empty;
ReadingTaskQuestionAnswer visitQuestionAnswer = null;
ReadingTaskQuestionAnswer globalQuestionAnswer = null;
switch (criterionType)
{
case CriterionType.RECIST1Point1:
if (readingCategory == ReadingCategory.Visit)
{
visitQuestionAnswer = await _repository.Where<ReadingTaskQuestionAnswer>(t => t.VisitTaskId == visitTaskId && t.ReadingQuestionTrial.QuestionType == QuestionType.Tumor).FirstNotNullAsync();
answer = visitQuestionAnswer.Answer;
}
else if (readingCategory == ReadingCategory.Global)
{
var questionAnsewer = await _repository.Where<ReadingGlobalTaskInfo>(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<ReadingTaskQuestionAnswer>(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<ReadingTaskQuestionAnswer>(t => t.VisitTaskId == judgeResultTaskId && t.ReadingQuestionTrial.QuestionType == QuestionType.Tumor).FirstNotNullAsync();
// answer = questionAnsewer.Answer;
//}
else
{
//---不应有 除访视、裁判、全局其他类型的任务进行发送邮件,请核查业务逻辑
throw new BusinessValidationFailedException(_localizer["TrialEmailN_InvalidTaskTypeForEmailSending"]);
}
if (answer == OverallAssessment.PD.GetEnumInt())
{
answer = "是";
}
else
{
answer = "否";
}
break;
case CriterionType.PCWG3:
if (readingCategory == ReadingCategory.Visit)
{
visitQuestionAnswer = await _repository.Where<ReadingTaskQuestionAnswer>(t => t.VisitTaskId == visitTaskId && t.ReadingQuestionTrial.QuestionType == QuestionType.SiteVisitForTumorEvaluation).FirstNotNullAsync();
answer = visitQuestionAnswer.Answer;
}
else if (readingCategory == ReadingCategory.Global)
{
var questionAnsewer = await _repository.Where<ReadingGlobalTaskInfo>(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<ReadingTaskQuestionAnswer>(t => t.VisitTaskId == visitTaskId && t.ReadingQuestionTrial.QuestionType == QuestionType.SiteVisitForTumorEvaluation).FirstNotNullAsync();
// answer = questionAnsewer.Answer;
//}
else
{
//---不应有 除访视、裁判、全局其他类型的任务进行发送邮件,请核查业务逻辑
throw new BusinessValidationFailedException(_localizer["TrialEmailN_InvalidTaskTypeForEmailSending"]);
}
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.IRECIST1Point1:
case CriterionType.RANO_BM:
case CriterionType.RANO:
case CriterionType.IWCLL2018:
case CriterionType.mRECISTHCC:
case CriterionType.Cheson2007:
case CriterionType.IMWG2016:
default:
//---该标准任务还未定义PD获取逻辑联系业务和后台开发协商后补充
throw new BusinessValidationFailedException(_localizer["TrialEmailN_PDLogicNotDefined"]);
}
return answer;
}
/// <summary>
/// 选择人员下拉
/// </summary>
/// <param name="trialId"></param>
/// <returns></returns>
public async Task<List<TrialUserType>> GetTrialUserTypeSelectList(Guid trialId)
{
var query = _trialUserRepository.Where(t => t.TrialId == trialId, false, true).IgnoreQueryFilters().Select(t => t.User.UserTypeRole).Distinct()
.ProjectTo<TrialUserType>(_mapper.ConfigurationProvider);
return await query.ToListAsync();
}
/// <summary>
/// 黑名单用户Id 列表
/// </summary>
/// <param name="trialId"></param>
/// <returns></returns>
public async Task<List<TrialSelectUser>> GetTrialUserIdSelectList(Guid trialId)
{
var query = _trialUserRepository.Where(t => t.TrialId == trialId, false, true).IgnoreQueryFilters()
.Select(t => new TrialSelectUser()
{
UserId = t.UserId,
UserName = t.User.UserName,
RealName = t.User.FullName,
UserTypeEnum = t.User.UserTypeEnum
}).Distinct();
return await query.ToListAsync();
}
/// <summary>
/// 获取系统 邮件配置 勾选列表
/// </summary>
/// <param name="queryEmailNoticeConfig"></param>
/// <returns></returns>
public async Task<PageOutput<TrialSelectEmailNoticeConfigView>> GetSysEmailNoticeConfigList(EmailNoticeConfigQuery queryEmailNoticeConfig)
{
var emailNoticeConfigQueryable = _emailNoticeConfigRepository
.WhereIf(queryEmailNoticeConfig.BusinessScenarioEnum != null, t => t.BusinessScenarioEnum == queryEmailNoticeConfig.BusinessScenarioEnum)
.WhereIf(queryEmailNoticeConfig.IsReturnRequired != null, t => t.IsReturnRequired == queryEmailNoticeConfig.IsReturnRequired)
.WhereIf(queryEmailNoticeConfig.IsEnable != null, t => t.IsEnable == queryEmailNoticeConfig.IsEnable)
.ProjectTo<TrialSelectEmailNoticeConfigView>(_mapper.ConfigurationProvider, new { trialId = queryEmailNoticeConfig.TrialId });
return await emailNoticeConfigQueryable.ToPagedListAsync(queryEmailNoticeConfig.PageIndex, queryEmailNoticeConfig.PageSize, queryEmailNoticeConfig.SortField, queryEmailNoticeConfig.Asc);
}
/// <summary>
/// 批量勾选 传递列表每行数据,后台进行处理转换,建立关联关系
/// </summary>
/// <param name="batchAddList"></param>
/// <returns></returns>
public async Task<IResponseOutput> BatchAddSysEmailConfig(List<BatchAddTrialEmailNoticeConfig> batchAddList)
{
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 _repository.Where<ReadingQuestionCriterionTrial>(t => t.TrialId == trialId && t.IsConfirm).Select(t => new { t.CriterionType, TrialReadingCriterionId = t.Id }).ToListAsync();
var addList = _mapper.Map<List<TrialEmailNoticeConfig>>(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.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();
return ResponseOutput.Ok();
}
[HttpPost]
public async Task<List<TrialEmailNoticeConfigView>> 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<TrialEmailNoticeConfigView>(_mapper.ConfigurationProvider);
return await trialEmailNoticeConfigQueryable.ToListAsync();
}
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
public async Task<IResponseOutput> AddOrUpdateTrialEmailNoticeConfig(TrialEmailNoticeConfigAddOrEdit addOrEditTrialEmailNoticeConfig)
{
await TestEmailConfigAsync(addOrEditTrialEmailNoticeConfig);
if (addOrEditTrialEmailNoticeConfig.Id == null)
{
var entity = _mapper.Map<TrialEmailNoticeConfig>(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 _repository.BatchDeleteAsync<TrialEmailNoticeUser>(t => t.TrialEmailNoticeConfigId == addOrEditTrialEmailNoticeConfig.Id);
await _repository.BatchDeleteAsync<TrialEmailBlackUser>(t => t.TrialEmailNoticeConfigId == addOrEditTrialEmailNoticeConfig.Id);
List<TrialEmailNoticeUser> trialEmailNoticeUsers = new List<TrialEmailNoticeUser>();
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 _repository.AddRangeAsync(trialEmailNoticeUsers);
foreach (var userid in addOrEditTrialEmailNoticeConfig.BlackUserIdList)
{
await _trialEmailBlackUserRepository.AddAsync(new TrialEmailBlackUser() { UserId = userid, TrialEmailNoticeConfigId = id });
}
await _trialEmailNoticeConfigRepository.UpdateFromDTOAsync(addOrEditTrialEmailNoticeConfig);
await _trialEmailNoticeConfigRepository.SaveChangesAsync();
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"] + ex.Message);
}
#region 人员还未加入,可以先配置邮件 历史废弃
//var toUserList = await _repository.Where<TrialUser>(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
}
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
[HttpDelete("{trialEmailNoticeConfigId:guid}")]
public async Task<IResponseOutput> DeleteTrialEmailNoticeConfig(Guid trialEmailNoticeConfigId)
{
var success = await _trialEmailNoticeConfigRepository.DeleteFromQueryAsync(t => t.Id == trialEmailNoticeConfigId, true);
return ResponseOutput.Ok();
}
}
}