//-------------------------------------------------------------------- // 此代码由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; using MassTransit; using DocumentFormat.OpenXml.Spreadsheet; using StackExchange.Redis; using Panda.DynamicWebApi.Attributes; using IdentityModel; using Microsoft.AspNetCore.Components.Routing; namespace IRaCIS.Core.Application.Contracts { /// /// TrialSiteSurveyService /// [ApiExplorerSettings(GroupName = "Trial")] public class TrialSiteSurveyService(IRepository _trialSiteSurveyRepository, IRepository _trialSiteUserSurveyRepository, IRepository _userRoleRepository, IRepository _identityUserRepository, IRepository _trialIdentityUserRepository, IRepository _trialRepository, IRepository _trialSiteRepository, IRepository _doctorRepository, IRepository _verificationCodeRepository, IRepository _trialUserRoleRepository, IRepository _trialSiteUserRoleRepository, 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(); } #region 多账户需要修改 /// /// 通过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 }; } } #endregion /// /// 验证邮箱验证码 获取医生信息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() { IdentityUserId = 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(); } #region 中心调研修改 /// /// 初始登陆界面 项目基本信息+下拉框数据 /// /// /// [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; } /// /// 实际这里只会是更新 添加在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); } /// /// 项目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); } /// /// 获取 项目 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(); } /// /// 驳回 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; 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) { 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.UserRole.UserTypeEnum == UserTypeEnum.SPM || u.UserRole.UserTypeEnum == UserTypeEnum.CPM)); var isSPMjoin = isTrialSPMJoin && hasSPMOrCPM; if (isSPMjoin) { survey.State = TrialSiteSurveyEnum.CRCSubmitted; survey.ReviewerUserId = null; survey.ReviewerTime = null; } else { survey.State = TrialSiteSurveyEnum.ToSubmit; survey.PreliminaryUserId = null; survey.ReviewerUserId = null; survey.PreliminaryTime = null; survey.ReviewerTime = null; } } 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(); } #endregion /// /// 验证后 如果数据库该项目不存在该邮箱 那么就插入记录 存在 /// /// /// /// /// [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 _trialSiteUserRoleRepository.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 _trialSiteUserRoleRepository.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; } /// /// 提交 后台自动识别是谁提交 /// /// /// [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.UserRole.UserTypeEnum == UserTypeEnum.SPM || u.UserRole.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.GroupBy(t => t.Email)) { var addUserRoleList = item.ToList(); //找下系统中是否存在该用户类型的 并且邮箱 或者手机的账户 var sysUserInfo = await _identityUserRepository.Where(t => t.EMail == item.Key, true).Include(t => t.UserRoleList).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 = _identityUserRepository.Select(t => t.Code).DefaultIfEmpty().Max() + 1; saveItem.UserCode = AppSettings.GetCodeStr(saveItem.Code, nameof(IdentityUser)); saveItem.UserName = saveItem.UserCode; saveItem.Password = MD5Helper.Md5(IRCEmailPasswordHelper.GenerateRandomPassword(10)); var userTypeIds = addUserRoleList.Select(t => t.UserTypeId).ToList(); var userTypeList = _userTypeRepository.Where(t => userTypeIds.Contains(t.Id)).Select(t => new { t.UserTypeEnum, UserTypeId = t.Id }).ToList(); saveItem.UserRoleList = new List(); foreach (var addUserRole in addUserRoleList) { var addRole = _mapper.Map(saveItem); addRole.UserTypeEnum = userTypeList.First(t => t.UserTypeId == addRole.UserTypeId).UserTypeEnum; addRole.UserTypeId = (Guid)addUserRole.UserTypeId; saveItem.UserRoleList.Add(addRole); } var newUser = await _identityUserRepository.AddAsync(saveItem); await _identityUserRepository.SaveChangesAsync(); sysUserInfo = newUser; foreach (var addUserRole in addUserRoleList) { //发送邮件的时候需要用到该字段 addUserRole.SystemUserId = sysUserInfo.Id; } } var trialSiteUserIdList = addUserRoleList.Select(t => t.Id).ToList(); await _trialSiteUserSurveyRepository.BatchUpdateNoTrackingAsync(t => trialSiteUserIdList.Contains(t.Id), u => new TrialSiteUserSurvey() { IsGenerateSuccess = true, SystemUserId = sysUserInfo.Id }); } else { var userTypeIds = addUserRoleList.Select(t => t.UserTypeId).ToList(); var userTypeList = _userTypeRepository.Where(t => userTypeIds.Contains(t.Id)).Select(t => new { t.UserTypeEnum, UserTypeId = t.Id }).ToList(); foreach (var addUserRole in addUserRoleList) { var find = sysUserInfo.UserRoleList.FirstOrDefault(t => t.UserTypeId == addUserRole.UserTypeId); if (find != null && find.IsUserRoleDisabled == true) { find.IsUserRoleDisabled = false; } else { var addRole = _mapper.Map(sysUserInfo); addRole.Id = NewId.NextSequentialGuid(); addRole.IdentityUserId = sysUserInfo.Id; addRole.UserTypeEnum = userTypeList.First(t => t.UserTypeId == addRole.UserTypeId).UserTypeEnum; addRole.UserTypeId = (Guid)addUserRole.UserTypeId; sysUserInfo.UserRoleList.Add(addRole); } } await _identityUserRepository.SaveChangesAsync(); } } await _trialSiteUserSurveyRepository.SaveChangesAsync(); } private async Task SendSiteSurveyUserJoinEmail(TrialSiteUserSurveyJoinCommand joinCommand) { var trialSiteSurvey = await _trialSiteSurveyRepository.FirstAsync(t => t.Id == joinCommand.TrialSiteSurveyId); foreach (var item in joinCommand.UserList.GroupBy(t => t.SystemUserId)) { var userRoleList = item.ToList(); var first = userRoleList.First(); if (userRoleList.Any(t => t.SystemUserId == null)) { //---生成账户Id 未取到值,请排查 throw new BusinessValidationFailedException(_localizer["TrialSiteSurvey_FailedToGenerateAccountId"]); } var trialId = joinCommand.TrialId; var userId = (Guid)item.Key; var trialSiteId = trialSiteSurvey.TrialSiteId; var sysUserInfo = await _identityUserRepository.Where(t => t.Id == userId, true).Include(t => t.UserRoleList).FirstOrDefaultAsync(); //判断是否加入到项目 var findTrialUser = await _trialIdentityUserRepository.FirstOrDefaultAsync(t => t.TrialId == trialId && t.IdentityUserId == userId, true); if (findTrialUser == null) { await _trialIdentityUserRepository.AddAsync(new TrialIdentityUser() { TrialId = trialId, IdentityUserId = userId, JoinTime = DateTime.Now, TrialUserRoleList = userRoleList.Select(t => new TrialUserRole() { TrialId = trialId, UserId = sysUserInfo.UserRoleList.Where(u => u.UserTypeId == t.UserTypeId).Select(t => t.Id).First() }).ToList() }); await _mailVerificationService.SiteSurveyUserJoinEmail(trialId, userId, joinCommand.BaseUrl, joinCommand.RouteUrl); } else if (findTrialUser.IsDeleted == true) { await _trialIdentityUserRepository.UpdatePartialFromQueryAsync(t => t.TrialId == trialId && t.IdentityUserId == userId, c => new TrialIdentityUser() { IsDeleted = false, DeletedTime = null, JoinTime = DateTime.Now, }); await _mailVerificationService.SiteSurveyUserJoinEmail(trialId, userId, joinCommand.BaseUrl, joinCommand.RouteUrl); } foreach (var userSuvey in userRoleList) { var userRoleId = sysUserInfo.UserRoleList.Where(t => t.UserTypeId == userSuvey.UserTypeId).First().Id; var findTrialSiteUser = await _trialSiteUserRoleRepository.FirstOrDefaultAsync(t => t.TrialId == trialId && t.UserId == userRoleId && t.TrialSiteId == trialSiteId, true); if (findTrialSiteUser == null) { await _trialSiteUserRoleRepository.AddAsync(new TrialSiteUserRole() { TrialId = trialId, TrialSiteId = trialSiteId, UserId = userRoleId }); } else { findTrialSiteUser.IsDeleted = false; findTrialSiteUser.DeletedTime = null; } findTrialSiteUser.IsDeleted = false; await _trialSiteUserSurveyRepository.UpdatePartialFromQueryAsync(t => t.Id == userSuvey.Id, u => new TrialSiteUserSurvey() { IsJoin = true }); } await _identityUserRepository.BatchUpdateNoTrackingAsync(t => t.Id == userId, u => new Domain.Models.IdentityUser() { Status = UserStateEnum.Enable }); await _trialSiteUserRoleRepository.SaveChangesAsync(); } 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 _trialSiteUserRoleRepository.UpdatePartialFromQueryAsync(t => t.TrialId == trialId && t.TrialSiteId == siteId && userIdList.Contains(t.UserRole.IdentityUserId), c => new TrialSiteUserRole() { IsDeleted = true, DeletedTime = DateTime.Now, }); await _trialSiteUserRoleRepository.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.GroupBy(t => t.Email)) { var addUserRoleList = item.ToList(); var first = addUserRoleList.FirstOrDefault(); //找下系统中是否存在该用户类型的 并且邮箱 或者手机的账户 var sysUserInfo = await _identityUserRepository.Where(t => t.EMail == item.Key, true).Include(t => t.UserRoleList).FirstOrDefaultAsync(); if (sysUserInfo == null) { var @lock = _distributedLockProvider.CreateLock($"UserCode"); using (await @lock.AcquireAsync()) { var saveItem = _mapper.Map(first); if (trialType == TrialType.NoneOfficial) { saveItem.IsTestUser = true; } // 中心调研生成账号 都是外部的 saveItem.IsZhiZhun = false; saveItem.Code = _identityUserRepository.Select(t => t.Code).DefaultIfEmpty().Max() + 1; saveItem.UserCode = AppSettings.GetCodeStr(saveItem.Code, nameof(IdentityUser)); saveItem.UserName = saveItem.UserCode; saveItem.UserRoleList = new List(); foreach (var addUserRole in addUserRoleList) { addUserRole.IsGeneratedAccount = true; //var trialSiteId = addUserRole.TrialSiteId; var addRole = _mapper.Map(saveItem); addRole.UserTypeEnum = addUserRole.UserTypeEnum; addRole.UserTypeId = addUserRole.UserTypeId; saveItem.UserRoleList.Add(addRole); } var newUser = await _identityUserRepository.AddAsync(saveItem); await _identityUserRepository.SaveChangesAsync(); sysUserInfo = newUser; } } else { foreach (var addUserRole in addUserRoleList) { var find = sysUserInfo.UserRoleList.FirstOrDefault(t => t.UserTypeEnum == addUserRole.UserTypeEnum && t.UserTypeId == addUserRole.UserTypeId); if (find != null && find.IsUserRoleDisabled == true) { find.IsUserRoleDisabled = false; } else { var addRole = _mapper.Map(sysUserInfo); addRole.Id = NewId.NextSequentialGuid(); addRole.IdentityUserId = sysUserInfo.Id; addRole.UserTypeEnum = addUserRole.UserTypeEnum; addRole.UserTypeId = addUserRole.UserTypeId; sysUserInfo.UserRoleList.Add(addRole); } } await _identityUserRepository.SaveChangesAsync(); } var userId = sysUserInfo.Id; //判断是否加入到项目 var findTrialUser = await _trialIdentityUserRepository.FirstOrDefaultAsync(t => t.TrialId == trialId && t.IdentityUserId == userId, true); if (findTrialUser == null) { await _trialIdentityUserRepository.AddAsync(new TrialIdentityUser() { TrialId = trialId, IdentityUserId = userId, JoinTime = DateTime.Now, TrialUserRoleList = sysUserInfo.UserRoleList.Select(t => new TrialUserRole() { TrialId = trialId, UserId = t.Id }).ToList() }); await _mailVerificationService.SiteSurveyUserJoinEmail(trialId, userId, baseUrl, routeUrl); } else if (findTrialUser.IsDeleted == true) { await _trialIdentityUserRepository.UpdatePartialFromQueryAsync(t => t.TrialId == trialId && t.IdentityUserId == userId, c => new TrialIdentityUser() { IsDeleted = false, DeletedTime = null, JoinTime = DateTime.Now, }); await _mailVerificationService.SiteSurveyUserJoinEmail(trialId, userId, baseUrl, routeUrl); } foreach (var userRole in addUserRoleList) { var userRoleId = sysUserInfo.UserRoleList.Where(t => t.UserTypeId == userRole.UserTypeId).First().Id; var findTrialSiteUser = await _trialSiteUserRoleRepository.FirstOrDefaultAsync(t => t.TrialId == trialId && t.UserId == userRoleId && t.TrialSiteId == userRole.TrialSiteId, true); if (findTrialSiteUser == null) { await _trialSiteUserRoleRepository.AddAsync(new TrialSiteUserRole() { TrialId = trialId, TrialSiteId = userRole.TrialSiteId, UserId = userRoleId }); } else { findTrialSiteUser.IsDeleted = false; findTrialSiteUser.DeletedTime = null; } findTrialSiteUser.IsDeleted = false; } await _trialSiteUserRoleRepository.SaveChangesAsync(); } } } }