//-------------------------------------------------------------------- // 此代码由T4模板自动生成 byzhouhang 20210918 // 生成时间 2021-12-23 13:20:59 // 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。 //-------------------------------------------------------------------- using IRaCIS.Application.Contracts; using IRaCIS.Core.Application.Service; using IRaCIS.Core.Application.Auth; using IRaCIS.Core.Application.Filter; using IRaCIS.Core.Application.Helper; using IRaCIS.Core.Domain.Share; using IRaCIS.Core.Infrastructure; using Medallion.Threading; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Options; using Microsoft.VisualBasic; using MimeKit; using Newtonsoft.Json; using System.Text.RegularExpressions; using static MassTransit.ValidationResultExtensions; using DocumentFormat.OpenXml.Vml.Spreadsheet; using IdentityModel.OidcClient; using IRaCIS.Core.Domain.Models; namespace IRaCIS.Core.Application.Contracts { /// /// TrialSiteSurveyService /// [ApiExplorerSettings(GroupName = "Trial")] public class TrialSiteSurveyService(IRepository _trialSiteSurveyRepository, IRepository _trialSiteUserSurveyRepository, IRepository _userRoleRepository, IRepository _trialRepository, IRepository _trialSiteRepository, IRepository _doctorRepository, IRepository _verificationCodeRepository, IRepository _trialUserRepository, IRepository _trialSiteUserRepository, IDistributedLockProvider _distributedLockProvider, ITokenService _tokenService, IRepository _userTypeRepository, IMailVerificationService _mailVerificationService, IOptionsMonitor systemEmailConfig, IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer) : BaseService, ITrialSiteSurveyService { private readonly SystemEmailSendConfig _systemEmailConfig = systemEmailConfig.CurrentValue; /// /// 发送验证码 /// /// /// [AllowAnonymous] public async Task SendEmialVerifyCode(SendEmialVerifyCodeInDto userInfo) { //检查手机或者邮箱是否有效 if (!Regex.IsMatch(userInfo.Email, @"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$")) { //---请输入正确的邮箱地址。 throw new BusinessValidationFailedException(_localizer["TrialSiteSurvey_InvalidEmail"]); } //邮箱 //验证码 6位 int verificationCode = new Random().Next(100000, 1000000); await _mailVerificationService.SendEmailVerification(userInfo.Email, verificationCode); return ResponseOutput.Ok(); } /// /// 通过UserId获取Doctorid /// /// /// [HttpPost] public async Task UseUserIDGetDoctorID(UseUserIDGetDoctorIDInDto inDto) { var userinfo = await _userRoleRepository.Where(x => x.Id == inDto.UserID).FirstOrDefaultAsync(); if (userinfo != null && userinfo.DoctorId != null) { return new UseUserIDGetDoctorIDOutDto() { DoctorID = userinfo.DoctorId }; } else { Doctor doctor = new Doctor() { }; var info = await _doctorRepository.AddAsync(doctor, true); await _userRoleRepository.BatchUpdateNoTrackingAsync(x => x.Id == inDto.UserID, x => new UserRole() { DoctorId = info.Id }); return new UseUserIDGetDoctorIDOutDto() { DoctorID = info.Id }; } } /// /// 根据邮箱获取DoctorId 没有的话创建一个 /// /// /// [HttpPost] public async Task UseEmialGetDoctorInfo(UseEmialGetDoctorInfoInDto inDto) { var dockerInfo = await _doctorRepository.Where(t => t.EMail == inDto.EmailOrPhone || t.Phone == inDto.EmailOrPhone).FirstOrDefaultAsync(); if (dockerInfo != null) { return new UseEmialGetDoctorInfoOutDto() { DoctorId = dockerInfo.Id }; } else { var isVirtual = true; if (inDto.TrialId != null) { isVirtual = await _trialRepository.Where(x => x.Id == inDto.TrialId).Select(x => x.TrialType != TrialType.OfficialTrial).FirstNotNullAsync(); } Doctor doctor = new Doctor() { EMail = inDto.EmailOrPhone, IsVirtual = isVirtual, AcceptingNewTrial = false, ActivelyReading = false, ResumeStatus = ResumeStatusEnum.Pass, CooperateStatus = ContractorStatusEnum.Noncooperation, ReviewStatus = ReviewerInformationConfirmStatus.ConfirmRefuse }; var info = await _doctorRepository.AddAsync(doctor, true); return new UseEmialGetDoctorInfoOutDto() { DoctorId = info.Id }; } } /// /// 验证邮箱验证码 获取医生信息Id /// /// /// [HttpPost] [AllowAnonymous] public async Task VerifyEmialGetDoctorInfo(VerifyEmialGetDoctorInfoInDto inDto) { var verificationRecord = await _verificationCodeRepository.Where().OrderByDescending(x => x.ExpirationTime).Where(t => (t.EmailOrPhone == inDto.EmailOrPhone) && t.Code == inDto.VerificationCode && t.CodeType == VerifyType.Email).FirstOrDefaultAsync(); VerifyEmialGetDoctorInfoOutDto result = new VerifyEmialGetDoctorInfoOutDto(); //检查数据库是否存在该验证码 if (verificationRecord == null) { //---验证码错误。 throw new BusinessValidationFailedException(_localizer["TrialSiteSurvey_WrongVerificationCode"]); } else { //检查验证码是否失效 if (verificationRecord.ExpirationTime < DateTime.Now) { //---验证码已经过期。 throw new BusinessValidationFailedException(_localizer["TrialSiteSurvey_ExpiredVerificationCode"]); } else //验证码正确 并且 没有超时 { //删除验证码历史记录 await _verificationCodeRepository.BatchDeleteNoTrackingAsync(t => t.Id == verificationRecord.Id); var dockerInfo = await _doctorRepository.Where(t => t.EMail == inDto.EmailOrPhone || t.Phone == inDto.EmailOrPhone).FirstOrDefaultAsync(); if (dockerInfo != null) { result.DoctorId = dockerInfo.Id; result.ReviewStatus = dockerInfo.ReviewStatus; } else { var isVirtual = true; if (inDto.TrialId != null) { isVirtual = await _trialRepository.Where(x => x.Id == inDto.TrialId).Select(x => x.TrialType != TrialType.OfficialTrial).FirstNotNullAsync(); } Doctor doctor = new Doctor() { EMail = inDto.EmailOrPhone, IsVirtual = isVirtual, AcceptingNewTrial = false, ActivelyReading = false, CooperateStatus = ContractorStatusEnum.Noncooperation, ReviewStatus = ReviewerInformationConfirmStatus.ConfirmRefuse }; var info = await _doctorRepository.AddAsync(doctor, true); //await _userRoleRepository.BatchUpdateNoTrackingAsync(x => x.EMail == inDto.EmailOrPhone, x => new User() //{ // DoctorId = info.DoctorId, //}); result.DoctorId = info.Id; result.ReviewStatus = info.ReviewStatus; } result.Token = _tokenService.GetToken(new UserTokenInfo() { UserRoleId = Guid.NewGuid() }); } } return result; } /// ///site 调研 发送验证码 /// /// /// [AllowAnonymous] public async Task SendVerifyCode(SiteSurveySendVerifyCode userInfo) { //检查手机或者邮箱是否有效 if (!Regex.IsMatch(userInfo.Email, @"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$")) { //---请输入正确的邮箱地址。 throw new BusinessValidationFailedException(_localizer["TrialSiteSurvey_InvalidEmail"]); } //邮箱 //验证码 6位 int verificationCode = new Random().Next(100000, 1000000); var trialInfo = await _trialRepository.FirstOrDefaultAsync(t => t.Id == userInfo.TrialId); await _mailVerificationService.AnolymousSendEmail(trialInfo.ResearchProgramNo, userInfo.Email, verificationCode); return ResponseOutput.Ok(); } /// /// 验证后 如果数据库该项目不存在该邮箱 那么就插入记录 存在 /// /// /// /// /// [HttpPost] [UnitOfWork] [AllowAnonymous] [TrialGlobalLimit("AfterStopCannNotOpt")] public async Task VerifySendCode(LoginDto userInfo, [FromServices] ITokenService _tokenService) { #region 20230804 修改调研表逻辑 var verifyRecord = await _verificationCodeRepository.FirstOrDefaultAsync(t => (t.EmailOrPhone == userInfo.EmailOrPhone) && t.Code == userInfo.verificationCode && t.CodeType == userInfo.verificationType); //检查数据库是否存在该验证码 if (verifyRecord == null) { //---验证码错误。 return ResponseOutput.NotOk(_localizer["TrialSiteSurvey_WrongVerificationCode"]); } else if (verifyRecord.ExpirationTime < DateTime.Now) { return ResponseOutput.NotOk(_localizer["TrialSiteSurvey_WrongVerificationCode"]); } else { //删除验证码历史记录 await _verificationCodeRepository.BatchDeleteNoTrackingAsync(t => t.Id == verifyRecord.Id); //验证码正确 不处理 } TrialSiteSurvey? currentEntity = null; var userList = await _trialSiteUserRepository.Where(t => t.TrialId == userInfo.TrialId && t.TrialSiteId == userInfo.TrialSiteId, false, true).ProjectTo(_mapper.ConfigurationProvider).ToListAsync(); //普通登录 if (userInfo.IsUpdate == false) { var dbEntityList = await _trialSiteSurveyRepository.Where(t => t.TrialId == userInfo.TrialId && t.TrialSiteId == userInfo.TrialSiteId).ToListAsync(); //没有记录 new一份 if (dbEntityList.Count == 0) { var addSurvey = _mapper.Map(userInfo); //从项目site 中找到已存在的 加到历史人员中 addSurvey.TrialSiteUserSurveyList = userList; currentEntity = await _trialSiteSurveyRepository.AddAsync(addSurvey); } else { //找到当前最新的调研表 var currentLatest = dbEntityList.OrderByDescending(t => t.CreateTime).FirstOrDefault(); if (currentLatest!.Email != userInfo.EmailOrPhone) { //---该中心下已经有其他用户已填写的调研表,您不被允许继续填写 return ResponseOutput.NotOk(_localizer["TrialSiteSurvey_AlreadyFilledByOtherUsers"]); } currentEntity = currentLatest; if (currentEntity.State != TrialSiteSurveyEnum.PMCreatedAndLock) { await UnlockSyncSiteUserAsync(userInfo.TrialId, userInfo.TrialSiteId, currentEntity.Id, userList); } } } //更新调研表 else { //找到最新的调研表 var currentLatest = await _trialSiteSurveyRepository.Where(t => t.TrialId == userInfo.TrialId && t.TrialSiteId == userInfo.TrialSiteId, true) .Include(u => u.TrialSiteEquipmentSurveyList).Include(u => u.TrialSiteUserSurveyList).OrderByDescending(t => t.CreateTime).FirstOrDefaultAsync(); if (currentLatest == null) { return ResponseOutput.NotOk(_localizer["TrialSite_NoSurveyToUpdate"]); } if (currentLatest.Email != userInfo.ReplaceUserEmailOrPhone) { //---该中心不存在该交接人的中心调研记录表,不允许选择更新。 return ResponseOutput.NotOk(_localizer["TrialSiteSurvey_NoRecordToUpdate"]); } //未锁定的状态 就改为废除 if (currentLatest.State != TrialSiteSurveyEnum.PMCreatedAndLock) { currentLatest.IsDeleted = true; } //锁定的 需要改状态么? else { } var copy = currentLatest.Clone(); copy.State = TrialSiteSurveyEnum.ToSubmit; copy.IsDeleted = false; copy.Phone = string.Empty; copy.UserName = string.Empty; copy.Email = userInfo.EmailOrPhone; copy.Id = Guid.Empty; copy.CreateTime = DateAndTime.Now; if (userInfo.ReplaceUserEmailOrPhone != userInfo.EmailOrPhone) { copy.UserName = String.Empty; copy.Phone = String.Empty; } copy.TrialSiteEquipmentSurveyList = currentLatest.TrialSiteEquipmentSurveyList.Clone(); copy.TrialSiteEquipmentSurveyList.ForEach(t => { t.Id = Guid.Empty; t.CreateTime = DateTime.Now; }); //锁定了的话,就不拷贝 if (currentLatest.State != TrialSiteSurveyEnum.PMCreatedAndLock) { copy.TrialSiteUserSurveyList = currentLatest.TrialSiteUserSurveyList.Clone().Where(t => t.IsHistoryUser == false).ToList(); copy.TrialSiteUserSurveyList.ForEach(t => { t.Id = Guid.Empty; t.IsGenerateSuccess = false; t.CreateTime = DateTime.Now; }); } //从项目site 中找到已存在的 加到历史人员中 copy.TrialSiteUserSurveyList.AddRange(userList); currentEntity = await _trialSiteSurveyRepository.AddAsync(copy); } //删除验证码历史记录 await _verificationCodeRepository.BatchDeleteNoTrackingAsync(t => t.EmailOrPhone == userInfo.EmailOrPhone && t.Code == userInfo.verificationCode && t.CodeType == userInfo.verificationType); await _trialSiteSurveyRepository.SaveChangesAsync(); return ResponseOutput.Ok(new { TrialSiteSurveyId = currentEntity!.Id, Token = _tokenService.GetToken(new UserTokenInfo() { UserRoleId = Guid.NewGuid(), UserName = "SiteSurvey", UserTypeEnum = UserTypeEnum.Undefined, }) }); #endregion } private async Task UnlockSyncSiteUserAsync(Guid trialId, Guid siteId, Guid trialSiteSurveyId, List userList) { var existList = await _trialSiteUserSurveyRepository.Where(t => t.IsHistoryUser && t.TrialSiteSurvey.TrialId == trialId && t.TrialSiteSurvey.TrialSiteId == siteId, true).ToListAsync(); foreach (var item in userList) { var find = existList.FirstOrDefault(t => t.SystemUserId == item.SystemUserId); //不存在就加入 if (find == null) { item.TrialSiteSurveyId = trialSiteSurveyId; await _trialSiteUserSurveyRepository.AddAsync(item); } else { find.IsHistoryUserOriginDeleted = item.IsHistoryUserOriginDeleted; } } await _trialSiteUserSurveyRepository.SaveChangesAsync(); } /// /// 直接查询相关所有数据 /// /// [HttpGet("{trialId:guid}/{trialSiteSurveyId:guid}")] public async Task GetSiteSurveyInfo(Guid trialSiteSurveyId, Guid trialId) { //有可能填表人提交了,但是此时PM手动对人员信息进行了更改,此时需要将数据同步下(选择在这里同步是因为 不想改动 中心人员哪里的两个接口的逻辑) var find = await _trialSiteSurveyRepository.FirstOrDefaultAsync(t => t.Id == trialSiteSurveyId, true); if (find.State != TrialSiteSurveyEnum.PMCreatedAndLock && find.IsDeleted != true) { var userList = await _trialSiteUserRepository.Where(t => t.TrialId == find.TrialId && t.TrialSiteId == find.TrialSiteId, false, true).ProjectTo(_mapper.ConfigurationProvider).ToListAsync(); await UnlockSyncSiteUserAsync(find.TrialId, find.TrialSiteId, find.Id, userList); } var result = await _trialSiteSurveyRepository.Where(t => t.Id == trialSiteSurveyId && t.TrialId == trialId).IgnoreQueryFilters() .ProjectTo(_mapper.ConfigurationProvider, new { isEn_Us = _userInfo.IsEn_Us }).FirstOrDefaultAsync().IfNullThrowException(); var siteSurveryConfig = _trialSiteSurveyRepository.Where(t => t.Id == trialSiteSurveyId).IgnoreQueryFilters().Select(t => t.Trial.TrialExtraConfigJsonStr).FirstOrDefault() ?? string.Empty; result.SiteSurveyFiledConfig = JsonConvert.DeserializeObject(siteSurveryConfig) ?? new TrialExtraConfig(); return result; } /// /// 实际这里只会是更新 添加在login的时候做了 /// /// /// [TrialGlobalLimit("AfterStopCannNotOpt")] public async Task AddOrUpdateTrialSiteSurvey(TrialSiteSurveyAddOrEdit addOrEditTrialSiteSurvey) { if (addOrEditTrialSiteSurvey.Id != null) { if (await _trialSiteSurveyRepository.AnyAsync(t => t.Id == addOrEditTrialSiteSurvey.Id && t.State == TrialSiteSurveyEnum.PMCreatedAndLock)) { //---中心调研已锁定,不允许操作。 return ResponseOutput.NotOk(_localizer["TrialSiteSurvey_Locked"]); } } if (addOrEditTrialSiteSurvey.Id == null) { var entity = _mapper.Map(addOrEditTrialSiteSurvey); await _trialSiteSurveyRepository.AddAsync(entity, true); return ResponseOutput.Ok(entity.Id.ToString()); } else { var entity = await _trialSiteSurveyRepository.Where(t => t.Id == addOrEditTrialSiteSurvey.Id, true).Include(x => x.ReviewerUser).Include(x => x.PreliminaryUser).FirstOrDefaultAsync(); _mapper.Map(addOrEditTrialSiteSurvey, entity); await _trialSiteSurveyRepository.SaveChangesAsync(); } return ResponseOutput.Ok(true); } /// /// 删除调研表 /// /// /// [HttpDelete("{trialSiteSurveyId:guid}/{trialId:guid}")] public async Task DeleteTrialSiteSurvey(Guid trialSiteSurveyId) { if (await _trialSiteSurveyRepository.AnyAsync(t => t.Id == trialSiteSurveyId && t.State == TrialSiteSurveyEnum.PMCreatedAndLock)) { //---中心调研已锁定,不允许操作。 return ResponseOutput.NotOk(_localizer["TrialSiteSurvey_Locked"]); } var success = await _trialSiteSurveyRepository.BatchDeleteNoTrackingAsync(t => t.Id == trialSiteSurveyId); return ResponseOutput.Result(success); } /// /// 获取 项目 site的调研记录 New /// /// [HttpPost] public async Task> GetTrialSiteSurveyList(TrialSiteSurveyQueryDTO inQuery) { var trialSiteSurveyQueryable = _trialSiteSurveyRepository.Where(t => t.TrialId == inQuery.TrialId).IgnoreQueryFilters() .WhereIf(inQuery.TrialSiteId != null, t => t.TrialSiteId == inQuery.TrialSiteId) .WhereIf(inQuery.IsDeleted != null, t => t.IsDeleted == inQuery.IsDeleted) .WhereIf(!string.IsNullOrWhiteSpace(inQuery.UserKeyInfo), t => t.UserName.Contains(inQuery.UserKeyInfo) || t.Phone.Contains(inQuery.UserKeyInfo) || t.Email.Contains(inQuery.UserKeyInfo)) .WhereIf(inQuery.State != null, t => t.State == inQuery.State) .WhereIf(inQuery.UpdateTimeBegin != null, t => t.UpdateTime >= inQuery.UpdateTimeBegin) .WhereIf(inQuery.UpdateTimeEnd != null, t => t.UpdateTime <= inQuery.UpdateTimeEnd) .ProjectTo(_mapper.ConfigurationProvider, new { isEn_Us = _userInfo.IsEn_Us }) .WhereIf(!string.IsNullOrWhiteSpace(inQuery.PreliminaryUserName), t => t.PreliminaryUser.RealName.Contains(inQuery.PreliminaryUserName)) .WhereIf(!string.IsNullOrWhiteSpace(inQuery.ReviewerUserName), t => t.ReviewerUser.RealName.Contains(inQuery.ReviewerUserName)) ; return await trialSiteSurveyQueryable.ToPagedListAsync(inQuery); } [HttpPost] public async Task> GetTrialSiteSurveySelectList(TrialSiteSurveySelectquery inQuery) { var trialSiteSurveyQueryable = _trialSiteSurveyRepository .Where(t => t.Id != inQuery.TrialSiteSurveyId) .Where(t => t.TrialId == inQuery.TrialId && t.TrialSiteId == inQuery.TrialSiteId).IgnoreQueryFilters() .ProjectTo(_mapper.ConfigurationProvider); return await trialSiteSurveyQueryable.ToListAsync(); } /// /// 项目Site调研用户列表 所有site的调研用户 最新的调研表的记录的用户 new /// /// public async Task> TrialSiteSurveyUserList(TrialSiteUserSurveyAllQuery inQuery) { var groupSelectIdQuery = _trialSiteSurveyRepository.Where(t => t.TrialId == inQuery.TrialId) .WhereIf(inQuery.TrialSiteId != null, t => t.TrialSiteId == inQuery.TrialSiteId) .WhereIf(!string.IsNullOrEmpty(inQuery.FormWriterKeyInfo), t => (t.UserName).Contains(inQuery.FormWriterKeyInfo) || t.Email.Contains(inQuery.FormWriterKeyInfo) || t.Phone.Contains(inQuery.FormWriterKeyInfo)) .GroupBy(t => t.TrialSiteId) .Select(g => g.OrderByDescending(u => u.CreateTime).Select(t => t.Id).First()); var query = _trialSiteUserSurveyRepository .Where(t => groupSelectIdQuery.Contains(t.TrialSiteSurveyId)) .WhereIf(inQuery.TrialRoleCode != null, t => t.TrialRoleCode == inQuery.TrialRoleCode) .WhereIf(inQuery.UserTypeId != null, t => t.UserTypeId == inQuery.UserTypeId) .WhereIf(inQuery.IsGenerateAccount != null, t => t.IsGenerateAccount == inQuery.IsGenerateAccount) .WhereIf(inQuery.State != null && inQuery.State != TrialSiteUserStateEnum.OverTime, t => t.InviteState == inQuery.State) .WhereIf(!string.IsNullOrEmpty(inQuery.UserName), t => (t.LastName + " / " + t.FirstName).Contains(inQuery.UserName)) .WhereIf(!string.IsNullOrEmpty(inQuery.OrganizationName), t => t.OrganizationName.Contains(inQuery.OrganizationName)) .ProjectTo(_mapper.ConfigurationProvider); return await query.ToPagedListAsync(inQuery); //return await query.ToPagedListAsync(queryParam.PageIndex, queryParam.PageSize, queryParam.SortField, queryParam.Asc); } /// /// 初始登陆界面 项目基本信息+下拉框数据 /// /// /// [AllowAnonymous] [HttpGet("{trialId:guid}")] public async Task GetTrialSurveyInitInfo(Guid trialId) { var info = await _trialRepository.Where(t => t.Id == trialId).IgnoreQueryFilters().ProjectTo(_mapper.ConfigurationProvider).FirstOrDefaultAsync().IfNullThrowException(); return info; } /// /// 驳回 New /// /// [TrialGlobalLimit("AfterStopCannNotOpt")] public async Task SubmissionRejection(TrialSiteSubmitBackCommand trialSiteSubmitBackCommand, [FromServices] IMailVerificationService _IMailVerificationService) { var trialSiteSurveyId = trialSiteSubmitBackCommand.TrialSiteSurveyId; var survey = await _trialSiteSurveyRepository.FirstOrDefaultAsync(t => t.Id == trialSiteSurveyId); survey.LatestBackReason = trialSiteSubmitBackCommand.LatestBackReason; //User? user = null; //var messageToSend = new MimeMessage(); if (await _trialSiteSurveyRepository.AnyAsync(t => t.State == TrialSiteSurveyEnum.PMCreatedAndLock && t.Id == trialSiteSurveyId)) { //---中心调研已锁定,不允许操作。 return ResponseOutput.NotOk(_localizer["TrialSiteSurvey_Locked"]); } if (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.SPM || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.CPM) { ////SPM 给填表人发 //messageToSend.To.Add(new MailboxAddress(String.Empty, survey.Email)); survey.State = TrialSiteSurveyEnum.ToSubmit; } else if (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ProjectManager || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.APM) { var isTrialSPMJoin = await _trialRepository.AnyAsync(t => t.Id == trialSiteSubmitBackCommand.TrialId && t.IsSPMJoinSiteSurvey); var hasSPMOrCPM = await _trialSiteSurveyRepository.AnyAsync(t => t.TrialId == trialSiteSubmitBackCommand.TrialId && t.Trial.TrialUserList.Any(u => u.User.UserTypeEnum == UserTypeEnum.SPM || u.User.UserTypeEnum == UserTypeEnum.CPM)); var isSPMjoin= isTrialSPMJoin && hasSPMOrCPM; if (isSPMjoin) { ////PM 给SPM发 (初审人) //user = await _userRoleRepository.FirstOrDefaultAsync(t => t.Id == survey.PreliminaryUserId); //messageToSend.To.Add(new MailboxAddress(String.Empty, survey.PreliminaryUserId == null ? survey.Email : user.EMail)); survey.State = TrialSiteSurveyEnum.CRCSubmitted; survey.ReviewerUserId = null; survey.ReviewerTime = null; } else { ////没有SPM 给填表人发 //messageToSend.To.Add(new MailboxAddress(String.Empty, survey.Email)); survey.State = TrialSiteSurveyEnum.ToSubmit; survey.PreliminaryUserId = null; survey.ReviewerUserId = null; survey.PreliminaryTime = null; survey.ReviewerTime = null; } } //await _IMailVerificationService.SiteSurveyRejectEmail(messageToSend, survey, trialSiteSubmitBackCommand.RouteUrl, user); await _trialSiteSurveyRepository.SaveChangesAsync(); return ResponseOutput.Ok(); } [HttpPut("{trialId:guid}/{trialSiteSurveyId:guid}")] [TrialGlobalLimit("AfterStopCannNotOpt")] public async Task AbandonSiteSurvey(Guid trialSiteSurveyId) { var survey = (await _trialSiteSurveyRepository.FirstOrDefaultAsync(t => t.Id == trialSiteSurveyId, true)).IfNullThrowException(); if (survey.State != TrialSiteSurveyEnum.ToSubmit) { //---只允许废除未提交的记录。 return ResponseOutput.NotOk(_localizer["TrialSiteSurvey_CancelUnsubmittedRecord"]); } survey.IsDeleted = true; await _trialSiteSurveyRepository.SaveChangesAsync(); return ResponseOutput.Ok(); } /// /// 提交 后台自动识别是谁提交 /// /// /// [HttpPost] [TrialGlobalLimit("AfterStopCannNotOpt")] [UnitOfWork] public async Task TrialSurveySubmit(TrialSiteSurvyeSubmitDTO siteSurvyeSubmit) { var trialId = siteSurvyeSubmit.TrialId; var trialSiteSurveyId = siteSurvyeSubmit.TrialSiteSurveyId; var trialSiteSurvey = (await _trialSiteSurveyRepository.Where(t => t.Id == trialSiteSurveyId, false, true).FirstOrDefaultAsync()).IfNullThrowException(); if (trialSiteSurvey.IsDeleted == true || trialSiteSurvey.State == TrialSiteSurveyEnum.PMCreatedAndLock) { throw new BusinessValidationFailedException(_localizer["TrialSiteSurvey_Invalid"]); } var siteUserList = await _trialSiteUserSurveyRepository.Where(t => t.TrialSiteSurveyId == trialSiteSurveyId) .Where(t => !(t.IsHistoryUser && t.IsHistoryUserDeleted == true)) .Select(t => new { t.TrialSiteSurveyId, t.IsGenerateAccount, t.IsGenerateSuccess, t.UserTypeId, UserTypeEnum = (UserTypeEnum?)t.UserTypeRole.UserTypeEnum, t.TrialRoleCode, t.Email, }).ToListAsync(); //var currentUserList = siteUserList.Where(t => t.TrialSiteSurveyId == trialSiteSurveyId).ToList(); if (!siteUserList.Any(t => t.UserTypeEnum == UserTypeEnum.ClinicalResearchCoordinator || t.UserTypeEnum == UserTypeEnum.CRA)) { throw new BusinessValidationFailedException(_localizer["TrialSiteSurvey_MissingAccount"]); } if (siteUserList.Where(t => t.IsGenerateAccount && t.UserTypeId != null).GroupBy(t => new { t.UserTypeId, t.Email }) .Any(g => g.Count() > 1)) { throw new BusinessValidationFailedException(_localizer["TrialSiteSurvey_DuplicateEmail"]); } if (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.Undefined || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator) { var hasSPMOrCPM = await _trialSiteSurveyRepository.AnyAsync(t => t.TrialId == trialId && t.Trial.TrialUserList.Any(u => u.User.UserTypeEnum == UserTypeEnum.SPM || u.User.UserTypeEnum == UserTypeEnum.CPM)); var isTrialSPMJoin = await _trialRepository.AnyAsync(t => t.Id == trialId && t.IsSPMJoinSiteSurvey); var isSPMjoin = isTrialSPMJoin && hasSPMOrCPM; if (isSPMjoin) { await _trialSiteSurveyRepository.UpdatePartialFromQueryAsync(t => t.Id == trialSiteSurveyId && t.State == TrialSiteSurveyEnum.ToSubmit, u => new TrialSiteSurvey() { State = TrialSiteSurveyEnum.CRCSubmitted }); } else { await _trialSiteSurveyRepository.UpdatePartialFromQueryAsync(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.UpdatePartialFromQueryAsync(t => t.Id == trialSiteSurveyId && t.State == TrialSiteSurveyEnum.CRCSubmitted, u => new TrialSiteSurvey() { State = TrialSiteSurveyEnum.SPMApproved, PreliminaryUserId = _userInfo.UserRoleId, PreliminaryTime = DateTime.Now }); } else if (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ProjectManager || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.APM) { var allUserList = _trialSiteUserSurveyRepository.Where(t => t.TrialSiteSurveyId == trialSiteSurveyId).ProjectTo(_mapper.ConfigurationProvider).ToList(); //已生成的不管 管的只需要是 生成失败的并且需要生成账号的 var needGenerateList = allUserList.Where(t => t.IsHistoryUser == false && t.IsGenerateAccount && t.IsJoin != true).ToList(); await GenerateAccountAsync(needGenerateList, trialId); //新加入的 或者历史人员退出改为加入的 var needSendEmailList = allUserList.Where(t => (t.IsHistoryUser == false && t.IsGenerateAccount && t.IsJoin != true) || (t.IsHistoryUser == true && t.IsHistoryUserOriginDeleted == true && t.IsHistoryUserDeleted == false)).ToList(); await SendSiteSurveyUserJoinEmail(new TrialSiteUserSurveyJoinCommand() { TrialId = trialId, TrialSiteSurveyId = trialSiteSurveyId, RouteUrl = siteSurvyeSubmit.RouteUrl, BaseUrl = siteSurvyeSubmit.BaseUrl, UserList = needSendEmailList }); var needQuitUserList = allUserList.Where(t => t.IsHistoryUser && t.IsHistoryUserOriginDeleted == false && t.IsHistoryUserDeleted == true).ToList(); await DealSiteUserQuitSiteAsync(trialId, trialSiteSurvey.TrialSiteId, needQuitUserList); //将历史锁定的调研表废弃 await _trialSiteSurveyRepository.BatchUpdateNoTrackingAsync(t => t.TrialId == trialId && t.TrialSiteId == trialSiteSurvey.TrialSiteId && t.State == TrialSiteSurveyEnum.PMCreatedAndLock && t.Id != trialSiteSurveyId, z => new TrialSiteSurvey() { IsDeleted = true }); } await _trialSiteSurveyRepository.SaveChangesAsync(); return ResponseOutput.Ok(); } private async Task GenerateAccountAsync(List needGenerateList, Guid trialId) { var trialType = _trialRepository.Where(t => t.Id == trialId).Select(t => t.TrialType).FirstOrDefault(); foreach (var item in needGenerateList) { //找下系统中是否存在该用户类型的 并且邮箱 或者手机的账户 var sysUserInfo = await _userRoleRepository.Where(t => t.UserTypeId == item.UserTypeId && t.EMail == item.Email).Include(t => t.UserTypeRole).FirstOrDefaultAsync(); if (sysUserInfo == null) { var @lock = _distributedLockProvider.CreateLock($"UserCode"); using (await @lock.AcquireAsync()) { var saveItem = _mapper.Map(item); if (trialType == TrialType.NoneOfficial) { saveItem.IsTestUser = true; } // 中心调研生成账号 都是外部的 saveItem.IsZhiZhun = false; saveItem.Code = _userRoleRepository.Select(t => t.Code).DefaultIfEmpty().Max() + 1; saveItem.UserCode = AppSettings.GetCodeStr(saveItem.Code, nameof(UserRole)); saveItem.UserName = saveItem.UserCode; saveItem.Password = MD5Helper.Md5(IRCEmailPasswordHelper.GenerateRandomPassword(10)); saveItem.UserTypeEnum = _userTypeRepository.Where(t => t.Id == saveItem.UserTypeId).Select(t => t.UserTypeEnum).First(); var newUser = _userRoleRepository.AddAsync(saveItem).Result; _ = _userRoleRepository.SaveChangesAsync().Result; sysUserInfo = newUser; } await _trialSiteUserSurveyRepository.BatchUpdateNoTrackingAsync(t => t.Id == item.Id, u => new TrialSiteUserSurvey() { IsGenerateSuccess = true, SystemUserId = sysUserInfo.Id }); } //发送邮件的时候需要用到该字段 item.SystemUserId = sysUserInfo.Id; } await _trialSiteUserSurveyRepository.SaveChangesAsync(); } private async Task SendSiteSurveyUserJoinEmail(TrialSiteUserSurveyJoinCommand joinCommand) { var trialSiteSurvey = await _trialSiteSurveyRepository.FirstAsync(t => t.Id == joinCommand.TrialSiteSurveyId); foreach (var userInfo in joinCommand.UserList) { if (userInfo.SystemUserId == null) { //---生成账户Id 未取到值,请排查 throw new BusinessValidationFailedException(_localizer["TrialSiteSurvey_FailedToGenerateAccountId"]); } var trialId = joinCommand.TrialId; var userId = (Guid)userInfo.SystemUserId; var trialSiteId = trialSiteSurvey.TrialSiteId; //判断TrialUser中是否存在 不存在就插入 var findTrialUser = await _trialUserRepository.FirstOrDefaultAsync(t => t.TrialId == trialId && t.UserId == userId, true); if (findTrialUser == null) { await _trialUserRepository.AddAsync(new TrialUser() { TrialId = trialId, UserId = userId, JoinTime = DateTime.Now }); await _mailVerificationService.SiteSurveyUserJoinEmail(trialId, userId, joinCommand.BaseUrl, joinCommand.RouteUrl); } else if (findTrialUser.IsDeleted == true) { await _trialUserRepository.UpdatePartialFromQueryAsync(t => t.TrialId == trialId && t.UserId == userId, c => new TrialUser() { IsDeleted = false, DeletedTime = null, JoinTime = DateTime.Now, }); await _mailVerificationService.SiteSurveyUserJoinEmail(trialId, userId, joinCommand.BaseUrl, joinCommand.RouteUrl); } var findTrialSiteUser = await _trialSiteUserRepository.FirstOrDefaultAsync(t => t.TrialId == trialId && t.UserId == userId && t.TrialSiteId == trialSiteId, true); if (findTrialSiteUser == null) { await _trialSiteUserRepository.AddAsync(new TrialSiteUser() { TrialId = trialId, TrialSiteId = trialSiteId, UserId = userId }); } else { findTrialSiteUser.IsDeleted = false; findTrialSiteUser.DeletedTime = null; } await _userRoleRepository.BatchUpdateNoTrackingAsync(t => t.Id == userId, u => new UserRole() { Status = UserStateEnum.Enable }); await _trialSiteUserSurveyRepository.UpdatePartialFromQueryAsync(t => t.Id == userInfo.Id, u => new TrialSiteUserSurvey() { IsJoin = true }); } await _trialSiteSurveyRepository.UpdatePartialFromQueryAsync(t => t.Id == trialSiteSurvey.Id && t.State == TrialSiteSurveyEnum.SPMApproved, u => new TrialSiteSurvey() { State = TrialSiteSurveyEnum.PMCreatedAndLock, ReviewerUserId = _userInfo.UserRoleId, ReviewerTime = DateTime.Now }); await _userRoleRepository.SaveChangesAsync(); return ResponseOutput.Ok(); } private async Task DealSiteUserQuitSiteAsync(Guid trialId, Guid siteId, List list) { var userIdList = list.Select(t => t.SystemUserId).ToList(); await _trialSiteUserRepository.UpdatePartialFromQueryAsync(t => t.TrialId == trialId && t.TrialSiteId == siteId && userIdList.Contains(t.UserId), c => new TrialSiteUser() { IsDeleted = true, DeletedTime = DateTime.Now, }); await _trialSiteUserRepository.SaveChangesAsync(); } public async Task ImportGenerateAccountAndJoinTrialAsync(Guid trialId, string baseUrl, string routeUrl, List list) { var trialType = _trialRepository.Where(t => t.Id == trialId).Select(t => t.TrialType).FirstOrDefault(); //判断是否有系统账号 foreach (var item in list) { //找下系统中是否存在该用户类型的 并且邮箱 或者手机的账户 var sysUserInfo = await _userRoleRepository.Where(t => t.UserTypeId == item.UserTypeId && t.EMail == item.Email).Include(t => t.UserTypeRole).FirstOrDefaultAsync(); if (sysUserInfo == null) { var @lock = _distributedLockProvider.CreateLock($"UserCode"); using (await @lock.AcquireAsync()) { var saveItem = _mapper.Map(item); if (trialType == TrialType.NoneOfficial) { saveItem.IsTestUser = true; } // 中心调研生成账号 都是外部的 saveItem.IsZhiZhun = false; saveItem.Code = _userRoleRepository.Select(t => t.Code).DefaultIfEmpty().Max() + 1; saveItem.UserCode = AppSettings.GetCodeStr(saveItem.Code, nameof(UserRole)); saveItem.UserName = saveItem.UserCode; //saveItem.UserTypeEnum = _userTypeRepository.Where(t => t.Id == saveItem.UserTypeId).Select(t => t.UserTypeEnum).First(); var newUser = _userRoleRepository.AddAsync(saveItem).Result; _ = _userRoleRepository.SaveChangesAsync().Result; sysUserInfo = newUser; } item.IsGeneratedAccount = true; } var userId = sysUserInfo.Id; var trialSiteId = item.TrialSiteId; //判断是否加入到项目 var findTrialUser = await _trialUserRepository.FirstOrDefaultAsync(t => t.TrialId == trialId && t.UserId == userId, true); if (findTrialUser == null) { await _trialUserRepository.AddAsync(new TrialUser() { TrialId = trialId, UserId = userId, JoinTime = DateTime.Now }); await _mailVerificationService.SiteSurveyUserJoinEmail(trialId, userId, baseUrl, routeUrl); } else if (findTrialUser.IsDeleted == true) { await _trialUserRepository.UpdatePartialFromQueryAsync(t => t.TrialId == trialId && t.UserId == userId, c => new TrialUser() { IsDeleted = false, DeletedTime = null, JoinTime = DateTime.Now, }); await _mailVerificationService.SiteSurveyUserJoinEmail(trialId, userId, baseUrl, routeUrl); } var findTrialSiteUser = await _trialSiteUserRepository.FirstOrDefaultAsync(t => t.TrialId == trialId && t.UserId == userId && t.TrialSiteId == trialSiteId, true); if (findTrialSiteUser == null) { await _trialSiteUserRepository.AddAsync(new TrialSiteUser() { TrialId = trialId, TrialSiteId = trialSiteId, UserId = userId }); } else { findTrialSiteUser.IsDeleted = false; findTrialSiteUser.DeletedTime = null; } await _userRoleRepository.BatchUpdateNoTrackingAsync(t => t.Id == userId, u => new UserRole() { Status = UserStateEnum.Enable }); await _trialSiteUserRepository.SaveChangesAsync(); } } } }