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

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