diff --git a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml index f92f0dec6..5f77c703a 100644 --- a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml +++ b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml @@ -411,7 +411,7 @@ - 不带Token 访问 用户选择 参与 不参与 Id: TrialExternalUserId + 不带Token 访问 用户选择 参与 不参与 Id: TrialExternalUserId 加入发送邮件 diff --git a/IRaCIS.Core.Application/Service/SiteSurvey/DTO/TrialSiteSurveyViewModel.cs b/IRaCIS.Core.Application/Service/SiteSurvey/DTO/TrialSiteSurveyViewModel.cs index 53d234504..95f71c2c9 100644 --- a/IRaCIS.Core.Application/Service/SiteSurvey/DTO/TrialSiteSurveyViewModel.cs +++ b/IRaCIS.Core.Application/Service/SiteSurvey/DTO/TrialSiteSurveyViewModel.cs @@ -254,12 +254,27 @@ namespace IRaCIS.Core.Application.Contracts [NotDefault] public Guid TrialId { get; set; } + public string RouteUrl { get; set; } = string.Empty; public List UserList { get; set; } = new List(); } + public class TrialSiteUserSurveyJoinCommand + { + [NotDefault] + public Guid TrialId { get; set; } + + public Guid TrialSiteSurveyId { get; set; } + + public string BaseUrl { get; set; } = string.Empty; + + public string RouteUrl { get; set; } = string.Empty; + + public List UserList { get; set; } = new List(); + } + public class TrialSiteSurvyeSubmitDTO { @@ -269,6 +284,7 @@ namespace IRaCIS.Core.Application.Contracts public Guid TrialSiteSurveyId { get; set; } + public string BaseUrl { get; set; } = string.Empty; public string RouteUrl { get; set; } = string.Empty; } diff --git a/IRaCIS.Core.Application/Service/SiteSurvey/TrialSiteSurveyService.cs b/IRaCIS.Core.Application/Service/SiteSurvey/TrialSiteSurveyService.cs index 65e384976..1f7782792 100644 --- a/IRaCIS.Core.Application/Service/SiteSurvey/TrialSiteSurveyService.cs +++ b/IRaCIS.Core.Application/Service/SiteSurvey/TrialSiteSurveyService.cs @@ -48,7 +48,7 @@ namespace IRaCIS.Core.Application.Contracts { var verificationType = VerifyType.Email; //检查手机或者邮箱是否有效 - if ( !Regex.IsMatch(userInfo.Email, @"^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$")) + if (!Regex.IsMatch(userInfo.Email, @"^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$")) { throw new BusinessValidationFailedException("Please input a legal email"); } @@ -60,7 +60,7 @@ namespace IRaCIS.Core.Application.Contracts var trialInfo = await _repository.FirstOrDefaultAsync(t => t.Id == userInfo.TrialId); - await _mailVerificationService.AnolymousSendEmail(trialInfo.ResearchProgramNo,userInfo.Email, verificationCode); + await _mailVerificationService.AnolymousSendEmail(trialInfo.ResearchProgramNo, userInfo.Email, verificationCode); return ResponseOutput.Ok(); @@ -681,6 +681,228 @@ namespace IRaCIS.Core.Application.Contracts } + + + /// + /// 提交 后台自动识别是谁提交 + /// + /// + /// + //[TypeFilter(typeof(TrialResourceFilter))] + [HttpPost] + public async Task TrialSurveySubmit(TrialSiteSurvyeSubmitDTO siteSurvyeSubmit) + { + + var trialId = siteSurvyeSubmit.TrialId; + var trialSiteSurveyId = siteSurvyeSubmit.TrialSiteSurveyId; + + if (_userInfo.IsAdmin) + { + return ResponseOutput.NotOk("不允许Admin操作"); + } + + + if (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.Undefined) + { + var hasSPMOrCPM = await _trialSiteSurveyRepository.AnyAsync(t => t.TrialId == trialId && t.Trial.TrialUserList.Any(u => u.User.UserTypeEnum == UserTypeEnum.SPM || u.User.UserTypeEnum == UserTypeEnum.CPM)); + + if (hasSPMOrCPM) + { + await _trialSiteSurveyRepository.BatchUpdateNoTrackingAsync(t => t.Id == trialSiteSurveyId && t.State == TrialSiteSurveyEnum.ToSubmit, u => new TrialSiteSurvey() { State = TrialSiteSurveyEnum.CRCSubmitted }); + + } + else + { + await _trialSiteSurveyRepository.BatchUpdateNoTrackingAsync(t => t.Id == trialSiteSurveyId && t.State == TrialSiteSurveyEnum.ToSubmit, u => new TrialSiteSurvey() { State = TrialSiteSurveyEnum.SPMApproved }); + + } + + } + else if (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.SPM || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.CPM) + { + + await _trialSiteSurveyRepository.BatchUpdateNoTrackingAsync(t => t.Id == trialSiteSurveyId && t.State == TrialSiteSurveyEnum.CRCSubmitted, u => new TrialSiteSurvey() { State = TrialSiteSurveyEnum.SPMApproved, PreliminaryUserId = _userInfo.Id, PreliminaryTime = DateTime.Now }); + + } + else if (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.APM || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.ProjectManager) + { + + var trialSiteSurvey = (await _trialSiteSurveyRepository.Where(t => t.Id == trialSiteSurveyId).FirstOrDefaultAsync()).IfNullThrowException(); + + + + //已生成的不管 管的只需要是 生成失败的并且需要生成账号的 + var needGenerateList = _trialSiteUserSurveyRepository.Where(t => t.TrialSiteSurveyId == trialSiteSurveyId && t.IsGenerateAccount && t.IsGenerateSuccess == false).ProjectTo(_mapper.ConfigurationProvider).ToList(); + + + //await SendInviteEmail(new InviteEmailCommand() { TrialId = trialId, RouteUrl = siteSurvyeSubmit.RouteUrl, UserList = needGenerateList }); + + + await GenerateAccountAsync(needGenerateList); + await SendSiteSurveyUserJoinEmail(new TrialSiteUserSurveyJoinCommand() { TrialId = trialId, RouteUrl = siteSurvyeSubmit.RouteUrl, BaseUrl = siteSurvyeSubmit.BaseUrl, UserList = needGenerateList }); + + await _trialSiteSurveyRepository.BatchUpdateNoTrackingAsync(t => t.Id == trialSiteSurveyId && t.State == TrialSiteSurveyEnum.SPMApproved, u => new TrialSiteSurvey() { State = TrialSiteSurveyEnum.PMCreatedAndLock, ReviewerUserId = _userInfo.Id, ReviewerTime = DateTime.Now }); + + } + + return ResponseOutput.Ok(); + } + + + + private async Task GenerateAccountAsync(List needGenerateList) + { + foreach (var item in needGenerateList) + { + + //找下系统中是否存在该用户类型的 并且邮箱 或者手机的账户 + var sysUserInfo = await _userRepository.Where(t => t.UserTypeId == item.UserTypeId && t.EMail == item.Email).Include(t => t.UserTypeRole).FirstOrDefaultAsync(); + + + if (sysUserInfo == null) + { + + lock (lockObj) + { + var saveItem = _mapper.Map(item); + + saveItem.Code = _userRepository.Select(t => t.Code).DefaultIfEmpty().Max() + 1; + + saveItem.UserCode = AppSettings.UserCodePrefix + saveItem.Code.ToString("D4"); + + saveItem.UserName = saveItem.UserCode; + + saveItem.UserTypeEnum = _repository.Where(t => t.Id == saveItem.UserTypeId).Select(t => t.UserTypeEnum).First(); + + //saveItem.Password = MD5Helper.Md5(verificationCode.ToString()); + + var newUser = _userRepository.AddAsync(saveItem).Result; + + + _ = _userRepository.SaveChangesAsync().Result; + + + sysUserInfo = newUser; + } + + } + + await _trialSiteUserSurveyRepository.UpdatePartialFromQueryAsync(t => t.Id == item.Id, u => new TrialSiteUserSurvey() { IsGenerateSuccess = true, SystemUserId = sysUserInfo.Id }); + + + + + } + + await _trialSiteUserSurveyRepository.SaveChangesAsync(); + } + + + public async Task SendSiteSurveyUserJoinEmail(TrialSiteUserSurveyJoinCommand joinCommand) + { + var trialSiteSurvey = (await _trialSiteSurveyRepository.Where(t => t.Id == joinCommand.TrialSiteSurveyId).FirstOrDefaultAsync()).IfNullThrowException(); + + var trialInfo = await _repository.FirstOrDefaultAsync(t => t.Id == joinCommand.TrialId); + + foreach (var userInfo in joinCommand.UserList) + { + var messageToSend = new MimeMessage(); + //发件地址 + messageToSend.From.Add(new MailboxAddress("GRR", "iracis_grr@163.com")); + //收件地址 + messageToSend.To.Add(new MailboxAddress(String.Empty, userInfo.Email)); + //主题 + messageToSend.Subject = $"[来自展影IRC] [{ trialInfo.ResearchProgramNo}]邀请信"; + + + var builder = new BodyBuilder(); + + var sysUserInfo = (await _userRepository.Where(t => t.Id == userInfo.SystemUserId).FirstOrDefaultAsync()).IfNullThrowException(); + + + builder.HtmlBody = @$" +
+
+
+ 尊敬的 {sysUserInfo.LastName + "/" + sysUserInfo.FirstName} ,您好: +
+
+ 展影医疗作为 实验方案号 {"'" + trialInfo.ResearchProgramNo + "'"} 项目的IRC供应商,诚邀您参加该项目IRC相关工作,欢迎您提供指导和建议,非常感谢! + 该项目采用电子化工作流,系统及您的账号信息如下: +
+
+
+ 项目编号: {trialInfo.TrialCode} +
+
+ 试验方案号: {trialInfo.ResearchProgramNo} +
+
+ 试验名称: {trialInfo.ExperimentName} +
+
+ 用户名: {sysUserInfo.UserName} +
+
+ 角色: {sysUserInfo.UserTypeRole.UserTypeShortName} +
+
+ {(sysUserInfo.IsFirstAdd ? "系统登录地址:" + joinCommand.BaseUrl : "首次登陆前,请通过该链接修改您的账户信息:" + joinCommand.RouteUrl)} +
+
+
+
+ "; + + + messageToSend.Body = builder.ToMessageBody(); + + using (var smtp = new MailKit.Net.Smtp.SmtpClient()) + { + + smtp.ServerCertificateValidationCallback = (s, c, h, e) => true; + + await smtp.ConnectAsync("smtp.163.com", 25, SecureSocketOptions.StartTls); + + await smtp.AuthenticateAsync("iracis_grr@163.com", "XLWVQKZAEKLDWOAH"); + + await smtp.SendAsync(messageToSend); + + await smtp.DisconnectAsync(true); + } + + + var trialId = joinCommand.TrialId; + var userId = sysUserInfo.Id; + var siteId = trialSiteSurvey.SiteId; + + //判断TrialUser中是否存在 不存在就插入 + if (!await _repository.AnyAsync(t => t.TrialId == trialId && t.UserId == userId)) + { + + await _repository.AddAsync(new TrialUser() { TrialId = trialId, UserId = userId }); + + await _repository.AddAsync(new TrialSiteUser() { TrialId = trialId, SiteId = siteId, UserId = userId }); + + await _userRepository.BatchUpdateNoTrackingAsync(t => t.Id == userId, u => new User() { Status = UserStateEnum.Enable }); + + await _trialSiteUserSurveyRepository.UpdatePartialFromQueryAsync(t => t.Id == userInfo.Id, u => new TrialSiteUserSurvey() { IsJoin = true }); + + + await _userRepository.SaveChangesAsync(); + } + } + + return ResponseOutput.Ok(); + + + } + + + + + + //废弃 //Site 调研邀请 public async Task SendInviteEmail(InviteEmailCommand inviteEmailCommand) { @@ -852,9 +1074,5 @@ namespace IRaCIS.Core.Application.Contracts return ResponseOutput.Ok(); } - - - - } } diff --git a/IRaCIS.Core.Application/Service/TrialSiteUser/DTO/TrialExternalUserViewModel.cs b/IRaCIS.Core.Application/Service/TrialSiteUser/DTO/TrialExternalUserViewModel.cs index 3bb15664a..39e33e1fa 100644 --- a/IRaCIS.Core.Application/Service/TrialSiteUser/DTO/TrialExternalUserViewModel.cs +++ b/IRaCIS.Core.Application/Service/TrialSiteUser/DTO/TrialExternalUserViewModel.cs @@ -26,6 +26,8 @@ namespace IRaCIS.Core.Application.ViewModel public Guid SystemUserId { get; set; } + + [JsonIgnore] public TrialExternalUserStateEnum InviteState { get; set; } @@ -84,10 +86,9 @@ namespace IRaCIS.Core.Application.ViewModel - public bool IsSendEmail { get; set; } + //public bool IsSendEmail { get; set; } - - public string RouteUrl { get; set; } = string.Empty; + //public string RouteUrl { get; set; } = string.Empty; } diff --git a/IRaCIS.Core.Application/Service/TrialSiteUser/TrialExternalUserService.cs b/IRaCIS.Core.Application/Service/TrialSiteUser/TrialExternalUserService.cs index 902692685..4df9d1ef8 100644 --- a/IRaCIS.Core.Application/Service/TrialSiteUser/TrialExternalUserService.cs +++ b/IRaCIS.Core.Application/Service/TrialSiteUser/TrialExternalUserService.cs @@ -128,25 +128,26 @@ namespace IRaCIS.Core.Application.Service await _trialExternalUseRepository.SaveChangesAsync(); - if (addOrEditTrialExternalUser.IsSendEmail) - { - await SendInviteEmail(new TrialExternalUserSendEmail() - { - //BaseUrl = addOrEditTrialExternalUser.BaseUrl, - RouteUrl = addOrEditTrialExternalUser.RouteUrl, - TrialId = addOrEditTrialExternalUser.TrialId, - SendUsers = new List() - { - new UserEmail() - { - Id = addEntity.Id, - Email=addEntity.Email, - IsSystemUser=addEntity.IsSystemUser, - SystemUserId=addEntity.SystemUserId - } - } - }); - } + //添加的时候就发邮件 现在省略 + //if (addOrEditTrialExternalUser.IsSendEmail) + //{ + // await SendInviteEmail(new TrialExternalUserSendEmail() + // { + // //BaseUrl = addOrEditTrialExternalUser.BaseUrl, + // RouteUrl = addOrEditTrialExternalUser.RouteUrl, + // TrialId = addOrEditTrialExternalUser.TrialId, + // SendUsers = new List() + // { + // new UserEmail() + // { + // Id = addEntity.Id, + // Email=addEntity.Email, + // IsSystemUser=addEntity.IsSystemUser, + // SystemUserId=addEntity.SystemUserId + // } + // } + // }); + //} return ResponseOutput.Ok(addEntity.Id.ToString()); @@ -204,6 +205,108 @@ namespace IRaCIS.Core.Application.Service } + //New 省掉邀请流程 + [HttpPost] + public async Task SendExternalUserJoinEmail(TrialExternalUserSendEmail sendEmail) + { + var trialInfo = await _repository.FirstOrDefaultAsync(t => t.Id == sendEmail.TrialId); + + foreach (var userInfo in sendEmail.SendUsers) + { + var messageToSend = new MimeMessage(); + //发件地址 + messageToSend.From.Add(new MailboxAddress("GRR", "iracis_grr@163.com")); + //收件地址 + messageToSend.To.Add(new MailboxAddress(String.Empty, userInfo.Email)); + //主题 + messageToSend.Subject = $"[来自展影IRC] [{ trialInfo.ResearchProgramNo}]邀请信"; + + + var builder = new BodyBuilder(); + + var sysUserInfo = (await _userRepository.Where(t => t.Id == userInfo.SystemUserId).FirstOrDefaultAsync()).IfNullThrowException(); + + + builder.HtmlBody = @$" +
+
+
+ 尊敬的 {sysUserInfo.LastName + "/" + sysUserInfo.FirstName} ,您好: +
+
+ 展影医疗作为 实验方案号 {"'" + trialInfo.ResearchProgramNo + "'"} 项目的IRC供应商,诚邀您参加该项目IRC相关工作,欢迎您提供指导和建议,非常感谢! + 该项目采用电子化工作流,系统及您的账号信息如下: +
+
+
+ 项目编号: {trialInfo.TrialCode} +
+
+ 试验方案号: {trialInfo.ResearchProgramNo} +
+
+ 试验名称: {trialInfo.ExperimentName} +
+
+ 用户名: {sysUserInfo.UserName} +
+
+ 角色: {sysUserInfo.UserTypeRole.UserTypeShortName} +
+
+ {(sysUserInfo.IsFirstAdd ? "系统登录地址:" + sendEmail.BaseUrl : "首次登陆前,请通过该链接修改您的账户信息:" + sendEmail.RouteUrl)} +
+
+
+
+ "; + + + messageToSend.Body = builder.ToMessageBody(); + + using (var smtp = new MailKit.Net.Smtp.SmtpClient()) + { + + smtp.ServerCertificateValidationCallback = (s, c, h, e) => true; + + await smtp.ConnectAsync("smtp.163.com", 25, SecureSocketOptions.StartTls); + + await smtp.AuthenticateAsync("iracis_grr@163.com", "XLWVQKZAEKLDWOAH"); + + await smtp.SendAsync(messageToSend); + + await smtp.DisconnectAsync(true); + } + + + var trialId = sendEmail.TrialId; + var userId = sysUserInfo.Id; + + //判断TrialUser中是否存在 不存在就插入 + if (!await _repository.AnyAsync(t => t.TrialId == trialId && t.UserId == userId)) + { + + await _repository.AddAsync(new TrialUser() { TrialId = trialId, UserId = userId }); + + await _userRepository.BatchUpdateNoTrackingAsync(t => t.Id == userId, u => new User() { Status = UserStateEnum.Enable }); + + await _trialExternalUseRepository.BatchUpdateNoTrackingAsync(t => t.Id == userInfo.Id, u => new TrialExternalUser() { IsJoin = true }); + + + await _userRepository.SaveChangesAsync(); + } + } + + return ResponseOutput.Ok(); + + } + + + + + + #region 老版本流程 现在废弃 + /// /// 勾选用户 批量发送邮件 /// @@ -251,12 +354,12 @@ namespace IRaCIS.Core.Application.Service "; - //< form action = '#' method = 'post' > - - // < button type = 'submit' style = 'margin-left:60px;font-size:14px;text-decoration: none;display: inline-block;height: 40px;width: 140px;background: #00D1B2;color:#fff;border-radius: 5px;line-height: 40px;text-align: center;border:none;margin-bottom: 100px;cursor: pointer' > 查看并确认 - - // - messageToSend.Body = builder.ToMessageBody(); + //< form action = '#' method = 'post' > + + // < button type = 'submit' style = 'margin-left:60px;font-size:14px;text-decoration: none;display: inline-block;height: 40px;width: 140px;background: #00D1B2;color:#fff;border-radius: 5px;line-height: 40px;text-align: center;border:none;margin-bottom: 100px;cursor: pointer' > 查看并确认 + + // + messageToSend.Body = builder.ToMessageBody(); using (var smtp = new MailKit.Net.Smtp.SmtpClient()) { @@ -289,7 +392,7 @@ namespace IRaCIS.Core.Application.Service /// - /// 不带Token 访问 用户选择 参与 不参与 Id: TrialExternalUserId + /// 不带Token 访问 用户选择 参与 不参与 Id: TrialExternalUserId 加入发送邮件 /// /// /// @@ -322,7 +425,7 @@ namespace IRaCIS.Core.Application.Service var success = await _trialExternalUseRepository.SaveChangesAsync(); - + if (editTrialUserPreparation.IsJoin == true) { var trialInfo = await _repository.FirstOrDefaultAsync(t => t.Id == needUpdate.TrialId); @@ -483,7 +586,7 @@ namespace IRaCIS.Core.Application.Service if (!await _trialUserRepository.AnyAsync(t => t.TrialId == trialId && t.UserId == userId)) { - await _trialUserRepository.AddAsync(new TrialUser() { TrialId = trialId, UserId = userId,JoinTime = DateTime.Now }); + await _trialUserRepository.AddAsync(new TrialUser() { TrialId = trialId, UserId = userId, JoinTime = DateTime.Now }); await _trialSiteUserRepository.AddAsync(new TrialSiteUser() { TrialId = trialId, SiteId = siteId, UserId = userId }); @@ -613,7 +716,7 @@ namespace IRaCIS.Core.Application.Service //} - + return ResponseOutput.Ok(); @@ -681,6 +784,11 @@ namespace IRaCIS.Core.Application.Service } + #endregion + + + + } } diff --git a/IRaCIS.Core.Domain/TrialSiteUser/TrialExternalUser.cs b/IRaCIS.Core.Domain/TrialSiteUser/TrialExternalUser.cs index df9f172fa..45074839a 100644 --- a/IRaCIS.Core.Domain/TrialSiteUser/TrialExternalUser.cs +++ b/IRaCIS.Core.Domain/TrialSiteUser/TrialExternalUser.cs @@ -75,11 +75,7 @@ namespace IRaCIS.Core.Domain.Models [Required] public string LastName { get; set; } - /// - /// 邀请状态 - /// - [Required] - public TrialExternalUserStateEnum InviteState { get; set; } = TrialExternalUserStateEnum.WaitSent; + ///// ///// 是否存在系统用户表中 @@ -98,15 +94,23 @@ namespace IRaCIS.Core.Domain.Models - public DateTime? ExpireTime { get; set; } + public bool? IsJoin { get; set; } - public bool? IsJoin { get; set; } + + + public DateTime? ExpireTime { get; set; } public DateTime? ConfirmTime { get; set; } public string RejectReason { get; set; } + /// + /// 邀请状态 + /// + [Required] + public TrialExternalUserStateEnum InviteState { get; set; } = TrialExternalUserStateEnum.WaitSent; + } }