irc-netcore-api/IRaCIS.Core.Application/Service/Common/MailService.cs

738 lines
31 KiB
C#

using IRaCIS.Core.Domain.Share;
using MimeKit;
using IRaCIS.Core.Application.Helper;
using MailKit;
using Microsoft.AspNetCore.Hosting;
using IRaCIS.Core.Application.Auth;
using AutoMapper;
using IRaCIS.Application.Contracts;
using Microsoft.Extensions.Options;
using Medallion.Threading;
using System.Text.RegularExpressions;
using IRaCIS.Core.Infrastructure;
using DocumentFormat.OpenXml.Spreadsheet;
using IRaCIS.Core.Application.Service.Reading.Dto;
using NPOI.SS.Formula.Functions;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
using IRaCIS.Core.Domain.Models;
using DocumentFormat.OpenXml.Office2013.Excel;
using IRaCIS.Core.Application.Contracts;
using DocumentFormat.OpenXml.Vml;
namespace IRaCIS.Application.Services
{
public interface IMailVerificationService
{
Task AnolymousSendEmail(string researchProgramNo, string emailAddress, int verificationCode);
Task SendEmailVerification(string emailAddress, int verificationCode);
Task SiteSurveyRejectEmail(MimeMessage messageToSend, TrialSiteSurvey trialSiteSurvey, string routeUrl, User? user = null);
Task SenMFAVerifyEmail(Guid userId, string userName, string emailAddress, int verificationCode, UserMFAType mfaType = UserMFAType.Login);
Task SendMailEditEmail(Guid userId, string userName, string emailAddress, int verificationCode);
Task AnolymousSendEmailForResetAccount(string emailAddress, int verificationCode);
Task AddUserSendEmailAsync(Guid userId, string baseUrl, string routeUrl);
Task AdminResetPwdSendEmailAsync(Guid userId, string pwdNotMd5 = "123456");
Task SiteSurveyUserJoinEmail(Guid trialId, Guid userId, string baseUrl, string rootUrl);
Task ExternalUserJoinEmail(Guid trialId, Guid userId, string baseUrl, string rootUrl);
Task<Guid> DoctorJoinTrialEmail(Guid trialId, Guid doctorId, string baseUrl, string rootUrl);
}
public class MailVerificationService : BaseService, IMailVerificationService
{
private readonly IRepository<VerificationCode> _verificationCodeRepository;
private readonly IRepository<SystemBasicData> _systemBasicDatarepository;
private readonly IRepository<User> _userRepository;
private readonly ITokenService _tokenService;
private readonly IRepository<Trial> _trialRepository;
private readonly IRepository<UserType> _userTypeRepository;
private readonly IRepository<Doctor> _doctorTypeRepository;
private readonly IDistributedLockProvider _distributedLockProvider;
private readonly SystemEmailSendConfig _systemEmailConfig;
private readonly IRepository<EmailNoticeConfig> _emailNoticeConfigrepository;
public MailVerificationService(IRepository<VerificationCode> verificationCodeRepository,
IRepository<SystemBasicData> systemBasicDatarepository,
IRepository<User> userRepository,
ITokenService tokenService,
IRepository<Trial> trialRepository,
IRepository<UserType> userTypeRepository,
IRepository<Doctor> doctorTypeRepository,
IRepository<EmailNoticeConfig> emailNoticeConfigRepository,
IOptionsMonitor<SystemEmailSendConfig> systemEmailConfig, IDistributedLockProvider distributedLockProvider)
{
_systemEmailConfig = systemEmailConfig.CurrentValue;
_verificationCodeRepository = verificationCodeRepository;
_systemBasicDatarepository = systemBasicDatarepository;
_tokenService = tokenService;
_userRepository = userRepository;
_trialRepository = trialRepository;
_userTypeRepository = userTypeRepository;
_doctorTypeRepository = doctorTypeRepository;
_distributedLockProvider = distributedLockProvider;
_emailNoticeConfigrepository = emailNoticeConfigRepository;
}
private async Task<MimeMessage> GetEmailSubejctAndHtmlInfoAndBuildAsync(EmailBusinessScenario scenario, MimeMessage messageToSend,
Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr)> emailFunc)
{
var configInfo = await _emailNoticeConfigrepository.Where(t => t.BusinessScenarioEnum == scenario).FirstOrDefaultAsync();
if (configInfo == null)
{
throw new BusinessValidationFailedException("系统未找到当前场景邮件配置信息,请联系运维人员核查");
}
var (topicStr, htmlBodyStr) = _userInfo.IsEn_Us ? (configInfo.EmailTopic, configInfo.EmailHtmlContent) : (configInfo.EmailTopicCN, configInfo.EmailHtmlContentCN);
try
{
//每个场景修改主题 和body的逻辑不一样
(topicStr, htmlBodyStr) = emailFunc((topicStr, htmlBodyStr));
}
catch (Exception ex)
{
throw new BusinessValidationFailedException("邮件模板内容有误,填充内容出现问题,请联系运维人员核查");
}
messageToSend.Subject = topicStr;
var builder = new BodyBuilder();
builder.HtmlBody = htmlBodyStr;
messageToSend.Body = builder.ToMessageBody();
return messageToSend;
}
private EventHandler<MessageSentEventArgs> GetEmailSuccessHandle(Guid userId, int verificationCode, string email = "")
{
EventHandler<MessageSentEventArgs> sucessHandle = (sender, args) =>
{
// args.Response
var code = verificationCode.ToString();
_ = _verificationCodeRepository.AddAsync(new VerificationCode()
{
CodeType = VerifyType.Email,
HasSend = true,
Code = code,
UserId = userId,
EmailOrPhone = email,
ExpirationTime = DateTime.Now.AddMinutes(3)
}).Result;
_ = _verificationCodeRepository.SaveChangesAsync().Result;
};
return sucessHandle;
}
private string ReplaceCompanyName(string needDealtxt)
{
var str = needDealtxt.Replace("{company}", _userInfo.IsEn_Us ? _systemEmailConfig.CompanyName : _systemEmailConfig.CompanyNameCN)
.Replace("{company abbreviation}", _userInfo.IsEn_Us ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN);
return str;
}
//MFA
public async Task SenMFAVerifyEmail(Guid userId, string userName, string emailAddress, int verificationCode, UserMFAType mfaType = UserMFAType.Login)
{
var messageToSend = new MimeMessage();
//发件地址
messageToSend.From.Add(new MailboxAddress(_systemEmailConfig.FromName, _systemEmailConfig.FromEmail));
//收件地址
messageToSend.To.Add(new MailboxAddress(userName, emailAddress));
//主题---[来自{0}] 关于MFA邮箱验证的提醒
var companyName = _userInfo.IsEn_Us ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN;
Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr)> emailConfigFunc = input =>
{
var topicStr = string.Format(input.topicStr, companyName);
var htmlBodyStr = string.Format(ReplaceCompanyName(input.htmlBodyStr),
userName,
_localizer[mfaType == UserMFAType.Login ? "Mail_EmailMFALoginEmail" : "Mail_EmailMFAUnlockEmail"],
verificationCode
);
return (topicStr, htmlBodyStr);
};
messageToSend = await GetEmailSubejctAndHtmlInfoAndBuildAsync(mfaType == UserMFAType.Login ? EmailBusinessScenario.MFALogin : EmailBusinessScenario.MFAUnlock, messageToSend, emailConfigFunc);
var sucessHandle = GetEmailSuccessHandle(userId, verificationCode, emailAddress);
await SendEmailHelper.SendEmailAsync(messageToSend, _systemEmailConfig, sucessHandle);
}
//用户重置邮箱
public async Task SendMailEditEmail(Guid userId, string userName, string emailAddress, int verificationCode)
{
var messageToSend = new MimeMessage();
//发件地址
messageToSend.From.Add(new MailboxAddress(_systemEmailConfig.FromName, _systemEmailConfig.FromEmail));
//收件地址
messageToSend.To.Add(new MailboxAddress(userName, emailAddress));
//主题
//---[来自展影IRC] 关于重置邮箱的提醒
var companyName = _userInfo.IsEn_Us ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN;
Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr)> emailConfigFunc = input =>
{
var topicStr = string.Format(input.topicStr, companyName);
var htmlBodyStr = string.Format(ReplaceCompanyName(input.htmlBodyStr),
userName,
//---您正在进行邮箱重置操作
_localizer["Mail_ResettingEmail"],
verificationCode
);
return (topicStr, htmlBodyStr);
};
messageToSend = await GetEmailSubejctAndHtmlInfoAndBuildAsync(EmailBusinessScenario.UserResetEmail, messageToSend, emailConfigFunc);
var sucessHandle = GetEmailSuccessHandle(userId, verificationCode, emailAddress);
await SendEmailHelper.SendEmailAsync(messageToSend, _systemEmailConfig, sucessHandle);
}
//不登录 通过邮箱重置密码
public async Task AnolymousSendEmailForResetAccount(string emailAddress, int verificationCode)
{
var messageToSend = new MimeMessage();
//发件地址
messageToSend.From.Add(new MailboxAddress(_systemEmailConfig.FromName, _systemEmailConfig.FromEmail));
//收件地址
messageToSend.To.Add(new MailboxAddress(String.Empty, emailAddress));
var companyName = _userInfo.IsEn_Us ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN;
Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr)> emailConfigFunc = input =>
{
var topicStr = string.Format(input.topicStr, companyName);
var htmlBodyStr = string.Format(ReplaceCompanyName(input.htmlBodyStr),
"",
//---您正在进行邮箱重置密码操作
_localizer["Mail_ResettingPassword"],
verificationCode
);
return (topicStr, htmlBodyStr);
};
messageToSend = await GetEmailSubejctAndHtmlInfoAndBuildAsync(EmailBusinessScenario.UnloginUseEmailResetPassword, messageToSend, emailConfigFunc);
////此时不知道用户
var sucessHandle = GetEmailSuccessHandle(Guid.Empty, verificationCode, emailAddress);
await SendEmailHelper.SendEmailAsync(messageToSend, _systemEmailConfig, sucessHandle);
}
/// <summary>
/// Reviewer简历录入 发送验证码
/// </summary>
/// <param name="emailAddress"></param>
/// <param name="verificationCode"></param>
/// <returns></returns>
public async Task SendEmailVerification(string emailAddress, int verificationCode)
{
var messageToSend = new MimeMessage();
//发件地址
messageToSend.From.Add(new MailboxAddress(_systemEmailConfig.FromName, _systemEmailConfig.FromEmail));
//收件地址
messageToSend.To.Add(new MailboxAddress(String.Empty, emailAddress));
//主题
//---[来自展影IRC]的提醒
var companyName = _userInfo.IsEn_Us ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN;
Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr)> emailConfigFunc = input =>
{
var topicStr = string.Format(input.topicStr, companyName);
var htmlBodyStr = string.Format(ReplaceCompanyName(input.htmlBodyStr),
"Sir or Madam",
//---您正在参与展影医疗IRC项目
_localizer["Mail_IRCProject", companyName],
verificationCode
);
return (topicStr, htmlBodyStr);
};
messageToSend = await GetEmailSubejctAndHtmlInfoAndBuildAsync(EmailBusinessScenario.UnloginUseEmailResetPassword, messageToSend, emailConfigFunc);
//此时不知道用户
var sucessHandle = GetEmailSuccessHandle(Guid.Empty, verificationCode, emailAddress);
await SendEmailHelper.SendEmailAsync(messageToSend, _systemEmailConfig, sucessHandle);
}
//中心调研 登陆
public async Task AnolymousSendEmail(string researchProgramNo, string emailAddress, int verificationCode)
{
var messageToSend = new MimeMessage();
//发件地址
messageToSend.From.Add(new MailboxAddress(_systemEmailConfig.FromName, _systemEmailConfig.FromEmail));
//收件地址
messageToSend.To.Add(new MailboxAddress(String.Empty, emailAddress));
//主题
//$"[来自展影IRC] [{researchProgramNo}] 关于中心调研的提醒";
var companyName = _userInfo.IsEn_Us ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN;
Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr)> emailConfigFunc = input =>
{
var topicStr = string.Format(input.topicStr, companyName, researchProgramNo);
var htmlBodyStr = string.Format(ReplaceCompanyName(input.htmlBodyStr),
"Sir or Madam",
//---您正在参与展影医疗IRC项目中心调研工作
_localizer["Mail_CenterResearchReminder", companyName],
verificationCode
);
return (topicStr, htmlBodyStr);
};
messageToSend = await GetEmailSubejctAndHtmlInfoAndBuildAsync(EmailBusinessScenario.SiteSurveyLogin, messageToSend, emailConfigFunc);
//此时不知道用户
var sucessHandle = GetEmailSuccessHandle(Guid.Empty, verificationCode, emailAddress);
await SendEmailHelper.SendEmailAsync(messageToSend, _systemEmailConfig, sucessHandle);
}
public async Task SiteSurveyRejectEmail(MimeMessage messageToSend, TrialSiteSurvey trialSiteSurvey, string routeUrl, User? user)
{
//发件地址
messageToSend.From.Add(new MailboxAddress(_systemEmailConfig.FromName, _systemEmailConfig.FromEmail));
var trialInfo = await _repository.FirstOrDefaultAsync<Trial>(t => t.Id == trialSiteSurvey.TrialId);
var siteInfo = await _repository.FirstOrDefaultAsync<TrialSite>(t => t.TrialId == trialSiteSurvey.TrialId && t.Id == trialSiteSurvey.TrialSiteId, true);
var companyName = _userInfo.IsEn_Us ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN;
Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr)> emailConfigFunc = input =>
{
var topicStr = string.Format(input.topicStr, companyName, trialInfo.ResearchProgramNo);
var htmlBodyStr = string.Format(ReplaceCompanyName(input.htmlBodyStr),
(user == null ? trialSiteSurvey.UserName : user.LastName + "/ " + user.FirstName),
trialInfo.TrialCode,
trialInfo.ResearchProgramNo,
trialInfo.ExperimentName,
siteInfo.TrialSiteCode,
siteInfo.TrialSiteAliasName,
trialSiteSurvey.LatestBackReason,
routeUrl,
(trialSiteSurvey.State == TrialSiteSurveyEnum.ToSubmit ? "inline - block" : "none")
);
return (topicStr, htmlBodyStr);
};
messageToSend = await GetEmailSubejctAndHtmlInfoAndBuildAsync(EmailBusinessScenario.SiteSurveyReject, messageToSend, emailConfigFunc);
await SendEmailHelper.SendEmailAsync(messageToSend, _systemEmailConfig);
}
//添加用户发送邮件
public async Task AddUserSendEmailAsync(Guid userId, string baseUrl, string routeUrl)
{
var sysUserInfo = (await _userRepository.Where(t => t.Id == userId).Include(t => t.UserTypeRole).FirstOrDefaultAsync()).IfNullThrowException();
var messageToSend = new MimeMessage();
//发件地址
messageToSend.From.Add(new MailboxAddress(_systemEmailConfig.FromName, _systemEmailConfig.FromEmail));
//收件地址
messageToSend.To.Add(new MailboxAddress(sysUserInfo.FullName, sysUserInfo.EMail));
//主题
//---[来自展影IRC] 关于创建账户的提醒
var token = _tokenService.GetToken(IRaCISClaims.Create(_mapper.Map<UserBasicInfo>(sysUserInfo)));
await _userRepository.BatchUpdateNoTrackingAsync(t => t.Id == sysUserInfo.Id, u => new User() { EmailToken = token });
routeUrl = routeUrl + "?UserId=" + sysUserInfo.Id + "&Email=" + sysUserInfo.EMail + "&UserName=" + sysUserInfo.UserName + "&UserType=" + sysUserInfo.UserTypeRole.UserTypeShortName + "&lang=" + (_userInfo.IsEn_Us ? "en" : "zh") + "&access_token=" + token;
var domain = baseUrl.Substring(0, baseUrl.IndexOf("/login"));
var redirectUrl = $"{domain}/api/User/UserRedirect?url={System.Web.HttpUtility.UrlEncode(routeUrl)}";
var companyName = _userInfo.IsEn_Us ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN;
Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr)> emailConfigFunc = input =>
{
var topicStr = string.Format(input.topicStr, companyName);
var htmlBodyStr = string.Format(ReplaceCompanyName(input.htmlBodyStr),
sysUserInfo.FullName,
sysUserInfo.UserName,
sysUserInfo.UserTypeRole.UserTypeShortName,
redirectUrl
);
return (topicStr, htmlBodyStr);
};
messageToSend = await GetEmailSubejctAndHtmlInfoAndBuildAsync(EmailBusinessScenario.SysCreateUser, messageToSend, emailConfigFunc);
await SendEmailHelper.SendEmailAsync(messageToSend, _systemEmailConfig);
}
//管理员重置密码发送邮件
public async Task AdminResetPwdSendEmailAsync(Guid userId, string pwdNotMd5 = "123456")
{
var sysUserInfo = (await _userRepository.Where(t => t.Id == userId).Include(t => t.UserTypeRole).FirstOrDefaultAsync()).IfNullThrowException();
var messageToSend = new MimeMessage();
//发件地址
messageToSend.From.Add(new MailboxAddress(_systemEmailConfig.FromName, _systemEmailConfig.FromEmail));
//收件地址
messageToSend.To.Add(new MailboxAddress(sysUserInfo.FullName, sysUserInfo.EMail));
//主题
//---[来自展影IRC] 关于重置账户密码的提醒
var companyName = _userInfo.IsEn_Us ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN;
Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr)> emailConfigFunc = input =>
{
var topicStr = string.Format(input.topicStr, companyName);
var htmlBodyStr = string.Format(ReplaceCompanyName(input.htmlBodyStr),
sysUserInfo.FullName,
sysUserInfo.UserName,
sysUserInfo.UserTypeRole.UserTypeShortName,
pwdNotMd5
);
return (topicStr, htmlBodyStr);
};
messageToSend = await GetEmailSubejctAndHtmlInfoAndBuildAsync(EmailBusinessScenario.SysResetPassword, messageToSend, emailConfigFunc);
await SendEmailHelper.SendEmailAsync(messageToSend, _systemEmailConfig);
}
//Site调研 用户加入项目
public async Task SiteSurveyUserJoinEmail(Guid trialId, Guid userId, string baseUrl, string rootUrl)
{
var sysUserInfo = (await _userRepository.Where(t => t.Id == userId).Include(t => t.UserTypeRole).FirstOrDefaultAsync()).IfNullThrowException();
var trialInfo = await _trialRepository.FirstOrDefaultAsync(t => t.Id == trialId);
var messageToSend = new MimeMessage();
//发件地址
messageToSend.From.Add(new MailboxAddress(_systemEmailConfig.FromName, _systemEmailConfig.FromEmail));
//收件地址
messageToSend.To.Add(new MailboxAddress(sysUserInfo.FullName, sysUserInfo.EMail));
//主题
// $"[来自展影IRC] [{trialInfo.ResearchProgramNo}]邀请信";
var token = _tokenService.GetToken(IRaCISClaims.Create(_mapper.Map<UserBasicInfo>(sysUserInfo)));
if (sysUserInfo.IsFirstAdd)
{
await _userRepository.BatchUpdateNoTrackingAsync(t => t.Id == sysUserInfo.Id, u => new User() { EmailToken = token });
}
var routeUrl = rootUrl + "?UserId=" + sysUserInfo.Id + "&Email=" + sysUserInfo.EMail + "&UserName=" + sysUserInfo.UserName + "&UserType=" + sysUserInfo.UserTypeRole.UserTypeShortName + "&lang=" + (_userInfo.IsEn_Us ? "en" : "zh") + "&access_token=" + token;
var domain = baseUrl.Substring(0, baseUrl.IndexOf("/login"));
var redirectUrl = $"{domain}/api/User/UserRedirect?url={System.Web.HttpUtility.UrlEncode(routeUrl)}";
var companyName = _userInfo.IsEn_Us ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN;
Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr)> emailConfigFunc = input =>
{
var topicStr = string.Format(input.topicStr, companyName, trialInfo.ResearchProgramNo);
var htmlBodyStr = string.Format(ReplaceCompanyName(input.htmlBodyStr),
sysUserInfo.FullName,
trialInfo.ExperimentName,
trialInfo.ResearchProgramNo,
trialInfo.TrialCode,
sysUserInfo.UserName,
sysUserInfo.UserTypeRole.UserTypeShortName,
sysUserInfo.IsFirstAdd ? redirectUrl : baseUrl
);
return (topicStr, htmlBodyStr);
};
messageToSend = await GetEmailSubejctAndHtmlInfoAndBuildAsync(sysUserInfo.IsFirstAdd ? EmailBusinessScenario.SiteUseOrExternalUserFirstrJoinTrial : EmailBusinessScenario.SiteUserOrExternalUserExistJoinTrial, messageToSend, emailConfigFunc);
await SendEmailHelper.SendEmailAsync(messageToSend, _systemEmailConfig);
}
//外部用户 加入项目
public async Task ExternalUserJoinEmail(Guid trialId, Guid userId, string baseUrl, string rootUrl)
{
var trialInfo = (await _trialRepository.FirstOrDefaultAsync(t => t.Id == trialId)).IfNullThrowException();
var sysUserInfo = (await _userRepository.Where(t => t.Id == userId).Include(t => t.UserTypeRole).FirstOrDefaultAsync()).IfNullThrowException();
var messageToSend = new MimeMessage();
//发件地址
messageToSend.From.Add(new MailboxAddress(_systemEmailConfig.FromName, _systemEmailConfig.FromEmail));
//收件地址
messageToSend.To.Add(new MailboxAddress(String.Empty, sysUserInfo.EMail));
//主题
// $"[来自展影IRC] [{trialInfo.ResearchProgramNo}]邀请信";
var token = _tokenService.GetToken(IRaCISClaims.Create(_mapper.Map<UserBasicInfo>(sysUserInfo)));
if (sysUserInfo.IsFirstAdd)
{
await _userRepository.BatchUpdateNoTrackingAsync(t => t.Id == sysUserInfo.Id, u => new User() { EmailToken = token });
}
var domain = baseUrl.Substring(0, baseUrl.IndexOf("/login"));
var routeUrl = rootUrl + "?UserId=" + sysUserInfo.Id + "&Email=" + sysUserInfo.EMail + "&UserName=" + sysUserInfo.UserName + "&UserType=" + sysUserInfo.UserTypeRole.UserTypeShortName + "&lang=" + (_userInfo.IsEn_Us ? "en" : "zh") + "&access_token=" + token;
var redirectUrl = $"{domain}/api/User/UserRedirect?url={System.Web.HttpUtility.UrlEncode(routeUrl)}";
var companyName = _userInfo.IsEn_Us ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN;
Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr)> emailConfigFunc = input =>
{
var topicStr = string.Format(input.topicStr, companyName, trialInfo.ResearchProgramNo);
var htmlBodyStr = string.Format(ReplaceCompanyName(input.htmlBodyStr),
sysUserInfo.FullName,
trialInfo.ExperimentName,
trialInfo.ResearchProgramNo,
trialInfo.TrialCode,
sysUserInfo.UserName,
sysUserInfo.UserTypeRole.UserTypeShortName,
sysUserInfo.IsFirstAdd ? redirectUrl : baseUrl
);
return (topicStr, htmlBodyStr);
};
messageToSend = await GetEmailSubejctAndHtmlInfoAndBuildAsync(sysUserInfo.IsFirstAdd ? EmailBusinessScenario.SiteUseOrExternalUserFirstrJoinTrial : EmailBusinessScenario.SiteUserOrExternalUserExistJoinTrial, messageToSend, emailConfigFunc);
await SendEmailHelper.SendEmailAsync(messageToSend, _systemEmailConfig, null);
}
//医生生成账号加入 或者已存在账号加入到项目中
public async Task<Guid> DoctorJoinTrialEmail(Guid trialId, Guid doctorId, string baseUrl, string rootUrl)
{
var doctor = await _doctorTypeRepository.FindAsync(doctorId);
User sysUserInfo = new User();
var userType = await _userTypeRepository.FirstAsync(t => t.UserTypeEnum == UserTypeEnum.IndependentReviewer);
var @lock = _distributedLockProvider.CreateLock($"UserCode");
using (await @lock.AcquireAsync())
{
var isDoctorHaveAccount = await _userRepository.AnyAsync(t => t.DoctorId == doctorId);
if (!isDoctorHaveAccount)
{
var saveItem = new User() { FirstName = doctor.FirstName, LastName = doctor.LastName, EMail = doctor.EMail };
var trialType = await _trialRepository.Where(t => t.Id == trialId).Select(t => t.TrialType).FirstOrDefaultAsync();
if (trialType == TrialType.NoneOfficial)
{
saveItem.IsTestUser = true;
}
saveItem.Code = _userRepository.Select(t => t.Code).DefaultIfEmpty().Max() + 1;
saveItem.UserCode = AppSettings.GetCodeStr(saveItem.Code, nameof(User));
saveItem.UserName = saveItem.UserCode;
saveItem.UserTypeEnum = UserTypeEnum.IndependentReviewer;
saveItem.DoctorId = doctorId;
saveItem.UserTypeId = userType.Id;
var savedUser = await _userRepository.AddAsync(saveItem);
//下面获取Token 需要这部分信息
sysUserInfo = savedUser.Clone();
sysUserInfo.UserTypeRole = userType;
await _userRepository.SaveChangesAsync();
}
else
{
sysUserInfo = (await _userRepository.Where(t => t.DoctorId == doctorId).Include(t => t.UserTypeRole).FirstOrDefaultAsync()).IfNullThrowException();
}
}
var trialInfo = await _trialRepository.FirstOrDefaultAsync(t => t.Id == trialId);
var messageToSend = new MimeMessage();
//发件地址
messageToSend.From.Add(new MailboxAddress(_systemEmailConfig.FromName, _systemEmailConfig.FromEmail));
//收件地址
messageToSend.To.Add(new MailboxAddress(doctor.FullName, doctor.EMail));
var basicInfo = IRaCISClaims.Create(_mapper.Map<UserBasicInfo>(sysUserInfo));
////第一次添加的时候 注意赋值
//basicInfo.PermissionStr = userType.PermissionStr;
//basicInfo.UserTypeShortName = userType.UserTypeShortName;
var token = _tokenService.GetToken(basicInfo);
if (sysUserInfo.IsFirstAdd)
{
await _userRepository.BatchUpdateNoTrackingAsync(t => t.Id == sysUserInfo.Id, u => new User() { EmailToken = token });
}
var routeUrl = rootUrl + "?UserId=" + sysUserInfo.Id + "&Email=" + sysUserInfo.EMail + "&UserName=" + sysUserInfo.UserName + "&UserType=" + userType.UserTypeShortName + "&lang=" + (_userInfo.IsEn_Us ? "en" : "zh") + "&access_token=" + token;
var domain = baseUrl.Substring(0, baseUrl.IndexOf("/login"));
var redirectUrl = $"{domain}/api/User/UserRedirect?url={System.Web.HttpUtility.UrlEncode(routeUrl)}";
//主题
// $"[来自展影IRC] [{trialInfo.ResearchProgramNo}]邀请信";
var companyName = _userInfo.IsEn_Us ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN;
Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr)> emailConfigFunc = input =>
{
var topicStr = string.Format(input.topicStr, companyName, trialInfo.ResearchProgramNo);
var htmlBodyStr = string.Format(ReplaceCompanyName(input.htmlBodyStr),
sysUserInfo.FullName,
trialInfo.ExperimentName,
trialInfo.ResearchProgramNo,
trialInfo.TrialCode,
sysUserInfo.UserName,
userType.UserTypeShortName,
sysUserInfo.IsFirstAdd ? redirectUrl : baseUrl
);
return (topicStr, htmlBodyStr);
};
messageToSend = await GetEmailSubejctAndHtmlInfoAndBuildAsync(sysUserInfo.IsFirstAdd ? EmailBusinessScenario.DoctorUserFirstJoinTrial : EmailBusinessScenario.DoctorUserExistJoinTrial, messageToSend, emailConfigFunc);
await SendEmailHelper.SendEmailAsync(messageToSend, _systemEmailConfig, null);
return sysUserInfo.Id;
}
}
}