//-------------------------------------------------------------------- // 此代码由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; using IRaCIS.Core.Application.ViewModel; using Microsoft.AspNetCore.Identity; using NPOI.SS.Formula.Functions; using System.Security.Policy; 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 _trialRepository.Where(t => t.Id == trialSiteSubmitBackCommand.TrialId).AnyAsync(t => t.TrialIdentityUserList.SelectMany(t => t.TrialUserRoleList).Any(t => t.UserRole.IdentityUser.Status == UserStateEnum.Enable && t.UserRole.IsUserRoleDisabled == false && (t.UserRole.UserTypeEnum == UserTypeEnum.SPM || t.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_ExpiredVerificationCode"]); } 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 _trialRepository.Where(t => t.Id == trialId).AnyAsync(t => t.TrialIdentityUserList.SelectMany(t => t.TrialUserRoleList).Any(t => t.UserRole.IdentityUser.Status == UserStateEnum.Enable && t.UserRole.IsUserRoleDisabled == false && (t.UserRole.UserTypeEnum == UserTypeEnum.SPM || t.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(); await GenerateAccountAndSendEmail(trialId, trialSiteSurveyId, trialSiteSurvey.TrialSiteId, siteSurvyeSubmit.BaseUrl, siteSurvyeSubmit.RouteUrl, allUserList); //将历史锁定的调研表废弃 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 GenerateAccountAndSendEmail(Guid trialId, Guid trialSiteSurveyId, Guid trialSiteId, string baseUrl, string routeUrl, List allUserList) { //已生成的不管 管的只需要是 生成失败的并且需要生成账号的 var needGenerateList = allUserList.Where(t => t.IsHistoryUser == false && t.IsGenerateAccount && t.IsJoin != true).ToList(); //新加入的 或者历史人员退出改为加入的 var needSendEmailList = allUserList.Where(t => (t.IsHistoryUser == false && t.IsGenerateAccount && t.IsJoin != true) || (t.IsHistoryUser == true && t.IsHistoryUserOriginDeleted == true && t.IsHistoryUserDeleted == false)).ToList(); 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 first = addUserRoleList.FirstOrDefault(); var userEmail = item.Key; var userTypeIdList = item.Select(t => t.UserTypeId).ToList(); var existSysUser = await _identityUserRepository.Where(t => t.EMail == userEmail, true).Include(t => t.UserRoleList).FirstOrDefaultAsync(); #region 人员生成 if (existSysUser != null) { //账号状态设置为启用 existSysUser.Status = UserStateEnum.Enable; foreach (var userTypeId in userTypeIdList) { var findRole = existSysUser.UserRoleList.FirstOrDefault(t => t.UserTypeId == userTypeId); if (findRole != null) { //存在该角色,设置为启用 findRole.IsUserRoleDisabled = false; } else { //不存在该角色,那么就添加 var addRole = _mapper.Map(existSysUser); addRole.Id = NewId.NextSequentialGuid(); addRole.UserTypeEnum = _userTypeRepository.Where(t => t.Id == userTypeId).Select(t => t.UserTypeEnum).First(); addRole.UserTypeId = userTypeId.Value; addRole.IsUserRoleDisabled = false; existSysUser.UserRoleList.Add(addRole); } } } else { //生成账户 并插入 var generateUser = _mapper.Map(first); if (trialType == TrialType.NoneOfficial) { generateUser.IsTestUser = true; } generateUser.Id = NewId.NextSequentialGuid(); // 外部人员生成账号 都是外部的 generateUser.IsZhiZhun = false; generateUser.Code = _identityUserRepository.Select(t => t.Code).DefaultIfEmpty().Max() + 1; generateUser.UserCode = AppSettings.GetCodeStr(generateUser.Code, nameof(IdentityUser)); //generateUser.UserName = generateUser.UserCode; generateUser.Password = MD5Helper.Md5(IRCEmailPasswordHelper.GenerateRandomPassword(10)); generateUser.Status = UserStateEnum.Enable; generateUser.UserRoleList = new List() { }; foreach (var userTypeId in userTypeIdList) { var addRole = _mapper.Map(generateUser); addRole.Id = NewId.NextSequentialGuid(); addRole.UserTypeEnum = _userTypeRepository.Where(t => t.Id == userTypeId).Select(t => t.UserTypeEnum).First(); addRole.UserTypeId = userTypeId.Value; generateUser.UserRoleList.Add(addRole); } var newAddUser = await _identityUserRepository.AddAsync(generateUser); existSysUser = newAddUser; } #endregion await _identityUserRepository.SaveChangesAsync(); var identityUserId = existSysUser.Id; #region 项目加入 var findTrialUser = await _trialIdentityUserRepository.Where(t => t.TrialId == trialId && t.IdentityUserId == identityUserId, true, true).Include(t => t.TrialUserRoleList).ThenInclude(t => t.UserRole).FirstOrDefaultAsync(); var isNeedSendEmail = false; if (findTrialUser == null) { //没有项目参与人员 findTrialUser = await _trialIdentityUserRepository.AddAsync(new TrialIdentityUser() { IdentityUserId = identityUserId, TrialId = trialId, JoinTime = DateTime.Now, TrialUserRoleList = userTypeIdList.Select(u => new TrialUserRole() { TrialId = trialId, UserId = existSysUser.UserRoleList.FirstOrDefault(t => t.UserTypeId == u).Id, }).ToList() }); isNeedSendEmail = true; } else { //有该人员 //是否有该角色 if (findTrialUser.IsDeleted == true) { findTrialUser.IsDeleted = false; findTrialUser.DeletedTime = null; findTrialUser.RemoveTime = null; findTrialUser.JoinTime = DateTime.Now; } foreach (var userTypeId in userTypeIdList) { //userRole 可能为null var findTrialUserRole = findTrialUser.TrialUserRoleList.Where(t => t.UserRole?.UserTypeId == userTypeId).FirstOrDefault(); if (findTrialUserRole == null) { isNeedSendEmail = true; //添加该角色 findTrialUser.TrialUserRoleList.Add(new TrialUserRole() { TrialUserId = findTrialUser.Id, TrialId = trialId, UserId = existSysUser.UserRoleList.FirstOrDefault(t => t.UserTypeId == userTypeId).Id }); } else { //如果禁用,那么启用 if (findTrialUserRole.IsDeleted == true) { findTrialUserRole.IsDeleted = false; findTrialUserRole.DeletedTime = null; } } } } #endregion #region 中心加入 foreach (var userTypeId in userTypeIdList) { var findUserRole = existSysUser.UserRoleList.Where(t => t.UserTypeId == userTypeId).FirstOrDefault(); var findTrialSiteUserRole = await _trialSiteUserRoleRepository.Where(t => t.TrialId == trialId && t.TrialSiteId == trialSiteId && t.UserId == findUserRole.Id, true, true).FirstOrDefaultAsync(); if (findTrialSiteUserRole != null) { findTrialSiteUserRole.IsDeleted = false; findTrialSiteUserRole.DeletedTime = null; } else { await _trialSiteUserRoleRepository.AddAsync(new TrialSiteUserRole() { TrialId = trialId, TrialSiteId = trialSiteId, UserId = findUserRole.Id }); } } #endregion if (isNeedSendEmail) { var dbUserType = _userTypeRepository.Where(t => userTypeIdList.Contains(t.Id)).ToList(); var usertyps = string.Join(',', dbUserType.Select(t => t.UserTypeName)); await _mailVerificationService.SiteSurveyUserJoinEmail(trialId, identityUserId, usertyps, baseUrl, routeUrl); } var userJoinIdList = item.Select(t => t.Id).ToList(); await _trialSiteUserSurveyRepository.UpdatePartialFromQueryAsync(t => userJoinIdList.Contains(t.Id), u => new TrialSiteUserSurvey() { IsJoin = true, SystemUserId = existSysUser.Id }); //中心调研设置用户角色退出 var needQuitUserList = item.Where(t => t.IsHistoryUser && t.IsHistoryUserOriginDeleted == false && t.IsHistoryUserDeleted == true).ToList(); var queitUserTypeIdList = needQuitUserList.Select(t => t.UserTypeId).ToList(); await _trialSiteUserRoleRepository.UpdatePartialFromQueryAsync(t => t.TrialId == trialId && t.TrialSiteId == trialSiteId && queitUserTypeIdList.Contains(t.UserRole.UserTypeId), c => new TrialSiteUserRole() { IsDeleted = true, DeletedTime = DateTime.Now, }); await _trialSiteUserRoleRepository.SaveChangesAsync(); } await _trialSiteSurveyRepository.UpdatePartialFromQueryAsync(t => t.Id == trialSiteSurveyId && t.State == TrialSiteSurveyEnum.SPMApproved, u => new TrialSiteSurvey() { State = TrialSiteSurveyEnum.PMCreatedAndLock, ReviewerUserId = _userInfo.UserRoleId, ReviewerTime = DateTime.Now }); } 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 userEmail = item.Key; var userTypeIdList = item.Select(t => t.UserTypeId).ToList(); var existSysUser = await _identityUserRepository.Where(t => t.EMail == userEmail, true).Include(t => t.UserRoleList).FirstOrDefaultAsync(); if (existSysUser != null) { //账号状态设置为启用 existSysUser.Status = UserStateEnum.Enable; foreach (var userTypeId in userTypeIdList) { var findRole = existSysUser.UserRoleList.FirstOrDefault(t => t.UserTypeId == userTypeId); if (findRole != null) { //存在该角色,设置为启用 findRole.IsUserRoleDisabled = false; } else { //不存在该角色,那么就添加 var addRole = _mapper.Map(existSysUser); addRole.Id = NewId.NextSequentialGuid(); addRole.UserTypeEnum = _userTypeRepository.Where(t => t.Id == userTypeId).Select(t => t.UserTypeEnum).First(); addRole.UserTypeId = userTypeId; addRole.IsUserRoleDisabled = false; existSysUser.UserRoleList.Add(addRole); } } } else { //生成账户 并插入 var generateUser = _mapper.Map(first); if (trialType == TrialType.NoneOfficial) { generateUser.IsTestUser = true; } generateUser.Id = NewId.NextSequentialGuid(); // 外部人员生成账号 都是外部的 generateUser.IsZhiZhun = false; generateUser.Code = _identityUserRepository.Select(t => t.Code).DefaultIfEmpty().Max() + 1; generateUser.UserCode = AppSettings.GetCodeStr(generateUser.Code, nameof(IdentityUser)); //generateUser.UserName = generateUser.UserCode; generateUser.Password = MD5Helper.Md5(IRCEmailPasswordHelper.GenerateRandomPassword(10)); generateUser.Status = UserStateEnum.Enable; generateUser.UserRoleList = new List() { }; foreach (var userTypeId in userTypeIdList) { var addRole = _mapper.Map(generateUser); addRole.Id = NewId.NextSequentialGuid(); addRole.UserTypeEnum = _userTypeRepository.Where(t => t.Id == userTypeId).Select(t => t.UserTypeEnum).First(); addRole.UserTypeId = userTypeId; generateUser.UserRoleList.Add(addRole); } var newAddUser = await _identityUserRepository.AddAsync(generateUser); existSysUser = newAddUser; } await _identityUserRepository.SaveChangesAsync(); var identityUserId = existSysUser.Id; var findTrialUser = await _trialIdentityUserRepository.Where(t => t.TrialId == trialId && t.IdentityUserId == identityUserId, true, true).Include(t => t.TrialUserRoleList).ThenInclude(t => t.UserRole).FirstOrDefaultAsync(); var isNeedSendEmail = false; if (findTrialUser == null) { //没有项目参与人员 findTrialUser = await _trialIdentityUserRepository.AddAsync(new TrialIdentityUser() { IdentityUserId = identityUserId, TrialId = trialId, JoinTime = DateTime.Now, TrialUserRoleList = userTypeIdList.Select(u => new TrialUserRole() { TrialId = trialId, UserId = existSysUser.UserRoleList.FirstOrDefault(t => t.UserTypeId == u).Id, }).ToList() }); isNeedSendEmail = true; } else { //有该人员 //是否有该角色 if (findTrialUser.IsDeleted == true) { findTrialUser.IsDeleted = false; findTrialUser.DeletedTime = null; findTrialUser.RemoveTime = null; findTrialUser.JoinTime = DateTime.Now; } foreach (var userTypeId in userTypeIdList) { var findTrialUserRole = findTrialUser.TrialUserRoleList.Where(t => t.UserRole?.UserTypeId == userTypeId).FirstOrDefault(); if (findTrialUserRole == null) { isNeedSendEmail = true; //添加该角色 findTrialUser.TrialUserRoleList.Add(new TrialUserRole() { TrialUserId = findTrialUser.Id, TrialId = trialId, UserId = existSysUser.UserRoleList.FirstOrDefault(t => t.UserTypeId == userTypeId).Id }); } else { //如果禁用,那么启用 if (findTrialUserRole.IsDeleted == true) { findTrialUserRole.IsDeleted = false; findTrialUserRole.DeletedTime = null; } } } } //加入到Site CRC foreach (var trialsSiteItem in addUserRoleList.GroupBy(t => t.TrialSiteId)) { var siteUserRoleList = trialsSiteItem.ToList(); foreach (var siteUserRole in siteUserRoleList) { var findUserRole = existSysUser.UserRoleList.Where(t => t.UserTypeId == siteUserRole.UserTypeId).FirstOrDefault(); if (findUserRole != null) { var findTrialSiteUserRole = await _trialSiteUserRoleRepository.Where(t => t.TrialId == trialId && t.TrialSiteId == trialsSiteItem.Key && t.UserId == findUserRole.Id, true, true).FirstOrDefaultAsync(); if (findTrialSiteUserRole != null) { findTrialSiteUserRole.IsDeleted = false; findTrialSiteUserRole.DeletedTime = null; } else { await _trialSiteUserRoleRepository.AddAsync(new TrialSiteUserRole() { TrialId = trialId, TrialSiteId = trialsSiteItem.Key, UserId = findUserRole.Id }); } } else { throw new BusinessValidationFailedException("database dirty data ,pleasse check"); } } } if (isNeedSendEmail) { var dbUserType = _userTypeRepository.Where(t => userTypeIdList.Contains(t.Id)).ToList(); var usertyps = string.Join(',', dbUserType.Select(t => t.UserTypeName)); await _mailVerificationService.SiteSurveyUserJoinEmail(trialId, identityUserId, usertyps, baseUrl, routeUrl); } await _trialSiteUserRoleRepository.SaveChangesAsync(); } } } }