医生发送邮件
This commit is contained in:
@@ -3485,7 +3485,7 @@
|
||||
入组流程-CRO确定医生名单 [ Approve]
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:IRaCIS.Application.Services.EnrollService.ConfirmReviewer(System.Guid,System.Guid[],System.Int32)">
|
||||
<member name="M:IRaCIS.Application.Services.EnrollService.ConfirmReviewer(IRaCIS.Core.Application.Service.WorkLoad.DTO.ConfirmReviewerCommand)">
|
||||
<summary>
|
||||
入组流程-后台确认医生入组[Confirm]
|
||||
</summary>
|
||||
|
||||
@@ -6,6 +6,7 @@ using Microsoft.AspNetCore.Hosting;
|
||||
using IRaCIS.Core.Application.Auth;
|
||||
using AutoMapper;
|
||||
using IRaCIS.Application.Contracts;
|
||||
using Nito.AsyncEx;
|
||||
|
||||
namespace IRaCIS.Application.Services
|
||||
{
|
||||
@@ -26,6 +27,8 @@ namespace IRaCIS.Application.Services
|
||||
|
||||
Task ExternalUserJoinEmail(Guid trialId, Guid userId, string baseUrl, string rootUrl);
|
||||
|
||||
Task DoctorJoinTrialEmail(Guid trialId, Guid doctorId, string baseUrl, string rootUrl);
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -43,6 +46,12 @@ namespace IRaCIS.Application.Services
|
||||
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,
|
||||
@@ -50,7 +59,9 @@ namespace IRaCIS.Application.Services
|
||||
IWebHostEnvironment hostEnvironment,
|
||||
IRepository<User> userRepository,
|
||||
ITokenService tokenService,
|
||||
IRepository<Trial> trialRepository,
|
||||
IRepository<Trial> trialRepository,
|
||||
IRepository<UserType> userTypeRepository,
|
||||
IRepository<Doctor> doctorTypeRepository,
|
||||
IMapper mapper)
|
||||
{
|
||||
_verificationCodeRepository = verificationCodeRepository;
|
||||
@@ -64,6 +75,9 @@ namespace IRaCIS.Application.Services
|
||||
_userRepository = userRepository;
|
||||
_trialRepository = trialRepository;
|
||||
|
||||
_userTypeRepository = userTypeRepository;
|
||||
_doctorTypeRepository = doctorTypeRepository;
|
||||
|
||||
}
|
||||
|
||||
//重置邮箱
|
||||
@@ -128,7 +142,6 @@ namespace IRaCIS.Application.Services
|
||||
|
||||
|
||||
|
||||
|
||||
//不登录 通过邮箱重置密码
|
||||
public async Task AnolymousSendEmailForResetAccount(string emailAddress, int verificationCode)
|
||||
{
|
||||
@@ -282,8 +295,8 @@ namespace IRaCIS.Application.Services
|
||||
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 domain = baseUrl.Substring(0, baseUrl.IndexOf("/login"));
|
||||
|
||||
var redirectUrl = $"{domain}/api/User/UserRedirect?url={ System.Web.HttpUtility.UrlEncode(routeUrl) }";
|
||||
|
||||
@@ -354,7 +367,7 @@ namespace IRaCIS.Application.Services
|
||||
}
|
||||
|
||||
|
||||
|
||||
//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();
|
||||
@@ -416,6 +429,7 @@ namespace IRaCIS.Application.Services
|
||||
|
||||
}
|
||||
|
||||
//外部用户 加入项目
|
||||
public async Task ExternalUserJoinEmail(Guid trialId, Guid userId, string baseUrl, string rootUrl)
|
||||
{
|
||||
var trialInfo = (await _trialRepository.FirstOrDefaultAsync(t => t.Id == trialId)).IfNullThrowException();
|
||||
@@ -480,6 +494,100 @@ namespace IRaCIS.Application.Services
|
||||
|
||||
|
||||
|
||||
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);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -67,6 +67,21 @@ namespace IRaCIS.Core.Application.Service.WorkLoad.DTO
|
||||
|
||||
}
|
||||
|
||||
public class ConfirmReviewerCommand
|
||||
{
|
||||
[NotDefault]
|
||||
public Guid TrialId { get; set; }
|
||||
|
||||
public Guid[] DoctorIdArray { get; set; } = new Guid [0];
|
||||
|
||||
public int ConfirmState { get; set; }
|
||||
|
||||
public string BaseUrl { get; set; } = string.Empty;
|
||||
|
||||
public string RouteUrl { get; set; } = string.Empty;
|
||||
}
|
||||
|
||||
|
||||
public class EnrollCommand
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
|
||||
@@ -20,6 +20,7 @@ namespace IRaCIS.Application.Services
|
||||
private readonly IRepository<Doctor> _doctorRepository;
|
||||
private readonly IRepository<EnrollDetail> _enrollDetailRepository;
|
||||
private readonly IRepository<Workload> _workloadRepository;
|
||||
private readonly IMailVerificationService _mailVerificationService;
|
||||
|
||||
|
||||
public EnrollService(IRepository<Trial> clinicalTrialProjectRepository,
|
||||
@@ -27,7 +28,9 @@ namespace IRaCIS.Application.Services
|
||||
IRepository<Enroll> intoGroupRepository,
|
||||
IRepository<Doctor> doctorRepository,
|
||||
IRepository<TrialPaymentPrice> TrialPaymentPriceRepository,
|
||||
IRepository<EnrollDetail> intoGroupDetailRepository, IRepository<Workload> workloadRepository)
|
||||
IRepository<EnrollDetail> intoGroupDetailRepository,
|
||||
IRepository<Workload> workloadRepository,
|
||||
IMailVerificationService mailVerificationService)
|
||||
{
|
||||
_trialRepository = clinicalTrialProjectRepository;
|
||||
_TrialPaymentPriceRepository = TrialPaymentPriceRepository;
|
||||
@@ -38,6 +41,8 @@ namespace IRaCIS.Application.Services
|
||||
_enrollDetailRepository = intoGroupDetailRepository;
|
||||
_workloadRepository = workloadRepository;
|
||||
|
||||
_mailVerificationService = mailVerificationService;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -344,10 +349,11 @@ namespace IRaCIS.Application.Services
|
||||
/// 入组流程-后台确认医生入组[Confirm]
|
||||
/// </summary>
|
||||
|
||||
[HttpPost("{trialId:guid}/{confirmState:int}")]
|
||||
[HttpPost]
|
||||
[TypeFilter(typeof(TrialResourceFilter))]
|
||||
[Authorize(Policy = IRaCISPolicy.PM_APM_SPM_CPM)]
|
||||
public async Task<IResponseOutput> ConfirmReviewer(Guid trialId, Guid[] doctorIdArray, int confirmState)
|
||||
[UnitOfWork]
|
||||
public async Task<IResponseOutput> ConfirmReviewer(ConfirmReviewerCommand confirmReviewerCommand)
|
||||
{
|
||||
//var trial = _trialRepository.FirstOrDefault(t => t.Id == trialId);
|
||||
//var existItem = _trialRepository.FindSingleOrDefault(u => u.Id == trialId && u.TrialStatus >= (int)TrialEnrollStatus.HasConfirmedDoctorNames);
|
||||
@@ -356,6 +362,8 @@ namespace IRaCIS.Application.Services
|
||||
////trial.TrialStatus = (int)TrialStatus.HasConfirmedDoctorNames;
|
||||
//_trialRepository.Update(trial);
|
||||
|
||||
var trialId = confirmReviewerCommand.TrialId;
|
||||
|
||||
var trial = await _trialRepository.FirstOrDefaultAsync(t => t.Id == trialId);
|
||||
|
||||
if (trial == null) return Null404NotFound(trial);
|
||||
@@ -364,16 +372,16 @@ namespace IRaCIS.Application.Services
|
||||
//更新入组表
|
||||
var intoGroupList = await _enrollRepository.Where(t => t.TrialId == trialId,true).ToListAsync();
|
||||
|
||||
if (confirmState == 1) //确认入组
|
||||
if (confirmReviewerCommand.ConfirmState == 1) //确认入组
|
||||
{
|
||||
foreach (var intoGroupItem in intoGroupList)
|
||||
{
|
||||
if (doctorIdArray.Contains(intoGroupItem.DoctorId))
|
||||
if (confirmReviewerCommand.DoctorIdArray.Contains(intoGroupItem.DoctorId))
|
||||
{
|
||||
intoGroupItem.EnrollStatus = (int)EnrollStatus.ConfirmIntoGroup;
|
||||
intoGroupItem.EnrollTime = DateTime.Now;
|
||||
|
||||
|
||||
await _mailVerificationService.DoctorJoinTrialEmail(trialId, intoGroupItem.DoctorId, confirmReviewerCommand.BaseUrl, confirmReviewerCommand.RouteUrl);
|
||||
await _enrollDetailRepository.AddAsync(new EnrollDetail()
|
||||
{
|
||||
DoctorId = intoGroupItem.DoctorId,
|
||||
@@ -385,11 +393,11 @@ namespace IRaCIS.Application.Services
|
||||
}
|
||||
|
||||
}
|
||||
else if (confirmState == 0)//回退上一步
|
||||
else if (confirmReviewerCommand.ConfirmState == 0)//回退上一步
|
||||
{
|
||||
foreach (var intoGroupItem in intoGroupList)
|
||||
{
|
||||
if (doctorIdArray.Contains(intoGroupItem.DoctorId))
|
||||
if (confirmReviewerCommand.DoctorIdArray.Contains(intoGroupItem.DoctorId))
|
||||
{
|
||||
intoGroupItem.EnrollStatus = (int)EnrollStatus.InviteIntoGroup;
|
||||
intoGroupItem.EnrollTime = null;
|
||||
|
||||
@@ -6,7 +6,7 @@ namespace IRaCIS.Application.Services
|
||||
{
|
||||
Task<IResponseOutput> AddOrUpdateEnroll(EnrollCommand addOrUpdateModel);
|
||||
Task<IResponseOutput> ApproveReviewer(Guid trialId, Guid[] doctorIdArray, int auditState);
|
||||
Task<IResponseOutput> ConfirmReviewer(Guid trialId, Guid[] doctorIdArray, int confirmState);
|
||||
//Task<IResponseOutput> ConfirmReviewer(Guid trialId, Guid[] doctorIdArray, int confirmState);
|
||||
Task<IResponseOutput> EnrollBackOrOut(Guid trialId, Guid doctorId, int optType, DateTime? outEnrollTime);
|
||||
Task<PageOutput<EnrollViewModel>> GetTrialDoctorList(EnrollGetQuery challengeQuery);
|
||||
Task<IResponseOutput> SelectReviewers(Guid trialId, Guid[] doctorIdArray);
|
||||
|
||||
Reference in New Issue
Block a user