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

594 lines
22 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 Nito.AsyncEx;
namespace IRaCIS.Application.Services
{
public interface IMailVerificationService
{
Task AnolymousSendEmail(string researchProgramNo, string emailAddress, int verificationCode);
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);
Task SiteSurveyUserJoinEmail(Guid trialId, Guid userId, string baseUrl, string rootUrl);
Task ExternalUserJoinEmail(Guid trialId, Guid userId, string baseUrl, string rootUrl);
Task DoctorJoinTrialEmail(Guid trialId, Guid doctorId, string baseUrl, string rootUrl);
}
public class MailVerificationService : IMailVerificationService
{
private readonly IRepository<VerificationCode> _verificationCodeRepository;
private readonly IRepository<SystemBasicData> _systemBasicDatarepository;
private readonly IWebHostEnvironment _hostEnvironment;
private readonly IRepository<User> _userRepository;
private readonly ITokenService _tokenService;
private readonly IMapper _mapper;
private readonly IRepository<Trial> _trialRepository;
private readonly IRepository<UserType> _userTypeRepository;
private readonly IRepository<Doctor> _doctorTypeRepository;
private readonly AsyncLock _mutex = new AsyncLock();
public MailVerificationService(IRepository<VerificationCode> verificationCodeRepository,
IRepository<SystemBasicData> systemBasicDatarepository,
IWebHostEnvironment hostEnvironment,
IRepository<User> userRepository,
ITokenService tokenService,
IRepository<Trial> trialRepository,
IRepository<UserType> userTypeRepository,
IRepository<Doctor> doctorTypeRepository,
IMapper mapper)
{
_verificationCodeRepository = verificationCodeRepository;
_systemBasicDatarepository = systemBasicDatarepository;
_hostEnvironment = hostEnvironment;
_mapper = mapper;
_tokenService = tokenService;
_userRepository = userRepository;
_trialRepository = trialRepository;
_userTypeRepository = userTypeRepository;
_doctorTypeRepository = doctorTypeRepository;
}
//重置邮箱
public async Task SendMailEditEmail(Guid userId, string userName, string emailAddress, int verificationCode)
{
var messageToSend = new MimeMessage();
//发件地址
messageToSend.From.Add(new MailboxAddress("GRR", "iracis_grr@163.com"));
//收件地址
messageToSend.To.Add(new MailboxAddress(userName, emailAddress));
//主题
messageToSend.Subject = "[来自展影IRC] 关于重置邮箱的提醒";
var builder = new BodyBuilder();
var pathToFile = _hostEnvironment.WebRootPath
+ Path.DirectorySeparatorChar.ToString()
+ "EmailTemplate"
+ Path.DirectorySeparatorChar.ToString()
+ "UserOptCommon.html";
using (StreamReader SourceReader = System.IO.File.OpenText(pathToFile))
{
var templateInfo = SourceReader.ReadToEnd();
builder.HtmlBody = string.Format(templateInfo,
$" 尊敬的 {userName} , ",
"您正在进行邮箱重置操作",
verificationCode
);
}
messageToSend.Body = builder.ToMessageBody();
EventHandler<MessageSentEventArgs> sucessHandle = (sender, args) =>
{
// args.Response
var code = verificationCode.ToString();
_ = _verificationCodeRepository.AddAsync(new VerificationCode()
{
CodeType = 0,
HasSend = true,
Code = code,
UserId = userId,
ExpirationTime = DateTime.Now.AddMinutes(3)
}).Result;
_ = _verificationCodeRepository.SaveChangesAsync().Result;
};
await SendEmailHelper.SendEmailAsync(messageToSend, sucessHandle);
}
//不登录 通过邮箱重置密码
public async Task AnolymousSendEmailForResetAccount(string emailAddress, int verificationCode)
{
var messageToSend = new MimeMessage();
//发件地址
messageToSend.From.Add(new MailboxAddress("GRR", "iracis_grr@163.com"));
//收件地址
messageToSend.To.Add(new MailboxAddress(String.Empty, emailAddress));
//主题
messageToSend.Subject = "[来自展影IRC] 关于重置密码的提醒";
var builder = new BodyBuilder();
var pathToFile = _hostEnvironment.WebRootPath
+ Path.DirectorySeparatorChar.ToString()
+ "EmailTemplate"
+ Path.DirectorySeparatorChar.ToString()
+ "UserOptCommon.html";
using (StreamReader SourceReader = System.IO.File.OpenText(pathToFile))
{
var templateInfo = SourceReader.ReadToEnd();
builder.HtmlBody = string.Format(templateInfo,
"",
"您正在进行邮箱重置密码操作",
verificationCode
);
}
messageToSend.Body = builder.ToMessageBody();
EventHandler<MessageSentEventArgs> sucessHandle = (sender, args) =>
{
var code = verificationCode.ToString();
_ = _verificationCodeRepository.AddAsync(new VerificationCode()
{
CodeType = Core.Domain.Share.VerifyType.Email,
HasSend = true,
Code = code,
UserId = Guid.Empty,//此时不知道用户
EmailOrPhone = emailAddress,
ExpirationTime = DateTime.Now.AddMinutes(3)
}).Result;
_ = _verificationCodeRepository.SaveChangesAsync().Result;
};
await SendEmailHelper.SendEmailAsync(messageToSend, sucessHandle);
}
//中心调研 登陆
public async Task AnolymousSendEmail(string researchProgramNo, string emailAddress, int verificationCode)
{
var messageToSend = new MimeMessage();
//发件地址
messageToSend.From.Add(new MailboxAddress("GRR", "iracis_grr@163.com"));
//收件地址
messageToSend.To.Add(new MailboxAddress(String.Empty, emailAddress));
//主题
messageToSend.Subject = $"[来自展影IRC] [{researchProgramNo}] 关于中心调研的提醒";
var builder = new BodyBuilder();
var pathToFile = _hostEnvironment.WebRootPath
+ Path.DirectorySeparatorChar.ToString()
+ "EmailTemplate"
+ Path.DirectorySeparatorChar.ToString()
+ "UserOptCommon.html";
using (StreamReader SourceReader = System.IO.File.OpenText(pathToFile))
{
var templateInfo = SourceReader.ReadToEnd();
builder.HtmlBody = string.Format(templateInfo,
"",
"您正在参与展影医疗IRC项目中心调研工作",
verificationCode
);
}
messageToSend.Body = builder.ToMessageBody();
EventHandler<MessageSentEventArgs> sucessHandle = (sender, args) =>
{
// args.Response
var code = verificationCode.ToString();
_ = _verificationCodeRepository.AddAsync(new VerificationCode()
{
CodeType = VerifyType.Email,
HasSend = true,
Code = code,
UserId = Guid.Empty,//此时不知道用户
EmailOrPhone = emailAddress,
ExpirationTime = DateTime.Now.AddMinutes(3)
}).Result;
_ = _verificationCodeRepository.SaveChangesAsync().Result;
};
await SendEmailHelper.SendEmailAsync(messageToSend, sucessHandle);
}
//添加用户发送邮件
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("GRR", "iracis_grr@163.com"));
//收件地址
messageToSend.To.Add(new MailboxAddress(sysUserInfo.FullName, sysUserInfo.EMail));
//主题
messageToSend.Subject = "[来自展影IRC] 关于创建账户的提醒";
var builder = new BodyBuilder();
var pathToFile = _hostEnvironment.WebRootPath
+ Path.DirectorySeparatorChar.ToString()
+ "EmailTemplate"
+ Path.DirectorySeparatorChar.ToString()
+ "AdminAddUser.html";
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 + "&access_token=" + token;
var domain = baseUrl.Substring(0, baseUrl.IndexOf("/login"));
var redirectUrl = $"{domain}/api/User/UserRedirect?url={ System.Web.HttpUtility.UrlEncode(routeUrl) }";
using (StreamReader SourceReader = System.IO.File.OpenText(pathToFile))
{
var templateInfo = SourceReader.ReadToEnd();
builder.HtmlBody = string.Format(templateInfo,
sysUserInfo.FullName,
sysUserInfo.UserName,
sysUserInfo.UserTypeRole.UserTypeShortName,
redirectUrl
);
}
messageToSend.Body = builder.ToMessageBody();
await SendEmailHelper.SendEmailAsync(messageToSend);
}
//管理员重置密码发送邮件
public async Task AdminResetPwdSendEmailAsync(Guid userId)
{
var sysUserInfo = (await _userRepository.Where(t => t.Id == userId).Include(t => t.UserTypeRole).FirstOrDefaultAsync()).IfNullThrowException();
var messageToSend = new MimeMessage();
//发件地址
messageToSend.From.Add(new MailboxAddress("GRR", "iracis_grr@163.com"));
//收件地址
messageToSend.To.Add(new MailboxAddress(sysUserInfo.FullName, sysUserInfo.EMail));
//主题
messageToSend.Subject = "[来自展影IRC] 关于重置账户密码的提醒";
var builder = new BodyBuilder();
var pathToFile = _hostEnvironment.WebRootPath
+ Path.DirectorySeparatorChar.ToString()
+ "EmailTemplate"
+ Path.DirectorySeparatorChar.ToString()
+ "AdminResetUser.html";
using (StreamReader SourceReader = System.IO.File.OpenText(pathToFile))
{
var templateInfo = SourceReader.ReadToEnd();
builder.HtmlBody = string.Format(templateInfo,
sysUserInfo.FullName,
sysUserInfo.UserName,
sysUserInfo.UserTypeRole.UserTypeShortName,
AppSettings.DefaultPassword
);
}
messageToSend.Body = builder.ToMessageBody();
await SendEmailHelper.SendEmailAsync(messageToSend);
}
//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("GRR", "iracis_grr@163.com"));
//收件地址
messageToSend.To.Add(new MailboxAddress(sysUserInfo.FullName, sysUserInfo.EMail));
//主题
messageToSend.Subject = $"[来自展影IRC] [{ trialInfo.ResearchProgramNo}]邀请信";
var builder = new BodyBuilder();
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 pathToFile = _hostEnvironment.WebRootPath
+ Path.DirectorySeparatorChar.ToString()
+ "EmailTemplate"
+ Path.DirectorySeparatorChar.ToString()
+ (sysUserInfo.IsFirstAdd ? "TrialUserFirstJoin.html" : "TrialUserExistJoin.html");
using (StreamReader SourceReader = System.IO.File.OpenText(pathToFile))
{
var templateInfo = SourceReader.ReadToEnd();
var routeUrl = rootUrl + "?UserId=" + sysUserInfo.Id + "&Email=" + sysUserInfo.EMail + "&UserName=" + sysUserInfo.UserName + "&UserType=" + sysUserInfo.UserTypeRole.UserTypeShortName + "&access_token=" + token;
var domain = baseUrl.Substring(0, baseUrl.IndexOf("/login"));
var redirectUrl = $"{domain}/api/User/UserRedirect?url={ System.Web.HttpUtility.UrlEncode(routeUrl) }";
builder.HtmlBody = string.Format(templateInfo,
sysUserInfo.FullName,
trialInfo.ExperimentName,
trialInfo.ResearchProgramNo,
trialInfo.TrialCode,
sysUserInfo.UserName,
sysUserInfo.UserTypeRole.UserTypeShortName,
sysUserInfo.IsFirstAdd ? redirectUrl : baseUrl
);
}
messageToSend.Body = builder.ToMessageBody();
await SendEmailHelper.SendEmailAsync(messageToSend, null);
}
//外部用户 加入项目
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("GRR", "iracis_grr@163.com"));
//收件地址
messageToSend.To.Add(new MailboxAddress(String.Empty, sysUserInfo.EMail));
//主题
messageToSend.Subject = $"[来自展影IRC] [{ trialInfo.ResearchProgramNo}]邀请信";
var builder = new BodyBuilder();
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 pathToFile = _hostEnvironment.WebRootPath
+ Path.DirectorySeparatorChar.ToString()
+ "EmailTemplate"
+ Path.DirectorySeparatorChar.ToString()
+ (sysUserInfo.IsFirstAdd ? "TrialUserFirstJoin.html" : "TrialUserExistJoin.html");
using (StreamReader SourceReader = System.IO.File.OpenText(pathToFile))
{
var templateInfo = SourceReader.ReadToEnd();
var domain = baseUrl.Substring(0, baseUrl.IndexOf("/login"));
var routeUrl = rootUrl + "?UserId=" + sysUserInfo.Id + "&Email=" + sysUserInfo.EMail + "&UserName=" + sysUserInfo.UserName + "&UserType=" + sysUserInfo.UserTypeRole.UserTypeShortName + "&access_token=" + token;
var redirectUrl = $"{domain}/api/User/UserRedirect?url={ System.Web.HttpUtility.UrlEncode(routeUrl) }";
builder.HtmlBody = string.Format(templateInfo,
sysUserInfo.FullName,
trialInfo.ExperimentName,
trialInfo.ResearchProgramNo,
trialInfo.TrialCode,
sysUserInfo.UserName,
sysUserInfo.UserTypeRole.UserTypeShortName,
sysUserInfo.IsFirstAdd ? redirectUrl : baseUrl
);
}
messageToSend.Body = builder.ToMessageBody();
await SendEmailHelper.SendEmailAsync(messageToSend, null);
}
public async Task DoctorJoinTrialEmail(Guid trialId, Guid doctorId, string baseUrl, string rootUrl)
{
var doctor = await _doctorTypeRepository.FindAsync(doctorId);
User sysUserInfo = null;
using (await _mutex.LockAsync())
{
var isDoctorHaveAccount = await _userRepository.AnyAsync(t => t.DoctorId == doctorId);
if (!isDoctorHaveAccount)
{
var saveItem = new User() { FirstName = doctor.FirstName, LastName = doctor.LastName, EMail = doctor.EMail };
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;
sysUserInfo = await _userRepository.AddAsync(saveItem);
await _userRepository.SaveChangesAsync();
}
else
{
sysUserInfo = (await _userRepository.Where(t => t.DoctorId == doctorId).Include(t => t.UserTypeRole).FirstOrDefaultAsync()).IfNullThrowException();
}
}
var userType= await _userTypeRepository.FirstAsync(t => t.UserTypeEnum== UserTypeEnum.IndependentReviewer);
var trialInfo = await _trialRepository.FirstOrDefaultAsync(t => t.Id == trialId);
var messageToSend = new MimeMessage();
//发件地址
messageToSend.From.Add(new MailboxAddress("GRR", "iracis_grr@163.com"));
//收件地址
messageToSend.To.Add(new MailboxAddress(doctor.FullName, doctor.EMail));
//主题
messageToSend.Subject = $"[来自展影IRC] [{ trialInfo.ResearchProgramNo}]邀请信";
var builder = new BodyBuilder();
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 pathToFile = _hostEnvironment.WebRootPath
+ Path.DirectorySeparatorChar.ToString()
+ "EmailTemplate"
+ Path.DirectorySeparatorChar.ToString()
+ (sysUserInfo.IsFirstAdd ? "TrialDoctorFirstJoin.html" : "TrialDoctorExistJoin.html");
using (StreamReader SourceReader = System.IO.File.OpenText(pathToFile))
{
var templateInfo = SourceReader.ReadToEnd();
var routeUrl = rootUrl + "?UserId=" + sysUserInfo.Id + "&Email=" + sysUserInfo.EMail + "&UserName=" + sysUserInfo.UserName + "&UserType=" + userType.UserTypeShortName + "&access_token=" + token;
var domain = baseUrl.Substring(0, baseUrl.IndexOf("/login"));
var redirectUrl = $"{domain}/api/User/UserRedirect?url={ System.Web.HttpUtility.UrlEncode(routeUrl) }";
builder.HtmlBody = string.Format(templateInfo,
sysUserInfo.FullName,
trialInfo.ExperimentName,
trialInfo.ResearchProgramNo,
trialInfo.TrialCode,
sysUserInfo.UserName,
sysUserInfo.UserTypeRole.UserTypeShortName,
sysUserInfo.IsFirstAdd ? redirectUrl : baseUrl
);
}
messageToSend.Body = builder.ToMessageBody();
await SendEmailHelper.SendEmailAsync(messageToSend, null);
}
}
}