diff --git a/IRaCIS.Core.API/Controllers/ExtraController.cs b/IRaCIS.Core.API/Controllers/ExtraController.cs index 80a114def..f15e31eca 100644 --- a/IRaCIS.Core.API/Controllers/ExtraController.cs +++ b/IRaCIS.Core.API/Controllers/ExtraController.cs @@ -254,7 +254,7 @@ namespace IRaCIS.Api.Controllers else { //正常登录才发送邮件 - await _userService.SendMFAEmail(userId); + await _userService.SendMFAEmail(new Core.Application.ViewModel.SendMfaCommand() { IdentityUserId= userId }); } diff --git a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml index ea66877a7..a464a5c18 100644 --- a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml +++ b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml @@ -489,14 +489,6 @@ - - - 重阅原任务跟踪处理 - - - - - PM 申请重阅 被同意 或者 PM 直接退回的时候影响 @@ -2269,19 +2261,16 @@ - + 发送MFA 验证邮件 - - - + 验证MFA 邮件 - @@ -16129,7 +16118,7 @@ SystemDocumentService - + SystemDocumentService diff --git a/IRaCIS.Core.Application/Service/Allocation/VisitTaskService.cs b/IRaCIS.Core.Application/Service/Allocation/VisitTaskService.cs index 2a02a744e..8d13ba8d7 100644 --- a/IRaCIS.Core.Application/Service/Allocation/VisitTaskService.cs +++ b/IRaCIS.Core.Application/Service/Allocation/VisitTaskService.cs @@ -1325,6 +1325,16 @@ public class VisitTaskService(IRepository _visitTaskRepository, var criterionConfig = (await _trialReadingCriterionRepository.Where(x => x.Id == trialReadingCriterionId).Select(x => new { x.ReadingTool, x.IsAutoCreate, x.IsReadingTaskViewInOrder }).FirstOrDefaultAsync()).IfNullThrowException(); + var isSPMJoinReReadingApproval = _trialRepository.Any(t => t.Id == trialId && t.IsSPMJoinReReadingApproval); + + var hasSPMOrCPM = await _trialRepository.Where(t => t.Id == trialId).SelectMany(t => t.TrialIdentityUserList).AnyAsync(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 = isSPMJoinReReadingApproval && hasSPMOrCPM; + foreach (var task in taskList) { @@ -1486,76 +1496,48 @@ public class VisitTaskService(IRepository _visitTaskRepository, } - - var rootReReadingTaskId = _visitTaskReReadingRepository.Where(t => t.NewReReadingTaskId == task.Id).Select(u => u.RootReReadingTaskId).FirstOrDefault(); - - //添加申请记录 - var visitTaskReReading = await _visitTaskReReadingRepository.AddAsync(new VisitTaskReReading() + //pm 申请重阅,并且SPM不参与,那么不增加申请记录,直接退回 + if (!isSPMjoin && IsPMOrAPm()) { - TrialId = applyReReadingCommand.TrialId, - RootReReadingTaskId = rootReReadingTaskId == Guid.Empty ? task.Id : rootReReadingTaskId, - OriginalReReadingTaskId = task.Id, - RequestReReadingTime = DateTime.Now, - RequestReReadingUserId = _userInfo.UserRoleId, - IsCopyOrigenalForms = applyReReadingCommand.IsCopyOrigenalForms, - IsCopyFollowForms = applyReReadingCommand.IsCopyFollowForms, - RequestReReadingReason = applyReReadingCommand.RequestReReadingReason, - RequestReReadingType = applyReReadingCommand.RequestReReadingType, + //不想看到申请记录 + foreach (var item in applyReReadingCommand.TaskIdList) + { + await AgreeReReading(item, RequestReReadingType.TrialGroupApply, null); + } + + } + else + { + var rootReReadingTaskId = _visitTaskReReadingRepository.Where(t => t.NewReReadingTaskId == task.Id).Select(u => u.RootReReadingTaskId).FirstOrDefault(); + + //添加申请记录 + var visitTaskReReading = await _visitTaskReReadingRepository.AddAsync(new VisitTaskReReading() + { + TrialId = applyReReadingCommand.TrialId, + RootReReadingTaskId = rootReReadingTaskId == Guid.Empty ? task.Id : rootReReadingTaskId, + OriginalReReadingTaskId = task.Id, + RequestReReadingTime = DateTime.Now, + RequestReReadingUserId = _userInfo.UserRoleId, + IsCopyOrigenalForms = applyReReadingCommand.IsCopyOrigenalForms, + IsCopyFollowForms = applyReReadingCommand.IsCopyFollowForms, + RequestReReadingReason = applyReReadingCommand.RequestReReadingReason, + RequestReReadingType = applyReReadingCommand.RequestReReadingType, + + }); + } + - }); } await _visitTaskRepository.SaveChangesAsync(); - #region 处理SPM 是否参与审批流程 - - var isSPMJoinReReadingApproval = _trialRepository.Any(t => t.Id == trialId && t.IsSPMJoinReReadingApproval); - - var hasSPMOrCPM = await _trialRepository.Where(t => t.Id == trialId).SelectMany(t => t.TrialIdentityUserList).AnyAsync(t => t.TrialUserRoleList.Any(t => t.UserRole.UserTypeEnum == UserTypeEnum.SPM || t.UserRole.UserTypeEnum == UserTypeEnum.CPM)); - - var isSPMjoin = isSPMJoinReReadingApproval && hasSPMOrCPM; - - if (!isSPMjoin && IsPMOrAPm()) - { - var requestRecordList = await _visitTaskReReadingRepository.Where(t => applyReReadingCommand.TaskIdList.Contains(t.OriginalReReadingTaskId) && t.RequestReReadingUserId == _userInfo.UserRoleId).ToListAsync(); - - await ConfirmReReading(new ConfirmReReadingCommand() - { - TrialId = trialId, - RequestReReadingResultEnum = RequestReReadingResult.Agree, - ConfirmReReadingList = requestRecordList.Select(t => new ConfirmReReadingDTO() { Id = t.Id, OriginalReReadingTaskId = t.OriginalReReadingTaskId }).ToList() - }); - } - - #endregion - - return ResponseOutput.Ok(); } - /// - /// 重阅原任务跟踪处理 - /// - /// - /// - /// - private void ReReadingTaskTrackingDeal(VisitTask origenalTask, ConfirmReReadingCommand agreeReReadingCommand) - { - if (origenalTask.ReReadingApplyState == ReReadingApplyState.DocotorHaveApplyed || origenalTask.ReReadingApplyState == ReReadingApplyState.TrialGroupHaveApplyed) - { - origenalTask.ReReadingApplyState = agreeReReadingCommand.RequestReReadingResultEnum == RequestReReadingResult.Agree ? ReReadingApplyState.Agree : ReReadingApplyState.Reject; - origenalTask.TaskState = agreeReReadingCommand.RequestReReadingResultEnum == RequestReReadingResult.Agree ? TaskState.HaveReturned : origenalTask.TaskState; - } - else - { - //---当前重阅任务状态不为已申请状态,不允许进行处理,请刷新页面 - throw new BusinessValidationFailedException(_localizer["VisitTask_InvalidReapplyStatus"]); - } - } private async Task SetMedicalReviewInvalidAsync(List influenceTaskList, bool isPMApply = true) { @@ -1626,12 +1608,9 @@ public class VisitTaskService(IRepository _visitTaskRepository, await _visitTaskReReadingRepository.BatchUpdateNoTrackingAsync(t => t.Id == item.Id, u => new VisitTaskReReading() { RequestReReadingConfirmUserId = _userInfo.UserRoleId, RequestReReadingResultEnum = RequestReReadingResult.Invalid }); //---当前申请重阅任务的状态,已被其他任务重阅已影响,不允许对该状态下的任务进行重阅同意与否操作 - return ResponseOutput.Ok(string.Empty, msg: _localizer["VisitTask_ReapplyStatusConflict"]); + throw new BusinessValidationFailedException(_localizer["VisitTask_ReapplyStatusConflict"]); } - - var criterionConfig = await _trialReadingCriterionRepository.Where(x => x.Id == origenalTask.TrialReadingCriterionId).Select(x => new { x.ReadingTool, x.CriterionType, x.IsAdditionalAssessment, x.IsReadingTaskViewInOrder }).FirstOrDefaultAsync(); - //更新申请信息 var visitTaskReReadingAppply = await _visitTaskReReadingRepository.FirstOrDefaultAsync(t => t.Id == item.Id); visitTaskReReadingAppply.RequestReReadingConfirmUserId = _userInfo.UserRoleId; @@ -1639,511 +1618,29 @@ public class VisitTaskService(IRepository _visitTaskRepository, visitTaskReReadingAppply.RequestReReadingRejectReason = agreeReReadingCommand.RequestReReadingRejectReason; - Expression> filterExpression = t => t.TrialId == trialId && t.SubjectId == origenalTask.SubjectId && (t.TaskState == TaskState.Effect || t.TaskState == TaskState.Freeze) && t.TaskAllocationState == TaskAllocationState.Allocated; - - //是否是一致性分析任务 正常申请 会影响一致性分析任务 - filterExpression = filterExpression.And(t => t.IsAnalysisCreate == origenalTask.IsAnalysisCreate); - - //IR 申请1.1 基线重阅,影响附加评估两个IR所有的任务 - var isIR1Point1AdditionalAssessmentBaseline = false; - - //附加评估 IR 和PM 看到的影响列表不一样 - - //1.1 有附加评估,会影响其他标准的任务 - if (criterionConfig.CriterionType == CriterionType.RECIST1Point1 && criterionConfig.IsAdditionalAssessment) - { - // PM申请 SPM / CPM审批 - if (visitTaskReReadingAppply.RequestReReadingType == RequestReReadingType.TrialGroupApply) - { - filterExpression = filterExpression.And(t => t.TrialReadingCriterionId == origenalTask.TrialReadingCriterionId || t.TrialReadingCriterion.CriterionType == CriterionType.RECIST1Pointt1_MB); - } - //IR 申请 PM审批 - else - { - - // 1.1 基线任务影响BM任务 - if ((IsPMOrAPm()) && _subjectVisitRepository.Any(t => t.Id == origenalTask.SourceSubjectVisitId && t.IsBaseLine == true)) - { - - isIR1Point1AdditionalAssessmentBaseline = true; - - } - // 1.1 非基线任务不影响BM任务 - else - { - filterExpression = filterExpression.And(t => t.TrialReadingCriterionId == origenalTask.TrialReadingCriterionId); - } - } - } - else - { - //默认影响的都是该标准的任务 - filterExpression = filterExpression.And(t => t.TrialReadingCriterionId == origenalTask.TrialReadingCriterionId); - } if (agreeReReadingCommand.RequestReReadingResultEnum == RequestReReadingResult.Agree) { - //PM申请 SPM / CPM审批 回退访视,因此这里不生成访视任务 影响多个标准的任务 - if (visitTaskReReadingAppply.RequestReReadingType == RequestReReadingType.TrialGroupApply) + + await AgreeReReading(origenalTask.Id, visitTaskReReadingAppply.RequestReReadingType, visitTaskReReadingAppply); + + //找到跟踪的实体 + var influenceTask = await _visitTaskRepository.FindAsync(origenalTask.Id); + + if (origenalTask.ReReadingApplyState == ReReadingApplyState.DocotorHaveApplyed || origenalTask.ReReadingApplyState == ReReadingApplyState.TrialGroupHaveApplyed) { - - // 不管有序 无序 都会 回退访视 - if (origenalTask.ReadingCategory == ReadingCategory.Visit) - { - //执行类似一致性核查回退流程 - await VisitBackAsync(origenalTask.SourceSubjectVisitId); - - } - else - { - //---仅允许同意访视类型的任务重阅 - throw new BusinessValidationFailedException(_localizer["VisitTask_ReReadTaskNotApplied"]); - } - - //有序阅片 - if (criterionConfig.IsReadingTaskViewInOrder == ReadingOrder.InOrder) - { - - - //访视影响当前以及当前之后的 两个阅片人的 - filterExpression = filterExpression.And(t => t.VisitTaskNum >= origenalTask.VisitTaskNum); - - - #region 影响的任务 - - - - var influenceTaskList = await _visitTaskRepository.Where(filterExpression, true).ToListAsync(); - - var trakingOrigenalTask = influenceTaskList.Where(t => t.Id == origenalTask.Id).FirstOrDefault(); - - foreach (var influenceTask in influenceTaskList) - { - //处理申请的任务 - if (influenceTask.Id == origenalTask.Id) - { - ReReadingTaskTrackingDeal(influenceTask, agreeReReadingCommand); - - await InfluenceAddtioncalEvaluationCritrionAsync(origenalTask, influenceTaskList.Where(t => t.Id != origenalTask.Id).Where(t => t.SourceSubjectVisitId != null).Select(t => t.SourceSubjectVisitId!.Value).Distinct().ToList()); - - await PMReReadingConfirmOrBackInfluenceAnalysisAsync(origenalTask.SubjectId); - - await SetMedicalReviewInvalidAsync(influenceTaskList); - - } - - - if (influenceTask.ReadingTaskState == ReadingTaskState.HaveSigned) - { - influenceTask.TaskState = TaskState.HaveReturned; - - trakingOrigenalTask?.TaskInfluenceList.Add(new TaskInfluence() { InfluenceTaskId = influenceTask.Id, OptType = ReReadingOrBackOptType.Return }); - } - else - { - influenceTask.TaskState = TaskState.Adbandon; - - trakingOrigenalTask?.TaskInfluenceList.Add(new TaskInfluence() { InfluenceTaskId = influenceTask.Id, OptType = ReReadingOrBackOptType.Abandon }); - } - - - } - #endregion - } - //无序阅片 没有 全局 肿瘤学 - else - { - - // 1.当前任务及裁判任务 - // 2.影响所有阅片人的任务 - - var judegTaskNum = origenalTask.VisitTaskNum + ReadingCommon.TaskNumDic[ReadingCategory.Judge]; - - filterExpression = filterExpression.And(t => t.VisitTaskNum == origenalTask.VisitTaskNum || t.VisitTaskNum == judegTaskNum); - - - var influenceTaskList = await _visitTaskRepository.Where(filterExpression, true).ToListAsync(); - - //影像列表为空就为null - var trakingOrigenalTask = influenceTaskList.Where(t => t.Id == origenalTask.Id).FirstOrDefault(); - - foreach (var influenceTask in influenceTaskList) - { - //处理申请的任务 - if (influenceTask.Id == origenalTask.Id) - { - ReReadingTaskTrackingDeal(influenceTask, agreeReReadingCommand); - - - await PMReReadingConfirmOrBackInfluenceAnalysisAsync(origenalTask.SubjectId); - - await SetMedicalReviewInvalidAsync(influenceTaskList); - - trakingOrigenalTask?.TaskInfluenceList.Add(new TaskInfluence() { InfluenceTaskId = influenceTask.Id, OptType = ReReadingOrBackOptType.Return }); - } - else - { - if (influenceTask.ReadingTaskState == ReadingTaskState.HaveSigned) - { - influenceTask.TaskState = TaskState.HaveReturned; - - trakingOrigenalTask?.TaskInfluenceList.Add(new TaskInfluence() { InfluenceTaskId = influenceTask.Id, OptType = ReReadingOrBackOptType.Return }); - } - else - { - influenceTask.TaskState = TaskState.Adbandon; - - trakingOrigenalTask?.TaskInfluenceList.Add(new TaskInfluence() { InfluenceTaskId = influenceTask.Id, OptType = ReReadingOrBackOptType.Abandon }); - } - } - } - - } - - - - } - //IR申请 PM 审批 注意这里有一致性分析的申请同意 不会回退访视,在此要生成影响的访视任务 - else if (visitTaskReReadingAppply.RequestReReadingType == RequestReReadingType.DocotorApply && (IsPMOrAPm() || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.AIR)) - { - - - - //有序阅片 - if (criterionConfig.IsReadingTaskViewInOrder == ReadingOrder.InOrder) - { - #region 有序 IR 申请 重阅 影响的其他访视查询 - - - - switch (origenalTask.ReadingCategory) - { - case ReadingCategory.Visit: - //影响后续访视已经读完的,正在读的,未读的不做处理 以及其他类型任务 - - //申请的是转化的,那么影响列表要排除转化之前的 - if (criterionConfig.CriterionType == CriterionType.IRECIST1Point1 && origenalTask.BeforeConvertedTaskId != null) - { - - - filterExpression = filterExpression.And(t => (t.VisitTaskNum > origenalTask.VisitTaskNum && - ( - ((t.ReadingCategory == ReadingCategory.Visit || t.ReadingCategory == ReadingCategory.Global) && t.DoctorUserId == origenalTask.DoctorUserId) - // 裁判 肿瘤学是另外的医生做 - || t.ReadingCategory == ReadingCategory.Judge - || t.ReadingCategory == ReadingCategory.Oncology - )) || t.Id == origenalTask.Id) - ; - } - else if (isIR1Point1AdditionalAssessmentBaseline) - { - filterExpression = filterExpression.And(t => t.VisitTaskNum >= origenalTask.VisitTaskNum && - ((( - ((t.ReadingCategory == ReadingCategory.Visit || t.ReadingCategory == ReadingCategory.Global) && t.DoctorUserId == origenalTask.DoctorUserId) - // 裁判 肿瘤学是另外的医生做 - || t.ReadingCategory == ReadingCategory.Judge - || t.ReadingCategory == ReadingCategory.Oncology - ) && t.TrialReadingCriterionId == origenalTask.TrialReadingCriterionId) || (t.TrialReadingCriterion.CriterionType == CriterionType.RECIST1Pointt1_MB)) - ); - } - else - { - filterExpression = filterExpression.And(t => t.VisitTaskNum >= origenalTask.VisitTaskNum && - ( - ((t.ReadingCategory == ReadingCategory.Visit || t.ReadingCategory == ReadingCategory.Global) && t.DoctorUserId == origenalTask.DoctorUserId) - // 裁判 肿瘤学是另外的医生做 - || t.ReadingCategory == ReadingCategory.Judge - || t.ReadingCategory == ReadingCategory.Oncology - ) - ); - } - - - - - - - break; - - - //不影响后续访视: (t.ReadingCategory == ReadingCategory.Visit && t.ReadingTaskState != ReadingTaskState.WaitReading) || - case ReadingCategory.Global: - - filterExpression = filterExpression.And(t => t.VisitTaskNum > origenalTask.VisitTaskNum && - ((t.DoctorUserId == origenalTask.DoctorUserId && t.ReadingCategory == ReadingCategory.Global) - || (t.ReadingCategory == ReadingCategory.Oncology) || (t.ReadingCategory == ReadingCategory.Judge)) || t.Id == origenalTask.Id); - break; - - case ReadingCategory.Oncology: - - //仅仅影响自己 后续任务如果是访视任务、全局任务或裁判任务,均不处理 - filterExpression = filterExpression.And(t => t.Id == origenalTask.Id); - break; - - case ReadingCategory.Judge: - - //裁判的影响自己 和后续肿瘤学阅片(不是自己做的) - filterExpression = filterExpression.And(t => t.Id == origenalTask.Id || t.VisitTaskNum > origenalTask.VisitTaskNum && t.ReadingCategory == ReadingCategory.Oncology); - - break; - - - default: - //---不支持重阅的任务类型 - throw new BusinessValidationFailedException(_localizer["VisitTask_UnsupportedTaskType"]); - - } - - #endregion - - - - var influenceTaskList = await _visitTaskRepository.Where(filterExpression, true).OrderBy(t => t.VisitTaskNum).ToListAsync(); - - var trakingOrigenalTask = influenceTaskList.Where(t => t.Id == origenalTask.Id).FirstOrDefault(); - - - - foreach (var influenceTask in influenceTaskList) - { - var beforeTaskState = influenceTask.TaskState; - - //已签名的任务 设置转变后的标志 - if (criterionConfig.CriterionType == CriterionType.IRECIST1Point1 && influenceTask.ReadingTaskState == ReadingTaskState.HaveSigned) - { - var isConvertedTask = _visitTaskRepository.Where(t => t.Id == influenceTask.Id).Select(t => t.IsConvertedTask).FirstOrDefault(); - - if (isConvertedTask) - { - influenceTask.IsHistoryConvertedTask = true; - } - } - - - //处理申请的任务 - if (influenceTask.Id == origenalTask.Id) - { - ReReadingTaskTrackingDeal(influenceTask, agreeReReadingCommand); - - - await SetMedicalReviewInvalidAsync(influenceTaskList, false); - - await InfluenceAddtioncalEvaluationCritrionAsync(origenalTask, influenceTaskList.Where(t => t.Id != origenalTask.Id).Where(t => t.SourceSubjectVisitId != null).Select(t => t.SourceSubjectVisitId!.Value).Distinct().ToList(), false); - - } - - - - if (influenceTask.ReadingTaskState == ReadingTaskState.HaveSigned) - { - influenceTask.TaskState = TaskState.HaveReturned; - - trakingOrigenalTask?.TaskInfluenceList.Add(new TaskInfluence() { InfluenceTaskId = influenceTask.Id, OptType = ReReadingOrBackOptType.Return }); - } - else - { - influenceTask.TaskState = TaskState.Adbandon; - - trakingOrigenalTask?.TaskInfluenceList.Add(new TaskInfluence() { InfluenceTaskId = influenceTask.Id, OptType = ReReadingOrBackOptType.Abandon }); - } - - - #region 受影响的任务生成 - - // 影响的任务 仅仅访视类别的才生成 或者就是IR 申请的任务 - if (influenceTask.ReadingCategory == ReadingCategory.Visit || influenceTask.Id == origenalTask.Id) - { - - - // 影响的其他标准的附加评估的任务不立即生成 比如1.1基线 重阅 PM 同意仅仅生成1.1任务,不生成BM任务 - if (criterionConfig.CriterionType == CriterionType.RECIST1Point1 && criterionConfig.IsAdditionalAssessment && influenceTask.TrialReadingCriterionId != origenalTask.TrialReadingCriterionId) - { - //BM标准的不生成任务 - continue; - } - - - // i1.1标准 当前任务是转变任务,并且影响列表里有转变之前的任务 那么该访视任务就不生成 - if (criterionConfig.CriterionType == CriterionType.IRECIST1Point1) - { - //申请的任务是冻结的任务(该任务发生转变) 影响自己 以及转变后的 以及后续任务 但是生成的时候,仅仅生成转变之前的 - //申请的是转变之后的任务 (转变生成的任务) 影响自己以及后续任务 生成转变后的任务 - if (influenceTask.BeforeConvertedTaskId != null && influenceTaskList.Any(t => t.Id == influenceTask.BeforeConvertedTaskId)) - { - //有转化的任务 和转化之前的任务时,转化后的任务时不生成的 - continue; - - } - - - } - - - await _visitTaskCommonService.AddTaskAsync(new GenerateTaskCommand() - { - TrialId = trialId, - - ReadingCategory = GenerateTaskCategory.ReReading, - - ReReadingTask = influenceTask, - - //同步才可以 - Action = (newTask) => - { - //申请表 设置新任务Id - visitTaskReReadingAppply.NewReReadingTaskId = newTask.Id; - - //生成的任务分配给原始医生 - newTask.DoctorUserId = origenalTask.DoctorUserId; - newTask.TaskAllocationState = TaskAllocationState.Allocated; - newTask.AllocateTime = DateTime.Now; - newTask.SuggesteFinishedTime = GetSuggessFinishTime(true, UrgentType.NotUrget); - - //拷贝原始表单 - if (visitTaskReReadingAppply.IsCopyOrigenalForms && influenceTask.Id == origenalTask.Id) - { - if (origenalTask.ReadingCategory == ReadingCategory.Visit) - { - CopyForms(newTask, origenalTask); - - } - - } - - //拷贝后续表单 - if (visitTaskReReadingAppply.IsCopyFollowForms && origenalTask.VisitTaskNum != influenceTask.VisitTaskNum) - { - if (origenalTask.ReadingCategory == ReadingCategory.Visit) - { - CopyForms(newTask, origenalTask); - } - - - } - - } - }); - - - - #endregion - - - } - - } - - - - } - //无序阅片 IR只会申请访视类型和裁判类型的任务 注意这里有一致性分析的申请同意 - else - { - - - //1.当前任务及裁判任务 - //2.影响当前阅片人的任务 - filterExpression = filterExpression.And(t => t.Id == origenalTask.Id || t.Id == origenalTask.JudgeVisitTaskId); - - - var influenceTaskList = await _visitTaskRepository.Where(filterExpression, true).ToListAsync(); - - var trakingOrigenalTask = influenceTaskList.Where(t => t.Id == origenalTask.Id).FirstOrDefault(); - - foreach (var influenceTask in influenceTaskList) - { - //申请原任务处理 - if (influenceTask.Id == origenalTask.Id) - { - ReReadingTaskTrackingDeal(influenceTask, agreeReReadingCommand); - - await SetMedicalReviewInvalidAsync(influenceTaskList, false); - - trakingOrigenalTask?.TaskInfluenceList.Add(new TaskInfluence() { InfluenceTaskId = influenceTask.Id, OptType = ReReadingOrBackOptType.Return }); - } - else - { - if (influenceTask.ReadingTaskState == ReadingTaskState.HaveSigned) - { - influenceTask.TaskState = TaskState.HaveReturned; - - trakingOrigenalTask?.TaskInfluenceList.Add(new TaskInfluence() { InfluenceTaskId = influenceTask.Id, OptType = ReReadingOrBackOptType.Return }); - } - else - { - influenceTask.TaskState = TaskState.Adbandon; - - trakingOrigenalTask?.TaskInfluenceList.Add(new TaskInfluence() { InfluenceTaskId = influenceTask.Id, OptType = ReReadingOrBackOptType.Abandon }); - } - } - - #region 受影响任务的生成 - - if (influenceTask.ReadingCategory == ReadingCategory.Visit || influenceTask.Id == origenalTask.Id) - { - await _visitTaskCommonService.AddTaskAsync(new GenerateTaskCommand() - { - TrialId = trialId, - - ReadingCategory = GenerateTaskCategory.ReReading, - - ReReadingTask = origenalTask, - - //同步才可以 - Action = (newTask) => - { - //申请表 设置新任务Id - visitTaskReReadingAppply.NewReReadingTaskId = newTask.Id; - - ////生成的任务分配给原始医生 - newTask.DoctorUserId = origenalTask.DoctorUserId; - newTask.TaskAllocationState = TaskAllocationState.Allocated; - newTask.AllocateTime = DateTime.Now; - newTask.SuggesteFinishedTime = GetSuggessFinishTime(true, UrgentType.NotUrget); - - - //裁判任务 需要进行特殊处理 在重阅逻辑里面处理 - - - if (visitTaskReReadingAppply.IsCopyOrigenalForms && influenceTask.Id == origenalTask.Id) - { - if (origenalTask.ReadingCategory == ReadingCategory.Visit) - { - CopyForms(newTask, origenalTask); - - } - - } - - //拷贝后续表单 - if (visitTaskReReadingAppply.IsCopyFollowForms && origenalTask.VisitTaskNum != influenceTask.VisitTaskNum) - { - if (origenalTask.ReadingCategory == ReadingCategory.Visit) - { - CopyForms(newTask, origenalTask); - - } - } - - - } - }); - - } - #endregion - - } - - } - + influenceTask.ReReadingApplyState = agreeReReadingCommand.RequestReReadingResultEnum == RequestReReadingResult.Agree ? ReReadingApplyState.Agree : ReReadingApplyState.Reject; + influenceTask.TaskState = agreeReReadingCommand.RequestReReadingResultEnum == RequestReReadingResult.Agree ? TaskState.HaveReturned : origenalTask.TaskState; } else { - //---不符合 PM申请 SPM / CPM审批 | IR申请 PM 审批 - throw new BusinessValidationFailedException(_localizer["VisitTask_ReReadTaskAlreadyAffected"]); + //---当前重阅任务状态不为已申请状态,不允许进行处理,请刷新页面 + throw new BusinessValidationFailedException(_localizer["VisitTask_InvalidReapplyStatus"]); } + + } else if (agreeReReadingCommand.RequestReReadingResultEnum == RequestReReadingResult.Reject) { @@ -2176,6 +1673,523 @@ public class VisitTaskService(IRepository _visitTaskRepository, return ResponseOutput.Ok(); } + private async Task AgreeReReading(Guid visiTaskId, RequestReReadingType requestReReadingType, VisitTaskReReading? visitTaskReReadingAppply = null) + { + + + var origenalTask = (await _visitTaskRepository.Where(t => t.Id == visiTaskId).FirstOrDefaultAsync()).IfNullThrowException(); + var trialId = origenalTask.TrialId; + + + var criterionConfig = await _trialReadingCriterionRepository.Where(x => x.Id == origenalTask.TrialReadingCriterionId).Select(x => new { x.ReadingTool, x.CriterionType, x.IsAdditionalAssessment, x.IsReadingTaskViewInOrder }).FirstOrDefaultAsync(); + + + Expression> filterExpression = t => t.TrialId == trialId && t.SubjectId == origenalTask.SubjectId && (t.TaskState == TaskState.Effect || t.TaskState == TaskState.Freeze) /*&& t.TaskAllocationState == TaskAllocationState.Allocated*/; + + //是否是一致性分析任务 正常申请 会影响一致性分析任务 + filterExpression = filterExpression.And(t => t.IsAnalysisCreate == origenalTask.IsAnalysisCreate); + + //IR 申请1.1 基线重阅,影响附加评估两个IR所有的任务 + var isIR1Point1AdditionalAssessmentBaseline = false; + + //附加评估 IR 和PM 看到的影响列表不一样 + + //1.1 有附加评估,会影响其他标准的任务 + if (criterionConfig.CriterionType == CriterionType.RECIST1Point1 && criterionConfig.IsAdditionalAssessment) + { + // PM申请 SPM / CPM审批 + if (requestReReadingType == RequestReReadingType.TrialGroupApply) + { + filterExpression = filterExpression.And(t => t.TrialReadingCriterionId == origenalTask.TrialReadingCriterionId || t.TrialReadingCriterion.CriterionType == CriterionType.RECIST1Pointt1_MB); + } + //IR 申请 PM审批 + else + { + + // 1.1 基线任务影响BM任务 + if ((IsPMOrAPm()) && _subjectVisitRepository.Any(t => t.Id == origenalTask.SourceSubjectVisitId && t.IsBaseLine == true)) + { + + isIR1Point1AdditionalAssessmentBaseline = true; + + } + // 1.1 非基线任务不影响BM任务 + else + { + filterExpression = filterExpression.And(t => t.TrialReadingCriterionId == origenalTask.TrialReadingCriterionId); + } + } + } + else + { + //默认影响的都是该标准的任务 + filterExpression = filterExpression.And(t => t.TrialReadingCriterionId == origenalTask.TrialReadingCriterionId); + } + + //PM申请 SPM / CPM审批 回退访视,因此这里不生成访视任务 影响多个标准的任务 + if (requestReReadingType == RequestReReadingType.TrialGroupApply) + { + + // 不管有序 无序 都会 回退访视 + if (origenalTask.ReadingCategory == ReadingCategory.Visit) + { + //执行类似一致性核查回退流程 + await VisitBackAsync(origenalTask.SourceSubjectVisitId); + + } + else + { + //---仅允许同意访视类型的任务重阅 + throw new BusinessValidationFailedException(_localizer["VisitTask_ReReadTaskNotApplied"]); + } + + //有序阅片 + if (criterionConfig.IsReadingTaskViewInOrder == ReadingOrder.InOrder) + { + + + //访视影响当前以及当前之后的 两个阅片人的 + filterExpression = filterExpression.And(t => t.VisitTaskNum >= origenalTask.VisitTaskNum); + + + #region 影响的任务 + + + + var influenceTaskList = await _visitTaskRepository.Where(filterExpression, true).ToListAsync(); + + var trakingOrigenalTask = influenceTaskList.Where(t => t.Id == origenalTask.Id).FirstOrDefault(); + + foreach (var influenceTask in influenceTaskList) + { + //处理申请的任务 + if (influenceTask.Id == origenalTask.Id) + { + + await InfluenceAddtioncalEvaluationCritrionAsync(origenalTask, influenceTaskList.Where(t => t.Id != origenalTask.Id).Where(t => t.SourceSubjectVisitId != null).Select(t => t.SourceSubjectVisitId!.Value).Distinct().ToList()); + + await PMReReadingConfirmOrBackInfluenceAnalysisAsync(origenalTask.SubjectId); + + await SetMedicalReviewInvalidAsync(influenceTaskList); + + } + + + if (influenceTask.ReadingTaskState == ReadingTaskState.HaveSigned) + { + influenceTask.TaskState = TaskState.HaveReturned; + + trakingOrigenalTask?.TaskInfluenceList.Add(new TaskInfluence() { InfluenceTaskId = influenceTask.Id, OptType = ReReadingOrBackOptType.Return }); + } + else + { + influenceTask.TaskState = TaskState.Adbandon; + + trakingOrigenalTask?.TaskInfluenceList.Add(new TaskInfluence() { InfluenceTaskId = influenceTask.Id, OptType = ReReadingOrBackOptType.Abandon }); + } + + + } + #endregion + } + //无序阅片 没有 全局 肿瘤学 + else + { + + // 1.当前任务及裁判任务 + // 2.影响所有阅片人的任务 + + var judegTaskNum = origenalTask.VisitTaskNum + ReadingCommon.TaskNumDic[ReadingCategory.Judge]; + + filterExpression = filterExpression.And(t => t.VisitTaskNum == origenalTask.VisitTaskNum || t.VisitTaskNum == judegTaskNum); + + + var influenceTaskList = await _visitTaskRepository.Where(filterExpression, true).ToListAsync(); + + //影像列表为空就为null + var trakingOrigenalTask = influenceTaskList.Where(t => t.Id == origenalTask.Id).FirstOrDefault(); + + foreach (var influenceTask in influenceTaskList) + { + //处理申请的任务 + if (influenceTask.Id == origenalTask.Id) + { + + + await PMReReadingConfirmOrBackInfluenceAnalysisAsync(origenalTask.SubjectId); + + await SetMedicalReviewInvalidAsync(influenceTaskList); + + trakingOrigenalTask?.TaskInfluenceList.Add(new TaskInfluence() { InfluenceTaskId = influenceTask.Id, OptType = ReReadingOrBackOptType.Return }); + } + else + { + if (influenceTask.ReadingTaskState == ReadingTaskState.HaveSigned) + { + influenceTask.TaskState = TaskState.HaveReturned; + + trakingOrigenalTask?.TaskInfluenceList.Add(new TaskInfluence() { InfluenceTaskId = influenceTask.Id, OptType = ReReadingOrBackOptType.Return }); + } + else + { + influenceTask.TaskState = TaskState.Adbandon; + + trakingOrigenalTask?.TaskInfluenceList.Add(new TaskInfluence() { InfluenceTaskId = influenceTask.Id, OptType = ReReadingOrBackOptType.Abandon }); + } + } + } + + } + + + + } + //IR申请 PM 审批 注意这里有一致性分析的申请同意 不会回退访视,在此要生成影响的访视任务 + else if (requestReReadingType == RequestReReadingType.DocotorApply && (IsPMOrAPm() || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.AIR)) + { + + + + //有序阅片 + if (criterionConfig.IsReadingTaskViewInOrder == ReadingOrder.InOrder) + { + #region 有序 IR 申请 重阅 影响的其他访视查询 + + + + switch (origenalTask.ReadingCategory) + { + case ReadingCategory.Visit: + //影响后续访视已经读完的,正在读的,未读的不做处理 以及其他类型任务 + + //申请的是转化的,那么影响列表要排除转化之前的 + if (criterionConfig.CriterionType == CriterionType.IRECIST1Point1 && origenalTask.BeforeConvertedTaskId != null) + { + + + filterExpression = filterExpression.And(t => (t.VisitTaskNum > origenalTask.VisitTaskNum && + ( + ((t.ReadingCategory == ReadingCategory.Visit || t.ReadingCategory == ReadingCategory.Global) && t.DoctorUserId == origenalTask.DoctorUserId) + // 裁判 肿瘤学是另外的医生做 + || t.ReadingCategory == ReadingCategory.Judge + || t.ReadingCategory == ReadingCategory.Oncology + )) || t.Id == origenalTask.Id) + ; + } + else if (isIR1Point1AdditionalAssessmentBaseline) + { + filterExpression = filterExpression.And(t => t.VisitTaskNum >= origenalTask.VisitTaskNum && + ((( + ((t.ReadingCategory == ReadingCategory.Visit || t.ReadingCategory == ReadingCategory.Global) && t.DoctorUserId == origenalTask.DoctorUserId) + // 裁判 肿瘤学是另外的医生做 + || t.ReadingCategory == ReadingCategory.Judge + || t.ReadingCategory == ReadingCategory.Oncology + ) && t.TrialReadingCriterionId == origenalTask.TrialReadingCriterionId) || (t.TrialReadingCriterion.CriterionType == CriterionType.RECIST1Pointt1_MB)) + ); + } + else + { + filterExpression = filterExpression.And(t => t.VisitTaskNum >= origenalTask.VisitTaskNum && + ( + ((t.ReadingCategory == ReadingCategory.Visit || t.ReadingCategory == ReadingCategory.Global) && t.DoctorUserId == origenalTask.DoctorUserId) + // 裁判 肿瘤学是另外的医生做 + || t.ReadingCategory == ReadingCategory.Judge + || t.ReadingCategory == ReadingCategory.Oncology + ) + ); + } + + + + + + + break; + + + //不影响后续访视: (t.ReadingCategory == ReadingCategory.Visit && t.ReadingTaskState != ReadingTaskState.WaitReading) || + case ReadingCategory.Global: + + filterExpression = filterExpression.And(t => t.VisitTaskNum > origenalTask.VisitTaskNum && + ((t.DoctorUserId == origenalTask.DoctorUserId && t.ReadingCategory == ReadingCategory.Global) + || (t.ReadingCategory == ReadingCategory.Oncology) || (t.ReadingCategory == ReadingCategory.Judge)) || t.Id == origenalTask.Id); + break; + + case ReadingCategory.Oncology: + + //仅仅影响自己 后续任务如果是访视任务、全局任务或裁判任务,均不处理 + filterExpression = filterExpression.And(t => t.Id == origenalTask.Id); + break; + + case ReadingCategory.Judge: + + //裁判的影响自己 和后续肿瘤学阅片(不是自己做的) + filterExpression = filterExpression.And(t => t.Id == origenalTask.Id || t.VisitTaskNum > origenalTask.VisitTaskNum && t.ReadingCategory == ReadingCategory.Oncology); + + break; + + + default: + //---不支持重阅的任务类型 + throw new BusinessValidationFailedException(_localizer["VisitTask_UnsupportedTaskType"]); + + } + + #endregion + + + + var influenceTaskList = await _visitTaskRepository.Where(filterExpression, true).OrderBy(t => t.VisitTaskNum).ToListAsync(); + + var trakingOrigenalTask = influenceTaskList.Where(t => t.Id == origenalTask.Id).FirstOrDefault(); + + + + foreach (var influenceTask in influenceTaskList) + { + var beforeTaskState = influenceTask.TaskState; + + //已签名的任务 设置转变后的标志 + if (criterionConfig.CriterionType == CriterionType.IRECIST1Point1 && influenceTask.ReadingTaskState == ReadingTaskState.HaveSigned) + { + var isConvertedTask = _visitTaskRepository.Where(t => t.Id == influenceTask.Id).Select(t => t.IsConvertedTask).FirstOrDefault(); + + if (isConvertedTask) + { + influenceTask.IsHistoryConvertedTask = true; + } + } + + + //处理申请的任务 + if (influenceTask.Id == origenalTask.Id) + { + + + await SetMedicalReviewInvalidAsync(influenceTaskList, false); + + await InfluenceAddtioncalEvaluationCritrionAsync(origenalTask, influenceTaskList.Where(t => t.Id != origenalTask.Id).Where(t => t.SourceSubjectVisitId != null).Select(t => t.SourceSubjectVisitId!.Value).Distinct().ToList(), false); + + } + + + + if (influenceTask.ReadingTaskState == ReadingTaskState.HaveSigned) + { + influenceTask.TaskState = TaskState.HaveReturned; + + trakingOrigenalTask?.TaskInfluenceList.Add(new TaskInfluence() { InfluenceTaskId = influenceTask.Id, OptType = ReReadingOrBackOptType.Return }); + } + else + { + influenceTask.TaskState = TaskState.Adbandon; + + trakingOrigenalTask?.TaskInfluenceList.Add(new TaskInfluence() { InfluenceTaskId = influenceTask.Id, OptType = ReReadingOrBackOptType.Abandon }); + } + + + #region 受影响的任务生成 + + // 影响的任务 仅仅访视类别的才生成 或者就是IR 申请的任务 + if (influenceTask.ReadingCategory == ReadingCategory.Visit || influenceTask.Id == origenalTask.Id) + { + + + // 影响的其他标准的附加评估的任务不立即生成 比如1.1基线 重阅 PM 同意仅仅生成1.1任务,不生成BM任务 + if (criterionConfig.CriterionType == CriterionType.RECIST1Point1 && criterionConfig.IsAdditionalAssessment && influenceTask.TrialReadingCriterionId != origenalTask.TrialReadingCriterionId) + { + //BM标准的不生成任务 + continue; + } + + + // i1.1标准 当前任务是转变任务,并且影响列表里有转变之前的任务 那么该访视任务就不生成 + if (criterionConfig.CriterionType == CriterionType.IRECIST1Point1) + { + //申请的任务是冻结的任务(该任务发生转变) 影响自己 以及转变后的 以及后续任务 但是生成的时候,仅仅生成转变之前的 + //申请的是转变之后的任务 (转变生成的任务) 影响自己以及后续任务 生成转变后的任务 + if (influenceTask.BeforeConvertedTaskId != null && influenceTaskList.Any(t => t.Id == influenceTask.BeforeConvertedTaskId)) + { + //有转化的任务 和转化之前的任务时,转化后的任务时不生成的 + continue; + + } + + + } + + + await _visitTaskCommonService.AddTaskAsync(new GenerateTaskCommand() + { + TrialId = trialId, + + ReadingCategory = GenerateTaskCategory.ReReading, + + ReReadingTask = influenceTask, + + //同步才可以 + Action = (newTask) => + { + + + //生成的任务分配给原始医生 + newTask.DoctorUserId = origenalTask.DoctorUserId; + newTask.TaskAllocationState = TaskAllocationState.Allocated; + newTask.AllocateTime = DateTime.Now; + newTask.SuggesteFinishedTime = GetSuggessFinishTime(true, UrgentType.NotUrget); + + if (visitTaskReReadingAppply != null) + { + //申请表 设置新任务Id + visitTaskReReadingAppply.NewReReadingTaskId = newTask.Id; + + //拷贝原始表单 + if (visitTaskReReadingAppply.IsCopyOrigenalForms && influenceTask.Id == origenalTask.Id) + { + if (origenalTask.ReadingCategory == ReadingCategory.Visit) + { + CopyForms(newTask, origenalTask); + + } + + } + + //拷贝后续表单 + if (visitTaskReReadingAppply.IsCopyFollowForms && origenalTask.VisitTaskNum != influenceTask.VisitTaskNum) + { + if (origenalTask.ReadingCategory == ReadingCategory.Visit) + { + CopyForms(newTask, origenalTask); + } + + + } + } + + } + }); + + + + #endregion + + + } + + } + + + + } + //无序阅片 IR只会申请访视类型和裁判类型的任务 注意这里有一致性分析的申请同意 + else + { + + + //1.当前任务及裁判任务 + //2.影响当前阅片人的任务 + filterExpression = filterExpression.And(t => t.Id == origenalTask.Id || t.Id == origenalTask.JudgeVisitTaskId); + + + var influenceTaskList = await _visitTaskRepository.Where(filterExpression, true).ToListAsync(); + + var trakingOrigenalTask = influenceTaskList.Where(t => t.Id == origenalTask.Id).FirstOrDefault(); + + foreach (var influenceTask in influenceTaskList) + { + //申请原任务处理 + if (influenceTask.Id == origenalTask.Id) + { + + await SetMedicalReviewInvalidAsync(influenceTaskList, false); + + trakingOrigenalTask?.TaskInfluenceList.Add(new TaskInfluence() { InfluenceTaskId = influenceTask.Id, OptType = ReReadingOrBackOptType.Return }); + } + else + { + if (influenceTask.ReadingTaskState == ReadingTaskState.HaveSigned) + { + influenceTask.TaskState = TaskState.HaveReturned; + + trakingOrigenalTask?.TaskInfluenceList.Add(new TaskInfluence() { InfluenceTaskId = influenceTask.Id, OptType = ReReadingOrBackOptType.Return }); + } + else + { + influenceTask.TaskState = TaskState.Adbandon; + + trakingOrigenalTask?.TaskInfluenceList.Add(new TaskInfluence() { InfluenceTaskId = influenceTask.Id, OptType = ReReadingOrBackOptType.Abandon }); + } + } + + #region 受影响任务的生成 + + if (influenceTask.ReadingCategory == ReadingCategory.Visit || influenceTask.Id == origenalTask.Id) + { + await _visitTaskCommonService.AddTaskAsync(new GenerateTaskCommand() + { + TrialId = trialId, + + ReadingCategory = GenerateTaskCategory.ReReading, + + ReReadingTask = origenalTask, + + //同步才可以 + Action = (newTask) => + { + + + ////生成的任务分配给原始医生 + newTask.DoctorUserId = origenalTask.DoctorUserId; + newTask.TaskAllocationState = TaskAllocationState.Allocated; + newTask.AllocateTime = DateTime.Now; + newTask.SuggesteFinishedTime = GetSuggessFinishTime(true, UrgentType.NotUrget); + + + //裁判任务 需要进行特殊处理 在重阅逻辑里面处理 + + if (visitTaskReReadingAppply != null) + { + //申请表 设置新任务Id + visitTaskReReadingAppply.NewReReadingTaskId = newTask.Id; + + if (visitTaskReReadingAppply.IsCopyOrigenalForms && influenceTask.Id == origenalTask.Id) + { + if (origenalTask.ReadingCategory == ReadingCategory.Visit) + { + CopyForms(newTask, origenalTask); + + } + + } + + //拷贝后续表单 + if (visitTaskReReadingAppply.IsCopyFollowForms && origenalTask.VisitTaskNum != influenceTask.VisitTaskNum) + { + if (origenalTask.ReadingCategory == ReadingCategory.Visit) + { + CopyForms(newTask, origenalTask); + + } + } + } + } + }); + + } + #endregion + + } + + } + + } + else + { + //---不符合 PM申请 SPM / CPM审批 | IR申请 PM 审批 + throw new BusinessValidationFailedException(_localizer["VisitTask_ReReadTaskAlreadyAffected"]); + } + } + private void CopyForms(VisitTask newTask, VisitTask origenalTask) { @@ -2602,7 +2616,7 @@ public class VisitTaskService(IRepository _visitTaskRepository, var criterionConfig = (await _trialReadingCriterionRepository.Where(x => x.Id == filterObj.TrialReadingCriterionId).Select(x => new { x.ReadingTool, x.CriterionType, x.IsAdditionalAssessment, x.IsReadingTaskViewInOrder }).FirstOrDefaultAsync()).IfNullThrowException(); - Expression> filterExpression = t => t.TrialId == trialId && t.SubjectId == filterObj.SubjectId && (t.TaskState == TaskState.Effect || t.TaskState == TaskState.Freeze) && t.TaskAllocationState == TaskAllocationState.Allocated; + Expression> filterExpression = t => t.TrialId == trialId && t.SubjectId == filterObj.SubjectId && (t.TaskState == TaskState.Effect || t.TaskState == TaskState.Freeze) /*&& t.TaskAllocationState == TaskAllocationState.Allocated*/; //是否是一致性分析任务 (一致性分析的任务 不会产生裁判 肿瘤学 仅仅有生成的访视和全局) diff --git a/IRaCIS.Core.Application/Service/Common/MailService.cs b/IRaCIS.Core.Application/Service/Common/MailService.cs index 665d2dc4f..46e6298f4 100644 --- a/IRaCIS.Core.Application/Service/Common/MailService.cs +++ b/IRaCIS.Core.Application/Service/Common/MailService.cs @@ -706,8 +706,8 @@ namespace IRaCIS.Core.Application.Service var userTypeEnumList = emailConfigInfo.EmailNoticeUserTypeList.Where(t => t.EmailUserType == EmailUserType.To).Select(t => t.UserType).ToList(); - var emailList = await _userRoleRepository.Where(t => userTypeEnumList.Contains(t.UserTypeEnum) && - (isHaveTrialId ? t.UserRoleTrials.Any(t => t.TrialId == feedBack.TrialId) : true)).Select(t => new { t.IdentityUser.EMail, t.UserTypeEnum, t.IdentityUser.FullName }).ToListAsync(); + var emailList = await _userRoleRepository.Where(t => userTypeEnumList.Contains(t.UserTypeEnum) && t.IsUserRoleDisabled == false && t.IdentityUser.Status == UserStateEnum.Enable && + (isHaveTrialId ? t.IdentityUser.UserTrialList.Any(t => t.TrialId == feedBack.TrialId && t.TrialUserRoleList.Any(c => userTypeEnumList.Contains(c.UserRole.UserTypeEnum))) : true)).Select(t => new { t.IdentityUser.EMail, t.UserTypeEnum, t.IdentityUser.FullName }).ToListAsync(); foreach (var email in emailList) diff --git a/IRaCIS.Core.Application/Service/Document/SystemDocumentService.cs b/IRaCIS.Core.Application/Service/Document/SystemDocumentService.cs index fe338b396..7f288fbb1 100644 --- a/IRaCIS.Core.Application/Service/Document/SystemDocumentService.cs +++ b/IRaCIS.Core.Application/Service/Document/SystemDocumentService.cs @@ -16,6 +16,7 @@ namespace IRaCIS.Core.Application.Services [ApiExplorerSettings(GroupName = "Trial")] public class SystemDocumentService(IRepository _systemDocumentRepository, IRepository _userRoleRepository, + IRepository _identityUserRepository, IRepository _systemDocConfirmedUserRepository, IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer) : BaseService, ISystemDocumentService { @@ -154,7 +155,7 @@ namespace IRaCIS.Core.Application.Services join confirm in _systemDocConfirmedUserRepository.Where() on new { ConfirmUserId = _userInfo.IdentityUserId, SystemDocumentId = sysDoc.Id } equals new { confirm.ConfirmUserId, confirm.SystemDocumentId } into cc from confirm in cc.DefaultIfEmpty() - join user in _userRoleRepository.Where() on _userInfo.UserRoleId equals user.Id + join user in _identityUserRepository.Where() on _userInfo.IdentityUserId equals user.Id select new UnionDocumentWithConfirmInfoView() { @@ -180,11 +181,14 @@ namespace IRaCIS.Core.Application.Services //UserTypeShortName = user.UserTypeRole.UserTypeShortName }; - return await query.WhereIf(inQuery.IsSigned == true, t => t.ConfirmTime != null) + var list = await query.WhereIf(inQuery.IsSigned == true, t => t.ConfirmTime != null) .WhereIf(inQuery.IsSigned == false, t => t.ConfirmTime == null) .ToPagedListAsync(inQuery); + return list; + + } diff --git a/IRaCIS.Core.Application/Service/Document/TrialDocumentService.cs b/IRaCIS.Core.Application/Service/Document/TrialDocumentService.cs index f6992c35e..de2d2d788 100644 --- a/IRaCIS.Core.Application/Service/Document/TrialDocumentService.cs +++ b/IRaCIS.Core.Application/Service/Document/TrialDocumentService.cs @@ -228,7 +228,7 @@ namespace IRaCIS.Core.Application.Services #region 统一用户修改 var systemDocQuery = - from sysDoc in _systemDocumentRepository.AsQueryable(false).Where(t => t.NeedConfirmedUserTypeList.Any(c => c.NeedConfirmUserTypeId == _userInfo.UserTypeId)) + from sysDoc in _systemDocumentRepository.AsQueryable(true).Where(t => t.NeedConfirmedUserTypeList.Any(c => c.NeedConfirmUserTypeId == _userInfo.UserTypeId)) from trialUser in _trialIdentityUserRepository.AsQueryable(false) .Where(t => t.TrialId == inQuery.TrialId && t.IdentityUserId == _userInfo.IdentityUserId && t.TrialUserRoleList.Any(t => sysDoc.NeedConfirmedUserTypeList.Any(c => c.NeedConfirmUserTypeId == t.UserRole.UserTypeId))) @@ -266,7 +266,7 @@ namespace IRaCIS.Core.Application.Services //项目文档查询 var trialDocQuery = - from trialDoc in _trialDocumentRepository.AsQueryable(false).Where(t => t.TrialId == inQuery.TrialId) + from trialDoc in _trialDocumentRepository.AsQueryable(true).Where(t => t.TrialId == inQuery.TrialId).Where(t => t.NeedConfirmedUserTypeList.Any(c => c.NeedConfirmUserTypeId == _userInfo.UserTypeId)) from trialUser in _trialIdentityUserRepository.AsQueryable(false).Where(t => t.TrialId == inQuery.TrialId && t.IdentityUserId == _userInfo.IdentityUserId && t.TrialUserRoleList.Any(t => trialDoc.NeedConfirmedUserTypeList.Any(c => c.NeedConfirmUserTypeId == t.UserRole.UserTypeId))) @@ -396,6 +396,8 @@ namespace IRaCIS.Core.Application.Services var unionQuery = systemDocQuery.Concat(trialDocQuery) + //过滤掉删除的,并且没有签名的 + .Where(t=>!(t.IsDeleted == true && t.ConfirmTime==null)) .WhereIf(!string.IsNullOrEmpty(inQuery.Name), t => t.Name.Contains(inQuery.Name)) .WhereIf(inQuery.FileTypeId != null, t => t.FileTypeId == inQuery.FileTypeId) .WhereIf(inQuery.IsSign == true, t => t.ConfirmTime != null) @@ -433,7 +435,7 @@ namespace IRaCIS.Core.Application.Services .CountAsync(); - var needSignSystemDocCount = await _systemDocumentRepository + var needSignSystemDocCount = await _systemDocumentRepository.AsQueryable(true) .Where(t => t.IsDeleted == false && !t.SystemDocConfirmedUserList.Any(t => t.ConfirmUserId == _userInfo.IdentityUserId && t.ConfirmTime != null) && t.NeedConfirmedUserTypeList.Any(u => u.NeedConfirmUserTypeId == _userInfo.UserTypeId)) .CountAsync(); @@ -868,9 +870,9 @@ namespace IRaCIS.Core.Application.Services var success = false; if (isSystemDoc) { - if (!await _systemDocConfirmedUserRepository.AnyAsync(t => t.SystemDocumentId == documentId && t.ConfirmUserId == _userInfo.UserRoleId)) + if (!await _systemDocConfirmedUserRepository.AnyAsync(t => t.SystemDocumentId == documentId && t.ConfirmUserId == _userInfo.IdentityUserId)) { - await _systemDocConfirmedUserRepository.AddAsync(new SystemDocConfirmedIdentityUser() { SystemDocumentId = documentId, ConfirmUserId = _userInfo.UserRoleId, SignFirstViewTime = DateTime.Now }); + await _systemDocConfirmedUserRepository.AddAsync(new SystemDocConfirmedIdentityUser() { SystemDocumentId = documentId, ConfirmUserId = _userInfo.IdentityUserId, SignFirstViewTime = DateTime.Now }); } @@ -878,10 +880,10 @@ namespace IRaCIS.Core.Application.Services else { - if (!await _trialDocConfirmedUserRepository.AnyAsync(t => t.TrialDocumentId == documentId && t.ConfirmUserId == _userInfo.UserRoleId)) + if (!await _trialDocConfirmedUserRepository.AnyAsync(t => t.TrialDocumentId == documentId && t.ConfirmUserId == _userInfo.IdentityUserId)) { - await _trialDocConfirmedUserRepository.AddAsync(new TrialDocConfirmedIdentityUser() { TrialDocumentId = documentId, ConfirmUserId = _userInfo.UserRoleId, SignFirstViewTime = DateTime.Now }); + await _trialDocConfirmedUserRepository.AddAsync(new TrialDocConfirmedIdentityUser() { TrialDocumentId = documentId, ConfirmUserId = _userInfo.IdentityUserId, SignFirstViewTime = DateTime.Now }); } @@ -896,9 +898,9 @@ namespace IRaCIS.Core.Application.Services [HttpPut("{documentId:guid}")] public async Task SetSystemDocFirstViewTime(Guid documentId) { - if (!await _systemDocConfirmedUserRepository.AnyAsync(t => t.SystemDocumentId == documentId && t.ConfirmUserId == _userInfo.UserRoleId)) + if (!await _systemDocConfirmedUserRepository.AnyAsync(t => t.SystemDocumentId == documentId && t.ConfirmUserId == _userInfo.IdentityUserId)) { - await _systemDocConfirmedUserRepository.AddAsync(new SystemDocConfirmedIdentityUser() { SystemDocumentId = documentId, ConfirmUserId = _userInfo.UserRoleId, SignFirstViewTime = DateTime.Now }); + await _systemDocConfirmedUserRepository.AddAsync(new SystemDocConfirmedIdentityUser() { SystemDocumentId = documentId, ConfirmUserId = _userInfo.IdentityUserId, SignFirstViewTime = DateTime.Now }); } @@ -913,7 +915,7 @@ namespace IRaCIS.Core.Application.Services if (!await _trialDocConfirmedUserRepository.AnyAsync(t => t.TrialDocumentId == documentId && t.ConfirmUserId == _userInfo.IdentityUserId)) { - await _trialDocConfirmedUserRepository.AddAsync(new TrialDocConfirmedIdentityUser() { TrialDocumentId = documentId, ConfirmUserId = _userInfo.UserRoleId, SignFirstViewTime = DateTime.Now }); + await _trialDocConfirmedUserRepository.AddAsync(new TrialDocConfirmedIdentityUser() { TrialDocumentId = documentId, ConfirmUserId = _userInfo.IdentityUserId, SignFirstViewTime = DateTime.Now }); } var success = await _trialDocConfirmedUserRepository.SaveChangesAsync(); @@ -932,7 +934,7 @@ namespace IRaCIS.Core.Application.Services if (userConfirmCommand.isSystemDoc) { - var sysDocConfirm = await _systemDocConfirmedUserRepository.FirstOrDefaultAsync(t => t.SystemDocumentId == userConfirmCommand.DocumentId && t.ConfirmUserId == _userInfo.UserRoleId, true); + var sysDocConfirm = await _systemDocConfirmedUserRepository.FirstOrDefaultAsync(t => t.SystemDocumentId == userConfirmCommand.DocumentId && t.ConfirmUserId == _userInfo.IdentityUserId, true); if (sysDocConfirm.ConfirmTime != null) { diff --git a/IRaCIS.Core.Application/Service/ImageAndDoc/StudyService.cs b/IRaCIS.Core.Application/Service/ImageAndDoc/StudyService.cs index 9530c8a15..95211567e 100644 --- a/IRaCIS.Core.Application/Service/ImageAndDoc/StudyService.cs +++ b/IRaCIS.Core.Application/Service/ImageAndDoc/StudyService.cs @@ -65,7 +65,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc } - [TrialGlobalLimit( "AfterStopCannNotOpt" )] + [TrialGlobalLimit("AfterStopCannNotOpt")] public async Task PreArchiveDicomStudy(PreArchiveDicomStudyCommand preArchiveStudyCommand) { @@ -122,7 +122,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc - [TrialGlobalLimit( "AfterStopCannNotOpt" )] + [TrialGlobalLimit("AfterStopCannNotOpt")] public async Task AddOrUpdateArchiveStudy(NewArchiveStudyCommand incommand) { @@ -321,6 +321,16 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc } + + //项目配置的影像部位 + var trialBodyPartList = _trialRepository.Where(t => t.Id == trialId).SelectMany(t => t.TrialBodyPartList).ToList(); + + if (trialBodyPartList.Count() == 1) + { + var first = trialBodyPartList.First(); + findStudy.BodyPartForEdit = first.Code; + } + var @lock2 = _distributedLockProvider.CreateLock($"StudyCommit"); using (await @lock2.AcquireAsync()) diff --git a/IRaCIS.Core.Application/Service/Management/DTO/UserLogViewModel.cs b/IRaCIS.Core.Application/Service/Management/DTO/UserLogViewModel.cs index ba9937576..9f062599b 100644 --- a/IRaCIS.Core.Application/Service/Management/DTO/UserLogViewModel.cs +++ b/IRaCIS.Core.Application/Service/Management/DTO/UserLogViewModel.cs @@ -30,6 +30,13 @@ namespace IRaCIS.Core.Application.ViewModel public string IPRegion { get; set; } } + public class SendMfaCommand + { + public Guid IdentityUserId { get; set; } + + public UserMFAType MFAType { get; set; } = UserMFAType.Login; + } + ///UserLogQuery 列表查询参数模型 public class UserLogQuery : PageInput { diff --git a/IRaCIS.Core.Application/Service/Management/Interface/IUserService.cs b/IRaCIS.Core.Application/Service/Management/Interface/IUserService.cs index 6c863dfbe..473297ed3 100644 --- a/IRaCIS.Core.Application/Service/Management/Interface/IUserService.cs +++ b/IRaCIS.Core.Application/Service/Management/Interface/IUserService.cs @@ -1,4 +1,5 @@ using IRaCIS.Application.Contracts; +using IRaCIS.Core.Application.ViewModel; using IRaCIS.Core.Domain.Share; namespace IRaCIS.Core.Application.Service @@ -10,9 +11,9 @@ namespace IRaCIS.Core.Application.Service //Task GetUser(Guid id); Task> GetUserList(UserListQueryDTO param); Task> Login(string userName, string password); - Task VerifyMFACodeAsync(Guid userId, string Code); + Task VerifyMFACodeAsync(string Code); - Task SendMFAEmail(Guid userId, UserMFAType mfaType = 0); + Task SendMFAEmail(SendMfaCommand sendMfa); Task GetUserBasicInfo(Guid userId, string pwd); Task ModifyPassword(EditPasswordCommand editPwModel); Task ResetPassword(Guid userId); diff --git a/IRaCIS.Core.Application/Service/Management/UserFeedBackService.cs b/IRaCIS.Core.Application/Service/Management/UserFeedBackService.cs index ab7d6c5d7..8b15454a4 100644 --- a/IRaCIS.Core.Application/Service/Management/UserFeedBackService.cs +++ b/IRaCIS.Core.Application/Service/Management/UserFeedBackService.cs @@ -61,8 +61,10 @@ namespace IRaCIS.Core.Application.Service throw new BusinessValidationFailedException("Id 或者VisitTaskId 必传一个"); } - var result = await _userFeedBackRepository.WhereIf(inQuery.Id == null, t => t.VisitTaskId == inQuery.VisitTaskId) - .WhereIf(inQuery.VisitTaskId == null, t => t.Id == inQuery.Id).ProjectTo(_mapper.ConfigurationProvider).FirstOrDefaultAsync(); + var result = await _userFeedBackRepository + .WhereIf(inQuery.Id != null, t => t.Id == inQuery.Id) + .WhereIf(inQuery.VisitTaskId != null, t => t.VisitTaskId == inQuery.VisitTaskId) + .ProjectTo(_mapper.ConfigurationProvider).FirstOrDefaultAsync(); diff --git a/IRaCIS.Core.Application/Service/Management/UserService.cs b/IRaCIS.Core.Application/Service/Management/UserService.cs index 670b21983..bf7441a9e 100644 --- a/IRaCIS.Core.Application/Service/Management/UserService.cs +++ b/IRaCIS.Core.Application/Service/Management/UserService.cs @@ -735,17 +735,16 @@ namespace IRaCIS.Core.Application.Service /// /// 发送MFA 验证邮件 /// - /// - /// + /// - [AllowAnonymous] - public async Task SendMFAEmail(Guid identityUserId, UserMFAType mfaType) + public async Task SendMFAEmail(SendMfaCommand sendMfa) { + var identityUserId = sendMfa.IdentityUserId == Guid.Empty ? _userInfo.IdentityUserId : sendMfa.IdentityUserId; var userInfo = await _identityUserRepository.Where(u => u.Id == identityUserId).Select(t => new { t.FullName, t.EMail }).FirstOrDefaultAsync(); int verificationCode = new Random().Next(100000, 1000000); - await _mailVerificationService.SenMFAVerifyEmail(identityUserId, userInfo.FullName, userInfo.EMail, verificationCode, (UserMFAType)mfaType); + await _mailVerificationService.SenMFAVerifyEmail(identityUserId, userInfo.FullName, userInfo.EMail, verificationCode, sendMfa.MFAType); var hiddenEmail = IRCEmailPasswordHelper.MaskEmail(userInfo.EMail); return ResponseOutput.Ok(hiddenEmail); @@ -754,12 +753,13 @@ namespace IRaCIS.Core.Application.Service /// /// 验证MFA 邮件 /// - /// /// /// /// - public async Task VerifyMFACodeAsync(Guid identityUserId, string Code) + public async Task VerifyMFACodeAsync(string Code) { + var identityUserId = _userInfo.IdentityUserId; + var verificationRecord = await _verificationCodeRepository.Where(t => t.UserId == identityUserId && t.Code == Code && t.CodeType == VerifyType.Email).OrderByDescending(x => x.ExpirationTime).FirstOrDefaultAsync(); VerifyEmialGetDoctorInfoOutDto result = new VerifyEmialGetDoctorInfoOutDto(); @@ -778,13 +778,9 @@ namespace IRaCIS.Core.Application.Service await _userLogRepository.AddAsync(new UserLog() { IP = _userInfo.IP, ActionUserName = _userInfo.UserName, TargetIdentityUserId = identityUserId, OptType = UserOptType.MFALoginFail }, true); //---验证码已经过期。 throw new BusinessValidationFailedException(_localizer["TrialSiteSurvey_ExpiredVerificationCode"]); - - } else //验证码正确 并且 没有超时 { - - //删除验证码历史记录 await _verificationCodeRepository.BatchDeleteNoTrackingAsync(t => t.Id == verificationRecord.Id); await _userLogRepository.AddAsync(new UserLog() { IP = _userInfo.IP, ActionUserName = _userInfo.UserName, TargetIdentityUserId = identityUserId, OptType = UserOptType.MFALogin }, true); @@ -1090,7 +1086,7 @@ namespace IRaCIS.Core.Application.Service else { //正常登录才发送邮件 - await SendMFAEmail(identityUserId, UserMFAType.Login); + await SendMFAEmail(new SendMfaCommand() { IdentityUserId = identityUserId, MFAType = UserMFAType.Login }); } diff --git a/IRaCIS.Core.Application/Service/SiteSurvey/TrialSiteSurveyService.cs b/IRaCIS.Core.Application/Service/SiteSurvey/TrialSiteSurveyService.cs index 83a40e9a1..8ef7d98b2 100644 --- a/IRaCIS.Core.Application/Service/SiteSurvey/TrialSiteSurveyService.cs +++ b/IRaCIS.Core.Application/Service/SiteSurvey/TrialSiteSurveyService.cs @@ -441,7 +441,11 @@ namespace IRaCIS.Core.Application.Contracts { var isTrialSPMJoin = await _trialRepository.AnyAsync(t => t.Id == trialSiteSubmitBackCommand.TrialId && t.IsSPMJoinSiteSurvey); - var hasSPMOrCPM = await _trialSiteSurveyRepository.AnyAsync(t => t.TrialId == trialSiteSubmitBackCommand.TrialId && t.Trial.TrialIdentityUserList.Any(u => u.TrialUserRoleList.Any(u => u.UserRole.UserTypeEnum == UserTypeEnum.SPM || u.UserRole.UserTypeEnum == UserTypeEnum.CPM))); + 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; @@ -792,7 +796,11 @@ namespace IRaCIS.Core.Application.Contracts if (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.Undefined || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator) { - var hasSPMOrCPM = await _trialSiteSurveyRepository.AnyAsync(t => t.TrialId == trialId && t.Trial.TrialIdentityUserList.Any(u => u.TrialUserRoleList.Any(u => u.UserRole.UserTypeEnum == UserTypeEnum.SPM || u.UserRole.UserTypeEnum == UserTypeEnum.CPM))); + 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); diff --git a/IRaCIS.Core.Application/Service/TrialSiteUser/DTO/UserTrialViewModel.cs b/IRaCIS.Core.Application/Service/TrialSiteUser/DTO/UserTrialViewModel.cs index aca922846..e55def7b9 100644 --- a/IRaCIS.Core.Application/Service/TrialSiteUser/DTO/UserTrialViewModel.cs +++ b/IRaCIS.Core.Application/Service/TrialSiteUser/DTO/UserTrialViewModel.cs @@ -171,7 +171,7 @@ namespace IRaCIS.Application.Contracts public bool IsDeleted { get; set; } - + public UserStateEnum Status { get; set; } public DateTime CreateTime { get; set; } public DateTime UpdateTime { get; set; } @@ -223,6 +223,7 @@ namespace IRaCIS.Application.Contracts public UserTypeEnum UserTypeEnum { get; set; } + public bool IsUserRoleDisabled { get; set; } public bool IsDeleted { get; set; } diff --git a/IRaCIS.Core.Application/Service/TrialSiteUser/PersonalWorkstation.cs b/IRaCIS.Core.Application/Service/TrialSiteUser/PersonalWorkstation.cs index ac1482d0a..7bd07c31e 100644 --- a/IRaCIS.Core.Application/Service/TrialSiteUser/PersonalWorkstation.cs +++ b/IRaCIS.Core.Application/Service/TrialSiteUser/PersonalWorkstation.cs @@ -71,9 +71,11 @@ namespace IRaCIS.Core.Application { var trialDocStat = await _trialRepository.Where(t => t.TrialStatusStr == StaticData.TrialState.TrialOngoing) .Where(t => t.TrialIdentityUserList.Any(t => t.IdentityUserId == _userInfo.IdentityUserId)) - .WhereIf(!_userInfo.IsAdmin, c => c.TrialDocumentList.Where(t => t.IsDeleted == false && t.NeedConfirmedUserTypeList.Any(t => t.NeedConfirmUserTypeId == _userInfo.UserTypeId) && !t.TrialDocConfirmedUserList.Any(t => t.ConfirmUserId == _userInfo.UserRoleId && t.ConfirmTime != null)) - .Count() > 0) - .ProjectTo(_mapper.ConfigurationProvider, new { userTypeEnumInt = _userInfo.UserTypeEnumInt, userId = _userInfo.UserRoleId, userTypeId = _userInfo.UserTypeId }) + .WhereIf(!_userInfo.IsAdmin, c => c.TrialDocumentList.Where(t => t.IsDeleted == false && + t.NeedConfirmedUserTypeList.Any(t => t.NeedConfirmUserTypeId == _userInfo.UserTypeId) + && !t.TrialDocConfirmedUserList.Any(t => t.ConfirmUserId == _userInfo.IdentityUserId && t.ConfirmTime != null)).Count() > 0 + ) + .ProjectTo(_mapper.ConfigurationProvider, new { userTypeEnumInt = _userInfo.UserTypeEnumInt, userId = _userInfo.IdentityUserId, userTypeId = _userInfo.UserTypeId }) .OrderByDescending(t => t.WaitSignCount) .ToPagedListAsync(inQuery); @@ -1117,10 +1119,10 @@ namespace IRaCIS.Core.Application var needSignTrialCount = await _trialRepository.Where(t => t.TrialStatusStr != StaticData.TrialState.TrialStopped) .Where(t => t.TrialIdentityUserList.Any(t => t.IdentityUserId == _userInfo.IdentityUserId)) .Where(c => c.TrialDocumentList.Where(t => t.IsDeleted == false && t.NeedConfirmedUserTypeList.Any(t => t.NeedConfirmUserTypeId == _userInfo.UserTypeId) - && !t.TrialDocConfirmedUserList.Any(t => t.ConfirmUserId == _userInfo.UserRoleId && t.ConfirmTime != null)).Count() > 0).CountAsync(); + && !t.TrialDocConfirmedUserList.Any(t => t.ConfirmUserId == _userInfo.IdentityUserId && t.ConfirmTime != null)).Count() > 0).CountAsync(); var needSignSysDocCont = await _systemDocumentRepository - .Where(t => t.IsDeleted == false && !t.SystemDocConfirmedUserList.Any(t => t.ConfirmUserId == _userInfo.UserRoleId && t.ConfirmTime != null)) + .Where(t => t.IsDeleted == false && !t.SystemDocConfirmedUserList.Any(t => t.ConfirmUserId == _userInfo.IdentityUserId && t.ConfirmTime != null)) //外部人员 只签署 文档类型枚举值有值的 .WhereIf(isInternal == false, t => t.DocUserSignType == DocUserSignType.InnerAndOuter) .SelectMany(t => t.NeedConfirmedUserTypeList) @@ -1129,10 +1131,10 @@ namespace IRaCIS.Core.Application var signedTrialCount = await _trialDocumentRepository.AsQueryable(true) .Where(t => t.Trial.TrialIdentityUserList.Any(t => t.IdentityUserId == _userInfo.IdentityUserId)) .Where(t => t.NeedConfirmedUserTypeList.Any(t => t.NeedConfirmUserTypeId == _userInfo.UserTypeId)) - .Where(t => t.TrialDocConfirmedUserList.Any(t => t.ConfirmUserId == _userInfo.UserRoleId && t.ConfirmTime != null)).CountAsync(); + .Where(t => t.TrialDocConfirmedUserList.Any(t => t.ConfirmUserId == _userInfo.IdentityUserId && t.ConfirmTime != null)).CountAsync(); var signedSysDocCont = await _systemDocumentRepository - .Where(t => t.IsDeleted == false && t.SystemDocConfirmedUserList.Any(t => t.ConfirmUserId == _userInfo.UserRoleId && t.ConfirmTime != null)) + .Where(t => t.IsDeleted == false && t.SystemDocConfirmedUserList.Any(t => t.ConfirmUserId == _userInfo.IdentityUserId && t.ConfirmTime != null)) .SelectMany(t => t.NeedConfirmedUserTypeList) .CountAsync(t => t.NeedConfirmUserTypeId == _userInfo.UserTypeId); diff --git a/IRaCIS.Core.Application/Service/TrialSiteUser/TrialMaintenanceService.cs b/IRaCIS.Core.Application/Service/TrialSiteUser/TrialMaintenanceService.cs index 2242e9d92..1be7735ef 100644 --- a/IRaCIS.Core.Application/Service/TrialSiteUser/TrialMaintenanceService.cs +++ b/IRaCIS.Core.Application/Service/TrialSiteUser/TrialMaintenanceService.cs @@ -57,10 +57,12 @@ namespace IRaCIS.Core.Application.Service UpdateTime = t.UpdateTime, UserName = t.IdentityUser.UserName, RemoveTime = t.RemoveTime, + Status = t.IdentityUser.Status, TrialUserRoleList = t.TrialUserRoleList.Select(ur => new TrialIdentityUserRoleDto() { Id = ur.Id, UserTypeShortName = ur.UserRole.UserTypeRole.UserTypeShortName, + IsUserRoleDisabled = ur.UserRole.IsUserRoleDisabled, IsDeleted = ur.IsDeleted, CreateTime = ur.CreateTime, UserTypeEnum = ur.UserRole.UserTypeEnum, @@ -111,7 +113,7 @@ namespace IRaCIS.Core.Application.Service [HttpPut] public async Task UpdateTrialUserRole(UpdateTrialUserRoleCommand updateCommand) { - await _trialUseRoleRepository.UpdatePartialFromQueryAsync(t => updateCommand.IdList.Contains(t.Id), u => new TrialUserRole() { IsDeleted = updateCommand.IsDeleted }, true); + await _trialUseRoleRepository.UpdatePartialFromQueryAsync(t => updateCommand.IdList.Contains(t.Id), u => new TrialUserRole() { IsDeleted = updateCommand.IsDeleted }, true, true); return ResponseOutput.Ok(); } @@ -132,7 +134,7 @@ namespace IRaCIS.Core.Application.Service //之前已经选择的用户 不放在列表中,现在又要改回去 废弃 - var query = _userRoleRepository.Where(t => t.UserTypeEnum != UserTypeEnum.SuperAdmin && t.IdentityUser.Status == UserStateEnum.Enable) + var query = _userRoleRepository.Where(t => t.UserTypeEnum != UserTypeEnum.SuperAdmin && t.IdentityUser.Status == UserStateEnum.Enable).IgnoreQueryFilters() //正式或者培训的项目 不能允许测试用户(必须正式用户) 同时必须是内部的用户 .WhereIf(trialType == TrialType.OfficialTrial || trialType == TrialType.Training, t => t.IdentityUser.IsTestUser == false && t.IdentityUser.IsZhiZhun) diff --git a/IRaCIS.Core.Application/Service/WorkLoad/EnrollService.cs b/IRaCIS.Core.Application/Service/WorkLoad/EnrollService.cs index 0a4ece20c..05ebbfe2a 100644 --- a/IRaCIS.Core.Application/Service/WorkLoad/EnrollService.cs +++ b/IRaCIS.Core.Application/Service/WorkLoad/EnrollService.cs @@ -175,7 +175,11 @@ namespace IRaCIS.Core.Application.Service var trial = await _trialRepository.FirstOrDefaultAsync(t => t.Id == trialId); - var hasSPMOrCPM = await _trialUserRoleRepository.Where(t => t.TrialId == trialId).AnyAsync(t => t.UserRole.UserTypeEnum == UserTypeEnum.SPM || t.UserRole.UserTypeEnum == UserTypeEnum.CPM); + 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 isSPMjoin = trial.IsSPMJoinReviewerSelect && hasSPMOrCPM; diff --git a/IRaCIS.Core.Application/TestService.cs b/IRaCIS.Core.Application/TestService.cs index 1ef6753fb..40637ab18 100644 --- a/IRaCIS.Core.Application/TestService.cs +++ b/IRaCIS.Core.Application/TestService.cs @@ -167,7 +167,7 @@ namespace IRaCIS.Core.Application.Service { var userList = _userRoleRepository.Where().ToList(); - foreach (var item in userList.GroupBy(t => t.EMail.Trim())) + foreach (var item in userList.GroupBy(t => t.EMail.Trim().ToLower())) { var emailUserIdList = item.Select(t => t.Id).ToList(); diff --git a/IRaCIS.Core.Domain/TrialSiteUser/TrialUser.cs b/IRaCIS.Core.Domain/TrialSiteUser/TrialUser.cs index e31e9ded0..74dc28502 100644 --- a/IRaCIS.Core.Domain/TrialSiteUser/TrialUser.cs +++ b/IRaCIS.Core.Domain/TrialSiteUser/TrialUser.cs @@ -3,7 +3,7 @@ namespace IRaCIS.Core.Domain.Models; [Comment("项目用户角色表")] [Table("TrialUser")] -public class TrialUserRole : BaseFullAuditEntity +public class TrialUserRole : BaseFullDeleteAuditEntity { #region 导航属性 [JsonIgnore] @@ -27,10 +27,6 @@ public class TrialUserRole : BaseFullAuditEntity public DateTime? JoinTime { get; set; } - public Guid? DeleteUserId { get; set; } - public bool IsDeleted { get; set; } - public DateTime? DeletedTime { get; set; } - public Guid TrialUserId { get; set; } } diff --git a/IRaCIS.Core.Infra.EFCore/Common/AuditingData.cs b/IRaCIS.Core.Infra.EFCore/Common/AuditingData.cs index e04dc12d7..890b14bd3 100644 --- a/IRaCIS.Core.Infra.EFCore/Common/AuditingData.cs +++ b/IRaCIS.Core.Infra.EFCore/Common/AuditingData.cs @@ -3000,12 +3000,13 @@ namespace IRaCIS.Core.Infra.EFCore.Common await InsertInspection(entity, type, x => new InspectionConvertDTO() { VisitTaskId = entity.VisitTaskId, - + ObjectRelationParentId = entity.VisitTaskId, - },new { - Answer= answer, - LiverSegmentation= liverSegmentation, + }, new + { + Answer = answer, + LiverSegmentation = liverSegmentation, }); } @@ -3331,36 +3332,42 @@ namespace IRaCIS.Core.Infra.EFCore.Common UserRealName = userRealName, }; + + var extraIdentification = string.Empty; + var isDistinctionInterface = true ; #region 标识区分 if (type == AuditOpt.Add) { + isDistinctionInterface = false; + //生成一致性分析任务 if (entity.IsSelfAnalysis == true) { - type = type + "/" + "SelfAnalysis"; + extraIdentification = "/SelfAnalysis"; } else if (entity.IsSelfAnalysis == false) { - type = type + "/" + "GroupAnalysis"; + extraIdentification = "/GroupAnalysis"; } else { - type = type + "/" + "NotAnalysis"; + extraIdentification = "/NotAnalysis"; } //区分任务类型 - type = type + "/" + (int)entity.ReadingCategory; + extraIdentification = extraIdentification + "/" + (int)entity.ReadingCategory; } else { + isDistinctionInterface = false; switch (_userInfo.RequestUrl) { //申请重阅 case "VisitTask/applyReReading": - type = type + "/" + (int)entity.ReReadingApplyState; + extraIdentification = "/" + (int)entity.ReReadingApplyState; break; @@ -3369,12 +3376,12 @@ namespace IRaCIS.Core.Infra.EFCore.Common if (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ProjectManager || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.APM) { - type = type + "/" + 1; + extraIdentification = "/" + 1; } else { - type = type + "/" + 2; + extraIdentification = "/" + 2; } break; @@ -3510,7 +3517,9 @@ namespace IRaCIS.Core.Infra.EFCore.Common { VisitTaskId = x.Id, - IsDistinctionInterface = type == AuditOpt.Update ? true : false, + IsDistinctionInterface = isDistinctionInterface, + + ExtraIndentification = extraIdentification, ObjectRelationParentId = entity.SourceSubjectVisitId != null ? entity.SourceSubjectVisitId : entity.SouceReadModuleId,