irc-netcore-api/IRaCIS.Core.Application/Service/Document/EmailSendService.cs

365 lines
17 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.

using DocumentFormat.OpenXml.EMMA;
using DocumentFormat.OpenXml.Spreadsheet;
using IRaCIS.Core.Application.Contracts;
using IRaCIS.Core.Application.Helper;
using IRaCIS.Core.Application.Service.Reading.Dto;
using IRaCIS.Core.Domain.Models;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Infrastructure;
using MailKit;
using Microsoft.Extensions.Options;
using Microsoft.VisualBasic;
using MimeKit;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Mail;
using System.Text;
using System.Threading.Tasks;
namespace IRaCIS.Core.Application.Service
{
public interface IEmailSendService
{
Task SendEnrollOrPdEmail(Guid visitTaskId, bool? isEnrollment, bool? isPDConfirm);
Task SendClinicalDataQuestionAsync(Guid visitTaskId, string content);
Task SendTrialImageQCTaskEmailAsync(Guid trialId);
Task SendTrialQCQuestionEmailAsync(Guid trialId);
Task SendTrialImageQuestionAsync(Guid trialId);
}
public class EmailSendService : BaseService, IEmailSendService
{
private readonly IRepository<TrialEmailNoticeConfig> _trialEmailNoticeConfigRepository;
private readonly IRepository<EmailNoticeConfig> _emailNoticeConfigRepository;
private readonly IRepository<Trial> _trialRepository;
private readonly IOptionsMonitor<SystemEmailSendConfig> _SystemEmailSendConfig;
public EmailSendService(IRepository<TrialEmailNoticeConfig> trialEmailNoticeConfigRepository, IRepository<EmailNoticeConfig> emailNoticeConfigRepository, IRepository<Trial> trialRepository, IOptionsMonitor<SystemEmailSendConfig> systemEmailSendConfig)
{
_trialEmailNoticeConfigRepository = trialEmailNoticeConfigRepository;
_emailNoticeConfigRepository = emailNoticeConfigRepository;
_trialRepository = trialRepository;
_SystemEmailSendConfig = systemEmailSendConfig;
}
//入组确认/PD确认
public async Task SendEnrollOrPdEmail(Guid visitTaskId, bool? isEnrollment, bool? isPDConfirm)
{
EmailBusinessScenario businessScenarioEnum;
bool? result = null;
if (isEnrollment != null && isPDConfirm == null)
{
businessScenarioEnum = EmailBusinessScenario.EnrollConfirmed;
result = isEnrollment;
}
else
{
businessScenarioEnum = EmailBusinessScenario.PDConfirmed;
result = isPDConfirm;
}
var taskInfo = await _repository.Where<VisitTask>(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 resultStr = _userInfo.IsEn_Us ? (result == true ? "Yes" : "No") : (result == true ? "是" : "否");
Func<TrialEmailNoticeConfig, (string topicStr, string htmlBodyStr)> topicAndHtmlFunc = trialEmailConfig =>
{
var topicStr = string.Format(_userInfo.IsEn_Us ? trialEmailConfig.EmailTopic : trialEmailConfig.EmailTopicCN, taskInfo.ResearchProgramNo, taskInfo.SubjectCode);
var htmlBodyStr = string.Format(_userInfo.IsEn_Us ? trialEmailConfig.EmailHtmlContent : trialEmailConfig.EmailHtmlContentCN,
taskInfo.ResearchProgramNo, taskInfo.SubjectCode, resultStr);
return (topicStr, htmlBodyStr);
};
await SendTrialEmailAsync(taskInfo.TrialId, businessScenarioEnum, topicAndHtmlFunc);
}
/// <summary>
/// 影像质控
/// </summary>
/// <param name="trialId"></param>
/// <returns></returns>
public async Task SendTrialImageQCTaskEmailAsync(Guid trialId)
{
var trialInfo = _repository.Where<Trial>(t => t.Id == trialId).Select(t => new { t.ResearchProgramNo, t.ExperimentName, t.TrialCode, t.TrialStatusStr }).FirstOrDefault();
//找到 该项目的IQC 用户Id
var userList = await _repository.Where<TrialUser>(t => t.TrialId == trialId).Where(t => t.User.UserTypeEnum == UserTypeEnum.IQC).Select(t => new { t.UserId, t.User.FullName }).ToListAsync();
//判断是否任务可以领取 ,可以的话 发送邮件
var userIdList = userList.Select(t => t.UserId).ToList();
foreach (var user in userList)
{
var userId = user.UserId;
//过滤项目 并且 将 _userInfo.Id 换位 当前发送邮件的Id
var query = _trialRepository.Where(t => t.Id == trialId)
.Where(t => t.QCProcessEnum != TrialQCProcess.NotAudit)
.Select(t => new
{
//待领取量
ToBeClaimedCount = t.SubjectVisitList.Where(u => u.SubmitState==SubmitStateEnum.Submitted && u.CurrentActionUserId == null && (u.PreliminaryAuditUserId == null || (u.PreliminaryAuditUserId != userId && u.ReviewAuditUserId == null))).Count(),
//待审核通过统计从已领取到QC提交之间的 已领取 待审核 审核中 (审核完成 领取人就会清理 所以只用查询当前领取人是自己的就好了)
ToBeReviewedCount = t.SubjectVisitList.Where(u => u.CurrentActionUserId == userId).Count()
});
var sendStat = await query.FirstOrDefaultAsync();
//当前人 有待领取的或者有待审核的才发邮件
if (sendStat != null && (sendStat.ToBeClaimedCount > 0 || sendStat.ToBeReviewedCount > 0))
{
Func<TrialEmailNoticeConfig, (string topicStr, string htmlBodyStr)> topicAndHtmlFunc = trialEmailConfig =>
{
var topicStr = string.Format(_userInfo.IsEn_Us ? trialEmailConfig.EmailTopic : trialEmailConfig.EmailTopicCN, trialInfo.ResearchProgramNo);
var htmlBodyStr = string.Format(_userInfo.IsEn_Us ? trialEmailConfig.EmailHtmlContent : trialEmailConfig.EmailHtmlContentCN,
user.FullName, DateTime.Now, sendStat.ToBeClaimedCount, sendStat.ToBeReviewedCount, _SystemEmailSendConfig.CurrentValue.SiteUrl);
return (topicStr, htmlBodyStr);
};
await SendTrialEmailAsync(trialId, EmailBusinessScenario.QCTask, topicAndHtmlFunc);
}
}
}
/// <summary>
/// QC质疑
/// </summary>
/// <param name="trialId"></param>
/// <returns></returns>
public async Task SendTrialQCQuestionEmailAsync(Guid trialId)
{
var trialInfo = _repository.Where<Trial>(t => t.Id == trialId).Select(t => new { t.ResearchProgramNo, t.ExperimentName, t.TrialCode, t.TrialStatusStr }).FirstOrDefault();
//找到 该项目的IQC 用户Id
var userList = await _repository.Where<TrialUser>(t => t.TrialId == trialId).Where(t => t.User.UserTypeEnum == UserTypeEnum.IQC).Select(t => new { t.UserId, t.User.FullName }).ToListAsync();
//判断是否任务可以领取 ,可以的话 发送邮件
foreach (var user in userList)
{
var userId = user.UserId;
//过滤项目 并且 将 _userInfo.Id 换位 当前发送邮件的Id
var query = _trialRepository
.Where(t => t.Id == trialId)
.Select(t => new
{
ReUploadTobeDealedCount = t.SubjectVisitList.SelectMany(c => c.QCChallengeList)
.Where(u => u.CreateUserId == userId && u.IsClosed == false && u.LatestReplyUser.UserTypeEnum == UserTypeEnum.ClinicalResearchCoordinator && u.ReuploadEnum == QCChanllengeReuploadEnum.CRCRequestReupload).Count(),
//质疑待处理
ToBeDealedCount = t.SubjectVisitList.SelectMany(c => c.QCChallengeList)
.Where(u => u.CreateUserId == userId && u.IsClosed == false && u.LatestReplyUser.UserTypeEnum == UserTypeEnum.ClinicalResearchCoordinator).Count(),
});
var sendStat = await query.FirstOrDefaultAsync();
//当前人
if (sendStat != null && (sendStat.ToBeDealedCount > 0 || sendStat.ReUploadTobeDealedCount > 0))
{
Func<TrialEmailNoticeConfig, (string topicStr, string htmlBodyStr)> topicAndHtmlFunc = trialEmailConfig =>
{
var topicStr = string.Format(_userInfo.IsEn_Us ? trialEmailConfig.EmailTopic : trialEmailConfig.EmailTopicCN, trialInfo.ResearchProgramNo);
var htmlBodyStr = string.Format(_userInfo.IsEn_Us ? trialEmailConfig.EmailHtmlContent : trialEmailConfig.EmailHtmlContentCN,
user.FullName, DateTime.Now, sendStat.ToBeDealedCount, sendStat.ReUploadTobeDealedCount, _SystemEmailSendConfig.CurrentValue.SiteUrl);
return (topicStr, htmlBodyStr);
};
await SendTrialEmailAsync(trialId, EmailBusinessScenario.QCQuestion, topicAndHtmlFunc);
}
}
}
/// <summary>
/// 影像质疑
/// </summary>
/// <param name="trialId"></param>
/// <returns></returns>
public async Task SendTrialImageQuestionAsync(Guid trialId)
{
var trialInfo = _repository.Where<Trial>(t => t.Id == trialId).Select(t => new { t.ResearchProgramNo, t.ExperimentName, t.TrialCode, t.TrialStatusStr }).FirstOrDefault();
//找到 该项目的CRC 用户Id
var userList = await _repository.Where<TrialUser>(t => t.TrialId == trialId).Where(t => t.User.UserTypeEnum == UserTypeEnum.ClinicalResearchCoordinator).Select(t => new { t.UserId, t.User.FullName }).ToListAsync();
//判断是否任务可以领取 ,可以的话 发送邮件
foreach (var user in userList)
{
var userId = user.UserId;
//过滤项目 并且 将 _userInfo.Id 换位 当前发送邮件的Id
var query = _trialRepository.Where(t=>t.Id==trialId)
.Select(t => new
{
//质疑待处理
ToBeDealedCount = t.SubjectVisitList.Where(t=>t.TrialSite.CRCUserList.Any(t=>t.UserId==userId)).SelectMany(c => c.QCChallengeList)
.Where(u => u.IsClosed == false && (u.LatestReplyUser.UserTypeEnum == UserTypeEnum.IQC || u.LatestReplyUserId==null)).Count(),
});
var sendStat = await query.FirstOrDefaultAsync();
//当前人
if (sendStat != null && (sendStat.ToBeDealedCount > 0))
{
Func<TrialEmailNoticeConfig, (string topicStr, string htmlBodyStr)> topicAndHtmlFunc = trialEmailConfig =>
{
var topicStr = string.Format(_userInfo.IsEn_Us ? trialEmailConfig.EmailTopic : trialEmailConfig.EmailTopicCN, trialInfo.ResearchProgramNo);
var htmlBodyStr = string.Format(_userInfo.IsEn_Us ? trialEmailConfig.EmailHtmlContent : trialEmailConfig.EmailHtmlContentCN,
user.FullName, DateTime.Now, sendStat.ToBeDealedCount, _SystemEmailSendConfig.CurrentValue.SiteUrl);
return (topicStr, htmlBodyStr);
};
await SendTrialEmailAsync(trialId, EmailBusinessScenario.ImageQuestion, topicAndHtmlFunc);
}
}
}
//临床数据质询
public async Task SendClinicalDataQuestionAsync(Guid visitTaskId, string content)
{
var info = await _repository.Where<VisitTask>(t => t.Id == visitTaskId, ignoreQueryFilters: true).Select(t => new { t.TrialId, t.Trial.ResearchProgramNo, t.Trial.TrialCode, t.SourceSubjectVisit.VisitName, t.Subject.Code }).FirstOrDefaultAsync();
Func<TrialEmailNoticeConfig, (string topicStr, string htmlBodyStr)> topicAndHtmlFunc = trialEmailConfig =>
{
var topicStr = string.Format(_userInfo.IsEn_Us ? trialEmailConfig.EmailTopic : trialEmailConfig.EmailTopicCN, info.ResearchProgramNo,info.Code,info.VisitName);
var htmlBodyStr = string.Format(_userInfo.IsEn_Us ? trialEmailConfig.EmailHtmlContent : trialEmailConfig.EmailHtmlContentCN,
info.ResearchProgramNo, info.Code, info.VisitName,_userInfo.UserName,content, _SystemEmailSendConfig.CurrentValue.SiteUrl);
return (topicStr, htmlBodyStr);
};
await SendTrialEmailAsync(info.TrialId, EmailBusinessScenario.ClinicalDataQuestion, topicAndHtmlFunc);
}
public async Task SendTrialEmailAsync(Guid trialId, EmailBusinessScenario businessScenario, Func<TrialEmailNoticeConfig, (string topicStr, string htmlBodyStr)> topicAndHtmlFunc, Guid? trialReadingCriterionId = null, Guid? subjectId = null)
{
//找到配置
var trialEmailConfig = await _trialEmailNoticeConfigRepository.Where(t => t.TrialId == trialId && t.TrialReadingCriterionId == trialReadingCriterionId && t.BusinessScenarioEnum == businessScenario, ignoreQueryFilters: true)
.Include(t => t.TrialEmailNoticeUserList).Include(t => t.TrialEmailBlackUserList).FirstOrDefaultAsync();
if (trialEmailConfig == null || trialEmailConfig.IsAutoSend == false)
{
return;
}
else
{
var sendEmailConfig = new SMTPEmailConfig();
var (topicStr, htmlBodyStr) = topicAndHtmlFunc(trialEmailConfig);
sendEmailConfig.TopicDescription = topicStr;
sendEmailConfig.HtmlBodyStr = htmlBodyStr;
var blackUserIdList = trialEmailConfig.TrialEmailBlackUserList.Select(t => t.UserId).ToList();
//收件人 如果是CRC CRA 要按照中心发送
var toUserTypeEnumList = trialEmailConfig.TrialEmailNoticeUserList.Where(t => t.EmailUserType == EmailUserType.To).Select(c => c.UserType).ToList();
var copyUserTypeEnumList = trialEmailConfig.TrialEmailNoticeUserList.Where(t => t.EmailUserType == EmailUserType.Copy).Select(c => c.UserType).ToList();
var allUserTypeEnumList = toUserTypeEnumList.Union(copyUserTypeEnumList).Distinct().ToList();
var allUserList = await _repository.Where<TrialUser>(t => t.TrialId == trialId && allUserTypeEnumList.Contains(t.User.UserTypeEnum)).Select(t => new { t.UserId, t.User.EMail, t.User.FullName, t.User.UserTypeEnum }).ToListAsync();
var toUserList = allUserList.Where(t => toUserTypeEnumList.Contains(t.UserTypeEnum))
.ToList();
if (subjectId != null)
{
toUserList = _repository.Where<TrialSiteUser>(t => t.TrialId == trialId && toUserTypeEnumList.Contains(t.User.UserTypeEnum) && t.TrialSite.SubjectList.Any(c => c.Id == subjectId)).Select(t => new { t.UserId, t.User.EMail, t.User.FullName, t.User.UserTypeEnum }).ToList();
}
//去除黑名单
toUserList = toUserList.Where(t => !blackUserIdList.Contains(t.UserId)).ToList();
var copyUserList = allUserList.Where(t => copyUserTypeEnumList.Contains(t.UserTypeEnum)).Where(t => !blackUserIdList.Contains(t.UserId)).ToList();
if (toUserList.Count() == 0)
{
//---没有收件人,无法发送邮件
throw new BusinessValidationFailedException(_localizer["TrialEmailN_NoRecipient"]);
}
if (trialEmailConfig.FromEmail.Contains("@") && !string.IsNullOrEmpty(trialEmailConfig.FromEmail))
{
sendEmailConfig.FromEmailAddress = new MimeKit.MailboxAddress(trialEmailConfig.FromName, trialEmailConfig.FromEmail);
sendEmailConfig.AuthorizationCode = trialEmailConfig.AuthorizationCode;
sendEmailConfig.UserName = trialEmailConfig.FromEmail;
sendEmailConfig.Host = trialEmailConfig.SMTPServerAddress;
sendEmailConfig.Port = trialEmailConfig.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));
}
}
await SendEmailHelper.SendEmailAsync(sendEmailConfig);
}
}
}
}