diff --git a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml index 72619802a..063780b32 100644 --- a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml +++ b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml @@ -1371,7 +1371,7 @@ - + 获取查询对象 @@ -1384,7 +1384,7 @@ - + 复制配置项及其子项 @@ -1398,14 +1398,14 @@ 数据集 - + 翻译稽查数据 - + 翻译稽查数据 @@ -10839,6 +10839,21 @@ SystemAnonymizationAddOrEdit 列表查询参数模型 + + + 质疑 + + + + + 一致性核查 + + + + + 复制 + + SystemNoticeView 列表视图模型 diff --git a/IRaCIS.Core.Application/Service/Allocation/VisitTaskService.cs b/IRaCIS.Core.Application/Service/Allocation/VisitTaskService.cs index 8a4e35553..d8345c225 100644 --- a/IRaCIS.Core.Application/Service/Allocation/VisitTaskService.cs +++ b/IRaCIS.Core.Application/Service/Allocation/VisitTaskService.cs @@ -24,2667 +24,1812 @@ using MassTransit; using System.Reactive.Subjects; using Subject = IRaCIS.Core.Domain.Models.Subject; -namespace IRaCIS.Core.Application.Service.Allocation +namespace IRaCIS.Core.Application.Service.Allocation; + +/// +/// 访视读片任务 +/// +[ApiExplorerSettings(GroupName = "Trial")] +public class VisitTaskService(IRepository _visitTaskRepository, + IRepository _trialRepository, + IRepository _subjectVisitRepository, + IRepository _taskAllocationRuleRepository, + IRepository _subjectRepository, + IRepository _subjectUserRepository, + IRepository _readModuleRepository, + IRepository _visitTaskReReadingRepository, + IRepository _taskMedicalReviewRepository, + IRepository _readingClinicalDataReposiotry, + IRepository _subjectCriteriaEvaluationRepository, + IRepository _subjectCriteriaEvaluationVisitFilterRepository, + IRepository _trialReadingCriterionRepository, + IRepository _readingQuestionCriterionTrialRepository, + IRepository _readingTaskQuestionAnswerRepository, + IRepository _dicomInstanceRepository, + IRepository _dicomSeriesRepository, + IRepository _subjectCanceDoctorRepository, + IRepository _readingTaskQuestionMarkRepository, + IRepository _readingTableAnswerRowInfoRepository, + IRepository _readingCustomTagRepository, + IRepository _taskInfluenceRepository, + IRepository _trialQCQuestionAnswerRepository, + IRepository _subjectCriteriaEvaluationVisitStudyFilterRepository) : BaseService, IVisitTaskService { + + + /// - /// 访视读片任务 - /// - [ApiExplorerSettings(GroupName = "Trial")] - public class VisitTaskService(IRepository _visitTaskRepository, - IRepository _trialRepository, - IRepository _subjectVisitRepository, - IRepository _taskAllocationRuleRepository, - IRepository _subjectRepository, - IRepository _subjectUserRepository, - IRepository _readModuleRepository, - IRepository _visitTaskReReadingRepository, - IRepository _taskMedicalReviewRepository, - IRepository _readingClinicalDataReposiotry, - IRepository _subjectCriteriaEvaluationRepository, - IRepository _subjectCriteriaEvaluationVisitFilterRepository, - IRepository _trialReadingCriterionRepository, - IRepository _readingQuestionCriterionTrialRepository, - IRepository _readingTaskQuestionAnswerRepository, - IRepository _dicomInstanceRepository, - IRepository _dicomSeriesRepository, - IRepository _subjectCanceDoctorRepository, - IRepository _readingTaskQuestionMarkRepository, - IRepository _readingTableAnswerRowInfoRepository, - IRepository _readingCustomTagRepository, - IRepository _taskInfluenceRepository, - IRepository _trialQCQuestionAnswerRepository, - IRepository _subjectCriteriaEvaluationVisitStudyFilterRepository) : BaseService, IVisitTaskService + /// 设置任务加急 + /// + /// + /// + [HttpPost] + public async Task SetTaskUrgent(SetTaskUrgentInDto inDto) + { + await _visitTaskRepository.UpdatePartialFromQueryAsync(inDto.VisitTaskId, x => new VisitTask() + { + IsUrgent = inDto.IsUrgent, + TaskUrgentType = inDto.TaskUrgentType, + TaskUrgentRemake = inDto.TaskUrgentRemake, + + }); + + return await _visitTaskRepository.SaveChangesAsync(); + } + + public async Task> GetTrialCriterionList(Guid trialId, bool isHaveSigned = true, bool? isAutoCreate = null) + { + var list = await _readingQuestionCriterionTrialRepository.Where(t => t.TrialId == trialId && t.IsConfirm) + + .OrderBy(t => t.ShowOrder) + .Select(t => new TrialReadingCriterionDto() + { + TrialReadingCriterionId = t.Id, + IsAutoCreate = t.IsAutoCreate, + IsAdditionalAssessment = t.IsAdditionalAssessment, + TrialReadingCriterionName = t.CriterionName, + CriterionType = t.CriterionType, + ReadingType = t.ReadingType, + ReadingInfoSignTime = t.ReadingInfoSignTime, + IsReadingPeriod = t.IsReadingPeriod, + IsArbitrationReading = t.IsArbitrationReading, + IsGlobalReading = t.IsGlobalReading, + IsOncologyReading = t.IsOncologyReading, + ImageDownloadEnum = t.ImageDownloadEnum, + ImageUploadEnum = t.ImageUploadEnum, + IsReadingTaskViewInOrder = t.IsReadingTaskViewInOrder + }) + .ToListAsync(); + + //if (list.Count == 0) + //{ + // //---该项目还未确认任何一个阅片标准 + // throw new BusinessValidationFailedException(_localizer["VisitTask_VisitTask_TaskAlreadyApplied"]); + + //} + + + return list.AsQueryable().WhereIf(isHaveSigned == true, t => t.ReadingInfoSignTime != null) + .WhereIf(isAutoCreate == false, t => t.IsAutoCreate == isAutoCreate).ToList(); + } + + + + + /// + /// Subject 任务类型 统计 +分配情况 + /// + /// + [HttpPost] + public async Task>> GetSubjectAssignAndTaskStatList(SubjectAssignStatQuery inQuery) + { + + var isAddtinoarlCriterion = await _trialReadingCriterionRepository.AnyAsync(t => t.Id == inQuery.TrialReadingCriterionId && t.IsAutoCreate == false); + + var subjectQuery = _subjectRepository.Where(t => t.TrialId == inQuery.TrialId && t.SubjectVisitTaskList.Any()) + .WhereIf(inQuery.TrialSiteId != null, t => t.TrialSiteId == inQuery.TrialSiteId) + .WhereIf(inQuery.SubjectId != null, t => t.Id == inQuery.SubjectId) + .WhereIf(inQuery.DoctorUserId != null, t => t.SubjectDoctorList.Any(t => t.DoctorUserId == inQuery.DoctorUserId && t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId)) + .WhereIf(!string.IsNullOrEmpty(inQuery.SubjectCode), t => t.Code.Contains(inQuery.SubjectCode)) + //未分配 + .WhereIf(inQuery.SubjectAllocateState == 0, t => !t.SubjectDoctorList.Any(t => t.AssignTime != null && t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId)) + //已分配 + .WhereIf(inQuery.SubjectAllocateState == 1, t => t.SubjectDoctorList.Any(t => t.AssignTime != null && t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId)) + + .WhereIf(inQuery.ArmList.Count > 0, t => !inQuery.ArmList.Except(t.SubjectDoctorList.Where(t => t.AssignTime != null && t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId).Select(c => c.ArmEnum)).Any()) + + + .WhereIf(isAddtinoarlCriterion, t => t.SubjectCriteriaEvaluationList.Where(t => t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId).Any(t => t.IsJoinEvaluation)) + + + .ProjectTo(_mapper.ConfigurationProvider, new { trialReadingCriterionId = inQuery.TrialReadingCriterionId }); + + + var pageList = await subjectQuery.ToPagedListAsync(inQuery,nameof(SubjectAssignStat.SubjectId)); + + + + var criterionConfig = (await _trialReadingCriterionRepository.Where(x => x.Id == inQuery.TrialReadingCriterionId).Select(x => new { x.ReadingTool, x.IsReadingTaskViewInOrder, x.ReadingType, x.IsArbitrationReading, x.IsOncologyReading, x.IsGlobalReading }).FirstOrDefaultAsync()).IfNullThrowException(); + + return ResponseOutput.Ok(pageList, criterionConfig); + } + + /// + /// 一次性分配所有医生 批量分配(添加),后端现在没限制 + /// + /// + /// + [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })] + public async Task BatchAssignDoctorToSubject(BatchAssignDoctorToSubjectCommand command) + { + //var inOrder = _trialRepository.Where(t => t.Id == command.TrialId).Select(t => t.IsReadingTaskViewInOrder).FirstOrDefault(); + + //var inOrder = _trialReadingCriterionRepository.Where(t => t.Id == command.TrialReadingCriterionId).Select(t => t.IsReadingTaskViewInOrder).FirstOrDefault(); + + + foreach (var subjectId in command.SubjectIdList) + { + foreach (var doctorArm in command.DoctorArmList) + { + if (!await _subjectUserRepository.Where(t => t.TrialReadingCriterionId == command.TrialReadingCriterionId).AnyAsync(t => t.SubjectId == subjectId && t.DoctorUserId == doctorArm.DoctorUserId && t.ArmEnum == doctorArm.ArmEnum && t.IsConfirmed && t.ReplacedSubjectUserId == null)) + { + await _subjectUserRepository.AddAsync(new SubjectUser() { TrialId = command.TrialId, TrialReadingCriterionId = command.TrialReadingCriterionId, ArmEnum = doctorArm.ArmEnum, DoctorUserId = doctorArm.DoctorUserId, SubjectId = subjectId, AssignTime = DateTime.Now }); + + //task.SuggesteFinishedTime = task.IsUrgent ? DateTime.Now.AddDays(2) : DateTime.Now.AddDays(7); + + } + + + Expression> updateWhere = t => t.TrialReadingCriterionId == command.TrialReadingCriterionId && t.SubjectId == subjectId && t.ArmEnum == doctorArm.ArmEnum && t.TrialId == command.TrialId && t.TaskAllocationState == TaskAllocationState.NotAllocate && t.TaskState == TaskState.Effect && t.IsAnalysisCreate == false; + + //if (inOrder) + //{ + // //针对有序阅片 只分配< 最小的 不是一致性核查通过状态 和不是失访 的访视 的任务 + // if (await _subjectVisitRepository.AnyAsync(t => t.SubjectId == subjectId && t.CheckState != CheckStateEnum.CVPassed && t.IsLostVisit == false)) + // { + // var notCheckPassedMinVisitNum = await _subjectVisitRepository.Where(t => t.SubjectId == subjectId && t.CheckState != CheckStateEnum.CVPassed).OrderBy(t => t.VisitNum).Select(t => t.VisitNum).FirstOrDefaultAsync(); + + // updateWhere = updateWhere.And(t => t.VisitTaskNum < notCheckPassedMinVisitNum); + + // } + + //} + + + await _visitTaskRepository + .UpdatePartialFromQueryAsync(updateWhere, + u => new VisitTask() + { + AllocateTime = DateTime.Now, + DoctorUserId = doctorArm.DoctorUserId, + TaskAllocationState = TaskAllocationState.Allocated, + + SuggesteFinishedTime = GetSuggessFinishTime(true, UrgentType.NotUrget), + }); + } + } + + await _subjectUserRepository.SaveChangesAsync(); + + + + + + return ResponseOutput.Ok(); + } + + + + /// + /// 阅片人维度 Subject统计表 + /// + /// + /// + /// + public async Task<(List, object)> GetDoctorSubjectStat(Guid trialId, Guid trialReadingCriterionId) + { + var list = await _taskAllocationRuleRepository.Where(t => t.TrialId == trialId) + .Where(t => t.Enroll.EnrollReadingCategoryList.Any(t => t.TrialReadingCriterionId == trialReadingCriterionId)) + .ProjectTo(_mapper.ConfigurationProvider, new { trialReadingCriterionId = trialReadingCriterionId }).ToListAsync(); + + var criterionConfig = (await _trialReadingCriterionRepository.Where(x => x.Id == trialReadingCriterionId).Select(x => new { x.ReadingTool, x.IsReadingTaskViewInOrder, x.ReadingType, x.IsArbitrationReading, x.IsOncologyReading }).FirstOrDefaultAsync()).IfNullThrowException(); + + return (list, criterionConfig); + } + + + /// + /// 获取Subject 分配医生情况 + /// + /// + /// + /// + public async Task<(List, object)> GetSubjectAssignedDoctorList(Guid subjectId, Guid trialReadingCriterionId) + { + var list = await _subjectUserRepository.Where(t => t.SubjectId == subjectId && t.ReplacedSubjectUserId == null && t.IsConfirmed && t.TrialReadingCriterionId == trialReadingCriterionId).ProjectTo(_mapper.ConfigurationProvider).ToListAsync(); + + var criterionConfig = (await _trialReadingCriterionRepository.Where(x => x.Id == trialReadingCriterionId).Select(x => new { x.ReadingTool, x.IsReadingTaskViewInOrder, x.ReadingType, x.IsGlobalReading, x.IsOncologyReading, x.IsArbitrationReading }).FirstOrDefaultAsync()).IfNullThrowException(); + + return (list, criterionConfig); + } + + + /// + /// 取消Subject 分配的医生 + /// + /// + /// + /// + [HttpPost] + [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })] + public async Task CancelSubjectAssignedDoctor(CancelSubjectDoctorCommand cancelCommand) + { + foreach (var command in cancelCommand.CancelList.Where(t => t.IsCancelAssign)) + { + if (await _visitTaskRepository.AnyAsync(t => t.TaskState == TaskState.Effect && t.TrialReadingCriterionId == cancelCommand.TrialReadingCriterionId && t.SubjectId == command.SubjectId && t.DoctorUserId == command.DoctorUserId && t.ArmEnum == command.ArmEnum && t.ReadingTaskState != ReadingTaskState.WaitReading)) + { + //---当前医生已开始做该Subject 该标准的任务,不允许取消分配 + throw new BusinessValidationFailedException(_localizer["VisitTask_DoctorConfigNotFound"]); + } + + await _subjectUserRepository.DeleteFromQueryAsync(t => t.Id == command.Id); + + await _visitTaskRepository.UpdatePartialFromQueryAsync(t => t.TrialReadingCriterionId == cancelCommand.TrialReadingCriterionId && t.SubjectId == command.SubjectId && t.DoctorUserId == command.DoctorUserId && t.ArmEnum == command.ArmEnum && t.ReadingTaskState == ReadingTaskState.WaitReading && t.TaskState == TaskState.Effect && t.IsAnalysisCreate == false, u => new VisitTask() + { + AllocateTime = null, + DoctorUserId = null, + TaskAllocationState = TaskAllocationState.NotAllocate, + SuggesteFinishedTime = null + }); + } + + var subjectId = cancelCommand.CancelList.First().SubjectId; + + await _subjectCanceDoctorRepository.AddAsync(new SubjectCanceDoctor() { SubjectId = subjectId, Note = cancelCommand.Note, TrialReadingCriterionId = cancelCommand.TrialReadingCriterionId }); + + await _visitTaskRepository.SaveChangesAsync(); + + return ResponseOutput.Ok(); + } + + + + + /// + /// 任务 手动分配 重新分配 确认 取消分配 + /// 分配 + /// + /// + [HttpPost] + [UnitOfWork] + [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })] + public async Task AssignSubjectTaskToDoctor(AssignSubjectTaskToDoctorCommand assignSubjectTaskToDoctorCommand) + { + var visitTask = await _visitTaskRepository.FirstOrDefaultAsync(t => t.Id == assignSubjectTaskToDoctorCommand.Id); + + if (assignSubjectTaskToDoctorCommand.TaskOptType == TaskOptType.Assign || assignSubjectTaskToDoctorCommand.TaskOptType == TaskOptType.ReAssign) + { + //手动分配验证规则 + + if (visitTask.SourceSubjectVisitId != null) + { + + if (await _visitTaskRepository.AnyAsync(t => t.SourceSubjectVisitId == visitTask.SourceSubjectVisitId && t.TaskAllocationState == TaskAllocationState.Allocated && t.DoctorUserId == assignSubjectTaskToDoctorCommand.DoctorUserId && t.Id != visitTask.Id)) + { + //---其中一个任务已分配给该医生,不允许分配 + return ResponseOutput.NotOk(_localizer["VisitTask_BackendDataError"]); + } + } + else if (visitTask.SouceReadModuleId != null) + { + if (await _visitTaskRepository.AnyAsync(t => t.SouceReadModuleId == visitTask.SouceReadModuleId && t.TaskAllocationState == TaskAllocationState.Allocated && t.DoctorUserId == assignSubjectTaskToDoctorCommand.DoctorUserId && t.Id != visitTask.Id)) + { + //---其中一个任务已分配给该医生,不允许分配 + return ResponseOutput.NotOk(_localizer["VisitTask_BackendDataError"]); + } + } + else + { + //---出现脏数据 任务来源字段没有值 + throw new BusinessValidationFailedException(_localizer["VisitTask_DirtyData"]); + } + + //PM 回退了 但是还没生成任务 当前任务编号前有访视进行了回退就不允许分配 + if (await _subjectVisitRepository.AnyAsync(t => t.SubjectId == visitTask.SubjectId && t.IsPMBackOrReReading && t.VisitNum <= visitTask.VisitTaskNum)) + { + //---该受试者有访视进入了退回流程,还未经过一致性核查通过,不允许分配 + return ResponseOutput.NotOk(_localizer["VisitTask_MissingTaskSource"]); + } + + + visitTask.AllocateTime = DateTime.Now; + visitTask.DoctorUserId = assignSubjectTaskToDoctorCommand.DoctorUserId; + visitTask.TaskAllocationState = TaskAllocationState.Allocated; + + visitTask.SuggesteFinishedTime = GetSuggessFinishTime(true, UrgentType.NotUrget); + + + + //await _subjectVisitRepository.BatchUpdateNoTrackingAsync(t => t.Id == visitTask.SourceSubjectVisitId, u => new SubjectVisit() { ReadingStatus = ReadingStatusEnum.ImageReading }); + + //await _readModuleRepository.BatchUpdateNoTrackingAsync(t => t.Id == visitTask.SouceReadModuleId, u => new ReadModule() { ReadingStatus = ReadingStatusEnum.ImageReading }); + } + + else if (assignSubjectTaskToDoctorCommand.TaskOptType == TaskOptType.ReAssign) + { + //验证 是不是两个任务都给了同一个医生 + + + + //是否删除配置规则表里的 Subject 医生绑定关系 重新添加绑定关系 + + //是否其该Subject 其他访视 绑定的医生 也同时变更? + + + } + + else if (assignSubjectTaskToDoctorCommand.TaskOptType == TaskOptType.Confirm) + { + visitTask.TaskAllocationState = TaskAllocationState.Allocated; + } + else if (assignSubjectTaskToDoctorCommand.TaskOptType == TaskOptType.CancelAssign) + { + visitTask.AllocateTime = null; + visitTask.DoctorUserId = null; + visitTask.TaskAllocationState = TaskAllocationState.NotAllocate; + + //await _subjectVisitRepository.BatchUpdateNoTrackingAsync(t => t.Id == visitTask.SourceSubjectVisitId, u => new SubjectVisit() { ReadingStatus = ReadingStatusEnum.TaskAllocate }); + + //await _readModuleRepository.BatchUpdateNoTrackingAsync(t => t.Id == visitTask.SouceReadModuleId, u => new ReadModule() { ReadingStatus = ReadingStatusEnum.TaskAllocate }); + } + await _visitTaskRepository.SaveChangesAsync(); + return ResponseOutput.Ok(); + } + + + + + /// + /// 获取手动分配 未分配的Subject列表(IsHaveAssigned 传递false) + /// + /// + [HttpPost] + public async Task> GetSubjectAssignList(SubjectAssignQuery inQuery) + { + var subjectQuery = _subjectRepository.Where(t => t.TrialId == inQuery.TrialId) + .WhereIf(inQuery.IsJudgeDoctor == false, t => t.SubjectVisitTaskList.Where(t => t.ArmEnum != Arm.JudgeArm).Any()) + .WhereIf(inQuery.IsJudgeDoctor, t => t.SubjectVisitTaskList.Where(t => t.ArmEnum == Arm.JudgeArm).Any()) + + .WhereIf(inQuery.TrialSiteId != null, t => t.TrialSiteId == inQuery.TrialSiteId) + .WhereIf(inQuery.SubjectId != null, t => t.Id == inQuery.SubjectId) + + .WhereIf(inQuery.IsHaveAssigned != null && inQuery.IsHaveAssigned == true && inQuery.IsJudgeDoctor == false, t => t.SubjectDoctorList.Where(t => t.ArmEnum != Arm.JudgeArm).Any()) + .WhereIf(inQuery.IsHaveAssigned != null && inQuery.IsHaveAssigned == true && inQuery.IsJudgeDoctor, t => t.SubjectDoctorList.Where(t => t.ArmEnum == Arm.JudgeArm).Any()) + .WhereIf(inQuery.IsHaveAssigned != null && inQuery.IsHaveAssigned == false && inQuery.IsJudgeDoctor == false, t => !t.SubjectDoctorList.Where(t => t.ArmEnum != Arm.JudgeArm).Any()) + .WhereIf(inQuery.IsHaveAssigned != null && inQuery.IsHaveAssigned == false && inQuery.IsJudgeDoctor, t => !t.SubjectDoctorList.Where(t => t.ArmEnum == Arm.JudgeArm).Any()) + + + .WhereIf(inQuery.IsAssignConfirmed != null && inQuery.IsAssignConfirmed == true && inQuery.IsJudgeDoctor == false, t => t.SubjectDoctorList.Where(t => t.ArmEnum != Arm.JudgeArm).All(u => u.IsConfirmed)) + .WhereIf(inQuery.IsAssignConfirmed != null && inQuery.IsAssignConfirmed == true && inQuery.IsJudgeDoctor, t => t.SubjectDoctorList.Where(t => t.ArmEnum == Arm.JudgeArm).All(u => u.IsConfirmed)) + + .WhereIf(inQuery.IsAssignConfirmed != null && inQuery.IsAssignConfirmed == false && inQuery.IsJudgeDoctor == false, t => t.SubjectDoctorList.Where(t => t.ArmEnum != Arm.JudgeArm).Any(u => u.IsConfirmed == false)) + .WhereIf(inQuery.IsAssignConfirmed != null && inQuery.IsAssignConfirmed == false && inQuery.IsJudgeDoctor, t => t.SubjectDoctorList.Where(t => t.ArmEnum == Arm.JudgeArm).Any(u => u.IsConfirmed == false)) + + .WhereIf(inQuery.DoctorUserId != null && inQuery.IsJudgeDoctor == false, t => t.SubjectDoctorList.Where(t => t.ArmEnum != Arm.JudgeArm).Any(t => t.DoctorUserId == inQuery.DoctorUserId)) + .WhereIf(inQuery.DoctorUserId != null && inQuery.IsJudgeDoctor, t => t.SubjectDoctorList.Where(t => t.ArmEnum == Arm.JudgeArm).Any(t => t.DoctorUserId == inQuery.DoctorUserId)) + .ProjectTo(_mapper.ConfigurationProvider, new { isJudgeDoctor = inQuery.IsJudgeDoctor }); + + var pageList = await subjectQuery.ToPagedListAsync(inQuery); + + return pageList; + } + + + /// + /// 批量为 多个Subject 分配医生 手动分配 IsReAssign 为true 批量删除 重新分配 + /// + /// + /// + [HttpPost] + [UnitOfWork] + [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })] + public async Task AssignSubjectDoctor(AssginSubjectDoctorCommand assginSubjectDoctorCommand) + { + var trialId = assginSubjectDoctorCommand.TrialId; + var doctorUserIdList = assginSubjectDoctorCommand.DoctorUserIdArmList.Select(t => t.DoctorUserId).ToList(); + + if (assginSubjectDoctorCommand.IsJudgeDoctor) + { + if (assginSubjectDoctorCommand.IsReAssign) + { + + //if (await _visitTaskRepository.AnyAsync(t => assginSubjectDoctorCommand.SubjectIdList.Contains(t.SubjectId) && t.DoctorUserId != null && t.ArmEnum == Arm.JudgeArm)) + //{ + // throw new BusinessValidationFailedException("有Subject任务已应用,不允许重新分配"); + //} + + + await _subjectUserRepository.BatchDeleteNoTrackingAsync(t => doctorUserIdList.Contains(t.DoctorUserId) && assginSubjectDoctorCommand.SubjectIdList.Contains(t.SubjectId) && t.ArmEnum == Arm.JudgeArm); + } + + + } + else + { + if (assginSubjectDoctorCommand.IsReAssign) + { + + //if (await _visitTaskRepository.AnyAsync(t => assginSubjectDoctorCommand.SubjectIdList.Contains(t.SubjectId) && t.DoctorUserId != null && t.ArmEnum != Arm.JudgeArm)) + //{ + // throw new BusinessValidationFailedException("有Subject任务已应用,不允许重新分配"); + //} + + + await _subjectUserRepository.BatchDeleteNoTrackingAsync(t => doctorUserIdList.Contains(t.DoctorUserId) && assginSubjectDoctorCommand.SubjectIdList.Contains(t.SubjectId) && t.ArmEnum != Arm.JudgeArm); + } + + + + } + foreach (var subjectId in assginSubjectDoctorCommand.SubjectIdList) + { + foreach (var doctorUserId in doctorUserIdList) + { + + var armEnum = assginSubjectDoctorCommand.DoctorUserIdArmList.Where(t => t.DoctorUserId == doctorUserId).First().ArmEnum; + + + if (await _subjectUserRepository.AnyAsync(t => t.TrialId == trialId && t.SubjectId == subjectId && t.DoctorUserId == doctorUserId && t.ArmEnum != armEnum && t.ReplacedSubjectUserId == null)) + { + //---有Subject 在其他Arm组已有该医生,不允许在新的组添加该医生 + throw new BusinessValidationFailedException(_localizer["VisitTask_InconsistentSubjectStatus"]); + } + + if (await _subjectUserRepository.AnyAsync(t => t.TrialId == trialId && t.SubjectId == subjectId && t.DoctorUserId == doctorUserId && t.ArmEnum == armEnum && t.ReplacedSubjectUserId == null)) + { + //---有Subject 已有该Arm组的医生,不允许继续分配,请刷新页面,确认页面数据是否过期 + throw new BusinessValidationFailedException(_localizer["VisitTask_DuplicateDoctorInArm"]); + } + else + { + await _subjectUserRepository.AddAsync(new SubjectUser() { TrialId = trialId, SubjectId = subjectId, DoctorUserId = doctorUserId, ArmEnum = armEnum, AssignTime = DateTime.Now }); + + } + + } + + } + + + await _subjectUserRepository.SaveChangesAsync(); + + return ResponseOutput.Ok(); + } + + /// + /// 批量取消Subject 分配的医生 + /// + /// 数量 + [HttpPost] + [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })] + public async Task CancelSubjectAssignDoctor(CancelSubjectAssignCommand cancelSubjectAssignCommand) + { + if (cancelSubjectAssignCommand.IsJudgeDoctor) + { + foreach (var subjectId in cancelSubjectAssignCommand.SubjectIdList) + { + if (await _visitTaskRepository.AnyAsync(t => t.SubjectId == subjectId && t.DoctorUserId != null && t.ArmEnum == Arm.JudgeArm)) + { + //---有Subject任务已应用,不允许取消分配 + throw new BusinessValidationFailedException(_localizer["VisitTask_DoctorAlreadyInArm"]); + } + + await _subjectUserRepository.DeleteFromQueryAsync(t => t.SubjectId == subjectId && t.ArmEnum == Arm.JudgeArm); + } + } + else + { + foreach (var subjectId in cancelSubjectAssignCommand.SubjectIdList) + { + if (await _visitTaskRepository.AnyAsync(t => t.SubjectId == subjectId && t.DoctorUserId != null && t.ArmEnum != Arm.JudgeArm)) + { + //---有Subject任务已应用,不允许取消分配 + throw new BusinessValidationFailedException(_localizer["VisitTask_DoctorAlreadyInArm"]); + } + + await _subjectUserRepository.DeleteFromQueryAsync(t => t.SubjectId == subjectId && t.ArmEnum != Arm.JudgeArm); + } + } + + await _subjectUserRepository.SaveChangesAsync(); + + return ResponseOutput.Ok(); + } + + + /// + /// 手动分配确认 绑定该Subject的已存在的任务给医生 + /// + /// + /// + [HttpPost] + [UnitOfWork] + [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })] + public async Task ManualAssignDoctorApplyTask(AssignConfirmCommand assignConfirmCommand) + { + var trialId = assignConfirmCommand.TrialId; + + //获取项目配置 判断应该分配几个医生 + //var trialConfig = (await _trialRepository.Where(t => t.Id == trialId).Select(t => new { TrialId = t.Id, t.ReadingType, t.IsFollowVisitAutoAssign, t.IsFollowGlobalVisitAutoAssign, t.FollowGlobalVisitAutoAssignDefaultState, t.TaskAllocateObjEnum }).FirstOrDefaultAsync()).IfNullThrowException(); + + //需要确认的Subject + var subjectIdList = assignConfirmCommand.SubjectDoctorUserList.Select(t => t.SubjectId).ToList(); + + //将关系确认 + if (assignConfirmCommand.SubjectDoctorUserList.Count == 0) + { + await _subjectUserRepository.BatchUpdateNoTrackingAsync(t => t.TrialId == trialId && t.IsConfirmed == false && t.ReplacedSubjectUserId == null, u => new SubjectUser() { IsConfirmed = true }); + } + else + { + await _subjectUserRepository.BatchUpdateNoTrackingAsync(t => t.TrialId == trialId && t.IsConfirmed == false && t.ReplacedSubjectUserId == null + && subjectIdList.Contains(t.SubjectId), u => new SubjectUser() { IsConfirmed = true }); + } + + + var taskList = _visitTaskRepository.Where(t => t.TrialId == assignConfirmCommand.TrialId && t.DoctorUserId == null, true) + .WhereIf(subjectIdList.Count > 0 && assignConfirmCommand.IsJudgeDoctor == false, t => subjectIdList.Contains(t.SubjectId) && t.Subject.SubjectDoctorList.Where(t => t.ArmEnum != Arm.JudgeArm).Any()) + .WhereIf(subjectIdList.Count > 0 && assignConfirmCommand.IsJudgeDoctor, t => subjectIdList.Contains(t.SubjectId) && t.Subject.SubjectDoctorList.Where(t => t.ArmEnum == Arm.JudgeArm).Any()) + //过滤掉 那些回退的subject + .Where(t => !t.Subject.SubjectVisitList.Any(t => t.IsPMBackOrReReading)) + + .ToList(); + + + foreach (var subjectTaskGroup in taskList.GroupBy(t => t.SubjectId)) + { + var subjectId = subjectTaskGroup.Key; + + + + //如果数据为空 那么就是确认所有已分配的 + List subjectDoctorIdArmList = new List(); + + if (assignConfirmCommand.SubjectDoctorUserList.Count == 0) + { + subjectDoctorIdArmList = _subjectUserRepository.Where(t => t.SubjectId == subjectId && t.ReplacedSubjectUserId == null).Select(t => new DoctorArm() { DoctorUserId = t.DoctorUserId, ArmEnum = t.ArmEnum }).ToList(); + } + else + { + subjectDoctorIdArmList = assignConfirmCommand.SubjectDoctorUserList.Where(t => t.SubjectId == subjectId).First().DoctorUserIdArmList; + } + + + foreach (var task in subjectTaskGroup.OrderBy(t => t.ArmEnum).ToList()) + { + + var subjectDoctorArm = subjectDoctorIdArmList.Where(t => t.ArmEnum == task.ArmEnum).FirstOrDefault(); + + if (subjectDoctorArm != null) + { + task.DoctorUserId = subjectDoctorArm.DoctorUserId; + task.AllocateTime = DateTime.Now; + task.TaskAllocationState = TaskAllocationState.Allocated; + + task.SuggesteFinishedTime = /*task.IsUrgent ? DateTime.Now.AddDays(2) : DateTime.Now.AddDays(7)*/ GetSuggessFinishTime(true, UrgentType.NotUrget); + + await _subjectVisitRepository.BatchUpdateNoTrackingAsync(t => t.Id == task.SourceSubjectVisitId, u => new SubjectVisit() { ReadingStatus = ReadingStatusEnum.ImageReading }); + + await _readModuleRepository.BatchUpdateNoTrackingAsync(t => t.Id == task.SouceReadModuleId, u => new ReadModule() { ReadingStatus = ReadingStatusEnum.ImageReading }); + + + } + else + { + //---在配置表中未找到配置的医生,无法应用绑定,请核对数据 + throw new BusinessValidationFailedException(_localizer["VisitTask_TaskAlreadyApplied"]); + } + + } + } + + + + await _visitTaskRepository.SaveChangesAsync(); + + return ResponseOutput.Ok(); + } + + + + /// + /// 访视任务 + /// + /// + /// + /// + [HttpPost] + public async Task> GetVisitTaskList(VisitTaskQuery inQuery, [FromServices] IVisitTaskHelpeService _visitTaskCommonService) + { + //以前访视未产生任务的,在查询这里要产生 + var svIdList = await _subjectVisitRepository.Where(t => t.TrialId == inQuery.TrialId && t.CheckState == CheckStateEnum.CVPassed && t.IsVisitTaskGenerated == false).Select(t => t.Id).ToListAsync(); + + //之前没有生成任务的逻辑 但是现在加了,任务要自动生成 + await _visitTaskCommonService.GenerateVisitTaskAsync(inQuery.TrialId, svIdList); + + + var visitTaskQueryable = _visitTaskRepository.Where(t => t.TrialId == inQuery.TrialId && t.IsAnalysisCreate == false) + .WhereIf(inQuery.ReadingCategory != null, t => t.ReadingCategory == inQuery.ReadingCategory) + .WhereIf(inQuery.ReadingCategory == null, t => t.ReadingCategory != ReadingCategory.Judge) + + .WhereIf(inQuery.TaskState != null, t => t.TaskState == inQuery.TaskState) + .WhereIf(inQuery.TrialSiteId != null, t => t.Subject.TrialSiteId == inQuery.TrialSiteId) + .WhereIf(inQuery.SubjectId != null, t => t.SubjectId == inQuery.SubjectId) + .WhereIf(inQuery.IsUrgent != null, t => t.IsUrgent == inQuery.IsUrgent) + .WhereIf(inQuery.DoctorUserId != null, t => t.DoctorUserId == inQuery.DoctorUserId) + .WhereIf(inQuery.ReadingCategory != null, t => t.ReadingCategory == inQuery.ReadingCategory) + .WhereIf(inQuery.TaskAllocationState != null, t => t.TaskAllocationState == inQuery.TaskAllocationState) + .WhereIf(inQuery.TrialReadingCriterionId != null, t => t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId) + + .WhereIf(!string.IsNullOrEmpty(inQuery.TrialSiteCode), t => (t.BlindTrialSiteCode.Contains(inQuery.TrialSiteCode!) && t.IsAnalysisCreate) || (t.Subject.TrialSite.TrialSiteCode.Contains(inQuery.TrialSiteCode!) && t.IsAnalysisCreate == false)) + .WhereIf(!string.IsNullOrEmpty(inQuery.TaskName), t => t.TaskName.Contains(inQuery.TaskName) || t.TaskBlindName.Contains(inQuery.TaskName)) + + .WhereIf(!string.IsNullOrEmpty(inQuery.SubjectCode), t => (t.Subject.Code.Contains(inQuery.SubjectCode) && t.IsAnalysisCreate == false) || (t.BlindSubjectCode.Contains(inQuery.SubjectCode) && t.IsAnalysisCreate)) + .WhereIf(inQuery.BeginAllocateDate != null, t => t.AllocateTime > inQuery.BeginAllocateDate) + .WhereIf(inQuery.EndAllocateDate != null, t => t.AllocateTime < inQuery.EndAllocateDate!.Value.AddDays(1)) + .ProjectTo(_mapper.ConfigurationProvider); + + var defalutSortArray = new string[] { nameof(VisitTaskView.IsUrgent) + " desc", nameof(VisitTaskView.SubjectCode), nameof(VisitTaskView.VisitTaskNum) }; + + var pageList = await visitTaskQueryable.ToPagedListAsync(inQuery, defalutSortArray); + + //var trialTaskConfig = _trialRepository.Where(t => t.Id == queryVisitTask.TrialId).ProjectTo(_mapper.ConfigurationProvider).FirstOrDefault(); + return pageList; + } + + + + /// + /// 裁判任务 + /// + /// + /// + [HttpPost] + public async Task/*, object)*/> GetJudgeVisitTaskList(VisitTaskQuery inQuery) + { + + var visitTaskQueryable = _visitTaskRepository.Where(t => t.TrialId == inQuery.TrialId && t.IsAnalysisCreate == false) + .Where(t => t.ReadingCategory == ReadingCategory.Judge) + + .WhereIf(inQuery.TaskState != null, t => t.TaskState == inQuery.TaskState) + .WhereIf(inQuery.ReadingCategory != null, t => t.ReadingCategory == inQuery.ReadingCategory) + .WhereIf(inQuery.TrialSiteId != null, t => t.Subject.TrialSiteId == inQuery.TrialSiteId) + .WhereIf(inQuery.SubjectId != null, t => t.SubjectId == inQuery.SubjectId) + .WhereIf(inQuery.IsUrgent != null, t => t.IsUrgent == inQuery.IsUrgent) + .WhereIf(inQuery.DoctorUserId != null, t => t.DoctorUserId == inQuery.DoctorUserId) + .WhereIf(inQuery.TaskAllocationState != null, t => t.TaskAllocationState == inQuery.TaskAllocationState) + .WhereIf(inQuery.ReadingTaskState != null, t => t.ReadingTaskState == inQuery.ReadingTaskState) + .WhereIf(inQuery.TrialReadingCriterionId != null, t => t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId) + + .WhereIf(!string.IsNullOrEmpty(inQuery.TrialSiteCode), t => (t.BlindTrialSiteCode.Contains(inQuery.TrialSiteCode!) && t.IsAnalysisCreate) || (t.Subject.TrialSite.TrialSiteCode.Contains(inQuery.TrialSiteCode!) && t.IsAnalysisCreate == false)) + .WhereIf(!string.IsNullOrEmpty(inQuery.TaskName), t => t.TaskName.Contains(inQuery.TaskName) || t.TaskBlindName.Contains(inQuery.TaskName)) + .WhereIf(!string.IsNullOrEmpty(inQuery.SubjectCode), t => (t.Subject.Code.Contains(inQuery.SubjectCode) && t.IsAnalysisCreate == false) || (t.BlindSubjectCode.Contains(inQuery.SubjectCode) && t.IsAnalysisCreate)) + .WhereIf(inQuery.BeginAllocateDate != null, t => t.AllocateTime > inQuery.BeginAllocateDate) + .WhereIf(inQuery.EndAllocateDate != null, t => t.AllocateTime < inQuery.EndAllocateDate!.Value.AddDays(1)) + .ProjectTo(_mapper.ConfigurationProvider); + + var defalutSortArray = new string[] { nameof(JudgeVisitTaskView.IsUrgent) + " desc", nameof(JudgeVisitTaskView.SubjectCode), nameof(JudgeVisitTaskView.VisitTaskNum) }; + + var pageList = await visitTaskQueryable.ToPagedListAsync(inQuery, defalutSortArray); + + return pageList; + //var trialTaskConfig = _trialRepository.Where(t => t.Id == queryVisitTask.TrialId).ProjectTo(_mapper.ConfigurationProvider).FirstOrDefault(); + + //return (pageList, trialTaskConfig); + } + + + /// + /// PM阅片跟踪 + /// + /// + /// + [HttpPost] + public async Task>> GetReadingTaskList(VisitTaskQuery inQuery) + { + var visitTaskQueryable = _visitTaskRepository.Where(t => t.TrialId == inQuery.TrialId && t.IsAnalysisCreate == false) + //.Where(t => t.IsAnalysisCreate == false && t.DoctorUserId != null) + + .WhereIf(inQuery.IsEffect == true, t => t.TaskState == TaskState.Effect || t.TaskState == TaskState.Freeze) + .WhereIf(inQuery.IsEffect == false, t => t.TaskState == TaskState.Adbandon || t.TaskState == TaskState.HaveReturned) + + .WhereIf(inQuery.TaskState != null, t => t.TaskState == inQuery.TaskState) + .WhereIf(inQuery.TrialSiteId != null, t => t.Subject.TrialSiteId == inQuery.TrialSiteId) + .WhereIf(inQuery.SubjectId != null, t => t.SubjectId == inQuery.SubjectId) + .WhereIf(inQuery.IsUrgent != null, t => t.IsUrgent == inQuery.IsUrgent) + .WhereIf(inQuery.DoctorUserId != null, t => t.DoctorUserId == inQuery.DoctorUserId) + .WhereIf(inQuery.ReadingCategory != null, t => t.ReadingCategory == inQuery.ReadingCategory) + .WhereIf(inQuery.ReadingTaskState != null, t => t.ReadingTaskState == inQuery.ReadingTaskState) + .WhereIf(inQuery.TaskAllocationState != null, t => t.TaskAllocationState == inQuery.TaskAllocationState) + .WhereIf(inQuery.TrialReadingCriterionId != null, t => t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId) + .WhereIf(inQuery.ReReadingApplyState != null, t => t.ReReadingApplyState == inQuery.ReReadingApplyState) + + .WhereIf(inQuery.CompleteClinicalDataEnum == CompleteClinicalDataEnum.Complete, t => t.IsClinicalDataSign && t.IsNeedClinicalDataSign == true) + .WhereIf(inQuery.CompleteClinicalDataEnum == CompleteClinicalDataEnum.NotComplete, t => t.IsClinicalDataSign == false && t.IsNeedClinicalDataSign == true) + .WhereIf(inQuery.CompleteClinicalDataEnum == CompleteClinicalDataEnum.NA, t => t.IsNeedClinicalDataSign == false) + .WhereIf(!string.IsNullOrEmpty(inQuery.TrialSiteCode), t => (t.BlindTrialSiteCode.Contains(inQuery.TrialSiteCode!) && t.IsAnalysisCreate) || (t.Subject.TrialSite.TrialSiteCode.Contains(inQuery.TrialSiteCode!) && t.IsAnalysisCreate == false)) + .WhereIf(!string.IsNullOrEmpty(inQuery.TaskName), t => t.TaskName.Contains(inQuery.TaskName) || t.TaskBlindName.Contains(inQuery.TaskName)) + .WhereIf(!string.IsNullOrEmpty(inQuery.SubjectCode), t => (t.Subject.Code.Contains(inQuery.SubjectCode) && t.IsAnalysisCreate == false) || (t.BlindSubjectCode.Contains(inQuery.SubjectCode) && t.IsAnalysisCreate)) + .WhereIf(inQuery.BeginAllocateDate != null, t => t.AllocateTime > inQuery.BeginAllocateDate) + .WhereIf(inQuery.EndAllocateDate != null, t => t.AllocateTime < inQuery.EndAllocateDate) + .WhereIf(inQuery.BeginSignTime != null, t => t.SignTime > inQuery.BeginSignTime) + .WhereIf(inQuery.EndSignTime != null, t => t.SignTime < inQuery.EndSignTime) + .ProjectTo(_mapper.ConfigurationProvider); + + var defalutSortArray = new string[] { nameof(ReadingTaskView.IsUrgent) + " desc", nameof(ReadingTaskView.SubjectCode), nameof(ReadingTaskView.VisitTaskNum) }; + + var pageList = await visitTaskQueryable.ToPagedListAsync(inQuery, defalutSortArray); + + var trialTaskConfig = _trialRepository.Where(t => t.Id == inQuery.TrialId).ProjectTo(_mapper.ConfigurationProvider).FirstOrDefault(); + + return ResponseOutput.Ok(pageList, trialTaskConfig); + } + + + /// + /// PM 重阅追踪 + /// + /// + /// + [HttpPost] + public async Task> GetReReadingTaskList(VisitTaskQuery inQuery) { + var visitTaskQueryable = _visitTaskReReadingRepository + .Where(t => t.OriginalReReadingTask.TrialId == inQuery.TrialId /*&& t.OriginalReReadingTask.IsAnalysisCreate == false*/) + .WhereIf(inQuery.RootReReadingTaskId != null, t => t.RootReReadingTaskId == inQuery.RootReReadingTaskId || t.OriginalReReadingTaskId == inQuery.RootReReadingTaskId) + .WhereIf(!string.IsNullOrEmpty(inQuery.TaskCode), t => t.OriginalReReadingTask.TaskCode.Contains(inQuery.TaskCode!) || t.RootReReadingTask.TaskCode.Contains(inQuery.TaskCode!)) + .WhereIf(inQuery.TrialSiteId != null, t => t.OriginalReReadingTask.Subject.TrialSiteId == inQuery.TrialSiteId) + .WhereIf(inQuery.TaskState != null, t => t.OriginalReReadingTask.TaskState == inQuery.TaskState) + .WhereIf(inQuery.ReReadingApplyState != null, t => t.OriginalReReadingTask.ReReadingApplyState == inQuery.ReReadingApplyState) + .WhereIf(inQuery.RequestReReadingType != null, t => t.RequestReReadingType == inQuery.RequestReReadingType) + .WhereIf(inQuery.SubjectId != null, t => t.OriginalReReadingTask.SubjectId == inQuery.SubjectId) + .WhereIf(inQuery.IsUrgent != null, t => t.OriginalReReadingTask.IsUrgent == inQuery.IsUrgent) + .WhereIf(inQuery.DoctorUserId != null, t => t.OriginalReReadingTask.DoctorUserId == inQuery.DoctorUserId) + .WhereIf(inQuery.ArmEnum != null, t => t.OriginalReReadingTask.ArmEnum == inQuery.ArmEnum) + .WhereIf(inQuery.ReadingTaskState != null, t => t.OriginalReReadingTask.ReadingTaskState == inQuery.ReadingTaskState) + .WhereIf(inQuery.TaskAllocationState != null, t => t.OriginalReReadingTask.TaskAllocationState == inQuery.TaskAllocationState) + .WhereIf(inQuery.TrialReadingCriterionId != null, t => t.OriginalReReadingTask.TrialReadingCriterionId == inQuery.TrialReadingCriterionId) + .WhereIf(inQuery.ReadingCategory != null, t => t.OriginalReReadingTask.ReadingCategory == inQuery.ReadingCategory) - /// - /// 设置任务加急 - /// - /// - /// - [HttpPost] - public async Task SetTaskUrgent(SetTaskUrgentInDto inDto) + .WhereIf(!string.IsNullOrEmpty(inQuery.RequestReReadingReason), t => t.RequestReReadingReason.Contains(inQuery.RequestReReadingReason)) + + .WhereIf(inQuery.RequestReReadingResultEnum != null, t => t.RequestReReadingResultEnum == inQuery.RequestReReadingResultEnum) + + + .WhereIf(!string.IsNullOrEmpty(inQuery.TrialSiteCode), t => (t.OriginalReReadingTask.BlindTrialSiteCode.Contains(inQuery.TrialSiteCode!) && t.OriginalReReadingTask.IsAnalysisCreate) || (t.OriginalReReadingTask.Subject.TrialSite.TrialSiteCode.Contains(inQuery.TrialSiteCode!) && t.OriginalReReadingTask.IsAnalysisCreate == false)) + .WhereIf(!string.IsNullOrEmpty(inQuery.TaskName), t => t.OriginalReReadingTask.TaskName.Contains(inQuery.TaskName) || t.OriginalReReadingTask.TaskBlindName.Contains(inQuery.TaskName)) + .WhereIf(!string.IsNullOrEmpty(inQuery.SubjectCode), t => ((t.OriginalReReadingTask.Subject.Code.Contains(inQuery.SubjectCode) || t.OriginalReReadingTask.Subject.MedicalNo.Contains(inQuery.SubjectCode)) && t.OriginalReReadingTask.IsAnalysisCreate == false) || (t.OriginalReReadingTask.BlindSubjectCode.Contains(inQuery.SubjectCode) && t.OriginalReReadingTask.IsAnalysisCreate)) + .WhereIf(inQuery.BeginAllocateDate != null, t => t.OriginalReReadingTask.AllocateTime > inQuery.BeginAllocateDate) + .WhereIf(inQuery.EndAllocateDate != null, t => t.OriginalReReadingTask.AllocateTime < inQuery.EndAllocateDate!.Value.AddDays(1)) + + .WhereIf(inQuery.BeginRequestReReadingTime != null, t => t.RequestReReadingTime >= inQuery.BeginRequestReReadingTime) + .WhereIf(inQuery.EndRequestReReadingTime != null, t => t.RequestReReadingTime <= inQuery.EndRequestReReadingTime!.Value.AddDays(1)) + + .ProjectTo(_mapper.ConfigurationProvider); + + //var defalutSortArray = new string[] { nameof(ReReadingTaskView.OriginalReReadingTask) + "." + nameof(ReReadingTaskView.OriginalReReadingTask.IsUrgent) + " desc", nameof(ReReadingTaskView.OriginalReReadingTask) + "." + nameof(ReReadingTaskView.OriginalReReadingTask.SubjectId), nameof(ReReadingTaskView.OriginalReReadingTask) + "." + nameof(ReReadingTaskView.OriginalReReadingTask.VisitTaskNum) }; + + var defalutSortArray = new string[] { + nameof(ReReadingTaskView.RequestReReadingResultEnum) , + nameof(ReReadingTaskView.OriginalReReadingTask) + "." + nameof(ReReadingTaskView.OriginalReReadingTask.IsUrgent) + " desc", + nameof(ReReadingTaskView.OriginalReReadingTask) + "." + nameof(ReReadingTaskView.OriginalReReadingTask.TaskState), + nameof(ReReadingTaskView.OriginalReReadingTask) + "." + nameof(ReReadingTaskView.OriginalReReadingTask.SubjectCode),nameof(ReReadingTaskView.OriginalReReadingTask) + "." + nameof(ReReadingTaskView.OriginalReReadingTask.VisitTaskNum) }; + + + + var pageList = await visitTaskQueryable.ToPagedListAsync(inQuery, defalutSortArray); + + return pageList; + } + + + /// + /// 获取IR 重阅影像阅片列表 + /// + /// + /// + [HttpPost] + public async Task> GetIRReReadingTaskList(VisitTaskQuery inQuery) + { + + var visitTaskQueryable = _visitTaskReReadingRepository + .Where(t => t.RequestReReadingType == RequestReReadingType.DocotorApply) + .Where(t => t.OriginalReReadingTask.DoctorUserId == _userInfo.Id) + .Where(t => t.OriginalReReadingTask.TrialId == inQuery.TrialId) + .WhereIf(inQuery.RequestReReadingResultEnum != null, t => t.RequestReReadingResultEnum == inQuery.RequestReReadingResultEnum) + .WhereIf(inQuery.RootReReadingTaskId != null, t => t.RootReReadingTaskId == inQuery.RootReReadingTaskId || t.OriginalReReadingTaskId == inQuery.RootReReadingTaskId) + .WhereIf(!string.IsNullOrEmpty(inQuery.TaskCode), t => t.OriginalReReadingTask.TaskCode.Contains(inQuery.TaskCode!) || t.RootReReadingTask.TaskCode.Contains(inQuery.TaskCode!)) + .WhereIf(inQuery.TaskState != null, t => t.OriginalReReadingTask.TaskState == inQuery.TaskState) + .WhereIf(inQuery.ReadingCategory != null, t => t.OriginalReReadingTask.ReadingCategory == inQuery.ReadingCategory) + .WhereIf(inQuery.ReReadingApplyState != null, t => t.OriginalReReadingTask.ReReadingApplyState == inQuery.ReReadingApplyState) + .WhereIf(inQuery.TrialSiteId != null, t => t.OriginalReReadingTask.Subject.TrialSiteId == inQuery.TrialSiteId) + .WhereIf(inQuery.SubjectId != null, t => t.OriginalReReadingTask.SubjectId == inQuery.SubjectId) + .WhereIf(inQuery.IsUrgent != null, t => t.OriginalReReadingTask.IsUrgent == inQuery.IsUrgent) + .WhereIf(inQuery.DoctorUserId != null, t => t.OriginalReReadingTask.DoctorUserId == inQuery.DoctorUserId) + .WhereIf(inQuery.ReadingTaskState != null, t => t.OriginalReReadingTask.ReadingTaskState == inQuery.ReadingTaskState) + .WhereIf(inQuery.TaskAllocationState != null, t => t.OriginalReReadingTask.TaskAllocationState == inQuery.TaskAllocationState) + .WhereIf(inQuery.TrialReadingCriterionId != null, t => t.OriginalReReadingTask.TrialReadingCriterionId == inQuery.TrialReadingCriterionId) + + + .WhereIf(!string.IsNullOrEmpty(inQuery.TrialSiteCode), t => (t.OriginalReReadingTask.BlindTrialSiteCode.Contains(inQuery.TrialSiteCode!) && t.OriginalReReadingTask.IsAnalysisCreate) || (t.OriginalReReadingTask.Subject.TrialSite.TrialSiteCode.Contains(inQuery.TrialSiteCode!) && t.OriginalReReadingTask.IsAnalysisCreate == false)) + .WhereIf(!string.IsNullOrEmpty(inQuery.TaskName), t => t.OriginalReReadingTask.TaskName.Contains(inQuery.TaskName) || t.NewReReadingTask.TaskBlindName.Contains(inQuery.TaskName)) + .WhereIf(!string.IsNullOrEmpty(inQuery.SubjectCode), t => (t.OriginalReReadingTask.Subject.Code.Contains(inQuery.SubjectCode) && t.OriginalReReadingTask.IsAnalysisCreate == false) || (t.OriginalReReadingTask.BlindSubjectCode.Contains(inQuery.SubjectCode) && t.OriginalReReadingTask.IsAnalysisCreate)) + .WhereIf(inQuery.BeginAllocateDate != null, t => t.OriginalReReadingTask.AllocateTime > inQuery.BeginAllocateDate) + .WhereIf(inQuery.EndAllocateDate != null, t => t.OriginalReReadingTask.AllocateTime < inQuery.EndAllocateDate!.Value.AddDays(1)) + .ProjectTo(_mapper.ConfigurationProvider); + + + + var defalutSortArray = new string[] { nameof(ReReadingTaskView.OriginalReReadingTask) + "." + nameof(ReReadingTaskView.OriginalReReadingTask.IsUrgent) + " desc", nameof(ReReadingTaskView.OriginalReReadingTask) + "." + nameof(ReReadingTaskView.OriginalReReadingTask.SubjectCode), nameof(ReReadingTaskView.OriginalReReadingTask) + "." + nameof(ReReadingTaskView.OriginalReReadingTask.VisitTaskNum) }; + + var pageList = await visitTaskQueryable.ToPagedListAsync(inQuery, defalutSortArray); + + return pageList; + } + + + //SPM 能看到项目组申请记录 + [HttpPost] + public async Task> GetSPMReReadingTaskList(VisitTaskQuery inQuery) + { + var visitTaskQueryable = _visitTaskReReadingRepository.Where(t => t.RequestReReadingType == RequestReReadingType.TrialGroupApply && t.OriginalReReadingTask.IsAnalysisCreate == false) + .Where(t => t.OriginalReReadingTask.TrialId == inQuery.TrialId) + .WhereIf(inQuery.RootReReadingTaskId != null, t => t.RootReReadingTaskId == inQuery.RootReReadingTaskId || t.OriginalReReadingTaskId == inQuery.RootReReadingTaskId) + .WhereIf(!string.IsNullOrEmpty(inQuery.TaskCode), t => t.OriginalReReadingTask.TaskCode.Contains(inQuery.TaskCode!) || t.RootReReadingTask.TaskCode.Contains(inQuery.TaskCode!)) + .WhereIf(inQuery.TaskState != null, t => t.OriginalReReadingTask.TaskState == inQuery.TaskState) + .WhereIf(inQuery.TrialSiteId != null, t => t.OriginalReReadingTask.Subject.TrialSiteId == inQuery.TrialSiteId) + .WhereIf(inQuery.SubjectId != null, t => t.OriginalReReadingTask.SubjectId == inQuery.SubjectId) + .WhereIf(inQuery.IsUrgent != null, t => t.OriginalReReadingTask.IsUrgent == inQuery.IsUrgent) + .WhereIf(inQuery.DoctorUserId != null, t => t.OriginalReReadingTask.DoctorUserId == inQuery.DoctorUserId) + .WhereIf(inQuery.ReadingTaskState != null, t => t.OriginalReReadingTask.ReadingTaskState == inQuery.ReadingTaskState) + .WhereIf(inQuery.TaskAllocationState != null, t => t.OriginalReReadingTask.TaskAllocationState == inQuery.TaskAllocationState) + .WhereIf(inQuery.TrialReadingCriterionId != null, t => t.OriginalReReadingTask.TrialReadingCriterionId == inQuery.TrialReadingCriterionId) + + .WhereIf(!string.IsNullOrEmpty(inQuery.TrialSiteCode), t => (t.OriginalReReadingTask.BlindTrialSiteCode.Contains(inQuery.TrialSiteCode!) && t.OriginalReReadingTask.IsAnalysisCreate) || (t.OriginalReReadingTask.Subject.TrialSite.TrialSiteCode.Contains(inQuery.TrialSiteCode!) && t.OriginalReReadingTask.IsAnalysisCreate == false)) + + .WhereIf(!string.IsNullOrEmpty(inQuery.TaskName), t => t.OriginalReReadingTask.TaskName.Contains(inQuery.TaskName) || t.NewReReadingTask.TaskBlindName.Contains(inQuery.TaskName)) + .WhereIf(!string.IsNullOrEmpty(inQuery.SubjectCode), t => (t.OriginalReReadingTask.Subject.Code.Contains(inQuery.SubjectCode) && t.OriginalReReadingTask.IsAnalysisCreate == false) || (t.OriginalReReadingTask.BlindSubjectCode.Contains(inQuery.SubjectCode) && t.OriginalReReadingTask.IsAnalysisCreate)) + .WhereIf(inQuery.BeginAllocateDate != null, t => t.OriginalReReadingTask.AllocateTime > inQuery.BeginAllocateDate) + .WhereIf(inQuery.EndAllocateDate != null, t => t.OriginalReReadingTask.AllocateTime < inQuery.EndAllocateDate!.Value.AddDays(1)) + .ProjectTo(_mapper.ConfigurationProvider); + + var defalutSortArray = new string[] { nameof(ReReadingTaskView.RequestReReadingTime) }; + + //var defalutSortArray = new string[] { nameof(ReReadingTaskView.OriginalReReadingTask) + "." + nameof(ReReadingTaskView.OriginalReReadingTask.IsUrgent) + " desc", nameof(ReReadingTaskView.OriginalReReadingTask) + "." + nameof(ReReadingTaskView.OriginalReReadingTask.SubjectId), nameof(ReReadingTaskView.OriginalReReadingTask) + "." + nameof(ReReadingTaskView.OriginalReReadingTask.VisitTaskNum) }; + + var pageList = await visitTaskQueryable.ToPagedListAsync(inQuery, defalutSortArray); + + return pageList; + } + + + + /// + /// IR 待阅片任务列表 + /// + /// + [HttpPost] + public async Task>> GetIRUnReadSubjectTaskList(IRUnReadSubjectQuery inQuery) + { + + var trialId = inQuery.TrialId; + var subjectCode = inQuery.SubjectCode; + + var trialReadingCriterionId = inQuery.TrialReadingCriterionId; + + var criterionConfig = await _trialReadingCriterionRepository.Where(x => x.Id == inQuery.TrialReadingCriterionId).FirstNotNullAsync(); + + var readingTool = criterionConfig.ReadingTool; + var isReadingTaskViewInOrder = criterionConfig.IsReadingTaskViewInOrder; + + + var result = new PageOutput() { - await _visitTaskRepository.UpdatePartialFromQueryAsync(inDto.VisitTaskId, x => new VisitTask() - { - IsUrgent = inDto.IsUrgent, - TaskUrgentType = inDto.TaskUrgentType, - TaskUrgentRemake = inDto.TaskUrgentRemake, + PageSize = inQuery.PageSize, + PageIndex = inQuery.PageIndex, + TotalCount = 0, + CurrentPageData = null, + }; + IRUnReadOutDto iRUnReadOut = new IRUnReadOutDto(); + + //subject 级别 有序 无序查询 + if (isReadingTaskViewInOrder == ReadingOrder.InOrder || isReadingTaskViewInOrder == ReadingOrder.SubjectRandom) + { + result = await GetSubjectReadingIQueryable(new GetReadingIQueryableInDto() + { + TrialId = trialId, + TrialReadingCriterionId = trialReadingCriterionId, + SubjectCode = inQuery.SubjectCode, + + PageIndex = inQuery.PageIndex, + PageSize = inQuery.PageSize, + Asc = inQuery.Asc, + SortField = inQuery.SortField, }); - - return await _visitTaskRepository.SaveChangesAsync(); + + } + //随机阅片 + else + { + var taskQuery = _visitTaskRepository.Where(x => x.TrialId == inQuery.TrialId && x.DoctorUserId == _userInfo.Id && x.TaskState == TaskState.Effect && x.TrialReadingCriterionId == trialReadingCriterionId) + .Where(x => !x.Subject.IsDeleted).Where(x => (x.IsNeedClinicalDataSign && x.IsClinicalDataSign) || !x.IsNeedClinicalDataSign); + + iRUnReadOut = new IRUnReadOutDto() + { + FinishJudgeTaskCount = await taskQuery.Where(x => x.ReadingCategory == ReadingCategory.Judge && x.ReadingTaskState == ReadingTaskState.HaveSigned).CountAsync(), + FinishTaskCount = await taskQuery.Where(x => x.ReadingCategory != ReadingCategory.Judge && x.ReadingTaskState == ReadingTaskState.HaveSigned).CountAsync(), + SuggesteFinishedTime = await taskQuery.Where(x => x.ReadingTaskState != ReadingTaskState.HaveSigned).MaxAsync(x => x.SuggesteFinishedTime), + UnReadJudgeTaskCount = await taskQuery.Where(x => x.ReadingCategory == ReadingCategory.Judge && x.ReadingTaskState != ReadingTaskState.HaveSigned).CountAsync(), + UnReadTaskCount = await taskQuery.Where(x => x.ReadingCategory != ReadingCategory.Judge && x.ReadingTaskState != ReadingTaskState.HaveSigned).CountAsync(), + }; } - public async Task> GetTrialCriterionList(Guid trialId, bool isHaveSigned = true, bool? isAutoCreate = null) + return ResponseOutput.Ok(result, new { - var list = await _readingQuestionCriterionTrialRepository.Where(t => t.TrialId == trialId && t.IsConfirm) + IsReadingTaskViewInOrder = isReadingTaskViewInOrder, + RandomReadInfo = iRUnReadOut, + ReadingTool = readingTool, + IseCRFShowInDicomReading = criterionConfig.IseCRFShowInDicomReading, + IsReadingShowSubjectInfo = criterionConfig.IsReadingShowSubjectInfo, + IsReadingShowPreviousResults = criterionConfig.IsReadingShowPreviousResults, + DigitPlaces = criterionConfig.DigitPlaces, + CriterionType = criterionConfig.CriterionType, + }); - .OrderBy(t => t.ShowOrder) - .Select(t => new TrialReadingCriterionDto() + + } + + /// + /// 获取subject有序 或者无序阅片IQuery对象 + /// + /// + /// + public async Task> GetSubjectReadingIQueryable(GetReadingIQueryableInDto inQuery) + { + var trialReadingCriterionId = inQuery.TrialReadingCriterionId; + var subjectCode = inQuery.SubjectCode; + var trialId = inQuery.TrialId; + var subjectId = inQuery.SubjectId; + + var critrion = await _trialReadingCriterionRepository.FindAsync(trialReadingCriterionId); + + if (critrion.IsReadingTaskViewInOrder == ReadingOrder.InOrder) + { + var visitQuery = _visitTaskRepository.Where(x => x.TrialId == inQuery.TrialId && x.DoctorUserId == _userInfo.Id && x.TaskState == TaskState.Effect) + + .WhereIf(inQuery.SubjectId != null, x => x.SubjectId == inQuery.SubjectId) + //前序 不存在 未生成任务的访视 + .WhereIf(critrion.IsAutoCreate == false, t => !t.Subject.SubjectCriteriaEvaluationVisitFilterList.Where(t => t.TrialReadingCriterionId == trialReadingCriterionId).Any(f => f.IsGeneratedTask == false && t.VisitTaskNum > f.SubjectVisit.VisitNum)) + + // 前序 不存在 未一致性核查未通过的 + .Where(t => !t.Subject.SubjectVisitList.Any(sv => sv.CheckState != CheckStateEnum.CVPassed && t.VisitTaskNum >= sv.VisitNum)) + //.WhereIf(critrion.IsAutoCreate == false, t => t.Subject.SubjectCriteriaEvaluationVisitFilterList.Where(t => t.TrialReadingCriterionId == trialReadingCriterionId).Any(t => t.IsGeneratedTask == false) ? + //t.VisitTaskNum <= t.Subject.SubjectCriteriaEvaluationVisitFilterList.Where(t => t.TrialReadingCriterionId == trialReadingCriterionId && t.IsGeneratedTask == false).Min(t => t.SubjectVisit.VisitNum) : true) + //.Where(t => t.Subject.SubjectVisitList.Any(t => t.CheckState != CheckStateEnum.CVPassed) ? t.VisitTaskNum <= t.Subject.SubjectVisitList.Where(t => t.CheckState != CheckStateEnum.CVPassed).Min(t => t.VisitNum) : true) + //满足前序访视不存在 需要签署但是未签署 sql 相当复杂 同时想查询所有未读的统计数字 就无法统计 byzhouhang + //但是加字段 IsFrontTaskNeedSignButNotSign 那么签名临床数据的时候,要对该subject 该标准的有效的任务 这个字段需要在签名的时候维护 采取这种方式 统计数字灵活 + //.Where(t => t.Subject.SubjectVisitTaskList.AsQueryable().Where(visitTaskLambda).Any(c => c.IsNeedClinicalDataSign == true && c.IsClinicalDataSign == false && c.VisitTaskNum < t.VisitTaskNum)) + .WhereIf(!string.IsNullOrEmpty(inQuery.SubjectCode), t => (t.Subject.Code.Contains(inQuery.SubjectCode!) && t.IsAnalysisCreate == false) || (t.BlindSubjectCode.Contains(inQuery.SubjectCode!) && t.IsAnalysisCreate)); + + + var visitGroupQuery = visitQuery.GroupBy(x => new { x.SubjectId, x.Subject.Code, x.BlindSubjectCode }); + + var visitTaskQuery = visitGroupQuery.Select(x => new IRUnReadSubjectView() + { + SubjectId = x.Key.SubjectId, + SubjectCode = x.Key.BlindSubjectCode == string.Empty ? x.Key.Code : x.Key.BlindSubjectCode, + + SuggesteFinishedTime = x.Where(y => y.TrialReadingCriterionId == trialReadingCriterionId && y.ReadingTaskState != ReadingTaskState.HaveSigned).Min(x => x.SuggesteFinishedTime), + + //未读任务量 + UnReadTaskCount = x.Where(y => y.TrialReadingCriterionId == trialReadingCriterionId && y.ReadingTaskState != ReadingTaskState.HaveSigned).Count(), + + //未读 里可读任务量 + UnReadCanReadTaskCount = x.Where(y => y.TrialReadingCriterionId == trialReadingCriterionId && y.ReadingTaskState != ReadingTaskState.HaveSigned && y.IsFrontTaskNeedSignButNotSign == false && (y.IsNeedClinicalDataSign == false || y.IsClinicalDataSign == true) + //不能对包含聚合或子查询的表达式执行聚合函数 + //&& !x.Any(t => t.ReadingTaskState != ReadingTaskState.HaveSigned && t.IsNeedClinicalDataSign == true && t.IsClinicalDataSign == false && t.VisitTaskNum y.TrialReadingCriterionId == trialReadingCriterionId && y.ReadingTaskState != ReadingTaskState.HaveSigned) + .Where(y => y.IsFrontTaskNeedSignButNotSign == false && (y.IsNeedClinicalDataSign == false || y.IsClinicalDataSign == true)) + .OrderBy(x => x.VisitTaskNum) + .Select(u => new IRUnreadTaskView() { - TrialReadingCriterionId = t.Id, - IsAutoCreate = t.IsAutoCreate, - IsAdditionalAssessment = t.IsAdditionalAssessment, - TrialReadingCriterionName = t.CriterionName, - CriterionType = t.CriterionType, - ReadingType = t.ReadingType, - ReadingInfoSignTime = t.ReadingInfoSignTime, - IsReadingPeriod = t.IsReadingPeriod, - IsArbitrationReading = t.IsArbitrationReading, - IsGlobalReading = t.IsGlobalReading, - IsOncologyReading = t.IsOncologyReading, - ImageDownloadEnum = t.ImageDownloadEnum, - ImageUploadEnum = t.ImageUploadEnum, - IsReadingTaskViewInOrder = t.IsReadingTaskViewInOrder + Id = u.Id, + IsUrgent = u.IsUrgent, + VisitNum = u.VisitTaskNum, + TaskBlindName = u.TaskBlindName, + VisistId = u.SourceSubjectVisitId, + SuggesteFinishedTime = u.SuggesteFinishedTime, + ReadingCategory = u.ReadingCategory, + IsAnalysisCreate = u.IsAnalysisCreate, + ArmEnum = u.ArmEnum, + TrialReadingCriterionId = u.TrialReadingCriterionId, + IsNeedClinicalDataSign = u.IsNeedClinicalDataSign, + IsClinicalDataSign = u.IsClinicalDataSign, + IsFrontTaskNeedSignButNotSign = u.IsFrontTaskNeedSignButNotSign }) - .ToListAsync(); - - //if (list.Count == 0) - //{ - // //---该项目还未确认任何一个阅片标准 - // throw new BusinessValidationFailedException(_localizer["VisitTask_VisitTask_TaskAlreadyApplied"]); - - //} + .ToList(), - return list.AsQueryable().WhereIf(isHaveSigned == true, t => t.ReadingInfoSignTime != null) - .WhereIf(isAutoCreate == false, t => t.IsAutoCreate == isAutoCreate).ToList(); - } + UrgentCount = x.Where(y => y.TrialReadingCriterionId == trialReadingCriterionId && y.ReadingTaskState != ReadingTaskState.HaveSigned) + .Where(y => y.IsFrontTaskNeedSignButNotSign == false && (y.IsNeedClinicalDataSign == false || y.IsClinicalDataSign == true)) + .Where(x => x.IsUrgent).Count(), + //已读任务量 + HaveReadTaskCount = x.Where(y => y.TrialReadingCriterionId == trialReadingCriterionId && y.ReadingTaskState == ReadingTaskState.HaveSigned).Count(), + ExistReadingApply = x.Any(y => (y.ReReadingApplyState == ReReadingApplyState.DocotorHaveApplyed && y.TrialReadingCriterionId == trialReadingCriterionId) || y.ReReadingApplyState == ReReadingApplyState.TrialGroupHaveApplyed), - - /// - /// Subject 任务类型 统计 +分配情况 - /// - /// - [HttpPost] - public async Task>> GetSubjectAssignAndTaskStatList(SubjectAssignStatQuery inQuery) - { - - var isAddtinoarlCriterion = await _trialReadingCriterionRepository.AnyAsync(t => t.Id == inQuery.TrialReadingCriterionId && t.IsAutoCreate == false); - - var subjectQuery = _subjectRepository.Where(t => t.TrialId == inQuery.TrialId && t.SubjectVisitTaskList.Any()) - .WhereIf(inQuery.TrialSiteId != null, t => t.TrialSiteId == inQuery.TrialSiteId) - .WhereIf(inQuery.SubjectId != null, t => t.Id == inQuery.SubjectId) - .WhereIf(inQuery.DoctorUserId != null, t => t.SubjectDoctorList.Any(t => t.DoctorUserId == inQuery.DoctorUserId && t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId)) - .WhereIf(!string.IsNullOrEmpty(inQuery.SubjectCode), t => t.Code.Contains(inQuery.SubjectCode)) - //未分配 - .WhereIf(inQuery.SubjectAllocateState == 0, t => !t.SubjectDoctorList.Any(t => t.AssignTime != null && t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId)) - //已分配 - .WhereIf(inQuery.SubjectAllocateState == 1, t => t.SubjectDoctorList.Any(t => t.AssignTime != null && t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId)) - - .WhereIf(inQuery.ArmList.Count > 0, t => !inQuery.ArmList.Except(t.SubjectDoctorList.Where(t => t.AssignTime != null && t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId).Select(c => c.ArmEnum)).Any()) - - - .WhereIf(isAddtinoarlCriterion, t => t.SubjectCriteriaEvaluationList.Where(t => t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId).Any(t => t.IsJoinEvaluation)) - - - .ProjectTo(_mapper.ConfigurationProvider, new { trialReadingCriterionId = inQuery.TrialReadingCriterionId }); - - - var pageList = await subjectQuery.ToPagedListAsync(inQuery,nameof(SubjectAssignStat.SubjectId)); - - - - var criterionConfig = (await _trialReadingCriterionRepository.Where(x => x.Id == inQuery.TrialReadingCriterionId).Select(x => new { x.ReadingTool, x.IsReadingTaskViewInOrder, x.ReadingType, x.IsArbitrationReading, x.IsOncologyReading, x.IsGlobalReading }).FirstOrDefaultAsync()).IfNullThrowException(); - - return ResponseOutput.Ok(pageList, criterionConfig); - } - - /// - /// 一次性分配所有医生 批量分配(添加),后端现在没限制 - /// - /// - /// - [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })] - public async Task BatchAssignDoctorToSubject(BatchAssignDoctorToSubjectCommand command) - { - //var inOrder = _trialRepository.Where(t => t.Id == command.TrialId).Select(t => t.IsReadingTaskViewInOrder).FirstOrDefault(); - - //var inOrder = _trialReadingCriterionRepository.Where(t => t.Id == command.TrialReadingCriterionId).Select(t => t.IsReadingTaskViewInOrder).FirstOrDefault(); - - - foreach (var subjectId in command.SubjectIdList) - { - foreach (var doctorArm in command.DoctorArmList) + //查出所有未读的 未读的可读的 在这个列表基础上 过滤下 y.IsFrontTaskNeedSignButNotSign==false && (y.IsNeedClinicalDataSign == false || y.IsClinicalDataSign == true) 这样容易排错 确认这三个字段是否维护有误 + UnReadTaskList = x.Where(y => y.TrialReadingCriterionId == trialReadingCriterionId && y.ReadingTaskState != ReadingTaskState.HaveSigned).OrderBy(x => x.VisitTaskNum) + .Select(u => new IRUnreadTaskView() { - if (!await _subjectUserRepository.Where(t => t.TrialReadingCriterionId == command.TrialReadingCriterionId).AnyAsync(t => t.SubjectId == subjectId && t.DoctorUserId == doctorArm.DoctorUserId && t.ArmEnum == doctorArm.ArmEnum && t.IsConfirmed && t.ReplacedSubjectUserId == null)) - { - await _subjectUserRepository.AddAsync(new SubjectUser() { TrialId = command.TrialId, TrialReadingCriterionId = command.TrialReadingCriterionId, ArmEnum = doctorArm.ArmEnum, DoctorUserId = doctorArm.DoctorUserId, SubjectId = subjectId, AssignTime = DateTime.Now }); + Id = u.Id, + IsUrgent = u.IsUrgent, + VisitNum = u.VisitTaskNum, + TaskBlindName = u.TaskBlindName, + VisistId = u.SourceSubjectVisitId, + SuggesteFinishedTime = u.SuggesteFinishedTime, + ReadingCategory = u.ReadingCategory, + IsAnalysisCreate = u.IsAnalysisCreate, + ArmEnum = u.ArmEnum, + TrialReadingCriterionId = u.TrialReadingCriterionId, + IsNeedClinicalDataSign = u.IsNeedClinicalDataSign, + IsClinicalDataSign = u.IsClinicalDataSign, + IsFrontTaskNeedSignButNotSign = u.IsFrontTaskNeedSignButNotSign + }) + .ToList(), + }).Where(x => x.UnReadCanReadTaskCount > 0)/*.OrderBy(x => x.UnReadCanReadTaskCount)*/; + // 有序阅片需要找到最小需要 - //task.SuggesteFinishedTime = task.IsUrgent ? DateTime.Now.AddDays(2) : DateTime.Now.AddDays(7); - } + // 不这样写会有问题 + var count = visitQuery.Where(y => y.TrialReadingCriterionId == trialReadingCriterionId && y.ReadingTaskState != ReadingTaskState.HaveSigned && y.IsFrontTaskNeedSignButNotSign == false && (y.IsNeedClinicalDataSign == false || y.IsClinicalDataSign == true)) + .GroupBy(x => new { x.SubjectId, x.Subject.Code, x.BlindSubjectCode }).Count(); + var result = new List(); - Expression> updateWhere = t => t.TrialReadingCriterionId == command.TrialReadingCriterionId && t.SubjectId == subjectId && t.ArmEnum == doctorArm.ArmEnum && t.TrialId == command.TrialId && t.TaskAllocationState == TaskAllocationState.NotAllocate && t.TaskState == TaskState.Effect && t.IsAnalysisCreate == false; + var propName = string.IsNullOrWhiteSpace(inQuery!.SortField) ? nameof(IRUnReadSubjectView.UnReadCanReadTaskCount) : inQuery.SortField; - //if (inOrder) - //{ - // //针对有序阅片 只分配< 最小的 不是一致性核查通过状态 和不是失访 的访视 的任务 - // if (await _subjectVisitRepository.AnyAsync(t => t.SubjectId == subjectId && t.CheckState != CheckStateEnum.CVPassed && t.IsLostVisit == false)) - // { - // var notCheckPassedMinVisitNum = await _subjectVisitRepository.Where(t => t.SubjectId == subjectId && t.CheckState != CheckStateEnum.CVPassed).OrderBy(t => t.VisitNum).Select(t => t.VisitNum).FirstOrDefaultAsync(); + var visitTaskOrderQuery = inQuery.Asc ? visitTaskQuery.OrderBy(propName) : visitTaskQuery.OrderBy(propName + " desc"); - // updateWhere = updateWhere.And(t => t.VisitTaskNum < notCheckPassedMinVisitNum); - // } - //} + result = await visitTaskOrderQuery + .Skip((inQuery.PageIndex - 1) * inQuery.PageSize) + .Take(inQuery.PageSize).ToListAsync(); - await _visitTaskRepository - .UpdatePartialFromQueryAsync(updateWhere, - u => new VisitTask() - { - AllocateTime = DateTime.Now, - DoctorUserId = doctorArm.DoctorUserId, - TaskAllocationState = TaskAllocationState.Allocated, - - SuggesteFinishedTime = GetSuggessFinishTime(true, UrgentType.NotUrget), - }); - } - } - - await _subjectUserRepository.SaveChangesAsync(); - - - - - - return ResponseOutput.Ok(); - } - - - - /// - /// 阅片人维度 Subject统计表 - /// - /// - /// - /// - public async Task<(List, object)> GetDoctorSubjectStat(Guid trialId, Guid trialReadingCriterionId) - { - var list = await _taskAllocationRuleRepository.Where(t => t.TrialId == trialId) - .Where(t => t.Enroll.EnrollReadingCategoryList.Any(t => t.TrialReadingCriterionId == trialReadingCriterionId)) - .ProjectTo(_mapper.ConfigurationProvider, new { trialReadingCriterionId = trialReadingCriterionId }).ToListAsync(); - - var criterionConfig = (await _trialReadingCriterionRepository.Where(x => x.Id == trialReadingCriterionId).Select(x => new { x.ReadingTool, x.IsReadingTaskViewInOrder, x.ReadingType, x.IsArbitrationReading, x.IsOncologyReading }).FirstOrDefaultAsync()).IfNullThrowException(); - - return (list, criterionConfig); - } - - - /// - /// 获取Subject 分配医生情况 - /// - /// - /// - /// - public async Task<(List, object)> GetSubjectAssignedDoctorList(Guid subjectId, Guid trialReadingCriterionId) - { - var list = await _subjectUserRepository.Where(t => t.SubjectId == subjectId && t.ReplacedSubjectUserId == null && t.IsConfirmed && t.TrialReadingCriterionId == trialReadingCriterionId).ProjectTo(_mapper.ConfigurationProvider).ToListAsync(); - - var criterionConfig = (await _trialReadingCriterionRepository.Where(x => x.Id == trialReadingCriterionId).Select(x => new { x.ReadingTool, x.IsReadingTaskViewInOrder, x.ReadingType, x.IsGlobalReading, x.IsOncologyReading, x.IsArbitrationReading }).FirstOrDefaultAsync()).IfNullThrowException(); - - return (list, criterionConfig); - } - - - /// - /// 取消Subject 分配的医生 - /// - /// - /// - /// - [HttpPost] - [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })] - public async Task CancelSubjectAssignedDoctor(CancelSubjectDoctorCommand cancelCommand) - { - foreach (var command in cancelCommand.CancelList.Where(t => t.IsCancelAssign)) - { - if (await _visitTaskRepository.AnyAsync(t => t.TaskState == TaskState.Effect && t.TrialReadingCriterionId == cancelCommand.TrialReadingCriterionId && t.SubjectId == command.SubjectId && t.DoctorUserId == command.DoctorUserId && t.ArmEnum == command.ArmEnum && t.ReadingTaskState != ReadingTaskState.WaitReading)) - { - //---当前医生已开始做该Subject 该标准的任务,不允许取消分配 - throw new BusinessValidationFailedException(_localizer["VisitTask_DoctorConfigNotFound"]); - } - - await _subjectUserRepository.DeleteFromQueryAsync(t => t.Id == command.Id); - - await _visitTaskRepository.UpdatePartialFromQueryAsync(t => t.TrialReadingCriterionId == cancelCommand.TrialReadingCriterionId && t.SubjectId == command.SubjectId && t.DoctorUserId == command.DoctorUserId && t.ArmEnum == command.ArmEnum && t.ReadingTaskState == ReadingTaskState.WaitReading && t.TaskState == TaskState.Effect && t.IsAnalysisCreate == false, u => new VisitTask() - { - AllocateTime = null, - DoctorUserId = null, - TaskAllocationState = TaskAllocationState.NotAllocate, - SuggesteFinishedTime = null - }); - } - - var subjectId = cancelCommand.CancelList.First().SubjectId; - - await _subjectCanceDoctorRepository.AddAsync(new SubjectCanceDoctor() { SubjectId = subjectId, Note = cancelCommand.Note, TrialReadingCriterionId = cancelCommand.TrialReadingCriterionId }); - - await _visitTaskRepository.SaveChangesAsync(); - - return ResponseOutput.Ok(); - } - - - - - /// - /// 任务 手动分配 重新分配 确认 取消分配 - /// 分配 - /// - /// - [HttpPost] - [UnitOfWork] - [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })] - public async Task AssignSubjectTaskToDoctor(AssignSubjectTaskToDoctorCommand assignSubjectTaskToDoctorCommand) - { - var visitTask = await _visitTaskRepository.FirstOrDefaultAsync(t => t.Id == assignSubjectTaskToDoctorCommand.Id); - - if (assignSubjectTaskToDoctorCommand.TaskOptType == TaskOptType.Assign || assignSubjectTaskToDoctorCommand.TaskOptType == TaskOptType.ReAssign) - { - //手动分配验证规则 - - if (visitTask.SourceSubjectVisitId != null) - { - - if (await _visitTaskRepository.AnyAsync(t => t.SourceSubjectVisitId == visitTask.SourceSubjectVisitId && t.TaskAllocationState == TaskAllocationState.Allocated && t.DoctorUserId == assignSubjectTaskToDoctorCommand.DoctorUserId && t.Id != visitTask.Id)) - { - //---其中一个任务已分配给该医生,不允许分配 - return ResponseOutput.NotOk(_localizer["VisitTask_BackendDataError"]); - } - } - else if (visitTask.SouceReadModuleId != null) - { - if (await _visitTaskRepository.AnyAsync(t => t.SouceReadModuleId == visitTask.SouceReadModuleId && t.TaskAllocationState == TaskAllocationState.Allocated && t.DoctorUserId == assignSubjectTaskToDoctorCommand.DoctorUserId && t.Id != visitTask.Id)) - { - //---其中一个任务已分配给该医生,不允许分配 - return ResponseOutput.NotOk(_localizer["VisitTask_BackendDataError"]); - } - } - else - { - //---出现脏数据 任务来源字段没有值 - throw new BusinessValidationFailedException(_localizer["VisitTask_DirtyData"]); - } - - //PM 回退了 但是还没生成任务 当前任务编号前有访视进行了回退就不允许分配 - if (await _subjectVisitRepository.AnyAsync(t => t.SubjectId == visitTask.SubjectId && t.IsPMBackOrReReading && t.VisitNum <= visitTask.VisitTaskNum)) - { - //---该受试者有访视进入了退回流程,还未经过一致性核查通过,不允许分配 - return ResponseOutput.NotOk(_localizer["VisitTask_MissingTaskSource"]); - } - - - visitTask.AllocateTime = DateTime.Now; - visitTask.DoctorUserId = assignSubjectTaskToDoctorCommand.DoctorUserId; - visitTask.TaskAllocationState = TaskAllocationState.Allocated; - - visitTask.SuggesteFinishedTime = GetSuggessFinishTime(true, UrgentType.NotUrget); - - - - //await _subjectVisitRepository.BatchUpdateNoTrackingAsync(t => t.Id == visitTask.SourceSubjectVisitId, u => new SubjectVisit() { ReadingStatus = ReadingStatusEnum.ImageReading }); - - //await _readModuleRepository.BatchUpdateNoTrackingAsync(t => t.Id == visitTask.SouceReadModuleId, u => new ReadModule() { ReadingStatus = ReadingStatusEnum.ImageReading }); - } - - else if (assignSubjectTaskToDoctorCommand.TaskOptType == TaskOptType.ReAssign) - { - //验证 是不是两个任务都给了同一个医生 - - - - //是否删除配置规则表里的 Subject 医生绑定关系 重新添加绑定关系 - - //是否其该Subject 其他访视 绑定的医生 也同时变更? - - - } - - else if (assignSubjectTaskToDoctorCommand.TaskOptType == TaskOptType.Confirm) - { - visitTask.TaskAllocationState = TaskAllocationState.Allocated; - } - else if (assignSubjectTaskToDoctorCommand.TaskOptType == TaskOptType.CancelAssign) - { - visitTask.AllocateTime = null; - visitTask.DoctorUserId = null; - visitTask.TaskAllocationState = TaskAllocationState.NotAllocate; - - //await _subjectVisitRepository.BatchUpdateNoTrackingAsync(t => t.Id == visitTask.SourceSubjectVisitId, u => new SubjectVisit() { ReadingStatus = ReadingStatusEnum.TaskAllocate }); - - //await _readModuleRepository.BatchUpdateNoTrackingAsync(t => t.Id == visitTask.SouceReadModuleId, u => new ReadModule() { ReadingStatus = ReadingStatusEnum.TaskAllocate }); - } - await _visitTaskRepository.SaveChangesAsync(); - return ResponseOutput.Ok(); - } - - - - - /// - /// 获取手动分配 未分配的Subject列表(IsHaveAssigned 传递false) - /// - /// - [HttpPost] - public async Task> GetSubjectAssignList(SubjectAssignQuery inQuery) - { - var subjectQuery = _subjectRepository.Where(t => t.TrialId == inQuery.TrialId) - .WhereIf(inQuery.IsJudgeDoctor == false, t => t.SubjectVisitTaskList.Where(t => t.ArmEnum != Arm.JudgeArm).Any()) - .WhereIf(inQuery.IsJudgeDoctor, t => t.SubjectVisitTaskList.Where(t => t.ArmEnum == Arm.JudgeArm).Any()) - - .WhereIf(inQuery.TrialSiteId != null, t => t.TrialSiteId == inQuery.TrialSiteId) - .WhereIf(inQuery.SubjectId != null, t => t.Id == inQuery.SubjectId) - - .WhereIf(inQuery.IsHaveAssigned != null && inQuery.IsHaveAssigned == true && inQuery.IsJudgeDoctor == false, t => t.SubjectDoctorList.Where(t => t.ArmEnum != Arm.JudgeArm).Any()) - .WhereIf(inQuery.IsHaveAssigned != null && inQuery.IsHaveAssigned == true && inQuery.IsJudgeDoctor, t => t.SubjectDoctorList.Where(t => t.ArmEnum == Arm.JudgeArm).Any()) - .WhereIf(inQuery.IsHaveAssigned != null && inQuery.IsHaveAssigned == false && inQuery.IsJudgeDoctor == false, t => !t.SubjectDoctorList.Where(t => t.ArmEnum != Arm.JudgeArm).Any()) - .WhereIf(inQuery.IsHaveAssigned != null && inQuery.IsHaveAssigned == false && inQuery.IsJudgeDoctor, t => !t.SubjectDoctorList.Where(t => t.ArmEnum == Arm.JudgeArm).Any()) - - - .WhereIf(inQuery.IsAssignConfirmed != null && inQuery.IsAssignConfirmed == true && inQuery.IsJudgeDoctor == false, t => t.SubjectDoctorList.Where(t => t.ArmEnum != Arm.JudgeArm).All(u => u.IsConfirmed)) - .WhereIf(inQuery.IsAssignConfirmed != null && inQuery.IsAssignConfirmed == true && inQuery.IsJudgeDoctor, t => t.SubjectDoctorList.Where(t => t.ArmEnum == Arm.JudgeArm).All(u => u.IsConfirmed)) - - .WhereIf(inQuery.IsAssignConfirmed != null && inQuery.IsAssignConfirmed == false && inQuery.IsJudgeDoctor == false, t => t.SubjectDoctorList.Where(t => t.ArmEnum != Arm.JudgeArm).Any(u => u.IsConfirmed == false)) - .WhereIf(inQuery.IsAssignConfirmed != null && inQuery.IsAssignConfirmed == false && inQuery.IsJudgeDoctor, t => t.SubjectDoctorList.Where(t => t.ArmEnum == Arm.JudgeArm).Any(u => u.IsConfirmed == false)) - - .WhereIf(inQuery.DoctorUserId != null && inQuery.IsJudgeDoctor == false, t => t.SubjectDoctorList.Where(t => t.ArmEnum != Arm.JudgeArm).Any(t => t.DoctorUserId == inQuery.DoctorUserId)) - .WhereIf(inQuery.DoctorUserId != null && inQuery.IsJudgeDoctor, t => t.SubjectDoctorList.Where(t => t.ArmEnum == Arm.JudgeArm).Any(t => t.DoctorUserId == inQuery.DoctorUserId)) - .ProjectTo(_mapper.ConfigurationProvider, new { isJudgeDoctor = inQuery.IsJudgeDoctor }); - - var pageList = await subjectQuery.ToPagedListAsync(inQuery); - - return pageList; - } - - - /// - /// 批量为 多个Subject 分配医生 手动分配 IsReAssign 为true 批量删除 重新分配 - /// - /// - /// - [HttpPost] - [UnitOfWork] - [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })] - public async Task AssignSubjectDoctor(AssginSubjectDoctorCommand assginSubjectDoctorCommand) - { - var trialId = assginSubjectDoctorCommand.TrialId; - var doctorUserIdList = assginSubjectDoctorCommand.DoctorUserIdArmList.Select(t => t.DoctorUserId).ToList(); - - if (assginSubjectDoctorCommand.IsJudgeDoctor) - { - if (assginSubjectDoctorCommand.IsReAssign) - { - - //if (await _visitTaskRepository.AnyAsync(t => assginSubjectDoctorCommand.SubjectIdList.Contains(t.SubjectId) && t.DoctorUserId != null && t.ArmEnum == Arm.JudgeArm)) - //{ - // throw new BusinessValidationFailedException("有Subject任务已应用,不允许重新分配"); - //} - - - await _subjectUserRepository.BatchDeleteNoTrackingAsync(t => doctorUserIdList.Contains(t.DoctorUserId) && assginSubjectDoctorCommand.SubjectIdList.Contains(t.SubjectId) && t.ArmEnum == Arm.JudgeArm); - } - - - } - else - { - if (assginSubjectDoctorCommand.IsReAssign) - { - - //if (await _visitTaskRepository.AnyAsync(t => assginSubjectDoctorCommand.SubjectIdList.Contains(t.SubjectId) && t.DoctorUserId != null && t.ArmEnum != Arm.JudgeArm)) - //{ - // throw new BusinessValidationFailedException("有Subject任务已应用,不允许重新分配"); - //} - - - await _subjectUserRepository.BatchDeleteNoTrackingAsync(t => doctorUserIdList.Contains(t.DoctorUserId) && assginSubjectDoctorCommand.SubjectIdList.Contains(t.SubjectId) && t.ArmEnum != Arm.JudgeArm); - } - - - - } - foreach (var subjectId in assginSubjectDoctorCommand.SubjectIdList) - { - foreach (var doctorUserId in doctorUserIdList) - { - - var armEnum = assginSubjectDoctorCommand.DoctorUserIdArmList.Where(t => t.DoctorUserId == doctorUserId).First().ArmEnum; - - - if (await _subjectUserRepository.AnyAsync(t => t.TrialId == trialId && t.SubjectId == subjectId && t.DoctorUserId == doctorUserId && t.ArmEnum != armEnum && t.ReplacedSubjectUserId == null)) - { - //---有Subject 在其他Arm组已有该医生,不允许在新的组添加该医生 - throw new BusinessValidationFailedException(_localizer["VisitTask_InconsistentSubjectStatus"]); - } - - if (await _subjectUserRepository.AnyAsync(t => t.TrialId == trialId && t.SubjectId == subjectId && t.DoctorUserId == doctorUserId && t.ArmEnum == armEnum && t.ReplacedSubjectUserId == null)) - { - //---有Subject 已有该Arm组的医生,不允许继续分配,请刷新页面,确认页面数据是否过期 - throw new BusinessValidationFailedException(_localizer["VisitTask_DuplicateDoctorInArm"]); - } - else - { - await _subjectUserRepository.AddAsync(new SubjectUser() { TrialId = trialId, SubjectId = subjectId, DoctorUserId = doctorUserId, ArmEnum = armEnum, AssignTime = DateTime.Now }); - - } - - } - - } - - - await _subjectUserRepository.SaveChangesAsync(); - - return ResponseOutput.Ok(); - } - - /// - /// 批量取消Subject 分配的医生 - /// - /// 数量 - [HttpPost] - [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })] - public async Task CancelSubjectAssignDoctor(CancelSubjectAssignCommand cancelSubjectAssignCommand) - { - if (cancelSubjectAssignCommand.IsJudgeDoctor) - { - foreach (var subjectId in cancelSubjectAssignCommand.SubjectIdList) - { - if (await _visitTaskRepository.AnyAsync(t => t.SubjectId == subjectId && t.DoctorUserId != null && t.ArmEnum == Arm.JudgeArm)) - { - //---有Subject任务已应用,不允许取消分配 - throw new BusinessValidationFailedException(_localizer["VisitTask_DoctorAlreadyInArm"]); - } - - await _subjectUserRepository.DeleteFromQueryAsync(t => t.SubjectId == subjectId && t.ArmEnum == Arm.JudgeArm); - } - } - else - { - foreach (var subjectId in cancelSubjectAssignCommand.SubjectIdList) - { - if (await _visitTaskRepository.AnyAsync(t => t.SubjectId == subjectId && t.DoctorUserId != null && t.ArmEnum != Arm.JudgeArm)) - { - //---有Subject任务已应用,不允许取消分配 - throw new BusinessValidationFailedException(_localizer["VisitTask_DoctorAlreadyInArm"]); - } - - await _subjectUserRepository.DeleteFromQueryAsync(t => t.SubjectId == subjectId && t.ArmEnum != Arm.JudgeArm); - } - } - - await _subjectUserRepository.SaveChangesAsync(); - - return ResponseOutput.Ok(); - } - - - /// - /// 手动分配确认 绑定该Subject的已存在的任务给医生 - /// - /// - /// - [HttpPost] - [UnitOfWork] - [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })] - public async Task ManualAssignDoctorApplyTask(AssignConfirmCommand assignConfirmCommand) - { - var trialId = assignConfirmCommand.TrialId; - - //获取项目配置 判断应该分配几个医生 - //var trialConfig = (await _trialRepository.Where(t => t.Id == trialId).Select(t => new { TrialId = t.Id, t.ReadingType, t.IsFollowVisitAutoAssign, t.IsFollowGlobalVisitAutoAssign, t.FollowGlobalVisitAutoAssignDefaultState, t.TaskAllocateObjEnum }).FirstOrDefaultAsync()).IfNullThrowException(); - - //需要确认的Subject - var subjectIdList = assignConfirmCommand.SubjectDoctorUserList.Select(t => t.SubjectId).ToList(); - - //将关系确认 - if (assignConfirmCommand.SubjectDoctorUserList.Count == 0) - { - await _subjectUserRepository.BatchUpdateNoTrackingAsync(t => t.TrialId == trialId && t.IsConfirmed == false && t.ReplacedSubjectUserId == null, u => new SubjectUser() { IsConfirmed = true }); - } - else - { - await _subjectUserRepository.BatchUpdateNoTrackingAsync(t => t.TrialId == trialId && t.IsConfirmed == false && t.ReplacedSubjectUserId == null - && subjectIdList.Contains(t.SubjectId), u => new SubjectUser() { IsConfirmed = true }); - } - - - var taskList = _visitTaskRepository.Where(t => t.TrialId == assignConfirmCommand.TrialId && t.DoctorUserId == null, true) - .WhereIf(subjectIdList.Count > 0 && assignConfirmCommand.IsJudgeDoctor == false, t => subjectIdList.Contains(t.SubjectId) && t.Subject.SubjectDoctorList.Where(t => t.ArmEnum != Arm.JudgeArm).Any()) - .WhereIf(subjectIdList.Count > 0 && assignConfirmCommand.IsJudgeDoctor, t => subjectIdList.Contains(t.SubjectId) && t.Subject.SubjectDoctorList.Where(t => t.ArmEnum == Arm.JudgeArm).Any()) - //过滤掉 那些回退的subject - .Where(t => !t.Subject.SubjectVisitList.Any(t => t.IsPMBackOrReReading)) - - .ToList(); - - - foreach (var subjectTaskGroup in taskList.GroupBy(t => t.SubjectId)) - { - var subjectId = subjectTaskGroup.Key; - - - - //如果数据为空 那么就是确认所有已分配的 - List subjectDoctorIdArmList = new List(); - - if (assignConfirmCommand.SubjectDoctorUserList.Count == 0) - { - subjectDoctorIdArmList = _subjectUserRepository.Where(t => t.SubjectId == subjectId && t.ReplacedSubjectUserId == null).Select(t => new DoctorArm() { DoctorUserId = t.DoctorUserId, ArmEnum = t.ArmEnum }).ToList(); - } - else - { - subjectDoctorIdArmList = assignConfirmCommand.SubjectDoctorUserList.Where(t => t.SubjectId == subjectId).First().DoctorUserIdArmList; - } - - - foreach (var task in subjectTaskGroup.OrderBy(t => t.ArmEnum).ToList()) - { - - var subjectDoctorArm = subjectDoctorIdArmList.Where(t => t.ArmEnum == task.ArmEnum).FirstOrDefault(); - - if (subjectDoctorArm != null) - { - task.DoctorUserId = subjectDoctorArm.DoctorUserId; - task.AllocateTime = DateTime.Now; - task.TaskAllocationState = TaskAllocationState.Allocated; - - task.SuggesteFinishedTime = /*task.IsUrgent ? DateTime.Now.AddDays(2) : DateTime.Now.AddDays(7)*/ GetSuggessFinishTime(true, UrgentType.NotUrget); - - await _subjectVisitRepository.BatchUpdateNoTrackingAsync(t => t.Id == task.SourceSubjectVisitId, u => new SubjectVisit() { ReadingStatus = ReadingStatusEnum.ImageReading }); - - await _readModuleRepository.BatchUpdateNoTrackingAsync(t => t.Id == task.SouceReadModuleId, u => new ReadModule() { ReadingStatus = ReadingStatusEnum.ImageReading }); - - - } - else - { - //---在配置表中未找到配置的医生,无法应用绑定,请核对数据 - throw new BusinessValidationFailedException(_localizer["VisitTask_TaskAlreadyApplied"]); - } - - } - } - - - - await _visitTaskRepository.SaveChangesAsync(); - - return ResponseOutput.Ok(); - } - - - - /// - /// 访视任务 - /// - /// - /// - /// - [HttpPost] - public async Task> GetVisitTaskList(VisitTaskQuery inQuery, [FromServices] IVisitTaskHelpeService _visitTaskCommonService) - { - //以前访视未产生任务的,在查询这里要产生 - var svIdList = await _subjectVisitRepository.Where(t => t.TrialId == inQuery.TrialId && t.CheckState == CheckStateEnum.CVPassed && t.IsVisitTaskGenerated == false).Select(t => t.Id).ToListAsync(); - - //之前没有生成任务的逻辑 但是现在加了,任务要自动生成 - await _visitTaskCommonService.GenerateVisitTaskAsync(inQuery.TrialId, svIdList); - - - var visitTaskQueryable = _visitTaskRepository.Where(t => t.TrialId == inQuery.TrialId && t.IsAnalysisCreate == false) - .WhereIf(inQuery.ReadingCategory != null, t => t.ReadingCategory == inQuery.ReadingCategory) - .WhereIf(inQuery.ReadingCategory == null, t => t.ReadingCategory != ReadingCategory.Judge) - - .WhereIf(inQuery.TaskState != null, t => t.TaskState == inQuery.TaskState) - .WhereIf(inQuery.TrialSiteId != null, t => t.Subject.TrialSiteId == inQuery.TrialSiteId) - .WhereIf(inQuery.SubjectId != null, t => t.SubjectId == inQuery.SubjectId) - .WhereIf(inQuery.IsUrgent != null, t => t.IsUrgent == inQuery.IsUrgent) - .WhereIf(inQuery.DoctorUserId != null, t => t.DoctorUserId == inQuery.DoctorUserId) - .WhereIf(inQuery.ReadingCategory != null, t => t.ReadingCategory == inQuery.ReadingCategory) - .WhereIf(inQuery.TaskAllocationState != null, t => t.TaskAllocationState == inQuery.TaskAllocationState) - .WhereIf(inQuery.TrialReadingCriterionId != null, t => t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId) - - .WhereIf(!string.IsNullOrEmpty(inQuery.TrialSiteCode), t => (t.BlindTrialSiteCode.Contains(inQuery.TrialSiteCode!) && t.IsAnalysisCreate) || (t.Subject.TrialSite.TrialSiteCode.Contains(inQuery.TrialSiteCode!) && t.IsAnalysisCreate == false)) - .WhereIf(!string.IsNullOrEmpty(inQuery.TaskName), t => t.TaskName.Contains(inQuery.TaskName) || t.TaskBlindName.Contains(inQuery.TaskName)) - - .WhereIf(!string.IsNullOrEmpty(inQuery.SubjectCode), t => (t.Subject.Code.Contains(inQuery.SubjectCode) && t.IsAnalysisCreate == false) || (t.BlindSubjectCode.Contains(inQuery.SubjectCode) && t.IsAnalysisCreate)) - .WhereIf(inQuery.BeginAllocateDate != null, t => t.AllocateTime > inQuery.BeginAllocateDate) - .WhereIf(inQuery.EndAllocateDate != null, t => t.AllocateTime < inQuery.EndAllocateDate!.Value.AddDays(1)) - .ProjectTo(_mapper.ConfigurationProvider); - - var defalutSortArray = new string[] { nameof(VisitTaskView.IsUrgent) + " desc", nameof(VisitTaskView.SubjectCode), nameof(VisitTaskView.VisitTaskNum) }; - - var pageList = await visitTaskQueryable.ToPagedListAsync(inQuery, defalutSortArray); - - //var trialTaskConfig = _trialRepository.Where(t => t.Id == queryVisitTask.TrialId).ProjectTo(_mapper.ConfigurationProvider).FirstOrDefault(); - return pageList; - } - - - - /// - /// 裁判任务 - /// - /// - /// - [HttpPost] - public async Task/*, object)*/> GetJudgeVisitTaskList(VisitTaskQuery inQuery) - { - - var visitTaskQueryable = _visitTaskRepository.Where(t => t.TrialId == inQuery.TrialId && t.IsAnalysisCreate == false) - .Where(t => t.ReadingCategory == ReadingCategory.Judge) - - .WhereIf(inQuery.TaskState != null, t => t.TaskState == inQuery.TaskState) - .WhereIf(inQuery.ReadingCategory != null, t => t.ReadingCategory == inQuery.ReadingCategory) - .WhereIf(inQuery.TrialSiteId != null, t => t.Subject.TrialSiteId == inQuery.TrialSiteId) - .WhereIf(inQuery.SubjectId != null, t => t.SubjectId == inQuery.SubjectId) - .WhereIf(inQuery.IsUrgent != null, t => t.IsUrgent == inQuery.IsUrgent) - .WhereIf(inQuery.DoctorUserId != null, t => t.DoctorUserId == inQuery.DoctorUserId) - .WhereIf(inQuery.TaskAllocationState != null, t => t.TaskAllocationState == inQuery.TaskAllocationState) - .WhereIf(inQuery.ReadingTaskState != null, t => t.ReadingTaskState == inQuery.ReadingTaskState) - .WhereIf(inQuery.TrialReadingCriterionId != null, t => t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId) - - .WhereIf(!string.IsNullOrEmpty(inQuery.TrialSiteCode), t => (t.BlindTrialSiteCode.Contains(inQuery.TrialSiteCode!) && t.IsAnalysisCreate) || (t.Subject.TrialSite.TrialSiteCode.Contains(inQuery.TrialSiteCode!) && t.IsAnalysisCreate == false)) - .WhereIf(!string.IsNullOrEmpty(inQuery.TaskName), t => t.TaskName.Contains(inQuery.TaskName) || t.TaskBlindName.Contains(inQuery.TaskName)) - .WhereIf(!string.IsNullOrEmpty(inQuery.SubjectCode), t => (t.Subject.Code.Contains(inQuery.SubjectCode) && t.IsAnalysisCreate == false) || (t.BlindSubjectCode.Contains(inQuery.SubjectCode) && t.IsAnalysisCreate)) - .WhereIf(inQuery.BeginAllocateDate != null, t => t.AllocateTime > inQuery.BeginAllocateDate) - .WhereIf(inQuery.EndAllocateDate != null, t => t.AllocateTime < inQuery.EndAllocateDate!.Value.AddDays(1)) - .ProjectTo(_mapper.ConfigurationProvider); - - var defalutSortArray = new string[] { nameof(JudgeVisitTaskView.IsUrgent) + " desc", nameof(JudgeVisitTaskView.SubjectCode), nameof(JudgeVisitTaskView.VisitTaskNum) }; - - var pageList = await visitTaskQueryable.ToPagedListAsync(inQuery, defalutSortArray); - - return pageList; - //var trialTaskConfig = _trialRepository.Where(t => t.Id == queryVisitTask.TrialId).ProjectTo(_mapper.ConfigurationProvider).FirstOrDefault(); - - //return (pageList, trialTaskConfig); - } - - - /// - /// PM阅片跟踪 - /// - /// - /// - [HttpPost] - public async Task>> GetReadingTaskList(VisitTaskQuery inQuery) - { - var visitTaskQueryable = _visitTaskRepository.Where(t => t.TrialId == inQuery.TrialId && t.IsAnalysisCreate == false) - //.Where(t => t.IsAnalysisCreate == false && t.DoctorUserId != null) - - .WhereIf(inQuery.IsEffect == true, t => t.TaskState == TaskState.Effect || t.TaskState == TaskState.Freeze) - .WhereIf(inQuery.IsEffect == false, t => t.TaskState == TaskState.Adbandon || t.TaskState == TaskState.HaveReturned) - - .WhereIf(inQuery.TaskState != null, t => t.TaskState == inQuery.TaskState) - .WhereIf(inQuery.TrialSiteId != null, t => t.Subject.TrialSiteId == inQuery.TrialSiteId) - .WhereIf(inQuery.SubjectId != null, t => t.SubjectId == inQuery.SubjectId) - .WhereIf(inQuery.IsUrgent != null, t => t.IsUrgent == inQuery.IsUrgent) - .WhereIf(inQuery.DoctorUserId != null, t => t.DoctorUserId == inQuery.DoctorUserId) - .WhereIf(inQuery.ReadingCategory != null, t => t.ReadingCategory == inQuery.ReadingCategory) - .WhereIf(inQuery.ReadingTaskState != null, t => t.ReadingTaskState == inQuery.ReadingTaskState) - .WhereIf(inQuery.TaskAllocationState != null, t => t.TaskAllocationState == inQuery.TaskAllocationState) - .WhereIf(inQuery.TrialReadingCriterionId != null, t => t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId) - .WhereIf(inQuery.ReReadingApplyState != null, t => t.ReReadingApplyState == inQuery.ReReadingApplyState) - - .WhereIf(inQuery.CompleteClinicalDataEnum == CompleteClinicalDataEnum.Complete, t => t.IsClinicalDataSign && t.IsNeedClinicalDataSign == true) - .WhereIf(inQuery.CompleteClinicalDataEnum == CompleteClinicalDataEnum.NotComplete, t => t.IsClinicalDataSign == false && t.IsNeedClinicalDataSign == true) - .WhereIf(inQuery.CompleteClinicalDataEnum == CompleteClinicalDataEnum.NA, t => t.IsNeedClinicalDataSign == false) - .WhereIf(!string.IsNullOrEmpty(inQuery.TrialSiteCode), t => (t.BlindTrialSiteCode.Contains(inQuery.TrialSiteCode!) && t.IsAnalysisCreate) || (t.Subject.TrialSite.TrialSiteCode.Contains(inQuery.TrialSiteCode!) && t.IsAnalysisCreate == false)) - .WhereIf(!string.IsNullOrEmpty(inQuery.TaskName), t => t.TaskName.Contains(inQuery.TaskName) || t.TaskBlindName.Contains(inQuery.TaskName)) - .WhereIf(!string.IsNullOrEmpty(inQuery.SubjectCode), t => (t.Subject.Code.Contains(inQuery.SubjectCode) && t.IsAnalysisCreate == false) || (t.BlindSubjectCode.Contains(inQuery.SubjectCode) && t.IsAnalysisCreate)) - .WhereIf(inQuery.BeginAllocateDate != null, t => t.AllocateTime > inQuery.BeginAllocateDate) - .WhereIf(inQuery.EndAllocateDate != null, t => t.AllocateTime < inQuery.EndAllocateDate) - .WhereIf(inQuery.BeginSignTime != null, t => t.SignTime > inQuery.BeginSignTime) - .WhereIf(inQuery.EndSignTime != null, t => t.SignTime < inQuery.EndSignTime) - .ProjectTo(_mapper.ConfigurationProvider); - - var defalutSortArray = new string[] { nameof(ReadingTaskView.IsUrgent) + " desc", nameof(ReadingTaskView.SubjectCode), nameof(ReadingTaskView.VisitTaskNum) }; - - var pageList = await visitTaskQueryable.ToPagedListAsync(inQuery, defalutSortArray); - - var trialTaskConfig = _trialRepository.Where(t => t.Id == inQuery.TrialId).ProjectTo(_mapper.ConfigurationProvider).FirstOrDefault(); - - return ResponseOutput.Ok(pageList, trialTaskConfig); - } - - - /// - /// PM 重阅追踪 - /// - /// - /// - [HttpPost] - public async Task> GetReReadingTaskList(VisitTaskQuery inQuery) - { - - - var visitTaskQueryable = _visitTaskReReadingRepository - .Where(t => t.OriginalReReadingTask.TrialId == inQuery.TrialId /*&& t.OriginalReReadingTask.IsAnalysisCreate == false*/) - .WhereIf(inQuery.RootReReadingTaskId != null, t => t.RootReReadingTaskId == inQuery.RootReReadingTaskId || t.OriginalReReadingTaskId == inQuery.RootReReadingTaskId) - .WhereIf(!string.IsNullOrEmpty(inQuery.TaskCode), t => t.OriginalReReadingTask.TaskCode.Contains(inQuery.TaskCode!) || t.RootReReadingTask.TaskCode.Contains(inQuery.TaskCode!)) - .WhereIf(inQuery.TrialSiteId != null, t => t.OriginalReReadingTask.Subject.TrialSiteId == inQuery.TrialSiteId) - .WhereIf(inQuery.TaskState != null, t => t.OriginalReReadingTask.TaskState == inQuery.TaskState) - .WhereIf(inQuery.ReReadingApplyState != null, t => t.OriginalReReadingTask.ReReadingApplyState == inQuery.ReReadingApplyState) - .WhereIf(inQuery.RequestReReadingType != null, t => t.RequestReReadingType == inQuery.RequestReReadingType) - .WhereIf(inQuery.SubjectId != null, t => t.OriginalReReadingTask.SubjectId == inQuery.SubjectId) - .WhereIf(inQuery.IsUrgent != null, t => t.OriginalReReadingTask.IsUrgent == inQuery.IsUrgent) - .WhereIf(inQuery.DoctorUserId != null, t => t.OriginalReReadingTask.DoctorUserId == inQuery.DoctorUserId) - .WhereIf(inQuery.ArmEnum != null, t => t.OriginalReReadingTask.ArmEnum == inQuery.ArmEnum) - .WhereIf(inQuery.ReadingTaskState != null, t => t.OriginalReReadingTask.ReadingTaskState == inQuery.ReadingTaskState) - .WhereIf(inQuery.TaskAllocationState != null, t => t.OriginalReReadingTask.TaskAllocationState == inQuery.TaskAllocationState) - .WhereIf(inQuery.TrialReadingCriterionId != null, t => t.OriginalReReadingTask.TrialReadingCriterionId == inQuery.TrialReadingCriterionId) - .WhereIf(inQuery.ReadingCategory != null, t => t.OriginalReReadingTask.ReadingCategory == inQuery.ReadingCategory) - - .WhereIf(!string.IsNullOrEmpty(inQuery.RequestReReadingReason), t => t.RequestReReadingReason.Contains(inQuery.RequestReReadingReason)) - - .WhereIf(inQuery.RequestReReadingResultEnum != null, t => t.RequestReReadingResultEnum == inQuery.RequestReReadingResultEnum) - - - .WhereIf(!string.IsNullOrEmpty(inQuery.TrialSiteCode), t => (t.OriginalReReadingTask.BlindTrialSiteCode.Contains(inQuery.TrialSiteCode!) && t.OriginalReReadingTask.IsAnalysisCreate) || (t.OriginalReReadingTask.Subject.TrialSite.TrialSiteCode.Contains(inQuery.TrialSiteCode!) && t.OriginalReReadingTask.IsAnalysisCreate == false)) - .WhereIf(!string.IsNullOrEmpty(inQuery.TaskName), t => t.OriginalReReadingTask.TaskName.Contains(inQuery.TaskName) || t.OriginalReReadingTask.TaskBlindName.Contains(inQuery.TaskName)) - .WhereIf(!string.IsNullOrEmpty(inQuery.SubjectCode), t => ((t.OriginalReReadingTask.Subject.Code.Contains(inQuery.SubjectCode) || t.OriginalReReadingTask.Subject.MedicalNo.Contains(inQuery.SubjectCode)) && t.OriginalReReadingTask.IsAnalysisCreate == false) || (t.OriginalReReadingTask.BlindSubjectCode.Contains(inQuery.SubjectCode) && t.OriginalReReadingTask.IsAnalysisCreate)) - .WhereIf(inQuery.BeginAllocateDate != null, t => t.OriginalReReadingTask.AllocateTime > inQuery.BeginAllocateDate) - .WhereIf(inQuery.EndAllocateDate != null, t => t.OriginalReReadingTask.AllocateTime < inQuery.EndAllocateDate!.Value.AddDays(1)) - - .WhereIf(inQuery.BeginRequestReReadingTime != null, t => t.RequestReReadingTime >= inQuery.BeginRequestReReadingTime) - .WhereIf(inQuery.EndRequestReReadingTime != null, t => t.RequestReReadingTime <= inQuery.EndRequestReReadingTime!.Value.AddDays(1)) - - .ProjectTo(_mapper.ConfigurationProvider); - - //var defalutSortArray = new string[] { nameof(ReReadingTaskView.OriginalReReadingTask) + "." + nameof(ReReadingTaskView.OriginalReReadingTask.IsUrgent) + " desc", nameof(ReReadingTaskView.OriginalReReadingTask) + "." + nameof(ReReadingTaskView.OriginalReReadingTask.SubjectId), nameof(ReReadingTaskView.OriginalReReadingTask) + "." + nameof(ReReadingTaskView.OriginalReReadingTask.VisitTaskNum) }; - - var defalutSortArray = new string[] { - nameof(ReReadingTaskView.RequestReReadingResultEnum) , - nameof(ReReadingTaskView.OriginalReReadingTask) + "." + nameof(ReReadingTaskView.OriginalReReadingTask.IsUrgent) + " desc", - nameof(ReReadingTaskView.OriginalReReadingTask) + "." + nameof(ReReadingTaskView.OriginalReReadingTask.TaskState), - nameof(ReReadingTaskView.OriginalReReadingTask) + "." + nameof(ReReadingTaskView.OriginalReReadingTask.SubjectCode),nameof(ReReadingTaskView.OriginalReReadingTask) + "." + nameof(ReReadingTaskView.OriginalReReadingTask.VisitTaskNum) }; - - - - var pageList = await visitTaskQueryable.ToPagedListAsync(inQuery, defalutSortArray); - - return pageList; - } - - - /// - /// 获取IR 重阅影像阅片列表 - /// - /// - /// - [HttpPost] - public async Task> GetIRReReadingTaskList(VisitTaskQuery inQuery) - { - - var visitTaskQueryable = _visitTaskReReadingRepository - .Where(t => t.RequestReReadingType == RequestReReadingType.DocotorApply) - .Where(t => t.OriginalReReadingTask.DoctorUserId == _userInfo.Id) - .Where(t => t.OriginalReReadingTask.TrialId == inQuery.TrialId) - .WhereIf(inQuery.RequestReReadingResultEnum != null, t => t.RequestReReadingResultEnum == inQuery.RequestReReadingResultEnum) - .WhereIf(inQuery.RootReReadingTaskId != null, t => t.RootReReadingTaskId == inQuery.RootReReadingTaskId || t.OriginalReReadingTaskId == inQuery.RootReReadingTaskId) - .WhereIf(!string.IsNullOrEmpty(inQuery.TaskCode), t => t.OriginalReReadingTask.TaskCode.Contains(inQuery.TaskCode!) || t.RootReReadingTask.TaskCode.Contains(inQuery.TaskCode!)) - .WhereIf(inQuery.TaskState != null, t => t.OriginalReReadingTask.TaskState == inQuery.TaskState) - .WhereIf(inQuery.ReadingCategory != null, t => t.OriginalReReadingTask.ReadingCategory == inQuery.ReadingCategory) - .WhereIf(inQuery.ReReadingApplyState != null, t => t.OriginalReReadingTask.ReReadingApplyState == inQuery.ReReadingApplyState) - .WhereIf(inQuery.TrialSiteId != null, t => t.OriginalReReadingTask.Subject.TrialSiteId == inQuery.TrialSiteId) - .WhereIf(inQuery.SubjectId != null, t => t.OriginalReReadingTask.SubjectId == inQuery.SubjectId) - .WhereIf(inQuery.IsUrgent != null, t => t.OriginalReReadingTask.IsUrgent == inQuery.IsUrgent) - .WhereIf(inQuery.DoctorUserId != null, t => t.OriginalReReadingTask.DoctorUserId == inQuery.DoctorUserId) - .WhereIf(inQuery.ReadingTaskState != null, t => t.OriginalReReadingTask.ReadingTaskState == inQuery.ReadingTaskState) - .WhereIf(inQuery.TaskAllocationState != null, t => t.OriginalReReadingTask.TaskAllocationState == inQuery.TaskAllocationState) - .WhereIf(inQuery.TrialReadingCriterionId != null, t => t.OriginalReReadingTask.TrialReadingCriterionId == inQuery.TrialReadingCriterionId) - - - .WhereIf(!string.IsNullOrEmpty(inQuery.TrialSiteCode), t => (t.OriginalReReadingTask.BlindTrialSiteCode.Contains(inQuery.TrialSiteCode!) && t.OriginalReReadingTask.IsAnalysisCreate) || (t.OriginalReReadingTask.Subject.TrialSite.TrialSiteCode.Contains(inQuery.TrialSiteCode!) && t.OriginalReReadingTask.IsAnalysisCreate == false)) - .WhereIf(!string.IsNullOrEmpty(inQuery.TaskName), t => t.OriginalReReadingTask.TaskName.Contains(inQuery.TaskName) || t.NewReReadingTask.TaskBlindName.Contains(inQuery.TaskName)) - .WhereIf(!string.IsNullOrEmpty(inQuery.SubjectCode), t => (t.OriginalReReadingTask.Subject.Code.Contains(inQuery.SubjectCode) && t.OriginalReReadingTask.IsAnalysisCreate == false) || (t.OriginalReReadingTask.BlindSubjectCode.Contains(inQuery.SubjectCode) && t.OriginalReReadingTask.IsAnalysisCreate)) - .WhereIf(inQuery.BeginAllocateDate != null, t => t.OriginalReReadingTask.AllocateTime > inQuery.BeginAllocateDate) - .WhereIf(inQuery.EndAllocateDate != null, t => t.OriginalReReadingTask.AllocateTime < inQuery.EndAllocateDate!.Value.AddDays(1)) - .ProjectTo(_mapper.ConfigurationProvider); - - - - var defalutSortArray = new string[] { nameof(ReReadingTaskView.OriginalReReadingTask) + "." + nameof(ReReadingTaskView.OriginalReReadingTask.IsUrgent) + " desc", nameof(ReReadingTaskView.OriginalReReadingTask) + "." + nameof(ReReadingTaskView.OriginalReReadingTask.SubjectCode), nameof(ReReadingTaskView.OriginalReReadingTask) + "." + nameof(ReReadingTaskView.OriginalReReadingTask.VisitTaskNum) }; - - var pageList = await visitTaskQueryable.ToPagedListAsync(inQuery, defalutSortArray); - - return pageList; - } - - - //SPM 能看到项目组申请记录 - [HttpPost] - public async Task> GetSPMReReadingTaskList(VisitTaskQuery inQuery) - { - var visitTaskQueryable = _visitTaskReReadingRepository.Where(t => t.RequestReReadingType == RequestReReadingType.TrialGroupApply && t.OriginalReReadingTask.IsAnalysisCreate == false) - .Where(t => t.OriginalReReadingTask.TrialId == inQuery.TrialId) - .WhereIf(inQuery.RootReReadingTaskId != null, t => t.RootReReadingTaskId == inQuery.RootReReadingTaskId || t.OriginalReReadingTaskId == inQuery.RootReReadingTaskId) - .WhereIf(!string.IsNullOrEmpty(inQuery.TaskCode), t => t.OriginalReReadingTask.TaskCode.Contains(inQuery.TaskCode!) || t.RootReReadingTask.TaskCode.Contains(inQuery.TaskCode!)) - .WhereIf(inQuery.TaskState != null, t => t.OriginalReReadingTask.TaskState == inQuery.TaskState) - .WhereIf(inQuery.TrialSiteId != null, t => t.OriginalReReadingTask.Subject.TrialSiteId == inQuery.TrialSiteId) - .WhereIf(inQuery.SubjectId != null, t => t.OriginalReReadingTask.SubjectId == inQuery.SubjectId) - .WhereIf(inQuery.IsUrgent != null, t => t.OriginalReReadingTask.IsUrgent == inQuery.IsUrgent) - .WhereIf(inQuery.DoctorUserId != null, t => t.OriginalReReadingTask.DoctorUserId == inQuery.DoctorUserId) - .WhereIf(inQuery.ReadingTaskState != null, t => t.OriginalReReadingTask.ReadingTaskState == inQuery.ReadingTaskState) - .WhereIf(inQuery.TaskAllocationState != null, t => t.OriginalReReadingTask.TaskAllocationState == inQuery.TaskAllocationState) - .WhereIf(inQuery.TrialReadingCriterionId != null, t => t.OriginalReReadingTask.TrialReadingCriterionId == inQuery.TrialReadingCriterionId) - - .WhereIf(!string.IsNullOrEmpty(inQuery.TrialSiteCode), t => (t.OriginalReReadingTask.BlindTrialSiteCode.Contains(inQuery.TrialSiteCode!) && t.OriginalReReadingTask.IsAnalysisCreate) || (t.OriginalReReadingTask.Subject.TrialSite.TrialSiteCode.Contains(inQuery.TrialSiteCode!) && t.OriginalReReadingTask.IsAnalysisCreate == false)) - - .WhereIf(!string.IsNullOrEmpty(inQuery.TaskName), t => t.OriginalReReadingTask.TaskName.Contains(inQuery.TaskName) || t.NewReReadingTask.TaskBlindName.Contains(inQuery.TaskName)) - .WhereIf(!string.IsNullOrEmpty(inQuery.SubjectCode), t => (t.OriginalReReadingTask.Subject.Code.Contains(inQuery.SubjectCode) && t.OriginalReReadingTask.IsAnalysisCreate == false) || (t.OriginalReReadingTask.BlindSubjectCode.Contains(inQuery.SubjectCode) && t.OriginalReReadingTask.IsAnalysisCreate)) - .WhereIf(inQuery.BeginAllocateDate != null, t => t.OriginalReReadingTask.AllocateTime > inQuery.BeginAllocateDate) - .WhereIf(inQuery.EndAllocateDate != null, t => t.OriginalReReadingTask.AllocateTime < inQuery.EndAllocateDate!.Value.AddDays(1)) - .ProjectTo(_mapper.ConfigurationProvider); - - var defalutSortArray = new string[] { nameof(ReReadingTaskView.RequestReReadingTime) }; - - //var defalutSortArray = new string[] { nameof(ReReadingTaskView.OriginalReReadingTask) + "." + nameof(ReReadingTaskView.OriginalReReadingTask.IsUrgent) + " desc", nameof(ReReadingTaskView.OriginalReReadingTask) + "." + nameof(ReReadingTaskView.OriginalReReadingTask.SubjectId), nameof(ReReadingTaskView.OriginalReReadingTask) + "." + nameof(ReReadingTaskView.OriginalReReadingTask.VisitTaskNum) }; - - var pageList = await visitTaskQueryable.ToPagedListAsync(inQuery, defalutSortArray); - - return pageList; - } - - - - /// - /// IR 待阅片任务列表 - /// - /// - [HttpPost] - public async Task>> GetIRUnReadSubjectTaskList(IRUnReadSubjectQuery inQuery) - { - - var trialId = inQuery.TrialId; - var subjectCode = inQuery.SubjectCode; - - var trialReadingCriterionId = inQuery.TrialReadingCriterionId; - - var criterionConfig = await _trialReadingCriterionRepository.Where(x => x.Id == inQuery.TrialReadingCriterionId).FirstNotNullAsync(); - - var readingTool = criterionConfig.ReadingTool; - var isReadingTaskViewInOrder = criterionConfig.IsReadingTaskViewInOrder; - - - var result = new PageOutput() + return new PageOutput() { PageSize = inQuery.PageSize, PageIndex = inQuery.PageIndex, - TotalCount = 0, - CurrentPageData = null, + TotalCount = count, + CurrentPageData = result, }; - - IRUnReadOutDto iRUnReadOut = new IRUnReadOutDto(); - - //subject 级别 有序 无序查询 - if (isReadingTaskViewInOrder == ReadingOrder.InOrder || isReadingTaskViewInOrder == ReadingOrder.SubjectRandom) - { - result = await GetSubjectReadingIQueryable(new GetReadingIQueryableInDto() - { - TrialId = trialId, - TrialReadingCriterionId = trialReadingCriterionId, - SubjectCode = inQuery.SubjectCode, - - PageIndex = inQuery.PageIndex, - PageSize = inQuery.PageSize, - Asc = inQuery.Asc, - SortField = inQuery.SortField, - }); - - } - //随机阅片 - else - { - var taskQuery = _visitTaskRepository.Where(x => x.TrialId == inQuery.TrialId && x.DoctorUserId == _userInfo.Id && x.TaskState == TaskState.Effect && x.TrialReadingCriterionId == trialReadingCriterionId) - .Where(x => !x.Subject.IsDeleted).Where(x => (x.IsNeedClinicalDataSign && x.IsClinicalDataSign) || !x.IsNeedClinicalDataSign); - - iRUnReadOut = new IRUnReadOutDto() - { - FinishJudgeTaskCount = await taskQuery.Where(x => x.ReadingCategory == ReadingCategory.Judge && x.ReadingTaskState == ReadingTaskState.HaveSigned).CountAsync(), - FinishTaskCount = await taskQuery.Where(x => x.ReadingCategory != ReadingCategory.Judge && x.ReadingTaskState == ReadingTaskState.HaveSigned).CountAsync(), - SuggesteFinishedTime = await taskQuery.Where(x => x.ReadingTaskState != ReadingTaskState.HaveSigned).MaxAsync(x => x.SuggesteFinishedTime), - UnReadJudgeTaskCount = await taskQuery.Where(x => x.ReadingCategory == ReadingCategory.Judge && x.ReadingTaskState != ReadingTaskState.HaveSigned).CountAsync(), - UnReadTaskCount = await taskQuery.Where(x => x.ReadingCategory != ReadingCategory.Judge && x.ReadingTaskState != ReadingTaskState.HaveSigned).CountAsync(), - }; - } - - return ResponseOutput.Ok(result, new - { - IsReadingTaskViewInOrder = isReadingTaskViewInOrder, - RandomReadInfo = iRUnReadOut, - ReadingTool = readingTool, - IseCRFShowInDicomReading = criterionConfig.IseCRFShowInDicomReading, - IsReadingShowSubjectInfo = criterionConfig.IsReadingShowSubjectInfo, - IsReadingShowPreviousResults = criterionConfig.IsReadingShowPreviousResults, - DigitPlaces = criterionConfig.DigitPlaces, - CriterionType = criterionConfig.CriterionType, - }); - - } - - /// - /// 获取subject有序 或者无序阅片IQuery对象 - /// - /// - /// - public async Task> GetSubjectReadingIQueryable(GetReadingIQueryableInDto inQuery) + else { - var trialReadingCriterionId = inQuery.TrialReadingCriterionId; - var subjectCode = inQuery.SubjectCode; - var trialId = inQuery.TrialId; - var subjectId = inQuery.SubjectId; - var critrion = await _trialReadingCriterionRepository.FindAsync(trialReadingCriterionId); - - if (critrion.IsReadingTaskViewInOrder == ReadingOrder.InOrder) + if (subjectId != null) { - var visitQuery = _visitTaskRepository.Where(x => x.TrialId == inQuery.TrialId && x.DoctorUserId == _userInfo.Id && x.TaskState == TaskState.Effect) + //找到 非一致性分析,未签名,状态正常的 并且任务名称是TimePoint的 任务 + var needDealTaskList = await _visitTaskRepository.Where(t => t.SubjectId == subjectId && t.TrialReadingCriterionId == trialReadingCriterionId && t.IsAnalysisCreate == false && t.DoctorUserId == _userInfo.Id + && t.ReadingTaskState != ReadingTaskState.HaveSigned && t.TaskBlindName == "Timepoint" && t.ReadingCategory == ReadingCategory.Visit + && (t.TaskState == TaskState.Effect || t.TaskState == TaskState.Freeze), true).ToListAsync(); - .WhereIf(inQuery.SubjectId != null, x => x.SubjectId == inQuery.SubjectId) - //前序 不存在 未生成任务的访视 - .WhereIf(critrion.IsAutoCreate == false, t => !t.Subject.SubjectCriteriaEvaluationVisitFilterList.Where(t => t.TrialReadingCriterionId == trialReadingCriterionId).Any(f => f.IsGeneratedTask == false && t.VisitTaskNum > f.SubjectVisit.VisitNum)) - - // 前序 不存在 未一致性核查未通过的 - .Where(t => !t.Subject.SubjectVisitList.Any(sv => sv.CheckState != CheckStateEnum.CVPassed && t.VisitTaskNum >= sv.VisitNum)) - //.WhereIf(critrion.IsAutoCreate == false, t => t.Subject.SubjectCriteriaEvaluationVisitFilterList.Where(t => t.TrialReadingCriterionId == trialReadingCriterionId).Any(t => t.IsGeneratedTask == false) ? - //t.VisitTaskNum <= t.Subject.SubjectCriteriaEvaluationVisitFilterList.Where(t => t.TrialReadingCriterionId == trialReadingCriterionId && t.IsGeneratedTask == false).Min(t => t.SubjectVisit.VisitNum) : true) - //.Where(t => t.Subject.SubjectVisitList.Any(t => t.CheckState != CheckStateEnum.CVPassed) ? t.VisitTaskNum <= t.Subject.SubjectVisitList.Where(t => t.CheckState != CheckStateEnum.CVPassed).Min(t => t.VisitNum) : true) - //满足前序访视不存在 需要签署但是未签署 sql 相当复杂 同时想查询所有未读的统计数字 就无法统计 byzhouhang - //但是加字段 IsFrontTaskNeedSignButNotSign 那么签名临床数据的时候,要对该subject 该标准的有效的任务 这个字段需要在签名的时候维护 采取这种方式 统计数字灵活 - //.Where(t => t.Subject.SubjectVisitTaskList.AsQueryable().Where(visitTaskLambda).Any(c => c.IsNeedClinicalDataSign == true && c.IsClinicalDataSign == false && c.VisitTaskNum < t.VisitTaskNum)) - .WhereIf(!string.IsNullOrEmpty(inQuery.SubjectCode), t => (t.Subject.Code.Contains(inQuery.SubjectCode!) && t.IsAnalysisCreate == false) || (t.BlindSubjectCode.Contains(inQuery.SubjectCode!) && t.IsAnalysisCreate)); - - - var visitGroupQuery = visitQuery.GroupBy(x => new { x.SubjectId, x.Subject.Code, x.BlindSubjectCode }); - - var visitTaskQuery = visitGroupQuery.Select(x => new IRUnReadSubjectView() + if (needDealTaskList.Count > 0) { - SubjectId = x.Key.SubjectId, - SubjectCode = x.Key.BlindSubjectCode == string.Empty ? x.Key.Code : x.Key.BlindSubjectCode, + //已完成的访视任务数量(包含重阅的) + var haveFinishedTaskCount = await _visitTaskRepository.CountAsync(t => t.SubjectId == subjectId && t.TrialReadingCriterionId == trialReadingCriterionId && t.IsAnalysisCreate == false && t.DoctorUserId == _userInfo.Id + && t.ReadingTaskState == ReadingTaskState.HaveSigned && t.ReadingCategory == ReadingCategory.Visit); - SuggesteFinishedTime = x.Where(y => y.TrialReadingCriterionId == trialReadingCriterionId && y.ReadingTaskState != ReadingTaskState.HaveSigned).Min(x => x.SuggesteFinishedTime), + //已经处理过的任务名称的数量 - //未读任务量 - UnReadTaskCount = x.Where(y => y.TrialReadingCriterionId == trialReadingCriterionId && y.ReadingTaskState != ReadingTaskState.HaveSigned).Count(), - - //未读 里可读任务量 - UnReadCanReadTaskCount = x.Where(y => y.TrialReadingCriterionId == trialReadingCriterionId && y.ReadingTaskState != ReadingTaskState.HaveSigned && y.IsFrontTaskNeedSignButNotSign == false && (y.IsNeedClinicalDataSign == false || y.IsClinicalDataSign == true) - //不能对包含聚合或子查询的表达式执行聚合函数 - //&& !x.Any(t => t.ReadingTaskState != ReadingTaskState.HaveSigned && t.IsNeedClinicalDataSign == true && t.IsClinicalDataSign == false && t.VisitTaskNum t.SubjectId == subjectId && t.TrialReadingCriterionId == trialReadingCriterionId && t.IsAnalysisCreate == false && t.DoctorUserId == _userInfo.Id + && t.ReadingTaskState != ReadingTaskState.HaveSigned && t.ReadingCategory == ReadingCategory.Visit && t.TaskBlindName != "Timepoint"); - UnReadCanReadTaskList = x.Where(y => y.TrialReadingCriterionId == trialReadingCriterionId && y.ReadingTaskState != ReadingTaskState.HaveSigned) - .Where(y => y.IsFrontTaskNeedSignButNotSign == false && (y.IsNeedClinicalDataSign == false || y.IsClinicalDataSign == true)) - .OrderBy(x => x.VisitTaskNum) - .Select(u => new IRUnreadTaskView() + + //随机赋值编号 比如要处理5个任务,实例化一个包含1-5的数组,每次随机取出一个 + List availableNumbers = Enumerable.Range(haveDealedTaskCount + haveFinishedTaskCount + 1, needDealTaskList.Count).ToList(); + Random rng = new Random(); + foreach (var visitTask in needDealTaskList) { - Id = u.Id, - IsUrgent = u.IsUrgent, - VisitNum = u.VisitTaskNum, - TaskBlindName = u.TaskBlindName, - VisistId = u.SourceSubjectVisitId, - SuggesteFinishedTime = u.SuggesteFinishedTime, - ReadingCategory = u.ReadingCategory, - IsAnalysisCreate = u.IsAnalysisCreate, - ArmEnum = u.ArmEnum, - TrialReadingCriterionId = u.TrialReadingCriterionId, - IsNeedClinicalDataSign = u.IsNeedClinicalDataSign, - IsClinicalDataSign = u.IsClinicalDataSign, - IsFrontTaskNeedSignButNotSign = u.IsFrontTaskNeedSignButNotSign - }) - .ToList(), + int randomIndex = rng.Next(availableNumbers.Count); + visitTask.TaskBlindName = $"Timepoint Ran {availableNumbers[randomIndex]}"; - UrgentCount = x.Where(y => y.TrialReadingCriterionId == trialReadingCriterionId && y.ReadingTaskState != ReadingTaskState.HaveSigned) - .Where(y => y.IsFrontTaskNeedSignButNotSign == false && (y.IsNeedClinicalDataSign == false || y.IsClinicalDataSign == true)) - .Where(x => x.IsUrgent).Count(), - - //已读任务量 - HaveReadTaskCount = x.Where(y => y.TrialReadingCriterionId == trialReadingCriterionId && y.ReadingTaskState == ReadingTaskState.HaveSigned).Count(), - - ExistReadingApply = x.Any(y => (y.ReReadingApplyState == ReReadingApplyState.DocotorHaveApplyed && y.TrialReadingCriterionId == trialReadingCriterionId) || y.ReReadingApplyState == ReReadingApplyState.TrialGroupHaveApplyed), - - //查出所有未读的 未读的可读的 在这个列表基础上 过滤下 y.IsFrontTaskNeedSignButNotSign==false && (y.IsNeedClinicalDataSign == false || y.IsClinicalDataSign == true) 这样容易排错 确认这三个字段是否维护有误 - UnReadTaskList = x.Where(y => y.TrialReadingCriterionId == trialReadingCriterionId && y.ReadingTaskState != ReadingTaskState.HaveSigned).OrderBy(x => x.VisitTaskNum) - .Select(u => new IRUnreadTaskView() - { - Id = u.Id, - IsUrgent = u.IsUrgent, - VisitNum = u.VisitTaskNum, - TaskBlindName = u.TaskBlindName, - VisistId = u.SourceSubjectVisitId, - SuggesteFinishedTime = u.SuggesteFinishedTime, - ReadingCategory = u.ReadingCategory, - IsAnalysisCreate = u.IsAnalysisCreate, - ArmEnum = u.ArmEnum, - TrialReadingCriterionId = u.TrialReadingCriterionId, - IsNeedClinicalDataSign = u.IsNeedClinicalDataSign, - IsClinicalDataSign = u.IsClinicalDataSign, - IsFrontTaskNeedSignButNotSign = u.IsFrontTaskNeedSignButNotSign - }) - .ToList(), - }).Where(x => x.UnReadCanReadTaskCount > 0)/*.OrderBy(x => x.UnReadCanReadTaskCount)*/; - // 有序阅片需要找到最小需要 - - - // 不这样写会有问题 - var count = visitQuery.Where(y => y.TrialReadingCriterionId == trialReadingCriterionId && y.ReadingTaskState != ReadingTaskState.HaveSigned && y.IsFrontTaskNeedSignButNotSign == false && (y.IsNeedClinicalDataSign == false || y.IsClinicalDataSign == true)) - .GroupBy(x => new { x.SubjectId, x.Subject.Code, x.BlindSubjectCode }).Count(); - - var result = new List(); - - var propName = string.IsNullOrWhiteSpace(inQuery!.SortField) ? nameof(IRUnReadSubjectView.UnReadCanReadTaskCount) : inQuery.SortField; - - var visitTaskOrderQuery = inQuery.Asc ? visitTaskQuery.OrderBy(propName) : visitTaskQuery.OrderBy(propName + " desc"); - - - - result = await visitTaskOrderQuery - .Skip((inQuery.PageIndex - 1) * inQuery.PageSize) - .Take(inQuery.PageSize).ToListAsync(); - - - return new PageOutput() - { - PageSize = inQuery.PageSize, - PageIndex = inQuery.PageIndex, - TotalCount = count, - CurrentPageData = result, - }; - } - else - { - - if (subjectId != null) - { - //找到 非一致性分析,未签名,状态正常的 并且任务名称是TimePoint的 任务 - var needDealTaskList = await _visitTaskRepository.Where(t => t.SubjectId == subjectId && t.TrialReadingCriterionId == trialReadingCriterionId && t.IsAnalysisCreate == false && t.DoctorUserId == _userInfo.Id - && t.ReadingTaskState != ReadingTaskState.HaveSigned && t.TaskBlindName == "Timepoint" && t.ReadingCategory == ReadingCategory.Visit - && (t.TaskState == TaskState.Effect || t.TaskState == TaskState.Freeze), true).ToListAsync(); - - if (needDealTaskList.Count > 0) - { - //已完成的访视任务数量(包含重阅的) - var haveFinishedTaskCount = await _visitTaskRepository.CountAsync(t => t.SubjectId == subjectId && t.TrialReadingCriterionId == trialReadingCriterionId && t.IsAnalysisCreate == false && t.DoctorUserId == _userInfo.Id - && t.ReadingTaskState == ReadingTaskState.HaveSigned && t.ReadingCategory == ReadingCategory.Visit); - - //已经处理过的任务名称的数量 - - var haveDealedTaskCount = await _visitTaskRepository.CountAsync(t => t.SubjectId == subjectId && t.TrialReadingCriterionId == trialReadingCriterionId && t.IsAnalysisCreate == false && t.DoctorUserId == _userInfo.Id - && t.ReadingTaskState != ReadingTaskState.HaveSigned && t.ReadingCategory == ReadingCategory.Visit && t.TaskBlindName != "Timepoint"); - - - - //随机赋值编号 比如要处理5个任务,实例化一个包含1-5的数组,每次随机取出一个 - List availableNumbers = Enumerable.Range(haveDealedTaskCount + haveFinishedTaskCount + 1, needDealTaskList.Count).ToList(); - Random rng = new Random(); - foreach (var visitTask in needDealTaskList) - { - int randomIndex = rng.Next(availableNumbers.Count); - - visitTask.TaskBlindName = $"Timepoint Ran {availableNumbers[randomIndex]}"; - - availableNumbers.RemoveAt(randomIndex); - } - await _visitTaskRepository.SaveChangesAsync(); + availableNumbers.RemoveAt(randomIndex); } + await _visitTaskRepository.SaveChangesAsync(); } - - var visitQuery = _visitTaskRepository.Where(x => x.TrialId == trialId && x.DoctorUserId == _userInfo.Id && x.TaskState == TaskState.Effect) - .WhereIf(inQuery.SubjectId != null, x => x.SubjectId == inQuery.SubjectId) - .WhereIf(!string.IsNullOrEmpty(subjectCode), t => (t.Subject.Code.Contains(subjectCode!) && t.IsAnalysisCreate == false) || (t.BlindSubjectCode.Contains(subjectCode!) && t.IsAnalysisCreate)); - - var visitGroupQuery = visitQuery.GroupBy(x => new { x.SubjectId, x.Subject.Code, x.BlindSubjectCode }); - - var visitTaskQuery = visitGroupQuery.Select(x => new IRUnReadSubjectView() - { - SubjectId = x.Key.SubjectId, - SubjectCode = x.Key.BlindSubjectCode == string.Empty ? x.Key.Code : x.Key.BlindSubjectCode, - - SuggesteFinishedTime = x.Where(y => y.TrialReadingCriterionId == trialReadingCriterionId && y.ReadingTaskState != ReadingTaskState.HaveSigned).Min(x => x.SuggesteFinishedTime), - - //未读任务量 - UnReadCanReadTaskCount = x.Where(y => y.TrialReadingCriterionId == trialReadingCriterionId && y.ReadingTaskState != ReadingTaskState.HaveSigned).Count(), - - UrgentCount = x.Where(y => y.TrialReadingCriterionId == trialReadingCriterionId && y.ReadingTaskState != ReadingTaskState.HaveSigned).Where(x => x.IsUrgent).Count(), - - //已读任务量 - HaveReadTaskCount = x.Where(y => y.TrialReadingCriterionId == trialReadingCriterionId && y.ReadingTaskState == ReadingTaskState.HaveSigned).Count(), - - ExistReadingApply = x.Any(y => (y.ReReadingApplyState == ReReadingApplyState.DocotorHaveApplyed && y.TrialReadingCriterionId == trialReadingCriterionId) || y.ReReadingApplyState == ReReadingApplyState.TrialGroupHaveApplyed), - - UnReadCanReadTaskList = x.Where(y => y.TrialReadingCriterionId == trialReadingCriterionId && y.ReadingTaskState != ReadingTaskState.HaveSigned) - .OrderBy(x => x.VisitTaskNum) - .Select(u => new IRUnreadTaskView() - { - Id = u.Id, - IsUrgent = u.IsUrgent, - VisitNum = u.VisitTaskNum, - TaskBlindName = u.TaskBlindName, - VisistId = u.SourceSubjectVisitId, - SuggesteFinishedTime = u.SuggesteFinishedTime, - ReadingCategory = u.ReadingCategory, - IsAnalysisCreate = u.IsAnalysisCreate, - ArmEnum = u.ArmEnum, - TrialReadingCriterionId = u.TrialReadingCriterionId, - IsNeedClinicalDataSign = u.IsNeedClinicalDataSign, - IsClinicalDataSign = u.IsClinicalDataSign, - IsFrontTaskNeedSignButNotSign = u.IsFrontTaskNeedSignButNotSign - }) - .ToList() - }).Where(x => x.UnReadCanReadTaskCount > 0); - - var pageList = await visitTaskQuery.ToPagedListAsync(inQuery, nameof(IRUnReadSubjectView.UnReadCanReadTaskCount) ); - - return pageList; } - } + var visitQuery = _visitTaskRepository.Where(x => x.TrialId == trialId && x.DoctorUserId == _userInfo.Id && x.TaskState == TaskState.Effect) + .WhereIf(inQuery.SubjectId != null, x => x.SubjectId == inQuery.SubjectId) + .WhereIf(!string.IsNullOrEmpty(subjectCode), t => (t.Subject.Code.Contains(subjectCode!) && t.IsAnalysisCreate == false) || (t.BlindSubjectCode.Contains(subjectCode!) && t.IsAnalysisCreate)); + var visitGroupQuery = visitQuery.GroupBy(x => new { x.SubjectId, x.Subject.Code, x.BlindSubjectCode }); - /// - /// IR 已阅片任务 - /// - /// - /// - [HttpPost] - public async Task> GetIRHaveReadTaskList(VisitTaskQuery inQuery) - { + var visitTaskQuery = visitGroupQuery.Select(x => new IRUnReadSubjectView() + { + SubjectId = x.Key.SubjectId, + SubjectCode = x.Key.BlindSubjectCode == string.Empty ? x.Key.Code : x.Key.BlindSubjectCode, + SuggesteFinishedTime = x.Where(y => y.TrialReadingCriterionId == trialReadingCriterionId && y.ReadingTaskState != ReadingTaskState.HaveSigned).Min(x => x.SuggesteFinishedTime), - var visitTaskQueryable = _visitTaskRepository.Where(t => t.TrialId == inQuery.TrialId) - .Where(t => t.DoctorUserId == _userInfo.Id && t.ReadingTaskState == ReadingTaskState.HaveSigned)//该医生 已经签名的数据 + //未读任务量 + UnReadCanReadTaskCount = x.Where(y => y.TrialReadingCriterionId == trialReadingCriterionId && y.ReadingTaskState != ReadingTaskState.HaveSigned).Count(), + UrgentCount = x.Where(y => y.TrialReadingCriterionId == trialReadingCriterionId && y.ReadingTaskState != ReadingTaskState.HaveSigned).Where(x => x.IsUrgent).Count(), - .WhereIf(inQuery.TrialSiteId != null, t => t.Subject.TrialSiteId == inQuery.TrialSiteId) - .WhereIf(inQuery.SubjectId != null, t => t.SubjectId == inQuery.SubjectId) - .WhereIf(inQuery.IsUrgent != null, t => t.IsUrgent == inQuery.IsUrgent) - .WhereIf(inQuery.ReadingCategory != null, t => t.ReadingCategory == inQuery.ReadingCategory) - .WhereIf(inQuery.TaskAllocationState != null, t => t.TaskAllocationState == inQuery.TaskAllocationState) - .WhereIf(inQuery.TrialReadingCriterionId != null, t => t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId) + //已读任务量 + HaveReadTaskCount = x.Where(y => y.TrialReadingCriterionId == trialReadingCriterionId && y.ReadingTaskState == ReadingTaskState.HaveSigned).Count(), + ExistReadingApply = x.Any(y => (y.ReReadingApplyState == ReReadingApplyState.DocotorHaveApplyed && y.TrialReadingCriterionId == trialReadingCriterionId) || y.ReReadingApplyState == ReReadingApplyState.TrialGroupHaveApplyed), - .WhereIf(inQuery.TaskState != null, t => t.TaskState == inQuery.TaskState) - .WhereIf(!string.IsNullOrEmpty(inQuery.TrialSiteCode), t => (t.BlindTrialSiteCode.Contains(inQuery.TrialSiteCode!) && t.IsAnalysisCreate) || (t.Subject.TrialSite.TrialSiteCode.Contains(inQuery.TrialSiteCode!) && t.IsAnalysisCreate == false)) - .WhereIf(!string.IsNullOrEmpty(inQuery.TaskName), t => t.TaskName.Contains(inQuery.TaskName) || t.TaskBlindName.Contains(inQuery.TaskName)) - .WhereIf(!string.IsNullOrEmpty(inQuery.SubjectCode), t => (t.Subject.Code.Contains(inQuery.SubjectCode) && t.IsAnalysisCreate == false) || (t.BlindSubjectCode.Contains(inQuery.SubjectCode) && t.IsAnalysisCreate)) - .WhereIf(inQuery.BeginAllocateDate != null, t => t.AllocateTime > inQuery.BeginAllocateDate) - .WhereIf(inQuery.EndAllocateDate != null, t => t.AllocateTime < inQuery.EndAllocateDate!.Value.AddDays(1)) - .ProjectTo(_mapper.ConfigurationProvider); + UnReadCanReadTaskList = x.Where(y => y.TrialReadingCriterionId == trialReadingCriterionId && y.ReadingTaskState != ReadingTaskState.HaveSigned) + .OrderBy(x => x.VisitTaskNum) + .Select(u => new IRUnreadTaskView() + { + Id = u.Id, + IsUrgent = u.IsUrgent, + VisitNum = u.VisitTaskNum, + TaskBlindName = u.TaskBlindName, + VisistId = u.SourceSubjectVisitId, + SuggesteFinishedTime = u.SuggesteFinishedTime, + ReadingCategory = u.ReadingCategory, + IsAnalysisCreate = u.IsAnalysisCreate, + ArmEnum = u.ArmEnum, + TrialReadingCriterionId = u.TrialReadingCriterionId, + IsNeedClinicalDataSign = u.IsNeedClinicalDataSign, + IsClinicalDataSign = u.IsClinicalDataSign, + IsFrontTaskNeedSignButNotSign = u.IsFrontTaskNeedSignButNotSign + }) + .ToList() + }).Where(x => x.UnReadCanReadTaskCount > 0); - var defalutSortArray = new string[] { nameof(IRHaveReadView.IsUrgent) + " desc", nameof(IRHaveReadView.SubjectCode), nameof(IRHaveReadView.VisitTaskNum) }; - - var pageList = await visitTaskQueryable.ToPagedListAsync(inQuery, defalutSortArray); + var pageList = await visitTaskQuery.ToPagedListAsync(inQuery, nameof(IRUnReadSubjectView.UnReadCanReadTaskCount) ); return pageList; } + } - [HttpPost] - [UnitOfWork] - public async Task AIRReReading(AIRReReadingCommand command, [FromServices] IVisitTaskHelpeService _visitTaskCommonService) + /// + /// IR 已阅片任务 + /// + /// + /// + [HttpPost] + public async Task> GetIRHaveReadTaskList(VisitTaskQuery inQuery) + { + + + var visitTaskQueryable = _visitTaskRepository.Where(t => t.TrialId == inQuery.TrialId) + .Where(t => t.DoctorUserId == _userInfo.Id && t.ReadingTaskState == ReadingTaskState.HaveSigned)//该医生 已经签名的数据 + + + .WhereIf(inQuery.TrialSiteId != null, t => t.Subject.TrialSiteId == inQuery.TrialSiteId) + .WhereIf(inQuery.SubjectId != null, t => t.SubjectId == inQuery.SubjectId) + .WhereIf(inQuery.IsUrgent != null, t => t.IsUrgent == inQuery.IsUrgent) + .WhereIf(inQuery.ReadingCategory != null, t => t.ReadingCategory == inQuery.ReadingCategory) + .WhereIf(inQuery.TaskAllocationState != null, t => t.TaskAllocationState == inQuery.TaskAllocationState) + .WhereIf(inQuery.TrialReadingCriterionId != null, t => t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId) + + + .WhereIf(inQuery.TaskState != null, t => t.TaskState == inQuery.TaskState) + .WhereIf(!string.IsNullOrEmpty(inQuery.TrialSiteCode), t => (t.BlindTrialSiteCode.Contains(inQuery.TrialSiteCode!) && t.IsAnalysisCreate) || (t.Subject.TrialSite.TrialSiteCode.Contains(inQuery.TrialSiteCode!) && t.IsAnalysisCreate == false)) + .WhereIf(!string.IsNullOrEmpty(inQuery.TaskName), t => t.TaskName.Contains(inQuery.TaskName) || t.TaskBlindName.Contains(inQuery.TaskName)) + .WhereIf(!string.IsNullOrEmpty(inQuery.SubjectCode), t => (t.Subject.Code.Contains(inQuery.SubjectCode) && t.IsAnalysisCreate == false) || (t.BlindSubjectCode.Contains(inQuery.SubjectCode) && t.IsAnalysisCreate)) + .WhereIf(inQuery.BeginAllocateDate != null, t => t.AllocateTime > inQuery.BeginAllocateDate) + .WhereIf(inQuery.EndAllocateDate != null, t => t.AllocateTime < inQuery.EndAllocateDate!.Value.AddDays(1)) + .ProjectTo(_mapper.ConfigurationProvider); + + var defalutSortArray = new string[] { nameof(IRHaveReadView.IsUrgent) + " desc", nameof(IRHaveReadView.SubjectCode), nameof(IRHaveReadView.VisitTaskNum) }; + + var pageList = await visitTaskQueryable.ToPagedListAsync(inQuery, defalutSortArray); + + return pageList; + } + + + + [HttpPost] + [UnitOfWork] + public async Task AIRReReading(AIRReReadingCommand command, [FromServices] IVisitTaskHelpeService _visitTaskCommonService) + { + var baseLineTaskList = await _visitTaskRepository.Where(t => t.TrialId == command.TrialId && t.TrialReadingCriterionId == command.TrialReadingCriterionId && t.DoctorUserId == _userInfo.Id + && t.TaskState == TaskState.Effect && t.ReadingCategory == ReadingCategory.Visit && t.ReadingTaskState == ReadingTaskState.HaveSigned && t.SourceSubjectVisit.IsBaseLine == true).ToListAsync(); + + var judegeList = await _visitTaskRepository.Where(t => t.TrialId == command.TrialId && t.TrialReadingCriterionId == command.TrialReadingCriterionId && t.DoctorUserId == _userInfo.Id + && t.TaskState == TaskState.Effect && t.ReadingCategory == ReadingCategory.Judge && t.ReadingTaskState == ReadingTaskState.HaveSigned).ToListAsync(); + + foreach (var item in judegeList) { - var baseLineTaskList = await _visitTaskRepository.Where(t => t.TrialId == command.TrialId && t.TrialReadingCriterionId == command.TrialReadingCriterionId && t.DoctorUserId == _userInfo.Id - && t.TaskState == TaskState.Effect && t.ReadingCategory == ReadingCategory.Visit && t.ReadingTaskState == ReadingTaskState.HaveSigned && t.SourceSubjectVisit.IsBaseLine == true).ToListAsync(); - - var judegeList = await _visitTaskRepository.Where(t => t.TrialId == command.TrialId && t.TrialReadingCriterionId == command.TrialReadingCriterionId && t.DoctorUserId == _userInfo.Id - && t.TaskState == TaskState.Effect && t.ReadingCategory == ReadingCategory.Judge && t.ReadingTaskState == ReadingTaskState.HaveSigned).ToListAsync(); - - foreach (var item in judegeList) + if (!baseLineTaskList.Any(t => t.SubjectId == item.SubjectId)) { - if (!baseLineTaskList.Any(t => t.SubjectId == item.SubjectId)) - { - baseLineTaskList.Add(item); - } + baseLineTaskList.Add(item); } - - - var baseLineTaskIdList = baseLineTaskList.Select(t => t.Id).ToList(); - - if (baseLineTaskIdList.Count == 0) - { - return ResponseOutput.Ok(); - } - - //if (baseLineTaskList == null) - //{ - // return ResponseOutput.NotOk("基线任务未阅完,不允许重阅基线任务"); - //} - - await ApplyReReading(new ApplyReReadingCommand() { IsCopyFollowForms = false, IsCopyOrigenalForms = false, TaskIdList = baseLineTaskIdList, TrialId = command.TrialId, RequestReReadingReason = "AIR自动重阅基线", RequestReReadingType = RequestReReadingType.DocotorApply }); - - - - var requestRecordList = await _visitTaskReReadingRepository.Where(t => baseLineTaskIdList.Contains(t.OriginalReReadingTaskId) && t.RequestReReadingUserId == _userInfo.Id && t.RequestReReadingReason == "AIR自动重阅基线").ToListAsync(); - - if (requestRecordList.Count != baseLineTaskIdList.Count) - { - //---后台数据有错误 - return ResponseOutput.NotOk(_localizer["VisitTask_DoctorConfiguration"]); - } - - await ConfirmReReading(new ConfirmReReadingCommand() - { - TrialId = command.TrialId, - RequestReReadingResultEnum = RequestReReadingResult.Agree, - //ConfirmReReadingList = new List() { new ConfirmReReadingDTO() { Id = requestRecord.Id, OriginalReReadingTaskId = task.Id } } - ConfirmReReadingList = requestRecordList.Select(t => new ConfirmReReadingDTO() { Id = t.Id, OriginalReReadingTaskId = t.OriginalReReadingTaskId }).ToList() - }, _visitTaskCommonService); - - return ResponseOutput.Ok(); - } + var baseLineTaskIdList = baseLineTaskList.Select(t => t.Id).ToList(); - /// - /// 申请重阅 1:IR 2:PM - /// - /// - /// - [HttpPost] - [UnitOfWork] - [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })] - - public async Task ApplyReReading(ApplyReReadingCommand applyReReadingCommand) + if (baseLineTaskIdList.Count == 0) { - - - var taskList = await _visitTaskRepository.Where(t => applyReReadingCommand.TaskIdList.Contains(t.Id), true).ToListAsync(); - - var trialReadingCriterionId = taskList.First()!.TrialReadingCriterionId; - - var criterionConfig = (await _trialReadingCriterionRepository.Where(x => x.Id == trialReadingCriterionId).Select(x => new { x.ReadingTool, x.IsAutoCreate, x.IsReadingTaskViewInOrder }).FirstOrDefaultAsync()).IfNullThrowException(); - - - foreach (var task in taskList) - { - - - if (task.ReadingTaskState != ReadingTaskState.HaveSigned || (task.TaskState != TaskState.Effect && task.TaskState != TaskState.Freeze)) - { - //---未阅片完成,或者未生效的任务不允许申请重阅 - throw new BusinessValidationFailedException(_localizer["VisitTask_BackendData"]); - } - - if (task.ReReadingApplyState == ReReadingApplyState.DocotorHaveApplyed || task.ReReadingApplyState == ReReadingApplyState.TrialGroupHaveApplyed || task.ReReadingApplyState == ReReadingApplyState.Agree) - { - //---重阅已申请,或者重阅已同意状态下不允许申请重阅 - throw new BusinessValidationFailedException(_localizer["VisitTask_UnreadTask"]); - } - - - - - if (IsPMOrAPm()) - { - if (criterionConfig.IsAutoCreate == false) - { - //---手动生成任务的不允许PM 申请影像重阅 - return ResponseOutput.NotOk(_localizer["VisitTask_NoPMRecheck"]); - } - - if (task.IsAnalysisCreate) - { - //---PM 不允许对一致性分析任务进行申请重阅 - throw new BusinessValidationFailedException(_localizer["VisitTask_Reapply"]); - } - - if (task.ReadingCategory != ReadingCategory.Visit) - { - //---PM 仅仅允许对访视类型的任务申请重阅 - throw new BusinessValidationFailedException(_localizer["VisitTask_ConsistencyAnalysis"]); - } - - - // 有序 一个受试者访视重阅未处理完,不能申请其他的 - if (criterionConfig.IsReadingTaskViewInOrder == ReadingOrder.InOrder) - { - if (await _visitTaskReReadingRepository.AnyAsync(t => t.OriginalReReadingTask.TrialId == task.TrialId && t.OriginalReReadingTask.SubjectId == task.SubjectId && t.OriginalReReadingTask.TaskState == TaskState.Effect - && t.OriginalReReadingTask.TrialReadingCriterionId == task.TrialReadingCriterionId - && t.OriginalReReadingTask.ReadingTaskState == ReadingTaskState.HaveSigned && t.RequestReReadingType == RequestReReadingType.TrialGroupApply && t.RequestReReadingResultEnum == RequestReReadingResult.Default)) - { - //---当前为有序阅片,该受试者已有访视已申请重阅还未处理(项目组申请),暂不能继续申请重阅 - return ResponseOutput.NotOk(_localizer["VisitTask_VisitTypeRestriction"]); - } - } - - - task.ReReadingApplyState = ReReadingApplyState.TrialGroupHaveApplyed; - - - } - if (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.IndependentReviewer) - { - task.ReReadingApplyState = ReReadingApplyState.DocotorHaveApplyed; - - - //在PM 的申请重阅的影响列表里也不能申请重阅 - - var pmApply = await _visitTaskReReadingRepository.Where(t => t.OriginalReReadingTask.TrialId == task.TrialId && t.OriginalReReadingTask.SubjectId == task.SubjectId && t.OriginalReReadingTask.TaskState == TaskState.Effect && t.OriginalReReadingTask.ReadingCategory == ReadingCategory.Visit - && t.OriginalReReadingTask.ReadingTaskState == ReadingTaskState.HaveSigned && t.RequestReReadingType == RequestReReadingType.TrialGroupApply && t.RequestReReadingResultEnum == RequestReReadingResult.Default).Include(t => t.OriginalReReadingTask).FirstOrDefaultAsync(); - - - // 有序 - if (criterionConfig.IsReadingTaskViewInOrder == ReadingOrder.InOrder) - { - // 针对同一个subject 不同阅片人 针对同一个访视申请重阅,是允许的,所以同一阅片人,针对同一suject 有访视申请重阅还未处理,不允许申请重阅 - if (await _visitTaskReReadingRepository.AnyAsync(t => t.OriginalReReadingTask.TrialId == task.TrialId && t.OriginalReReadingTask.SubjectId == task.SubjectId && t.OriginalReReadingTask.TaskState == TaskState.Effect - && t.OriginalReReadingTask.TrialReadingCriterionId == task.TrialReadingCriterionId && t.OriginalReReadingTask.DoctorUserId == task.DoctorUserId - && t.OriginalReReadingTask.ReadingTaskState == ReadingTaskState.HaveSigned && t.RequestReReadingType == RequestReReadingType.DocotorApply && t.RequestReReadingResultEnum == RequestReReadingResult.Default)) - { - //---当前为有序阅片,该受试者已有访视已申请重阅还未处理,暂不能继续申请重阅 - throw new BusinessValidationFailedException(_localizer["VisitTask_SequentialReading"]); - } - - - - if (pmApply != null) - { - var originalTask = pmApply.OriginalReReadingTask; - - //PM 有序影响列表 - if (await _visitTaskRepository.Where(t => t.TrialId == originalTask.TrialId && t.SubjectId == originalTask.SubjectId && t.TaskState == TaskState.Effect && t.TaskAllocationState == TaskAllocationState.Allocated && t.IsAnalysisCreate == false && t.TrialReadingCriterionId == originalTask.TrialReadingCriterionId && t.VisitTaskNum >= originalTask.VisitTaskNum) - .AnyAsync(t => t.VisitTaskNum == task.VisitTaskNum)) - { - //---当前为有序阅片,影像存在问题,项目组已申请回退,暂不能申请重阅 - throw new BusinessValidationFailedException(_localizer["VisitTask_ImageProblem"]); - } - - } - - - - Expression> filterExpression = t => t.TrialId == task.TrialId && t.SubjectId == task.SubjectId && t.TaskState == TaskState.Effect && t.TrialReadingCriterionId == task.TrialReadingCriterionId - && t.DoctorUserId == task.DoctorUserId && t.IsAnalysisCreate == false && t.VisitTaskNum > task.VisitTaskNum; - - - - if (task.ReadingCategory == ReadingCategory.Global && await _visitTaskRepository.AnyAsync(filterExpression.And(t => t.ReadingCategory == ReadingCategory.Global))) - { - //---有序阅片,只允许申请该受试者阅片人最后一次完成全局任务重阅 - throw new BusinessValidationFailedException(_localizer["VisitTask_LastReading"]); - } - - if (task.ReadingCategory == ReadingCategory.Oncology && await _visitTaskRepository.AnyAsync(filterExpression.And(t => t.ReadingCategory == ReadingCategory.Oncology && t.ReadingTaskState == ReadingTaskState.HaveSigned))) - { - //---有序阅片,只允许申请该受试者阅片人最后一次完成肿瘤学任务重阅 - throw new BusinessValidationFailedException(_localizer["VisitTask_LastOncologistRecheck"]); - } - - if (task.ReadingCategory == ReadingCategory.Judge && await _visitTaskRepository.AnyAsync(filterExpression.And(t => t.ReadingCategory == ReadingCategory.Judge && t.ReadingTaskState == ReadingTaskState.HaveSigned))) - { - //---有序阅片,只允许申请该受试者阅片人最后一次完成裁判的任务重阅 - throw new BusinessValidationFailedException(_localizer["VisitTask_LastAdjudicatorRecheck"]); - } - - } - else - { - - if (pmApply != null) - { - var originalTask = pmApply.OriginalReReadingTask; - - //PM 无序影响列表 - if (await _visitTaskRepository.Where(t => t.TrialId == originalTask.TrialId && t.SubjectId == originalTask.SubjectId && t.TaskState == TaskState.Effect && t.TaskAllocationState == TaskAllocationState.Allocated && t.IsAnalysisCreate == false && t.TrialReadingCriterionId == originalTask.TrialReadingCriterionId) - .Where(t => t.Id == originalTask.Id || t.Id == originalTask.JudgeVisitTaskId) - .AnyAsync(t => t.VisitTaskNum == task.VisitTaskNum)) - { - //---当前为无序阅片,影像存在问题,项目组已申请回退,暂不能申请重阅 - throw new BusinessValidationFailedException(_localizer["VisitTask_RandomInvalidRereading"]); - } - - } - - //也要支持裁判重阅240701 - - if (task.ReadingCategory != ReadingCategory.Visit && task.ReadingCategory != ReadingCategory.Judge) - { - //---无序阅片,仅仅允许IR 申请 访视、裁判类型类别的任务进行重阅 - throw new BusinessValidationFailedException(_localizer["VisitTask_IRGlobalRecheck"]); - } - } - - } - - //AIR 不加验证 - if (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.AIR) - { - task.ReReadingApplyState = ReReadingApplyState.DocotorHaveApplyed; - } - - - - 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.Id, - IsCopyOrigenalForms = applyReReadingCommand.IsCopyOrigenalForms, - IsCopyFollowForms = applyReReadingCommand.IsCopyFollowForms, - RequestReReadingReason = applyReReadingCommand.RequestReReadingReason, - RequestReReadingType = applyReReadingCommand.RequestReReadingType, - - }); - } - - - await _visitTaskRepository.SaveChangesAsync(); - return ResponseOutput.Ok(); } + //if (baseLineTaskList == null) + //{ + // return ResponseOutput.NotOk("基线任务未阅完,不允许重阅基线任务"); + //} - /// - /// 重阅原任务跟踪处理 - /// - /// - /// - /// - private void ReReadingTaskTrackingDeal(VisitTask origenalTask, ConfirmReReadingCommand agreeReReadingCommand) + await ApplyReReading(new ApplyReReadingCommand() { IsCopyFollowForms = false, IsCopyOrigenalForms = false, TaskIdList = baseLineTaskIdList, TrialId = command.TrialId, RequestReReadingReason = "AIR自动重阅基线", RequestReReadingType = RequestReReadingType.DocotorApply }); + + + + var requestRecordList = await _visitTaskReReadingRepository.Where(t => baseLineTaskIdList.Contains(t.OriginalReReadingTaskId) && t.RequestReReadingUserId == _userInfo.Id && t.RequestReReadingReason == "AIR自动重阅基线").ToListAsync(); + + if (requestRecordList.Count != baseLineTaskIdList.Count) { - 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"]); - } - + //---后台数据有错误 + return ResponseOutput.NotOk(_localizer["VisitTask_DoctorConfiguration"]); } - private async Task SetMedicalReviewInvalidAsync(List influenceTaskList, bool isPMApply = true) + await ConfirmReReading(new ConfirmReReadingCommand() { - //将医学审核设置为失效 - var taskIdList = influenceTaskList.Select(t => t.Id).ToList(); + TrialId = command.TrialId, + RequestReReadingResultEnum = RequestReReadingResult.Agree, + //ConfirmReReadingList = new List() { new ConfirmReReadingDTO() { Id = requestRecord.Id, OriginalReReadingTaskId = task.Id } } + ConfirmReReadingList = requestRecordList.Select(t => new ConfirmReReadingDTO() { Id = t.Id, OriginalReReadingTaskId = t.OriginalReReadingTaskId }).ToList() + }, _visitTaskCommonService); - //PM 申请 医学审核任务状态为待审核、审核中的,设置为失效。 + return ResponseOutput.Ok(); - //IR 申请 当前任务进入医学审核,医学审核任务未签名且结论中是否有问题项,答案为否的,设置为失效 + } - if (isPMApply) - { - await _taskMedicalReviewRepository.UpdatePartialFromQueryAsync(t => taskIdList.Contains(t.VisitTaskId) && t.AuditState != MedicalReviewAuditState.HaveSigned, u => new TaskMedicalReview() { IsInvalid = true }); - } - else - { - await _taskMedicalReviewRepository.UpdatePartialFromQueryAsync(t => taskIdList.Contains(t.VisitTaskId) && t.IsHaveQuestion == false && t.AuditState != MedicalReviewAuditState.HaveSigned, u => new TaskMedicalReview() { IsInvalid = true }); - } - } + /// + /// 申请重阅 1:IR 2:PM + /// + /// + /// + [HttpPost] + [UnitOfWork] + [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })] - /// - /// PM 申请重阅 被同意 或者 PM 直接退回的时候影响 - /// - /// - /// - private async Task PMReReadingConfirmOrBackInfluenceAnalysisAsync(Guid subjectId) - { - if (await _visitTaskRepository.AnyAsync(t => t.IsAnalysisCreate && t.SubjectId == subjectId)) - { - await _subjectRepository.UpdatePartialFromQueryAsync(t => t.Id == subjectId, u => new Subject() { IsReReadingOrBackInfluenceAnalysis = true }); + public async Task ApplyReReading(ApplyReReadingCommand applyReReadingCommand) + { - } - } + var taskList = await _visitTaskRepository.Where(t => applyReReadingCommand.TaskIdList.Contains(t.Id), true).ToListAsync(); - public DateTime GetSuggessFinishTime(bool isInOrder, UrgentType urgentType) + var trialReadingCriterionId = taskList.First()!.TrialReadingCriterionId; + + var criterionConfig = (await _trialReadingCriterionRepository.Where(x => x.Id == trialReadingCriterionId).Select(x => new { x.ReadingTool, x.IsAutoCreate, x.IsReadingTaskViewInOrder }).FirstOrDefaultAsync()).IfNullThrowException(); + + + foreach (var task in taskList) { - var datetime = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, 22, 0, 0).AddDays(7); - return datetime; - } - - /// - /// 确认重阅与否 1同意 2 拒绝 - /// - /// - /// - /// - [HttpPost] - [UnitOfWork] - [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })] - - public async Task ConfirmReReading(ConfirmReReadingCommand agreeReReadingCommand, [FromServices] IVisitTaskHelpeService _visitTaskCommonService) - { - - var trialId = agreeReReadingCommand.TrialId; - - foreach (var item in agreeReReadingCommand.ConfirmReReadingList) + if (task.ReadingTaskState != ReadingTaskState.HaveSigned || (task.TaskState != TaskState.Effect && task.TaskState != TaskState.Freeze)) { - - var origenalTask = (await _visitTaskRepository.Where(t => item.OriginalReReadingTaskId == t.Id).FirstOrDefaultAsync()).IfNullThrowException(); - - - if ((origenalTask.TaskState != TaskState.Effect && origenalTask.TaskState != TaskState.Freeze)) - { - await _visitTaskReReadingRepository.BatchUpdateNoTrackingAsync(t => t.Id == item.Id, u => new VisitTaskReReading() { RequestReReadingConfirmUserId = _userInfo.Id, RequestReReadingResultEnum = RequestReReadingResult.Invalid }); - - //---当前申请重阅任务的状态,已被其他任务重阅已影响,不允许对该状态下的任务进行重阅同意与否操作 - return ResponseOutput.Ok(string.Empty, msg: _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.Id; - visitTaskReReadingAppply.RequestReReadingResultEnum = agreeReReadingCommand.RequestReReadingResultEnum; - 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 && (IsSpmOrCPM())) - { - 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 && (IsSpmOrCPM())) - { - - // 不管有序 无序 都会 回退访视 - 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 - - } - - } - - } - else - { - //---不符合 PM申请 SPM / CPM审批 | IR申请 PM 审批 - throw new BusinessValidationFailedException(_localizer["VisitTask_ReReadTaskAlreadyAffected"]); - } - - } - else if (agreeReReadingCommand.RequestReReadingResultEnum == RequestReReadingResult.Reject) - { - - if (origenalTask.ReReadingApplyState == ReReadingApplyState.DocotorHaveApplyed || origenalTask.ReReadingApplyState == ReReadingApplyState.TrialGroupHaveApplyed) - { - await _visitTaskRepository.UpdatePartialFromQueryAsync(t => t.Id == origenalTask.Id, u => new VisitTask() - { - ReReadingApplyState = ReReadingApplyState.Reject - }); - } - else - { - //---当前重阅任务状态不为已申请状态,不允许进行处理,请刷新页面 - throw new BusinessValidationFailedException(_localizer["VisitTask_InvalidReapplyStatus"]); - } - - } - - - - + //---未阅片完成,或者未生效的任务不允许申请重阅 + throw new BusinessValidationFailedException(_localizer["VisitTask_BackendData"]); + } + + if (task.ReReadingApplyState == ReReadingApplyState.DocotorHaveApplyed || task.ReReadingApplyState == ReReadingApplyState.TrialGroupHaveApplyed || task.ReReadingApplyState == ReReadingApplyState.Agree) + { + //---重阅已申请,或者重阅已同意状态下不允许申请重阅 + throw new BusinessValidationFailedException(_localizer["VisitTask_UnreadTask"]); } - - await _visitTaskRepository.SaveChangesAsync(); - - return ResponseOutput.Ok(); - } - - private void CopyForms(VisitTask newTask, VisitTask origenalTask) - { - - //自定义 - var readingCustomTagList = _readingCustomTagRepository.Where(t => t.VisitTaskId == origenalTask.Id).ToList(); - - foreach (var item in readingCustomTagList) - { - item.Id = Guid.Empty; - item.VisitTaskId = newTask.Id; - } - - _ = _readingCustomTagRepository.AddRangeAsync(readingCustomTagList).Result; - - - var readingTaskQuestionMarkList = _readingTaskQuestionMarkRepository.Where(t => t.VisitTaskId == origenalTask.Id).ToList(); - - foreach (var item in readingTaskQuestionMarkList) - { - item.Id = Guid.Empty; - item.VisitTaskId = newTask.Id; - } - - _ = _readingTaskQuestionMarkRepository.AddRangeAsync(readingTaskQuestionMarkList).Result; - - var readingTaskQuestionAnswerList = _readingTaskQuestionAnswerRepository.Where(t => t.VisitTaskId == origenalTask.Id).ToList(); - - foreach (var item in readingTaskQuestionAnswerList) - { - item.Id = Guid.Empty; - item.VisitTaskId = newTask.Id; - } - _ = _readingTaskQuestionAnswerRepository.AddRangeAsync(readingTaskQuestionAnswerList).Result; - - - - //ReadingTableAnswerRowInfo ReadingTableQuestionAnswer 一起加 - var readingTableAnswerRowInfoList = _readingTableAnswerRowInfoRepository.Where(t => t.VisitTaskId == origenalTask.Id).Include(t => t.LesionAnswerList).ToList(); - - foreach (var item in readingTableAnswerRowInfoList) - { - - var originalVisitTaskId = item.VisitTaskId; - var originalFristAddTaskId = item.FristAddTaskId; - - item.Id = NewId.NextSequentialGuid(); - item.VisitTaskId = newTask.Id; - - //默认值是当前任务添加的 - item.FristAddTaskId = originalVisitTaskId == originalFristAddTaskId ? newTask.Id : item.FristAddTaskId; - - - foreach (var item2 in item.LesionAnswerList) - { - item2.Id = Guid.Empty; - item2.RowId = item.Id; - item2.VisitTaskId = newTask.Id; - } - } - - _ = _readingTableAnswerRowInfoRepository.AddRangeAsync(readingTableAnswerRowInfoList).Result; - - - - - - } - - - /// - /// PM 设置任务 退回 - /// - /// - [HttpPut("{trialId:guid}/{taskId:guid}")] - [UnitOfWork] - [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })] - - public async Task PMSetTaskBack(Guid trialId, Guid taskId) - { - - //var trialConfig = (await _trialRepository.Where(t => t.Id == trialId).Select(t => new { TrialId = t.Id, t.IsReadingTaskViewInOrder, t.ReadingType }).FirstOrDefaultAsync()).IfNullThrowException(); - - - var task = (await _visitTaskRepository.Where(t => t.Id == taskId).FirstOrDefaultAsync()).IfNullThrowException(); - - var criterionConfig = (await _trialReadingCriterionRepository.Where(x => x.Id == task.TrialReadingCriterionId).Select(x => new { x.ReadingTool, x.CriterionType, x.IsAutoCreate, x.IsAdditionalAssessment, x.IsReadingTaskViewInOrder }).FirstOrDefaultAsync()).IfNullThrowException(); - - if (criterionConfig.IsAutoCreate == false) - { - //---手动生成任务的不允许在此入口影像退回 - return ResponseOutput.NotOk(_localizer["VisitTask_NoImageReturn"]); - } - - if (task.TaskState != TaskState.Effect || task.ReadingCategory != ReadingCategory.Visit || task.ReadingTaskState == ReadingTaskState.HaveSigned) - { - //---仅仅允许针对生效、未完成的访视任务进行退回操作,请刷新页面数据 - return ResponseOutput.NotOk(_localizer["VisitTask_NonEffectiveTaskCannotBeReturned"]); - } - - - if (await _subjectVisitRepository.AnyAsync(t => t.Id == task.SourceSubjectVisitId && t.CheckState != CheckStateEnum.CVPassed)) - { - //---当前访视已回退到影像上传,不允许继续回退! - return ResponseOutput.NotOk(_localizer["VisitTask_NoFurtherReturn"]); - } - - - if (task.IsAnalysisCreate) - { - //---一致性分析的任务,不允许设置退回 - return ResponseOutput.NotOk(_localizer["VisitTask_ConsistencyTaskCannotBeReturned"]); - } - - Expression> filterExpression = t => t.TrialId == trialId && t.SubjectId == task.SubjectId && (t.TaskState == TaskState.Effect || t.TaskState == TaskState.Freeze) && t.TaskAllocationState == TaskAllocationState.Allocated; - - - #region 退回到访视 不区分标准 - //if (criterionConfig.CriterionType == CriterionType.RECIST1Point1 && criterionConfig.IsAdditionalAssessment) - //{ - // //影像退回,必定影响两个标准的任务 - // filterExpression = filterExpression.And(t => t.TrialReadingCriterionId == task.TrialReadingCriterionId || t.TrialReadingCriterion.CriterionType == CriterionType.RECIST1Pointt1_MB); - - - //} - //else - //{ - // //默认影响的都是该标准的任务 - // filterExpression = filterExpression.And(t => t.TrialReadingCriterionId == task.TrialReadingCriterionId); - //} - #endregion - - - //PM 才允许操作 if (IsPMOrAPm()) { + if (criterionConfig.IsAutoCreate == false) + { + //---手动生成任务的不允许PM 申请影像重阅 + return ResponseOutput.NotOk(_localizer["VisitTask_NoPMRecheck"]); + } - #region 有序 无序公用流程 + if (task.IsAnalysisCreate) + { + //---PM 不允许对一致性分析任务进行申请重阅 + throw new BusinessValidationFailedException(_localizer["VisitTask_Reapply"]); + } + + if (task.ReadingCategory != ReadingCategory.Visit) + { + //---PM 仅仅允许对访视类型的任务申请重阅 + throw new BusinessValidationFailedException(_localizer["VisitTask_ConsistencyAnalysis"]); + } - //执行类似一致性核查回退流程 回退访视到影像上传流程 - await VisitBackAsync(task.SourceSubjectVisitId); - - #endregion - - - - //有序 + // 有序 一个受试者访视重阅未处理完,不能申请其他的 if (criterionConfig.IsReadingTaskViewInOrder == ReadingOrder.InOrder) { - - //Expression> filterExpression = t => t.TrialId == trialId && t.SubjectId == task.SubjectId && t.TaskState == TaskState.Effect && t.IsAnalysisCreate == false && t.TaskAllocationState == TaskAllocationState.Allocated; - - filterExpression = filterExpression.And(t => t.IsAnalysisCreate == false); - - - - //另一个阅片人的任务根据任务进度自动进入PM退回或PM申请重阅 - filterExpression = filterExpression.And(t => t.VisitTaskNum >= task.VisitTaskNum); - - - var influenceTaskList = await _visitTaskRepository.Where(filterExpression, true).ToListAsync(); - - - - #region 方式二 - - - //pm退回的时候,影响的任务里不一定有该任务id 双重 分配了一个人,退回的时候,选择的是未分配的 - - //var origenalTask = influenceTaskList.Where(t => t.Id == task.Id).FirstOrDefault(); - - var origenalTask = await _visitTaskRepository.FindAsync(task.Id); - - - foreach (var influenceTask in influenceTaskList) + if (await _visitTaskReReadingRepository.AnyAsync(t => t.OriginalReReadingTask.TrialId == task.TrialId && t.OriginalReReadingTask.SubjectId == task.SubjectId && t.OriginalReReadingTask.TaskState == TaskState.Effect + && t.OriginalReReadingTask.TrialReadingCriterionId == task.TrialReadingCriterionId + && t.OriginalReReadingTask.ReadingTaskState == ReadingTaskState.HaveSigned && t.RequestReReadingType == RequestReReadingType.TrialGroupApply && t.RequestReReadingResultEnum == RequestReReadingResult.Default)) { - - //已签名的任务 设置转变后的标志 - 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 == task.Id) - { - - await InfluenceAddtioncalEvaluationCritrionAsync(task, influenceTaskList.Where(t => t.Id != task.Id).Where(t => t.SourceSubjectVisitId != null).Select(t => t.SourceSubjectVisitId!.Value).Distinct().ToList()); - - await PMReReadingConfirmOrBackInfluenceAnalysisAsync(influenceTask.SubjectId); - - await SetMedicalReviewInvalidAsync(influenceTaskList); - - - influenceTask.IsPMSetBack = true; - } - - if (influenceTask.ReadingTaskState == ReadingTaskState.HaveSigned) - { - influenceTask.TaskState = TaskState.HaveReturned; - origenalTask.TaskInfluenceList.Add(new TaskInfluence() { InfluenceTaskId = influenceTask.Id, OptType = ReReadingOrBackOptType.Return }); - } - else - { - influenceTask.TaskState = TaskState.Adbandon; - origenalTask.TaskInfluenceList.Add(new TaskInfluence() { InfluenceTaskId = influenceTask.Id, OptType = ReReadingOrBackOptType.Abandon }); - } - + //---当前为有序阅片,该受试者已有访视已申请重阅还未处理(项目组申请),暂不能继续申请重阅 + return ResponseOutput.NotOk(_localizer["VisitTask_VisitTypeRestriction"]); } - - #endregion - - - } - else - { - //无序 无序阅片没有 全局 肿瘤学 - // 申请该访视的任务 申请人失效 另外一个人重阅重置或者失效 + task.ReReadingApplyState = ReReadingApplyState.TrialGroupHaveApplyed; - var currentVisitList = await _visitTaskRepository.Where(t => t.SourceSubjectVisitId == task.SourceSubjectVisitId && t.ReadingCategory == ReadingCategory.Visit && (t.TaskState == TaskState.Effect || t.TaskState == TaskState.Freeze) && t.VisitTaskNum == task.VisitTaskNum, true).ToListAsync(); - - await SetMedicalReviewInvalidAsync(currentVisitList); - - //var origenalTask = currentVisitList.Where(t => t.Id == task.Id).First(); - - var origenalTask = await _visitTaskRepository.FindAsync(task.Id); - - foreach (var influenceTask in currentVisitList) - { - if (influenceTask.ReadingTaskState == ReadingTaskState.HaveSigned) - { - //另外阅片人完成阅片了 就设置为重阅重置 - influenceTask.TaskState = TaskState.HaveReturned; - - origenalTask.TaskInfluenceList.Add(new TaskInfluence() { InfluenceTaskId = influenceTask.Id, OptType = ReReadingOrBackOptType.Return }); - } - else - { - influenceTask.TaskState = TaskState.Adbandon; - - origenalTask.TaskInfluenceList.Add(new TaskInfluence() { InfluenceTaskId = influenceTask.Id, OptType = ReReadingOrBackOptType.Abandon }); - } - - } - - } } - else + if (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.IndependentReviewer) { - //---仅PM 可以进行回退操作 - return ResponseOutput.NotOk(_localizer["VisitTask_PMOnlyAllowedForReturn"]); - } + task.ReReadingApplyState = ReReadingApplyState.DocotorHaveApplyed; + //在PM 的申请重阅的影响列表里也不能申请重阅 + + var pmApply = await _visitTaskReReadingRepository.Where(t => t.OriginalReReadingTask.TrialId == task.TrialId && t.OriginalReReadingTask.SubjectId == task.SubjectId && t.OriginalReReadingTask.TaskState == TaskState.Effect && t.OriginalReReadingTask.ReadingCategory == ReadingCategory.Visit + && t.OriginalReReadingTask.ReadingTaskState == ReadingTaskState.HaveSigned && t.RequestReReadingType == RequestReReadingType.TrialGroupApply && t.RequestReReadingResultEnum == RequestReReadingResult.Default).Include(t => t.OriginalReReadingTask).FirstOrDefaultAsync(); - - - await _visitTaskRepository.SaveChangesAsync(); - - return ResponseOutput.Ok(); - } - - - /// - /// 基线退回 影响附加评估标准 是否参与评估 - /// - /// - private async Task InfluenceAddtioncalEvaluationCritrionAsync(VisitTask task, List otherVisitIdList, bool isImageBack = true) - { - - var criterion = await _trialReadingCriterionRepository.FindAsync(task.TrialReadingCriterionId); - - if (criterion.CriterionType == CriterionType.RECIST1Point1) - { - //影像回退了|| IR 申请及基线重阅 - if (_subjectVisitRepository.Any(t => t.Id == task.SourceSubjectVisitId && t.IsBaseLine)) + // 有序 + if (criterionConfig.IsReadingTaskViewInOrder == ReadingOrder.InOrder) { - await _subjectCriteriaEvaluationRepository.UpdatePartialFromQueryAsync(t => t.TrialReadingCriterion.IsAutoCreate == false && t.SubjectId == task.SubjectId, u => new SubjectCriteriaEvaluation() + // 针对同一个subject 不同阅片人 针对同一个访视申请重阅,是允许的,所以同一阅片人,针对同一suject 有访视申请重阅还未处理,不允许申请重阅 + if (await _visitTaskReReadingRepository.AnyAsync(t => t.OriginalReReadingTask.TrialId == task.TrialId && t.OriginalReReadingTask.SubjectId == task.SubjectId && t.OriginalReReadingTask.TaskState == TaskState.Effect + && t.OriginalReReadingTask.TrialReadingCriterionId == task.TrialReadingCriterionId && t.OriginalReReadingTask.DoctorUserId == task.DoctorUserId + && t.OriginalReReadingTask.ReadingTaskState == ReadingTaskState.HaveSigned && t.RequestReReadingType == RequestReReadingType.DocotorApply && t.RequestReReadingResultEnum == RequestReReadingResult.Default)) { - IsJoinEvaluation = false - }); - - //删除筛选的访视数据 - await _subjectCriteriaEvaluationVisitFilterRepository.BatchDeleteNoTrackingAsync(t => t.TrialReadingCriterion.CriterionType == CriterionType.RECIST1Pointt1_MB && t.SubjectId == task.SubjectId); - - //删除筛选的序列数据 - await _subjectCriteriaEvaluationVisitStudyFilterRepository.BatchDeleteNoTrackingAsync(t => t.TrialReadingCriterion.CriterionType == CriterionType.RECIST1Pointt1_MB && t.SubjectVisit.SubjectId == task.SubjectId); - } - else if (isImageBack) - { - //当前访视筛选状态重置,任务生成状态重置 - if (task.SourceSubjectVisitId != null) - { - await _subjectCriteriaEvaluationVisitFilterRepository.UpdatePartialFromQueryAsync(t => t.TrialReadingCriterion.CriterionType == CriterionType.RECIST1Pointt1_MB && t.SubjectVisit.SubjectId == task.SubjectId && t.SubjectVisitId == task.SourceSubjectVisitId, - t => new SubjectCriteriaEvaluationVisitFilter() - { - ImageFilterState = ImageFilterState.None, - ImageDeterminationResultState = ImageDeterminationResultState.None, - IsGeneratedTask = false - }); - - //删除序列数据 - await _subjectCriteriaEvaluationVisitStudyFilterRepository.BatchDeleteNoTrackingAsync(t => t.TrialReadingCriterion.CriterionType == CriterionType.RECIST1Pointt1_MB && t.SubjectVisit.SubjectId == task.SubjectId && t.SubjectVisitId == task.SourceSubjectVisitId); + //---当前为有序阅片,该受试者已有访视已申请重阅还未处理,暂不能继续申请重阅 + throw new BusinessValidationFailedException(_localizer["VisitTask_SequentialReading"]); } - //BM后续访视 ,筛选状态不变,任务生成状态重置(实际该访视任务状态 可能是重阅重置了或者失效了,需要后续生成,或者取消分配了,需要后续重新分配) - await _subjectCriteriaEvaluationVisitFilterRepository.UpdatePartialFromQueryAsync(t => t.TrialReadingCriterion.CriterionType == CriterionType.RECIST1Pointt1_MB && t.SubjectVisit.SubjectId == task.SubjectId && otherVisitIdList.Contains(t.SubjectVisitId), - t => new SubjectCriteriaEvaluationVisitFilter() + + if (pmApply != null) + { + var originalTask = pmApply.OriginalReReadingTask; + + //PM 有序影响列表 + if (await _visitTaskRepository.Where(t => t.TrialId == originalTask.TrialId && t.SubjectId == originalTask.SubjectId && t.TaskState == TaskState.Effect && t.TaskAllocationState == TaskAllocationState.Allocated && t.IsAnalysisCreate == false && t.TrialReadingCriterionId == originalTask.TrialReadingCriterionId && t.VisitTaskNum >= originalTask.VisitTaskNum) + .AnyAsync(t => t.VisitTaskNum == task.VisitTaskNum)) { - IsGeneratedTask = false - }); + //---当前为有序阅片,影像存在问题,项目组已申请回退,暂不能申请重阅 + throw new BusinessValidationFailedException(_localizer["VisitTask_ImageProblem"]); + } + + } + + + + Expression> filterExpression = t => t.TrialId == task.TrialId && t.SubjectId == task.SubjectId && t.TaskState == TaskState.Effect && t.TrialReadingCriterionId == task.TrialReadingCriterionId + && t.DoctorUserId == task.DoctorUserId && t.IsAnalysisCreate == false && t.VisitTaskNum > task.VisitTaskNum; + + + + if (task.ReadingCategory == ReadingCategory.Global && await _visitTaskRepository.AnyAsync(filterExpression.And(t => t.ReadingCategory == ReadingCategory.Global))) + { + //---有序阅片,只允许申请该受试者阅片人最后一次完成全局任务重阅 + throw new BusinessValidationFailedException(_localizer["VisitTask_LastReading"]); + } + + if (task.ReadingCategory == ReadingCategory.Oncology && await _visitTaskRepository.AnyAsync(filterExpression.And(t => t.ReadingCategory == ReadingCategory.Oncology && t.ReadingTaskState == ReadingTaskState.HaveSigned))) + { + //---有序阅片,只允许申请该受试者阅片人最后一次完成肿瘤学任务重阅 + throw new BusinessValidationFailedException(_localizer["VisitTask_LastOncologistRecheck"]); + } + + if (task.ReadingCategory == ReadingCategory.Judge && await _visitTaskRepository.AnyAsync(filterExpression.And(t => t.ReadingCategory == ReadingCategory.Judge && t.ReadingTaskState == ReadingTaskState.HaveSigned))) + { + //---有序阅片,只允许申请该受试者阅片人最后一次完成裁判的任务重阅 + throw new BusinessValidationFailedException(_localizer["VisitTask_LastAdjudicatorRecheck"]); + } + } else { - //IR 端 非基线申请重阅 不影响 + + if (pmApply != null) + { + var originalTask = pmApply.OriginalReReadingTask; + + //PM 无序影响列表 + if (await _visitTaskRepository.Where(t => t.TrialId == originalTask.TrialId && t.SubjectId == originalTask.SubjectId && t.TaskState == TaskState.Effect && t.TaskAllocationState == TaskAllocationState.Allocated && t.IsAnalysisCreate == false && t.TrialReadingCriterionId == originalTask.TrialReadingCriterionId) + .Where(t => t.Id == originalTask.Id || t.Id == originalTask.JudgeVisitTaskId) + .AnyAsync(t => t.VisitTaskNum == task.VisitTaskNum)) + { + //---当前为无序阅片,影像存在问题,项目组已申请回退,暂不能申请重阅 + throw new BusinessValidationFailedException(_localizer["VisitTask_RandomInvalidRereading"]); + } + + } + + //也要支持裁判重阅240701 + + if (task.ReadingCategory != ReadingCategory.Visit && task.ReadingCategory != ReadingCategory.Judge) + { + //---无序阅片,仅仅允许IR 申请 访视、裁判类型类别的任务进行重阅 + throw new BusinessValidationFailedException(_localizer["VisitTask_IRGlobalRecheck"]); + } } + } - - - } - - //包括临床数据签名状态 - private async Task VisitBackAsync(Guid? subjectVisitId) - { - var sv = (await _subjectVisitRepository.FirstOrDefaultAsync(t => t.Id == subjectVisitId)).IfNullThrowException(); - - - //需要重新产生任务 - sv.IsVisitTaskGenerated = false; - sv.IsPMBackOrReReading = true; - - sv.AuditState = AuditStateEnum.None; - sv.SubmitState = SubmitStateEnum.ToSubmit; - sv.ReadingStatus = ReadingStatusEnum.ImageNotSubmit; - - //回退后,回退状态恢复 - sv.RequestBackState = RequestBackStateEnum.NotRequest; - sv.IsCheckBack = false; - sv.CheckBackTime = null; - sv.CheckState = CheckStateEnum.None; - sv.CheckChallengeState = CheckChanllengeTypeEnum.None; - - sv.SVENDTC = null; - sv.SVSTDTC = null; - - sv.PreliminaryAuditTime = null; - sv.SubmitTime = null; - sv.ReviewAuditTime = null; - sv.CurrentActionUserExpireTime = null; - - - sv.IsTake = false; - sv.CurrentActionUserId = null; - sv.PreliminaryAuditUserId = null; - sv.ReviewAuditUserId = null; - - - if (sv.IsBaseLine) + //AIR 不加验证 + if (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.AIR) { - await _readingClinicalDataReposiotry.UpdatePartialFromQueryAsync(t => t.ReadingId == sv.Id && (t.ClinicalDataTrialSet.ClinicalDataLevel == ClinicalLevel.Subject || t.ClinicalDataTrialSet.ClinicalDataLevel == ClinicalLevel.SubjectVisit), c => new ReadingClinicalData() { IsSign = false, ReadingClinicalDataState = ReadingClinicalDataStatus.HaveUploaded }); - + task.ReReadingApplyState = ReReadingApplyState.DocotorHaveApplyed; } - else + + + + var rootReReadingTaskId = _visitTaskReReadingRepository.Where(t => t.NewReReadingTaskId == task.Id).Select(u => u.RootReReadingTaskId).FirstOrDefault(); + + //添加申请记录 + var visitTaskReReading = await _visitTaskReReadingRepository.AddAsync(new VisitTaskReReading() { - await _readingClinicalDataReposiotry.UpdatePartialFromQueryAsync(t => t.ReadingId == sv.Id && t.ClinicalDataTrialSet.ClinicalDataLevel == ClinicalLevel.SubjectVisit, c => new ReadingClinicalData() - { - IsSign = false, - ReadingClinicalDataState = ReadingClinicalDataStatus.HaveUploaded, - IsBlind = null, - IsComplete = null - }); + TrialId = applyReReadingCommand.TrialId, + RootReReadingTaskId = rootReReadingTaskId == Guid.Empty ? task.Id : rootReReadingTaskId, + OriginalReReadingTaskId = task.Id, + RequestReReadingTime = DateTime.Now, + RequestReReadingUserId = _userInfo.Id, + IsCopyOrigenalForms = applyReReadingCommand.IsCopyOrigenalForms, + IsCopyFollowForms = applyReReadingCommand.IsCopyFollowForms, + RequestReReadingReason = applyReReadingCommand.RequestReReadingReason, + RequestReReadingType = applyReReadingCommand.RequestReReadingType, + + }); + } + + + await _visitTaskRepository.SaveChangesAsync(); + + 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) + { + //将医学审核设置为失效 + var taskIdList = influenceTaskList.Select(t => t.Id).ToList(); + + //PM 申请 医学审核任务状态为待审核、审核中的,设置为失效。 + + //IR 申请 当前任务进入医学审核,医学审核任务未签名且结论中是否有问题项,答案为否的,设置为失效 + + if (isPMApply) + { + await _taskMedicalReviewRepository.UpdatePartialFromQueryAsync(t => taskIdList.Contains(t.VisitTaskId) && t.AuditState != MedicalReviewAuditState.HaveSigned, u => new TaskMedicalReview() { IsInvalid = true }); + + } + else + { + + await _taskMedicalReviewRepository.UpdatePartialFromQueryAsync(t => taskIdList.Contains(t.VisitTaskId) && t.IsHaveQuestion == false && t.AuditState != MedicalReviewAuditState.HaveSigned, u => new TaskMedicalReview() { IsInvalid = true }); + } + } + + /// + /// PM 申请重阅 被同意 或者 PM 直接退回的时候影响 + /// + /// + /// + private async Task PMReReadingConfirmOrBackInfluenceAnalysisAsync(Guid subjectId) + { + if (await _visitTaskRepository.AnyAsync(t => t.IsAnalysisCreate && t.SubjectId == subjectId)) + { + await _subjectRepository.UpdatePartialFromQueryAsync(t => t.Id == subjectId, u => new Subject() { IsReReadingOrBackInfluenceAnalysis = true }); + + } + + } + + public DateTime GetSuggessFinishTime(bool isInOrder, UrgentType urgentType) + { + + var datetime = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, 22, 0, 0).AddDays(7); + + return datetime; + } + + /// + /// 确认重阅与否 1同意 2 拒绝 + /// + /// + /// + /// + [HttpPost] + [UnitOfWork] + [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })] + + public async Task ConfirmReReading(ConfirmReReadingCommand agreeReReadingCommand, [FromServices] IVisitTaskHelpeService _visitTaskCommonService) + { + + var trialId = agreeReReadingCommand.TrialId; + + foreach (var item in agreeReReadingCommand.ConfirmReReadingList) + { + + var origenalTask = (await _visitTaskRepository.Where(t => item.OriginalReReadingTaskId == t.Id).FirstOrDefaultAsync()).IfNullThrowException(); + + + if ((origenalTask.TaskState != TaskState.Effect && origenalTask.TaskState != TaskState.Freeze)) + { + await _visitTaskReReadingRepository.BatchUpdateNoTrackingAsync(t => t.Id == item.Id, u => new VisitTaskReReading() { RequestReReadingConfirmUserId = _userInfo.Id, RequestReReadingResultEnum = RequestReReadingResult.Invalid }); + + //---当前申请重阅任务的状态,已被其他任务重阅已影响,不允许对该状态下的任务进行重阅同意与否操作 + return ResponseOutput.Ok(string.Empty, msg: _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(); - //await _repository.AddAsync(new CheckChallengeDialog() { SubjectVisitId = subjectVisitId, TalkContent = "PM/APM同意一致性核查回退。", UserTypeEnum = (UserTypeEnum)_userInfo.UserTypeEnumInt }); - - await _trialQCQuestionAnswerRepository.BatchDeleteNoTrackingAsync(t => t.SubjectVisitId == subjectVisitId); - await _dicomInstanceRepository.BatchDeleteNoTrackingAsync(t => t.DicomSerie.IsDeleted); - await _dicomSeriesRepository.BatchDeleteNoTrackingAsync(t => t.IsDeleted); - - var success = await _subjectVisitRepository.SaveChangesAsync(); - - } + //更新申请信息 + var visitTaskReReadingAppply = await _visitTaskReReadingRepository.FirstOrDefaultAsync(t => t.Id == item.Id); + visitTaskReReadingAppply.RequestReReadingConfirmUserId = _userInfo.Id; + visitTaskReReadingAppply.RequestReReadingResultEnum = agreeReReadingCommand.RequestReReadingResultEnum; + visitTaskReReadingAppply.RequestReReadingRejectReason = agreeReReadingCommand.RequestReReadingRejectReason; - private bool IsPMOrAPm() - { - return _userInfo.UserTypeEnumInt == (int)UserTypeEnum.ProjectManager || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.APM; - } + Expression> filterExpression = t => t.TrialId == trialId && t.SubjectId == origenalTask.SubjectId && (t.TaskState == TaskState.Effect || t.TaskState == TaskState.Freeze) && t.TaskAllocationState == TaskAllocationState.Allocated; - private bool IsSpmOrCPM() - { - return _userInfo.UserTypeEnumInt == (int)UserTypeEnum.SPM || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.CPM; - } + //是否是一致性分析任务 正常申请 会影响一致性分析任务 + filterExpression = filterExpression.And(t => t.IsAnalysisCreate == origenalTask.IsAnalysisCreate); - /// - /// 影响提示列表 重阅仅仅针对已完成的任务申请 退回针对的是未完成的(退回仅仅针对是访视类型的) - /// - /// - /// 重阅还是直接回退 - /// 申请记录的Id - /// - [HttpGet("{taskId:guid}/{isReReading:bool}")] - public async Task<(List, object)> GetReReadingOrBackInfluenceTaskList(Guid taskId, bool isReReading, Guid? applyId) - { - var isIRAppyTaskInfluenced = false; - - var filterObj = (await _visitTaskRepository.FirstOrDefaultNoTrackingAsync(t => t.Id == taskId)).IfNullThrowException(); - var trialId = filterObj.TrialId; - - 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; - - //是否是一致性分析任务 (一致性分析的任务 不会产生裁判 肿瘤学 仅仅有生成的访视和全局) - - filterExpression = filterExpression.And(t => t.IsAnalysisCreate == filterObj.IsAnalysisCreate); - - //IR 申请1.1 基线重阅,影响附加评估所有的任务 + //IR 申请1.1 基线重阅,影响附加评估两个IR所有的任务 var isIR1Point1AdditionalAssessmentBaseline = false; //附加评估 IR 和PM 看到的影响列表不一样 + + //1.1 有附加评估,会影响其他标准的任务 if (criterionConfig.CriterionType == CriterionType.RECIST1Point1 && criterionConfig.IsAdditionalAssessment) { - - // IR 申请 PM 同意 - if (((IsPMOrAPm() && applyId != null && await _visitTaskReReadingRepository.AnyAsync(t => t.Id == applyId && t.CreateUser.UserTypeEnum == UserTypeEnum.IndependentReviewer)) - || (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.IndependentReviewer && applyId == null))) + // PM申请 SPM / CPM审批 + if (visitTaskReReadingAppply.RequestReReadingType == RequestReReadingType.TrialGroupApply && (IsSpmOrCPM())) + { + 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 == filterObj.SourceSubjectVisitId && t.IsBaseLine == true)) + if ((IsPMOrAPm()) && _subjectVisitRepository.Any(t => t.Id == origenalTask.SourceSubjectVisitId && t.IsBaseLine == true)) { isIR1Point1AdditionalAssessmentBaseline = true; - //filterExpression = filterExpression.And(t => t.TrialReadingCriterionId == filterObj.TrialReadingCriterionId || t.TrialReadingCriterion.CriterionType == CriterionType.RECIST1Pointt1_MB); - } // 1.1 非基线任务不影响BM任务 else { - filterExpression = filterExpression.And(t => t.TrialReadingCriterionId == filterObj.TrialReadingCriterionId); + filterExpression = filterExpression.And(t => t.TrialReadingCriterionId == origenalTask.TrialReadingCriterionId); } - - } - //(1、PM回退,PM申请重阅,SPM同意回退) - else - { - filterExpression = filterExpression.And(t => t.TrialReadingCriterionId == filterObj.TrialReadingCriterionId || t.TrialReadingCriterion.CriterionType == CriterionType.RECIST1Pointt1_MB); - } } else { //默认影响的都是该标准的任务 - filterExpression = filterExpression.And(t => t.TrialReadingCriterionId == filterObj.TrialReadingCriterionId); + filterExpression = filterExpression.And(t => t.TrialReadingCriterionId == origenalTask.TrialReadingCriterionId); } - - //重阅影响 - if (isReReading) + if (agreeReReadingCommand.RequestReReadingResultEnum == RequestReReadingResult.Agree) { - - - - //IR 申请 PM 同意 仅仅影响自己 - - if ((IsPMOrAPm() && applyId != null && await _visitTaskReReadingRepository.AnyAsync(t => t.Id == applyId && t.CreateUser.UserTypeEnum == UserTypeEnum.IndependentReviewer)) - || (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.IndependentReviewer && applyId == null)) + //PM申请 SPM / CPM审批 回退访视,因此这里不生成访视任务 影响多个标准的任务 + if (visitTaskReReadingAppply.RequestReReadingType == RequestReReadingType.TrialGroupApply && (IsSpmOrCPM())) { - //当前任务及其之后的所有访视任务、全局任务、裁判任务、肿瘤学阅片任务 + // 不管有序 无序 都会 回退访视 + if (origenalTask.ReadingCategory == ReadingCategory.Visit) + { + //执行类似一致性核查回退流程 + await VisitBackAsync(origenalTask.SourceSubjectVisitId); - //有序 + } + else + { + //---仅允许同意访视类型的任务重阅 + throw new BusinessValidationFailedException(_localizer["VisitTask_ReReadTaskNotApplied"]); + } + + //有序阅片 if (criterionConfig.IsReadingTaskViewInOrder == ReadingOrder.InOrder) { - switch (filterObj.ReadingCategory) + + //访视影响当前以及当前之后的 两个阅片人的 + 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) { - case ReadingCategory.Visit: - //影响当前医生 以及当前医生之后的 1、访视任务 已经读完的 - //2、后续任务如果是全局、肿瘤学阅片任务,状态为阅片完成标记为重阅重置;若在阅片中,则标记为失效;若为待阅片,则标记为失效; - //3、当前任务、后续访视任务或者全局任务触发了裁判任务,若裁判任务状态为阅片完成,则标记为重阅重置;若在阅片中或待阅片,则标记为失效 + //处理申请的任务 + if (influenceTask.Id == origenalTask.Id) + { + ReReadingTaskTrackingDeal(influenceTask, agreeReReadingCommand); - //申请的是转化的,那么影响列表要排除转化之前的 - if (criterionConfig.CriterionType == CriterionType.IRECIST1Point1 && filterObj.BeforeConvertedTaskId != null) + 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; - - filterExpression = filterExpression.And(t => (t.VisitTaskNum > filterObj.VisitTaskNum && - ( - ((t.ReadingCategory == ReadingCategory.Visit || t.ReadingCategory == ReadingCategory.Global) && t.DoctorUserId == filterObj.DoctorUserId) - // 裁判 肿瘤学是另外的医生做 - || t.ReadingCategory == ReadingCategory.Judge - || t.ReadingCategory == ReadingCategory.Oncology - )) || t.Id == filterObj.Id) - ; - } - // IR 申请1.1 基线重阅,影响附加评估所有的任务 - else if (isIR1Point1AdditionalAssessmentBaseline) - { - filterExpression = filterExpression.And(t => t.VisitTaskNum >= filterObj.VisitTaskNum && - ((( - ((t.ReadingCategory == ReadingCategory.Visit || t.ReadingCategory == ReadingCategory.Global) && t.DoctorUserId == filterObj.DoctorUserId) - // 裁判 肿瘤学是另外的医生做 - || t.ReadingCategory == ReadingCategory.Judge - || t.ReadingCategory == ReadingCategory.Oncology - ) && t.TrialReadingCriterionId == filterObj.TrialReadingCriterionId) || (t.TrialReadingCriterion.CriterionType == CriterionType.RECIST1Pointt1_MB)) - ); + trakingOrigenalTask?.TaskInfluenceList.Add(new TaskInfluence() { InfluenceTaskId = influenceTask.Id, OptType = ReReadingOrBackOptType.Return }); } else { - filterExpression = filterExpression.And(t => t.VisitTaskNum >= filterObj.VisitTaskNum && + 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 == filterObj.DoctorUserId) + ((t.ReadingCategory == ReadingCategory.Visit || t.ReadingCategory == ReadingCategory.Global) && t.DoctorUserId == origenalTask.DoctorUserId) // 裁判 肿瘤学是另外的医生做 || t.ReadingCategory == ReadingCategory.Judge || t.ReadingCategory == ReadingCategory.Oncology @@ -2696,43 +1841,28 @@ namespace IRaCIS.Core.Application.Service.Allocation + break; + + //不影响后续访视: (t.ReadingCategory == ReadingCategory.Visit && t.ReadingTaskState != ReadingTaskState.WaitReading) || case ReadingCategory.Global: - // 1、后续任务如果是访视任务,均不处理; - //2、后续任务如果是全局、状态为阅片完成则标记为重阅重置,若阅片中或待阅片则不处理; - //3、当前任务或者全局任务触发了裁判任务,若裁判任务状态为阅片完成,则标记为重阅重置;若在阅片中或待阅片,则标记为失效 - //4、后续任务为肿瘤学阅片任务,状态为阅片完成标记为重阅重置;若在阅片中,则标记为失效;若为待阅片,则标记为失效; - - //filterExpression = filterExpression.And(t => t.VisitTaskNum >= filterObj.VisitTaskNum && - //((t.DoctorUserId == filterObj.DoctorUserId && ((t.ReadingCategory == ReadingCategory.Visit && t.ReadingTaskState == ReadingTaskState.HaveSigned) || t.ReadingCategory == ReadingCategory.Global)) || (t.ReadingCategory == ReadingCategory.Oncology) || (t.ReadingCategory == ReadingCategory.Judge))); - - - filterExpression = filterExpression.And(t => t.VisitTaskNum > filterObj.VisitTaskNum && - ( - (t.DoctorUserId == filterObj.DoctorUserId && t.ReadingCategory == ReadingCategory.Global) - || (t.ReadingCategory == ReadingCategory.Oncology) - || (t.ReadingCategory == ReadingCategory.Judge) - ) || t.Id == filterObj.Id); - + 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; - //1、后续任务如果是访视任务、全局任务或裁判任务,均不处理; case ReadingCategory.Oncology: - //仅仅影响自己 - filterExpression = filterExpression.And(t => t.Id == filterObj.Id); + //仅仅影响自己 后续任务如果是访视任务、全局任务或裁判任务,均不处理 + filterExpression = filterExpression.And(t => t.Id == origenalTask.Id); break; - //(只允许申请该阅片人最后一次完成裁判的任务重阅)申请的时候做了限制 case ReadingCategory.Judge: - // 1、后续任务如果是访视任务、全局任务,均不处理; - //2、后续若有肿瘤学阅片,若肿瘤学阅片任务状态为阅片完成,则标记为重阅重置;若为阅片中则标记为失效,如为待阅片,则取消分配 - //裁判的影响自己 和后续肿瘤学阅片(不是自己做的) - filterExpression = filterExpression.And(t => t.Id == filterObj.Id || t.VisitTaskNum > filterObj.VisitTaskNum && t.ReadingCategory == ReadingCategory.Oncology); + filterExpression = filterExpression.And(t => t.Id == origenalTask.Id || t.VisitTaskNum > origenalTask.VisitTaskNum && t.ReadingCategory == ReadingCategory.Oncology); break; @@ -2740,373 +1870,1242 @@ namespace IRaCIS.Core.Application.Service.Allocation 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 == filterObj.Id || t.Id == filterObj.JudgeVisitTaskId); - } + filterExpression = filterExpression.And(t => t.Id == origenalTask.Id || t.Id == origenalTask.JudgeVisitTaskId); - //throw new BusinessValidationFailedException("仅允许PM 同意 IR 申请的任务"); - } - //PM 影响所有阅片人 仅仅针对访视 SPM CPM 调用 + var influenceTaskList = await _visitTaskRepository.Where(filterExpression, true).ToListAsync(); - else if (((IsSpmOrCPM()) && applyId != null && - await _visitTaskReReadingRepository.AnyAsync(t => t.Id == applyId && (t.CreateUser.UserTypeEnum == UserTypeEnum.ProjectManager || t.CreateUser.UserTypeEnum == UserTypeEnum.APM)) && filterObj.IsAnalysisCreate == false && filterObj.ReadingCategory == ReadingCategory.Visit) - || (IsPMOrAPm() && applyId == null)) - { + var trakingOrigenalTask = influenceTaskList.Where(t => t.Id == origenalTask.Id).FirstOrDefault(); - - - - //有序 - if (criterionConfig.IsReadingTaskViewInOrder == ReadingOrder.InOrder) - { - switch (filterObj.ReadingCategory) + foreach (var influenceTask in influenceTaskList) { - case ReadingCategory.Visit: + //申请原任务处理 + if (influenceTask.Id == origenalTask.Id) + { + ReReadingTaskTrackingDeal(influenceTask, agreeReReadingCommand); - //访视影响当前以及当前之后的 两个阅片人的 - filterExpression = filterExpression.And(t => t.VisitTaskNum >= filterObj.VisitTaskNum); + await SetMedicalReviewInvalidAsync(influenceTaskList, false); - break; + 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 - default: - //---不支持重阅的任务类型 - throw new BusinessValidationFailedException(_localizer["VisitTask_UnsupportedTaskType"]); } - if (await _visitTaskReReadingRepository.AnyAsync(t => t.RequestReReadingType == RequestReReadingType.DocotorApply && t.RequestReReadingResultEnum == RequestReReadingResult.Default && - t.OriginalReReadingTask.VisitTaskNum >= filterObj.VisitTaskNum && t.OriginalReReadingTask.SubjectId == filterObj.SubjectId && t.OriginalReReadingTask.TrialReadingCriterionId == filterObj.TrialReadingCriterionId && t.OriginalReReadingTask.IsAnalysisCreate == filterObj.IsAnalysisCreate)) - { - isIRAppyTaskInfluenced = true; - } - } - //无序 - else - { - // 1.当前任务及裁判任务 - // 2.影响所有阅片人的任务 - - var judegTaskNum = filterObj.VisitTaskNum + ReadingCommon.TaskNumDic[ReadingCategory.Judge]; - - filterExpression = filterExpression.And(t => t.VisitTaskNum == filterObj.VisitTaskNum || t.VisitTaskNum == judegTaskNum); } - //throw new BusinessValidationFailedException("仅允许SPM CPM 同意 PM 申请的非 一致性分析的访视任务"); } else { - //---当前用户查看列表未定义 - throw new BusinessValidationFailedException(_localizer["VisitTask_UndefinedList"]); + //---不符合 PM申请 SPM / CPM审批 | IR申请 PM 审批 + throw new BusinessValidationFailedException(_localizer["VisitTask_ReReadTaskAlreadyAffected"]); } - - } - - - //退回影响 仅仅针对是访视类型的 影响多个标准的任务 - else + else if (agreeReReadingCommand.RequestReReadingResultEnum == RequestReReadingResult.Reject) { - if (filterObj.IsAnalysisCreate) + if (origenalTask.ReReadingApplyState == ReReadingApplyState.DocotorHaveApplyed || origenalTask.ReReadingApplyState == ReReadingApplyState.TrialGroupHaveApplyed) { - //---不允许退回一致性分析任务 - throw new BusinessValidationFailedException(_localizer["VisitTask_NoConsistencyReturn"]); - } - - if (filterObj.ReadingCategory == ReadingCategory.Visit && IsPMOrAPm()) - { - //有序 - if (criterionConfig.IsReadingTaskViewInOrder == ReadingOrder.InOrder) + await _visitTaskRepository.UpdatePartialFromQueryAsync(t => t.Id == origenalTask.Id, u => new VisitTask() { - // 当前任务及其之后的所有访视任务 两个阅片人的 - - //2.当前任务未完成,不会产生全局任务。后续任务均为访视任务,且均为待阅片,取消分配; - filterExpression = filterExpression.And(t => t.VisitTaskNum >= filterObj.VisitTaskNum); - - - if (await _visitTaskReReadingRepository.AnyAsync(t => t.RequestReReadingType == RequestReReadingType.DocotorApply && t.RequestReReadingResultEnum == RequestReReadingResult.Default && - t.OriginalReReadingTask.VisitTaskNum >= filterObj.VisitTaskNum && t.OriginalReReadingTask.SubjectId == filterObj.SubjectId && t.OriginalReReadingTask.TrialReadingCriterionId == filterObj.TrialReadingCriterionId && t.OriginalReReadingTask.IsAnalysisCreate == filterObj.IsAnalysisCreate)) - { - isIRAppyTaskInfluenced = true; - } - } - //无序 - else - { - //自己和另一个人的当前任务 退回针对的是未完成的肯定不会有裁判 - filterExpression = filterExpression.And(t => t.VisitTaskNum == filterObj.VisitTaskNum); - } + ReReadingApplyState = ReReadingApplyState.Reject + }); } else { - //---仅仅访视类型的任务支持PM退回 - throw new BusinessValidationFailedException(_localizer["VisitTask_VisitTypeTaskAllowedForPMOnly"]); + //---当前重阅任务状态不为已申请状态,不允许进行处理,请刷新页面 + throw new BusinessValidationFailedException(_localizer["VisitTask_InvalidReapplyStatus"]); } } - var list = await _visitTaskRepository.Where(filterExpression) - //IR 申请的时候,仅仅看到影响自己的 - .WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.IndependentReviewer, t => t.DoctorUserId == _userInfo.Id) - .OrderBy(t => t.VisitTaskNum).ProjectTo(_mapper.ConfigurationProvider).ToListAsync(); - #region 影响后的操作 - foreach (var influenceTask in list) + + } + + + + + + await _visitTaskRepository.SaveChangesAsync(); + + return ResponseOutput.Ok(); + } + + private void CopyForms(VisitTask newTask, VisitTask origenalTask) + { + + //自定义 + var readingCustomTagList = _readingCustomTagRepository.Where(t => t.VisitTaskId == origenalTask.Id).ToList(); + + foreach (var item in readingCustomTagList) + { + item.Id = Guid.Empty; + item.VisitTaskId = newTask.Id; + } + + _ = _readingCustomTagRepository.AddRangeAsync(readingCustomTagList).Result; + + + var readingTaskQuestionMarkList = _readingTaskQuestionMarkRepository.Where(t => t.VisitTaskId == origenalTask.Id).ToList(); + + foreach (var item in readingTaskQuestionMarkList) + { + item.Id = Guid.Empty; + item.VisitTaskId = newTask.Id; + } + + _ = _readingTaskQuestionMarkRepository.AddRangeAsync(readingTaskQuestionMarkList).Result; + + var readingTaskQuestionAnswerList = _readingTaskQuestionAnswerRepository.Where(t => t.VisitTaskId == origenalTask.Id).ToList(); + + foreach (var item in readingTaskQuestionAnswerList) + { + item.Id = Guid.Empty; + item.VisitTaskId = newTask.Id; + } + _ = _readingTaskQuestionAnswerRepository.AddRangeAsync(readingTaskQuestionAnswerList).Result; + + + + //ReadingTableAnswerRowInfo ReadingTableQuestionAnswer 一起加 + var readingTableAnswerRowInfoList = _readingTableAnswerRowInfoRepository.Where(t => t.VisitTaskId == origenalTask.Id).Include(t => t.LesionAnswerList).ToList(); + + foreach (var item in readingTableAnswerRowInfoList) + { + + var originalVisitTaskId = item.VisitTaskId; + var originalFristAddTaskId = item.FristAddTaskId; + + item.Id = NewId.NextSequentialGuid(); + item.VisitTaskId = newTask.Id; + + //默认值是当前任务添加的 + item.FristAddTaskId = originalVisitTaskId == originalFristAddTaskId ? newTask.Id : item.FristAddTaskId; + + + foreach (var item2 in item.LesionAnswerList) { - influenceTask.OptType = influenceTask.ReadingTaskState == ReadingTaskState.HaveSigned ? ReReadingOrBackOptType.Return : ReReadingOrBackOptType.Abandon; + item2.Id = Guid.Empty; + item2.RowId = item.Id; + item2.VisitTaskId = newTask.Id; } + } + + _ = _readingTableAnswerRowInfoRepository.AddRangeAsync(readingTableAnswerRowInfoList).Result; + + + + + + } + + + /// + /// PM 设置任务 退回 + /// + /// + [HttpPut("{trialId:guid}/{taskId:guid}")] + [UnitOfWork] + [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })] + + public async Task PMSetTaskBack(Guid trialId, Guid taskId) + { + + //var trialConfig = (await _trialRepository.Where(t => t.Id == trialId).Select(t => new { TrialId = t.Id, t.IsReadingTaskViewInOrder, t.ReadingType }).FirstOrDefaultAsync()).IfNullThrowException(); + + + var task = (await _visitTaskRepository.Where(t => t.Id == taskId).FirstOrDefaultAsync()).IfNullThrowException(); + + var criterionConfig = (await _trialReadingCriterionRepository.Where(x => x.Id == task.TrialReadingCriterionId).Select(x => new { x.ReadingTool, x.CriterionType, x.IsAutoCreate, x.IsAdditionalAssessment, x.IsReadingTaskViewInOrder }).FirstOrDefaultAsync()).IfNullThrowException(); + + if (criterionConfig.IsAutoCreate == false) + { + //---手动生成任务的不允许在此入口影像退回 + return ResponseOutput.NotOk(_localizer["VisitTask_NoImageReturn"]); + } + + if (task.TaskState != TaskState.Effect || task.ReadingCategory != ReadingCategory.Visit || task.ReadingTaskState == ReadingTaskState.HaveSigned) + { + //---仅仅允许针对生效、未完成的访视任务进行退回操作,请刷新页面数据 + return ResponseOutput.NotOk(_localizer["VisitTask_NonEffectiveTaskCannotBeReturned"]); + } + + + if (await _subjectVisitRepository.AnyAsync(t => t.Id == task.SourceSubjectVisitId && t.CheckState != CheckStateEnum.CVPassed)) + { + //---当前访视已回退到影像上传,不允许继续回退! + return ResponseOutput.NotOk(_localizer["VisitTask_NoFurtherReturn"]); + } + + + if (task.IsAnalysisCreate) + { + //---一致性分析的任务,不允许设置退回 + return ResponseOutput.NotOk(_localizer["VisitTask_ConsistencyTaskCannotBeReturned"]); + } + + Expression> filterExpression = t => t.TrialId == trialId && t.SubjectId == task.SubjectId && (t.TaskState == TaskState.Effect || t.TaskState == TaskState.Freeze) && t.TaskAllocationState == TaskAllocationState.Allocated; + + + #region 退回到访视 不区分标准 + //if (criterionConfig.CriterionType == CriterionType.RECIST1Point1 && criterionConfig.IsAdditionalAssessment) + //{ + // //影像退回,必定影响两个标准的任务 + // filterExpression = filterExpression.And(t => t.TrialReadingCriterionId == task.TrialReadingCriterionId || t.TrialReadingCriterion.CriterionType == CriterionType.RECIST1Pointt1_MB); + + + //} + //else + //{ + // //默认影响的都是该标准的任务 + // filterExpression = filterExpression.And(t => t.TrialReadingCriterionId == task.TrialReadingCriterionId); + //} + #endregion + + + //PM 才允许操作 + if (IsPMOrAPm()) + { + + #region 有序 无序公用流程 + + + //执行类似一致性核查回退流程 回退访视到影像上传流程 + await VisitBackAsync(task.SourceSubjectVisitId); + #endregion - return (list, new { IsIRAppyTaskInfluenced = isIRAppyTaskInfluenced }); + + //有序 + if (criterionConfig.IsReadingTaskViewInOrder == ReadingOrder.InOrder) + { + + //Expression> filterExpression = t => t.TrialId == trialId && t.SubjectId == task.SubjectId && t.TaskState == TaskState.Effect && t.IsAnalysisCreate == false && t.TaskAllocationState == TaskAllocationState.Allocated; + + filterExpression = filterExpression.And(t => t.IsAnalysisCreate == false); + + + + //另一个阅片人的任务根据任务进度自动进入PM退回或PM申请重阅 + filterExpression = filterExpression.And(t => t.VisitTaskNum >= task.VisitTaskNum); + + + var influenceTaskList = await _visitTaskRepository.Where(filterExpression, true).ToListAsync(); + + + + #region 方式二 + + + //pm退回的时候,影响的任务里不一定有该任务id 双重 分配了一个人,退回的时候,选择的是未分配的 + + //var origenalTask = influenceTaskList.Where(t => t.Id == task.Id).FirstOrDefault(); + + var origenalTask = await _visitTaskRepository.FindAsync(task.Id); + + + foreach (var influenceTask in influenceTaskList) + { + + //已签名的任务 设置转变后的标志 + 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 == task.Id) + { + + await InfluenceAddtioncalEvaluationCritrionAsync(task, influenceTaskList.Where(t => t.Id != task.Id).Where(t => t.SourceSubjectVisitId != null).Select(t => t.SourceSubjectVisitId!.Value).Distinct().ToList()); + + await PMReReadingConfirmOrBackInfluenceAnalysisAsync(influenceTask.SubjectId); + + await SetMedicalReviewInvalidAsync(influenceTaskList); + + + influenceTask.IsPMSetBack = true; + } + + if (influenceTask.ReadingTaskState == ReadingTaskState.HaveSigned) + { + influenceTask.TaskState = TaskState.HaveReturned; + origenalTask.TaskInfluenceList.Add(new TaskInfluence() { InfluenceTaskId = influenceTask.Id, OptType = ReReadingOrBackOptType.Return }); + } + else + { + influenceTask.TaskState = TaskState.Adbandon; + origenalTask.TaskInfluenceList.Add(new TaskInfluence() { InfluenceTaskId = influenceTask.Id, OptType = ReReadingOrBackOptType.Abandon }); + } + + } + + #endregion + + + + } + + else + { + //无序 无序阅片没有 全局 肿瘤学 + + // 申请该访视的任务 申请人失效 另外一个人重阅重置或者失效 + + var currentVisitList = await _visitTaskRepository.Where(t => t.SourceSubjectVisitId == task.SourceSubjectVisitId && t.ReadingCategory == ReadingCategory.Visit && (t.TaskState == TaskState.Effect || t.TaskState == TaskState.Freeze) && t.VisitTaskNum == task.VisitTaskNum, true).ToListAsync(); + + await SetMedicalReviewInvalidAsync(currentVisitList); + + //var origenalTask = currentVisitList.Where(t => t.Id == task.Id).First(); + + var origenalTask = await _visitTaskRepository.FindAsync(task.Id); + + foreach (var influenceTask in currentVisitList) + { + if (influenceTask.ReadingTaskState == ReadingTaskState.HaveSigned) + { + //另外阅片人完成阅片了 就设置为重阅重置 + influenceTask.TaskState = TaskState.HaveReturned; + + origenalTask.TaskInfluenceList.Add(new TaskInfluence() { InfluenceTaskId = influenceTask.Id, OptType = ReReadingOrBackOptType.Return }); + } + else + { + influenceTask.TaskState = TaskState.Adbandon; + + origenalTask.TaskInfluenceList.Add(new TaskInfluence() { InfluenceTaskId = influenceTask.Id, OptType = ReReadingOrBackOptType.Abandon }); + } + + } + + } } - - - - - /// - /// 获取已影响的列表 - /// - /// - public async Task> GetInfluencedTaskList(Guid taskId) + else { - var list = await _taskInfluenceRepository.Where(t => t.OriginalTaskId == taskId)/*.Select(t => t.InfluenceTask)*/.ProjectTo(_mapper.ConfigurationProvider).ToListAsync(); - - return list; + //---仅PM 可以进行回退操作 + return ResponseOutput.NotOk(_localizer["VisitTask_PMOnlyAllowedForReturn"]); } - #region 暂时废弃 - - - ///// - ///// 自动一次性分配所有未分配的 Subject 给医生 暂时废弃 - ///// - ///// - ///// - //[HttpPost] - //[UnitOfWork] - //[Obsolete] - //public async Task AutoSubjectAssignDoctor(AutoSubjectAssignCommand autoSubjectAssignCommand) - //{ - // //自动分配的话,需要把手动分配的给删掉 - - - // var trialId = autoSubjectAssignCommand.TrialId; - // var isJudge = autoSubjectAssignCommand.IsJudgeDoctor; - - - // //获取项目配置 判断应该分配几个医生 - // var trialConfig = (await _trialRepository.Where(t => t.Id == trialId).Select(t => new { TrialId = t.Id/*, t.ReadingType*/, t.IsFollowVisitAutoAssign, t.IsFollowGlobalVisitAutoAssign, t.FollowGlobalVisitAutoAssignDefaultState, t.TaskAllocateObjEnum }).FirstOrDefaultAsync()).IfNullThrowException(); - - - // //获取 已产生任务的Subject 目前分配情况 - // var subjectList = _subjectRepository.Where(t => t.TrialId == trialId) - // .WhereIf(isJudge == false, t => t.SubjectVisitTaskList.Where(t => t.ArmEnum != Arm.JudgeArm).Any()) - // .WhereIf(isJudge, t => t.SubjectVisitTaskList.Where(t => t.ArmEnum == Arm.JudgeArm).Any()) - // ////过滤掉 那些回退的subject - // //.Where(t => !t.SubjectVisitList.Any(t => t.IsPMBackOrReReading)) - // .Select(t => new - // { - // SubjectId = t.Id, - - // //给Subject分配医生的时候, 未确认绑定关系的 - // DoctorUserList = t.SubjectDoctorList.Where(t => isJudge ? t.ArmEnum == Arm.JudgeArm : t.ArmEnum != Arm.JudgeArm).Where(t => t.OrignalSubjectUserId == null).Select(t => new { t.DoctorUserId, t.ArmEnum }), - // //IsApplyed = t.SubjectDoctorList.Where(t => isJudge ? t.ArmEnum == Arm.JudgeArm : t.ArmEnum != Arm.JudgeArm).Where(t => t.OrignalSubjectUserId == null).SelectMany(t => t.SubjectArmVisitTaskList).Any(c => c.DoctorUserId != null) - // IsApplyed = false - // }).ToList(); - - // //已产生任务的Subject数量(裁判情况下,就是产生裁判任务Subject 的数量) - // var subjectCount = subjectList.Count; - - // //获取医生列表(裁判是裁判的医生列表) - // var waitAllocationDoctorList = _taskAllocationRuleRepository.Where(t => t.TrialId == trialId && t.IsEnable) - // .Where(t => t.IsJudgeDoctor == isJudge) - // .Select(t => new AutoAssignResultDTO() { DoctorUserId = t.DoctorUserId, PlanReadingRatio = t.PlanReadingRatio, SubjectCount = subjectCount }) - // .ToList(); - - // if (waitAllocationDoctorList.Count == 0) - // { - // throw new BusinessValidationFailedException("启用的医生数量为0"); - // } - - - // //已分配的 医生的情况 - // var haveAssignedSubjectDoctorList = subjectList.Clone().SelectMany(t => t.DoctorUserList.Select(c => new { t.SubjectId, c.DoctorUserId, c.ArmEnum })).ToList(); - - // //将目前已分配的情况 换到医生的维度 - // foreach (var waitAllocationDoctor in waitAllocationDoctorList) - // { - // waitAllocationDoctor.SubjectArmList = haveAssignedSubjectDoctorList.Where(t => t.DoctorUserId == waitAllocationDoctor.DoctorUserId) - // .Select(g => new SubjectArm() - // { - // SubjectId = g.SubjectId, - // ArmEnum = g.ArmEnum - // }).ToList(); - // } - - - // #region 完全按照Subject 遍历去分 - - - // //仅仅分配未应用的 而且 没有分配医生的 - // foreach (var subject in subjectList.Where(t => t.IsApplyed == false && !t.DoctorUserList.Any())) - // { - // //该Subject 已经分配的医生数量 - // var hasAssignDoctorCount = subject.DoctorUserList.Count(); - - // if (isJudge) - // { - // if (hasAssignDoctorCount > 1) - // { - // throw new BusinessValidationFailedException("当前有Subject裁判绑定医生数量大于1"); - - // } - - // var allocateDoctor = waitAllocationDoctorList.OrderByDescending(t => t.Weight).ThenByDescending(t => t.PlanReadingRatio).FirstOrDefault(); - - // //将分配结果记录 - // waitAllocationDoctorList.FirstOrDefault(t => t.DoctorUserId == allocateDoctor.DoctorUserId).SubjectArmList.Add(new SubjectArm() - // { - // SubjectId = subject.SubjectId, - // ArmEnum = Arm.JudgeArm - // }); - - // await _subjectUserRepository.AddAsync(new SubjectUser() { TrialId = trialId, SubjectId = subject.SubjectId, DoctorUserId = allocateDoctor.DoctorUserId, ArmEnum = Arm.JudgeArm, AssignTime = DateTime.Now }); - - // } - // else - // { - - // //分配两个医生 - // if (trialConfig.ReadingType == ReadingMethod.Double) - // { - - - // if (hasAssignDoctorCount > 2) - // { - // throw new BusinessValidationFailedException("双重阅片当前有Subject绑定医生数量大于2"); - - // } - - // var allocateDoctorList = waitAllocationDoctorList.OrderByDescending(t => t.Weight).ThenByDescending(t => t.PlanReadingRatio).Take(2).ToList(); - - - // #region 看阅片人之前在Subject哪个组做的多 - - // var preferredDoctor1Arm = waitAllocationDoctorList.Where(t => t.DoctorUserId == allocateDoctorList[0].DoctorUserId) - // .SelectMany(t => t.SubjectArmList).GroupBy(t => t.ArmEnum) - // .Select(g => new { ArmEnum = g.Key, SubjectCount = g.Count() }) - // .OrderByDescending(t => t.SubjectCount).FirstOrDefault()?.ArmEnum; - - // var preferredDoctor2Arm = waitAllocationDoctorList.Where(t => t.DoctorUserId == allocateDoctorList[1].DoctorUserId) - // .SelectMany(t => t.SubjectArmList).GroupBy(t => t.ArmEnum) - // .Select(g => new { ArmEnum = g.Key, SubjectCount = g.Count() }) - // .OrderByDescending(t => t.SubjectCount).FirstOrDefault()?.ArmEnum; - - // //存放医生分配的Arm - // var doctor1Arm = Arm.DoubleReadingArm1; - // var doctor2Arm = Arm.DoubleReadingArm2; - - // if (preferredDoctor1Arm == null && preferredDoctor2Arm == null || - // preferredDoctor1Arm == null && preferredDoctor2Arm == Arm.DoubleReadingArm2 || - // preferredDoctor1Arm == Arm.DoubleReadingArm1 && preferredDoctor2Arm == null || - // preferredDoctor1Arm == Arm.DoubleReadingArm1 && preferredDoctor2Arm == Arm.DoubleReadingArm2 - // ) - // { - // doctor1Arm = Arm.DoubleReadingArm1; - // doctor2Arm = Arm.DoubleReadingArm2; - // } - // else if (preferredDoctor1Arm == null && preferredDoctor2Arm == Arm.DoubleReadingArm1 || - // preferredDoctor1Arm == Arm.DoubleReadingArm2 && preferredDoctor2Arm == Arm.DoubleReadingArm1 || - // preferredDoctor1Arm == Arm.DoubleReadingArm2 && preferredDoctor2Arm == null) - // { - // doctor1Arm = Arm.DoubleReadingArm2; - // doctor2Arm = Arm.DoubleReadingArm1; - // } - - // else if (preferredDoctor1Arm == Arm.DoubleReadingArm1 && preferredDoctor2Arm == Arm.DoubleReadingArm1) - // { - // doctor1Arm = Arm.DoubleReadingArm1; - // doctor2Arm = Arm.DoubleReadingArm2; - // } - // else if (preferredDoctor1Arm == Arm.DoubleReadingArm2 && preferredDoctor2Arm == Arm.DoubleReadingArm2) - // { - // doctor1Arm = Arm.DoubleReadingArm2; - // doctor2Arm = Arm.DoubleReadingArm1; - // } - - // #endregion - - - // await _subjectUserRepository.AddAsync(new SubjectUser() { TrialId = trialId, SubjectId = subject.SubjectId, DoctorUserId = allocateDoctorList[0].DoctorUserId, ArmEnum = doctor1Arm, AssignTime = DateTime.Now }); - - - // //将分配结果记录 - // waitAllocationDoctorList.FirstOrDefault(t => t.DoctorUserId == allocateDoctorList[0].DoctorUserId).SubjectArmList.Add(new SubjectArm() - // { - // SubjectId = subject.SubjectId, - // ArmEnum = doctor1Arm - // }); - - - // await _subjectUserRepository.AddAsync(new SubjectUser() { TrialId = trialId, SubjectId = subject.SubjectId, DoctorUserId = allocateDoctorList[1].DoctorUserId, ArmEnum = doctor2Arm, AssignTime = DateTime.Now }); - - // //将分配结果记录 - // waitAllocationDoctorList.FirstOrDefault(t => t.DoctorUserId == allocateDoctorList[1].DoctorUserId).SubjectArmList.Add(new SubjectArm() - // { - // SubjectId = subject.SubjectId, - // ArmEnum = doctor2Arm - // }); - // } - // else if (trialConfig.ReadingType == ReadingMethod.Single) - // { - // if (hasAssignDoctorCount > 1) - // { - // throw new BusinessValidationFailedException("单重阅片当前有Subject绑定医生数量大于1"); - // } - - // var allocateDoctor = waitAllocationDoctorList.OrderByDescending(t => t.Weight).ThenByDescending(t => t.PlanReadingRatio).FirstOrDefault(); - - // //将分配结果记录 - // waitAllocationDoctorList.FirstOrDefault(t => t.DoctorUserId == allocateDoctor.DoctorUserId).SubjectArmList.Add(new SubjectArm() - // { - // SubjectId = subject.SubjectId, - // ArmEnum = Arm.SingleReadingArm - // }); - - // await _subjectUserRepository.AddAsync(new SubjectUser() { TrialId = trialId, SubjectId = subject.SubjectId, DoctorUserId = allocateDoctor.DoctorUserId, ArmEnum = Arm.SingleReadingArm, AssignTime = DateTime.Now }); - - // } - - // } - - // } - - - // #endregion + await _visitTaskRepository.SaveChangesAsync(); - - - // await _subjectUserRepository.SaveChangesAsync(); - // return ResponseOutput.Ok(); - - //} - - - #endregion + return ResponseOutput.Ok(); } + + + /// + /// 基线退回 影响附加评估标准 是否参与评估 + /// + /// + private async Task InfluenceAddtioncalEvaluationCritrionAsync(VisitTask task, List otherVisitIdList, bool isImageBack = true) + { + + var criterion = await _trialReadingCriterionRepository.FindAsync(task.TrialReadingCriterionId); + + if (criterion.CriterionType == CriterionType.RECIST1Point1) + { + //影像回退了|| IR 申请及基线重阅 + if (_subjectVisitRepository.Any(t => t.Id == task.SourceSubjectVisitId && t.IsBaseLine)) + { + await _subjectCriteriaEvaluationRepository.UpdatePartialFromQueryAsync(t => t.TrialReadingCriterion.IsAutoCreate == false && t.SubjectId == task.SubjectId, u => new SubjectCriteriaEvaluation() + { + IsJoinEvaluation = false + }); + + //删除筛选的访视数据 + await _subjectCriteriaEvaluationVisitFilterRepository.BatchDeleteNoTrackingAsync(t => t.TrialReadingCriterion.CriterionType == CriterionType.RECIST1Pointt1_MB && t.SubjectId == task.SubjectId); + + //删除筛选的序列数据 + await _subjectCriteriaEvaluationVisitStudyFilterRepository.BatchDeleteNoTrackingAsync(t => t.TrialReadingCriterion.CriterionType == CriterionType.RECIST1Pointt1_MB && t.SubjectVisit.SubjectId == task.SubjectId); + } + else if (isImageBack) + { + //当前访视筛选状态重置,任务生成状态重置 + if (task.SourceSubjectVisitId != null) + { + await _subjectCriteriaEvaluationVisitFilterRepository.UpdatePartialFromQueryAsync(t => t.TrialReadingCriterion.CriterionType == CriterionType.RECIST1Pointt1_MB && t.SubjectVisit.SubjectId == task.SubjectId && t.SubjectVisitId == task.SourceSubjectVisitId, + t => new SubjectCriteriaEvaluationVisitFilter() + { + ImageFilterState = ImageFilterState.None, + ImageDeterminationResultState = ImageDeterminationResultState.None, + IsGeneratedTask = false + }); + + //删除序列数据 + await _subjectCriteriaEvaluationVisitStudyFilterRepository.BatchDeleteNoTrackingAsync(t => t.TrialReadingCriterion.CriterionType == CriterionType.RECIST1Pointt1_MB && t.SubjectVisit.SubjectId == task.SubjectId && t.SubjectVisitId == task.SourceSubjectVisitId); + } + + + //BM后续访视 ,筛选状态不变,任务生成状态重置(实际该访视任务状态 可能是重阅重置了或者失效了,需要后续生成,或者取消分配了,需要后续重新分配) + await _subjectCriteriaEvaluationVisitFilterRepository.UpdatePartialFromQueryAsync(t => t.TrialReadingCriterion.CriterionType == CriterionType.RECIST1Pointt1_MB && t.SubjectVisit.SubjectId == task.SubjectId && otherVisitIdList.Contains(t.SubjectVisitId), + t => new SubjectCriteriaEvaluationVisitFilter() + { + IsGeneratedTask = false + }); + } + else + { + //IR 端 非基线申请重阅 不影响 + } + } + + + + } + + //包括临床数据签名状态 + private async Task VisitBackAsync(Guid? subjectVisitId) + { + var sv = (await _subjectVisitRepository.FirstOrDefaultAsync(t => t.Id == subjectVisitId)).IfNullThrowException(); + + + //需要重新产生任务 + sv.IsVisitTaskGenerated = false; + sv.IsPMBackOrReReading = true; + + sv.AuditState = AuditStateEnum.None; + sv.SubmitState = SubmitStateEnum.ToSubmit; + sv.ReadingStatus = ReadingStatusEnum.ImageNotSubmit; + + //回退后,回退状态恢复 + sv.RequestBackState = RequestBackStateEnum.NotRequest; + sv.IsCheckBack = false; + sv.CheckBackTime = null; + sv.CheckState = CheckStateEnum.None; + sv.CheckChallengeState = CheckChanllengeTypeEnum.None; + + sv.SVENDTC = null; + sv.SVSTDTC = null; + + sv.PreliminaryAuditTime = null; + sv.SubmitTime = null; + sv.ReviewAuditTime = null; + sv.CurrentActionUserExpireTime = null; + + + sv.IsTake = false; + sv.CurrentActionUserId = null; + sv.PreliminaryAuditUserId = null; + sv.ReviewAuditUserId = null; + + + if (sv.IsBaseLine) + { + await _readingClinicalDataReposiotry.UpdatePartialFromQueryAsync(t => t.ReadingId == sv.Id && (t.ClinicalDataTrialSet.ClinicalDataLevel == ClinicalLevel.Subject || t.ClinicalDataTrialSet.ClinicalDataLevel == ClinicalLevel.SubjectVisit), c => new ReadingClinicalData() { IsSign = false, ReadingClinicalDataState = ReadingClinicalDataStatus.HaveUploaded }); + + } + else + { + await _readingClinicalDataReposiotry.UpdatePartialFromQueryAsync(t => t.ReadingId == sv.Id && t.ClinicalDataTrialSet.ClinicalDataLevel == ClinicalLevel.SubjectVisit, c => new ReadingClinicalData() + { + IsSign = false, + ReadingClinicalDataState = ReadingClinicalDataStatus.HaveUploaded, + IsBlind = null, + IsComplete = null + }); + } + + + + //await _repository.AddAsync(new CheckChallengeDialog() { SubjectVisitId = subjectVisitId, TalkContent = "PM/APM同意一致性核查回退。", UserTypeEnum = (UserTypeEnum)_userInfo.UserTypeEnumInt }); + + await _trialQCQuestionAnswerRepository.BatchDeleteNoTrackingAsync(t => t.SubjectVisitId == subjectVisitId); + await _dicomInstanceRepository.BatchDeleteNoTrackingAsync(t => t.DicomSerie.IsDeleted); + await _dicomSeriesRepository.BatchDeleteNoTrackingAsync(t => t.IsDeleted); + + var success = await _subjectVisitRepository.SaveChangesAsync(); + + } + + + private bool IsPMOrAPm() + { + return _userInfo.UserTypeEnumInt == (int)UserTypeEnum.ProjectManager || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.APM; + } + + private bool IsSpmOrCPM() + { + return _userInfo.UserTypeEnumInt == (int)UserTypeEnum.SPM || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.CPM; + } + + /// + /// 影响提示列表 重阅仅仅针对已完成的任务申请 退回针对的是未完成的(退回仅仅针对是访视类型的) + /// + /// + /// 重阅还是直接回退 + /// 申请记录的Id + /// + [HttpGet("{taskId:guid}/{isReReading:bool}")] + public async Task<(List, object)> GetReReadingOrBackInfluenceTaskList(Guid taskId, bool isReReading, Guid? applyId) + { + var isIRAppyTaskInfluenced = false; + + var filterObj = (await _visitTaskRepository.FirstOrDefaultNoTrackingAsync(t => t.Id == taskId)).IfNullThrowException(); + var trialId = filterObj.TrialId; + + 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; + + //是否是一致性分析任务 (一致性分析的任务 不会产生裁判 肿瘤学 仅仅有生成的访视和全局) + + filterExpression = filterExpression.And(t => t.IsAnalysisCreate == filterObj.IsAnalysisCreate); + + //IR 申请1.1 基线重阅,影响附加评估所有的任务 + var isIR1Point1AdditionalAssessmentBaseline = false; + + //附加评估 IR 和PM 看到的影响列表不一样 + if (criterionConfig.CriterionType == CriterionType.RECIST1Point1 && criterionConfig.IsAdditionalAssessment) + { + + // IR 申请 PM 同意 + if (((IsPMOrAPm() && applyId != null && await _visitTaskReReadingRepository.AnyAsync(t => t.Id == applyId && t.CreateUser.UserTypeEnum == UserTypeEnum.IndependentReviewer)) + || (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.IndependentReviewer && applyId == null))) + { + + // 1.1 基线任务影响BM任务 + if (IsPMOrAPm() && _subjectVisitRepository.Any(t => t.Id == filterObj.SourceSubjectVisitId && t.IsBaseLine == true)) + { + + isIR1Point1AdditionalAssessmentBaseline = true; + //filterExpression = filterExpression.And(t => t.TrialReadingCriterionId == filterObj.TrialReadingCriterionId || t.TrialReadingCriterion.CriterionType == CriterionType.RECIST1Pointt1_MB); + + + } + // 1.1 非基线任务不影响BM任务 + else + { + filterExpression = filterExpression.And(t => t.TrialReadingCriterionId == filterObj.TrialReadingCriterionId); + } + + } + //(1、PM回退,PM申请重阅,SPM同意回退) + else + { + filterExpression = filterExpression.And(t => t.TrialReadingCriterionId == filterObj.TrialReadingCriterionId || t.TrialReadingCriterion.CriterionType == CriterionType.RECIST1Pointt1_MB); + + } + } + else + { + //默认影响的都是该标准的任务 + filterExpression = filterExpression.And(t => t.TrialReadingCriterionId == filterObj.TrialReadingCriterionId); + } + + + + //重阅影响 + if (isReReading) + { + + + + //IR 申请 PM 同意 仅仅影响自己 + + if ((IsPMOrAPm() && applyId != null && await _visitTaskReReadingRepository.AnyAsync(t => t.Id == applyId && t.CreateUser.UserTypeEnum == UserTypeEnum.IndependentReviewer)) + || (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.IndependentReviewer && applyId == null)) + { + + //当前任务及其之后的所有访视任务、全局任务、裁判任务、肿瘤学阅片任务 + + //有序 + if (criterionConfig.IsReadingTaskViewInOrder == ReadingOrder.InOrder) + { + + switch (filterObj.ReadingCategory) + { + case ReadingCategory.Visit: + //影响当前医生 以及当前医生之后的 1、访视任务 已经读完的 + //2、后续任务如果是全局、肿瘤学阅片任务,状态为阅片完成标记为重阅重置;若在阅片中,则标记为失效;若为待阅片,则标记为失效; + //3、当前任务、后续访视任务或者全局任务触发了裁判任务,若裁判任务状态为阅片完成,则标记为重阅重置;若在阅片中或待阅片,则标记为失效 + + //申请的是转化的,那么影响列表要排除转化之前的 + if (criterionConfig.CriterionType == CriterionType.IRECIST1Point1 && filterObj.BeforeConvertedTaskId != null) + { + + + filterExpression = filterExpression.And(t => (t.VisitTaskNum > filterObj.VisitTaskNum && + ( + ((t.ReadingCategory == ReadingCategory.Visit || t.ReadingCategory == ReadingCategory.Global) && t.DoctorUserId == filterObj.DoctorUserId) + // 裁判 肿瘤学是另外的医生做 + || t.ReadingCategory == ReadingCategory.Judge + || t.ReadingCategory == ReadingCategory.Oncology + )) || t.Id == filterObj.Id) + ; + } + // IR 申请1.1 基线重阅,影响附加评估所有的任务 + else if (isIR1Point1AdditionalAssessmentBaseline) + { + filterExpression = filterExpression.And(t => t.VisitTaskNum >= filterObj.VisitTaskNum && + ((( + ((t.ReadingCategory == ReadingCategory.Visit || t.ReadingCategory == ReadingCategory.Global) && t.DoctorUserId == filterObj.DoctorUserId) + // 裁判 肿瘤学是另外的医生做 + || t.ReadingCategory == ReadingCategory.Judge + || t.ReadingCategory == ReadingCategory.Oncology + ) && t.TrialReadingCriterionId == filterObj.TrialReadingCriterionId) || (t.TrialReadingCriterion.CriterionType == CriterionType.RECIST1Pointt1_MB)) + ); + } + else + { + filterExpression = filterExpression.And(t => t.VisitTaskNum >= filterObj.VisitTaskNum && + ( + ((t.ReadingCategory == ReadingCategory.Visit || t.ReadingCategory == ReadingCategory.Global) && t.DoctorUserId == filterObj.DoctorUserId) + // 裁判 肿瘤学是另外的医生做 + || t.ReadingCategory == ReadingCategory.Judge + || t.ReadingCategory == ReadingCategory.Oncology + ) + ); + } + + + + + + break; + + case ReadingCategory.Global: + + // 1、后续任务如果是访视任务,均不处理; + //2、后续任务如果是全局、状态为阅片完成则标记为重阅重置,若阅片中或待阅片则不处理; + //3、当前任务或者全局任务触发了裁判任务,若裁判任务状态为阅片完成,则标记为重阅重置;若在阅片中或待阅片,则标记为失效 + //4、后续任务为肿瘤学阅片任务,状态为阅片完成标记为重阅重置;若在阅片中,则标记为失效;若为待阅片,则标记为失效; + + //filterExpression = filterExpression.And(t => t.VisitTaskNum >= filterObj.VisitTaskNum && + //((t.DoctorUserId == filterObj.DoctorUserId && ((t.ReadingCategory == ReadingCategory.Visit && t.ReadingTaskState == ReadingTaskState.HaveSigned) || t.ReadingCategory == ReadingCategory.Global)) || (t.ReadingCategory == ReadingCategory.Oncology) || (t.ReadingCategory == ReadingCategory.Judge))); + + + filterExpression = filterExpression.And(t => t.VisitTaskNum > filterObj.VisitTaskNum && + ( + (t.DoctorUserId == filterObj.DoctorUserId && t.ReadingCategory == ReadingCategory.Global) + || (t.ReadingCategory == ReadingCategory.Oncology) + || (t.ReadingCategory == ReadingCategory.Judge) + ) || t.Id == filterObj.Id); + + break; + + //1、后续任务如果是访视任务、全局任务或裁判任务,均不处理; + case ReadingCategory.Oncology: + + //仅仅影响自己 + filterExpression = filterExpression.And(t => t.Id == filterObj.Id); + break; + + //(只允许申请该阅片人最后一次完成裁判的任务重阅)申请的时候做了限制 + case ReadingCategory.Judge: + + // 1、后续任务如果是访视任务、全局任务,均不处理; + //2、后续若有肿瘤学阅片,若肿瘤学阅片任务状态为阅片完成,则标记为重阅重置;若为阅片中则标记为失效,如为待阅片,则取消分配 + + //裁判的影响自己 和后续肿瘤学阅片(不是自己做的) + filterExpression = filterExpression.And(t => t.Id == filterObj.Id || t.VisitTaskNum > filterObj.VisitTaskNum && t.ReadingCategory == ReadingCategory.Oncology); + + break; + + + default: + //---不支持重阅的任务类型 + throw new BusinessValidationFailedException(_localizer["VisitTask_UnsupportedTaskType"]); + } + } + //无序 + else + { + //1.当前任务及裁判任务 + //2.影响当前阅片人的任务 + filterExpression = filterExpression.And(t => t.Id == filterObj.Id || t.Id == filterObj.JudgeVisitTaskId); + } + + + //throw new BusinessValidationFailedException("仅允许PM 同意 IR 申请的任务"); + } + //PM 影响所有阅片人 仅仅针对访视 SPM CPM 调用 + + else if (((IsSpmOrCPM()) && applyId != null && + await _visitTaskReReadingRepository.AnyAsync(t => t.Id == applyId && (t.CreateUser.UserTypeEnum == UserTypeEnum.ProjectManager || t.CreateUser.UserTypeEnum == UserTypeEnum.APM)) && filterObj.IsAnalysisCreate == false && filterObj.ReadingCategory == ReadingCategory.Visit) + || (IsPMOrAPm() && applyId == null)) + { + + + + + //有序 + if (criterionConfig.IsReadingTaskViewInOrder == ReadingOrder.InOrder) + { + switch (filterObj.ReadingCategory) + { + case ReadingCategory.Visit: + + //访视影响当前以及当前之后的 两个阅片人的 + filterExpression = filterExpression.And(t => t.VisitTaskNum >= filterObj.VisitTaskNum); + + break; + + default: + //---不支持重阅的任务类型 + throw new BusinessValidationFailedException(_localizer["VisitTask_UnsupportedTaskType"]); + } + + if (await _visitTaskReReadingRepository.AnyAsync(t => t.RequestReReadingType == RequestReReadingType.DocotorApply && t.RequestReReadingResultEnum == RequestReReadingResult.Default && + t.OriginalReReadingTask.VisitTaskNum >= filterObj.VisitTaskNum && t.OriginalReReadingTask.SubjectId == filterObj.SubjectId && t.OriginalReReadingTask.TrialReadingCriterionId == filterObj.TrialReadingCriterionId && t.OriginalReReadingTask.IsAnalysisCreate == filterObj.IsAnalysisCreate)) + { + isIRAppyTaskInfluenced = true; + } + } + //无序 + else + { + // 1.当前任务及裁判任务 + // 2.影响所有阅片人的任务 + + var judegTaskNum = filterObj.VisitTaskNum + ReadingCommon.TaskNumDic[ReadingCategory.Judge]; + + filterExpression = filterExpression.And(t => t.VisitTaskNum == filterObj.VisitTaskNum || t.VisitTaskNum == judegTaskNum); + } + + //throw new BusinessValidationFailedException("仅允许SPM CPM 同意 PM 申请的非 一致性分析的访视任务"); + } + else + { + //---当前用户查看列表未定义 + throw new BusinessValidationFailedException(_localizer["VisitTask_UndefinedList"]); + } + + + + } + + + //退回影响 仅仅针对是访视类型的 影响多个标准的任务 + else + { + + if (filterObj.IsAnalysisCreate) + { + //---不允许退回一致性分析任务 + throw new BusinessValidationFailedException(_localizer["VisitTask_NoConsistencyReturn"]); + } + + if (filterObj.ReadingCategory == ReadingCategory.Visit && IsPMOrAPm()) + { + //有序 + if (criterionConfig.IsReadingTaskViewInOrder == ReadingOrder.InOrder) + { + // 当前任务及其之后的所有访视任务 两个阅片人的 + + //2.当前任务未完成,不会产生全局任务。后续任务均为访视任务,且均为待阅片,取消分配; + filterExpression = filterExpression.And(t => t.VisitTaskNum >= filterObj.VisitTaskNum); + + + if (await _visitTaskReReadingRepository.AnyAsync(t => t.RequestReReadingType == RequestReReadingType.DocotorApply && t.RequestReReadingResultEnum == RequestReReadingResult.Default && + t.OriginalReReadingTask.VisitTaskNum >= filterObj.VisitTaskNum && t.OriginalReReadingTask.SubjectId == filterObj.SubjectId && t.OriginalReReadingTask.TrialReadingCriterionId == filterObj.TrialReadingCriterionId && t.OriginalReReadingTask.IsAnalysisCreate == filterObj.IsAnalysisCreate)) + { + isIRAppyTaskInfluenced = true; + } + } + //无序 + else + { + //自己和另一个人的当前任务 退回针对的是未完成的肯定不会有裁判 + filterExpression = filterExpression.And(t => t.VisitTaskNum == filterObj.VisitTaskNum); + } + } + else + { + //---仅仅访视类型的任务支持PM退回 + throw new BusinessValidationFailedException(_localizer["VisitTask_VisitTypeTaskAllowedForPMOnly"]); + } + + } + + var list = await _visitTaskRepository.Where(filterExpression) + //IR 申请的时候,仅仅看到影响自己的 + .WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.IndependentReviewer, t => t.DoctorUserId == _userInfo.Id) + .OrderBy(t => t.VisitTaskNum).ProjectTo(_mapper.ConfigurationProvider).ToListAsync(); + + #region 影响后的操作 + + foreach (var influenceTask in list) + { + influenceTask.OptType = influenceTask.ReadingTaskState == ReadingTaskState.HaveSigned ? ReReadingOrBackOptType.Return : ReReadingOrBackOptType.Abandon; + } + #endregion + + + return (list, new { IsIRAppyTaskInfluenced = isIRAppyTaskInfluenced }); + + } + + + + + /// + /// 获取已影响的列表 + /// + /// + public async Task> GetInfluencedTaskList(Guid taskId) + { + var list = await _taskInfluenceRepository.Where(t => t.OriginalTaskId == taskId)/*.Select(t => t.InfluenceTask)*/.ProjectTo(_mapper.ConfigurationProvider).ToListAsync(); + + return list; + } + + + #region 暂时废弃 + + + ///// + ///// 自动一次性分配所有未分配的 Subject 给医生 暂时废弃 + ///// + ///// + ///// + //[HttpPost] + //[UnitOfWork] + //[Obsolete] + //public async Task AutoSubjectAssignDoctor(AutoSubjectAssignCommand autoSubjectAssignCommand) + //{ + // //自动分配的话,需要把手动分配的给删掉 + + + // var trialId = autoSubjectAssignCommand.TrialId; + // var isJudge = autoSubjectAssignCommand.IsJudgeDoctor; + + + // //获取项目配置 判断应该分配几个医生 + // var trialConfig = (await _trialRepository.Where(t => t.Id == trialId).Select(t => new { TrialId = t.Id/*, t.ReadingType*/, t.IsFollowVisitAutoAssign, t.IsFollowGlobalVisitAutoAssign, t.FollowGlobalVisitAutoAssignDefaultState, t.TaskAllocateObjEnum }).FirstOrDefaultAsync()).IfNullThrowException(); + + + // //获取 已产生任务的Subject 目前分配情况 + // var subjectList = _subjectRepository.Where(t => t.TrialId == trialId) + // .WhereIf(isJudge == false, t => t.SubjectVisitTaskList.Where(t => t.ArmEnum != Arm.JudgeArm).Any()) + // .WhereIf(isJudge, t => t.SubjectVisitTaskList.Where(t => t.ArmEnum == Arm.JudgeArm).Any()) + // ////过滤掉 那些回退的subject + // //.Where(t => !t.SubjectVisitList.Any(t => t.IsPMBackOrReReading)) + // .Select(t => new + // { + // SubjectId = t.Id, + + // //给Subject分配医生的时候, 未确认绑定关系的 + // DoctorUserList = t.SubjectDoctorList.Where(t => isJudge ? t.ArmEnum == Arm.JudgeArm : t.ArmEnum != Arm.JudgeArm).Where(t => t.OrignalSubjectUserId == null).Select(t => new { t.DoctorUserId, t.ArmEnum }), + // //IsApplyed = t.SubjectDoctorList.Where(t => isJudge ? t.ArmEnum == Arm.JudgeArm : t.ArmEnum != Arm.JudgeArm).Where(t => t.OrignalSubjectUserId == null).SelectMany(t => t.SubjectArmVisitTaskList).Any(c => c.DoctorUserId != null) + // IsApplyed = false + // }).ToList(); + + // //已产生任务的Subject数量(裁判情况下,就是产生裁判任务Subject 的数量) + // var subjectCount = subjectList.Count; + + // //获取医生列表(裁判是裁判的医生列表) + // var waitAllocationDoctorList = _taskAllocationRuleRepository.Where(t => t.TrialId == trialId && t.IsEnable) + // .Where(t => t.IsJudgeDoctor == isJudge) + // .Select(t => new AutoAssignResultDTO() { DoctorUserId = t.DoctorUserId, PlanReadingRatio = t.PlanReadingRatio, SubjectCount = subjectCount }) + // .ToList(); + + // if (waitAllocationDoctorList.Count == 0) + // { + // throw new BusinessValidationFailedException("启用的医生数量为0"); + // } + + + // //已分配的 医生的情况 + // var haveAssignedSubjectDoctorList = subjectList.Clone().SelectMany(t => t.DoctorUserList.Select(c => new { t.SubjectId, c.DoctorUserId, c.ArmEnum })).ToList(); + + // //将目前已分配的情况 换到医生的维度 + // foreach (var waitAllocationDoctor in waitAllocationDoctorList) + // { + // waitAllocationDoctor.SubjectArmList = haveAssignedSubjectDoctorList.Where(t => t.DoctorUserId == waitAllocationDoctor.DoctorUserId) + // .Select(g => new SubjectArm() + // { + // SubjectId = g.SubjectId, + // ArmEnum = g.ArmEnum + // }).ToList(); + // } + + + // #region 完全按照Subject 遍历去分 + + + // //仅仅分配未应用的 而且 没有分配医生的 + // foreach (var subject in subjectList.Where(t => t.IsApplyed == false && !t.DoctorUserList.Any())) + // { + // //该Subject 已经分配的医生数量 + // var hasAssignDoctorCount = subject.DoctorUserList.Count(); + + // if (isJudge) + // { + // if (hasAssignDoctorCount > 1) + // { + // throw new BusinessValidationFailedException("当前有Subject裁判绑定医生数量大于1"); + + // } + + // var allocateDoctor = waitAllocationDoctorList.OrderByDescending(t => t.Weight).ThenByDescending(t => t.PlanReadingRatio).FirstOrDefault(); + + // //将分配结果记录 + // waitAllocationDoctorList.FirstOrDefault(t => t.DoctorUserId == allocateDoctor.DoctorUserId).SubjectArmList.Add(new SubjectArm() + // { + // SubjectId = subject.SubjectId, + // ArmEnum = Arm.JudgeArm + // }); + + // await _subjectUserRepository.AddAsync(new SubjectUser() { TrialId = trialId, SubjectId = subject.SubjectId, DoctorUserId = allocateDoctor.DoctorUserId, ArmEnum = Arm.JudgeArm, AssignTime = DateTime.Now }); + + // } + // else + // { + + // //分配两个医生 + // if (trialConfig.ReadingType == ReadingMethod.Double) + // { + + + // if (hasAssignDoctorCount > 2) + // { + // throw new BusinessValidationFailedException("双重阅片当前有Subject绑定医生数量大于2"); + + // } + + // var allocateDoctorList = waitAllocationDoctorList.OrderByDescending(t => t.Weight).ThenByDescending(t => t.PlanReadingRatio).Take(2).ToList(); + + + // #region 看阅片人之前在Subject哪个组做的多 + + // var preferredDoctor1Arm = waitAllocationDoctorList.Where(t => t.DoctorUserId == allocateDoctorList[0].DoctorUserId) + // .SelectMany(t => t.SubjectArmList).GroupBy(t => t.ArmEnum) + // .Select(g => new { ArmEnum = g.Key, SubjectCount = g.Count() }) + // .OrderByDescending(t => t.SubjectCount).FirstOrDefault()?.ArmEnum; + + // var preferredDoctor2Arm = waitAllocationDoctorList.Where(t => t.DoctorUserId == allocateDoctorList[1].DoctorUserId) + // .SelectMany(t => t.SubjectArmList).GroupBy(t => t.ArmEnum) + // .Select(g => new { ArmEnum = g.Key, SubjectCount = g.Count() }) + // .OrderByDescending(t => t.SubjectCount).FirstOrDefault()?.ArmEnum; + + // //存放医生分配的Arm + // var doctor1Arm = Arm.DoubleReadingArm1; + // var doctor2Arm = Arm.DoubleReadingArm2; + + // if (preferredDoctor1Arm == null && preferredDoctor2Arm == null || + // preferredDoctor1Arm == null && preferredDoctor2Arm == Arm.DoubleReadingArm2 || + // preferredDoctor1Arm == Arm.DoubleReadingArm1 && preferredDoctor2Arm == null || + // preferredDoctor1Arm == Arm.DoubleReadingArm1 && preferredDoctor2Arm == Arm.DoubleReadingArm2 + // ) + // { + // doctor1Arm = Arm.DoubleReadingArm1; + // doctor2Arm = Arm.DoubleReadingArm2; + // } + // else if (preferredDoctor1Arm == null && preferredDoctor2Arm == Arm.DoubleReadingArm1 || + // preferredDoctor1Arm == Arm.DoubleReadingArm2 && preferredDoctor2Arm == Arm.DoubleReadingArm1 || + // preferredDoctor1Arm == Arm.DoubleReadingArm2 && preferredDoctor2Arm == null) + // { + // doctor1Arm = Arm.DoubleReadingArm2; + // doctor2Arm = Arm.DoubleReadingArm1; + // } + + // else if (preferredDoctor1Arm == Arm.DoubleReadingArm1 && preferredDoctor2Arm == Arm.DoubleReadingArm1) + // { + // doctor1Arm = Arm.DoubleReadingArm1; + // doctor2Arm = Arm.DoubleReadingArm2; + // } + // else if (preferredDoctor1Arm == Arm.DoubleReadingArm2 && preferredDoctor2Arm == Arm.DoubleReadingArm2) + // { + // doctor1Arm = Arm.DoubleReadingArm2; + // doctor2Arm = Arm.DoubleReadingArm1; + // } + + // #endregion + + + // await _subjectUserRepository.AddAsync(new SubjectUser() { TrialId = trialId, SubjectId = subject.SubjectId, DoctorUserId = allocateDoctorList[0].DoctorUserId, ArmEnum = doctor1Arm, AssignTime = DateTime.Now }); + + + // //将分配结果记录 + // waitAllocationDoctorList.FirstOrDefault(t => t.DoctorUserId == allocateDoctorList[0].DoctorUserId).SubjectArmList.Add(new SubjectArm() + // { + // SubjectId = subject.SubjectId, + // ArmEnum = doctor1Arm + // }); + + + // await _subjectUserRepository.AddAsync(new SubjectUser() { TrialId = trialId, SubjectId = subject.SubjectId, DoctorUserId = allocateDoctorList[1].DoctorUserId, ArmEnum = doctor2Arm, AssignTime = DateTime.Now }); + + // //将分配结果记录 + // waitAllocationDoctorList.FirstOrDefault(t => t.DoctorUserId == allocateDoctorList[1].DoctorUserId).SubjectArmList.Add(new SubjectArm() + // { + // SubjectId = subject.SubjectId, + // ArmEnum = doctor2Arm + // }); + // } + // else if (trialConfig.ReadingType == ReadingMethod.Single) + // { + // if (hasAssignDoctorCount > 1) + // { + // throw new BusinessValidationFailedException("单重阅片当前有Subject绑定医生数量大于1"); + // } + + // var allocateDoctor = waitAllocationDoctorList.OrderByDescending(t => t.Weight).ThenByDescending(t => t.PlanReadingRatio).FirstOrDefault(); + + // //将分配结果记录 + // waitAllocationDoctorList.FirstOrDefault(t => t.DoctorUserId == allocateDoctor.DoctorUserId).SubjectArmList.Add(new SubjectArm() + // { + // SubjectId = subject.SubjectId, + // ArmEnum = Arm.SingleReadingArm + // }); + + // await _subjectUserRepository.AddAsync(new SubjectUser() { TrialId = trialId, SubjectId = subject.SubjectId, DoctorUserId = allocateDoctor.DoctorUserId, ArmEnum = Arm.SingleReadingArm, AssignTime = DateTime.Now }); + + // } + + // } + + // } + + + // #endregion + + + + + + + + // await _subjectUserRepository.SaveChangesAsync(); + // return ResponseOutput.Ok(); + + //} + + + #endregion } diff --git a/IRaCIS.Core.Application/Service/Common/DTO/FrontAuditConfigViewModel.cs b/IRaCIS.Core.Application/Service/Common/DTO/FrontAuditConfigViewModel.cs index 13a4d84e2..b2d76c285 100644 --- a/IRaCIS.Core.Application/Service/Common/DTO/FrontAuditConfigViewModel.cs +++ b/IRaCIS.Core.Application/Service/Common/DTO/FrontAuditConfigViewModel.cs @@ -7,7 +7,7 @@ using System; using IRaCIS.Core.Domain.Share; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; -using IRaCIS.Core.Infra.EFCore.Common.Dto; +using IRaCIS.Core.Infra.EFCore.Common; namespace IRaCIS.Core.Application.ViewModel { diff --git a/IRaCIS.Core.Application/Service/Inspection/DTO/InspectionViewModel.cs b/IRaCIS.Core.Application/Service/Inspection/DTO/InspectionViewModel.cs new file mode 100644 index 000000000..858d8bd08 --- /dev/null +++ b/IRaCIS.Core.Application/Service/Inspection/DTO/InspectionViewModel.cs @@ -0,0 +1,73 @@ +using IRaCIS.Core.Domain.Share; +using System.ComponentModel.DataAnnotations; +namespace IRaCIS.Core.Application.ViewModel; + +public class DateDto +{ + public string Code { get; set; } + + public string DateType { get; set; } + + public string Identification { get; set; } +} + +public class SetInspectionEnumValueDto +{ + [NotDefault] + public Guid TrialId { get; set; } + + [NotDefault] + public List AuditDataIds { get; set; } + + + +} + + +public class AccessToDialogueInDto +{ + public Guid Id { get; set; } + + public AccessToDialogueEnum Type { get; set; } + + public DateTime Createtime { get; set; } +} + + +public class AccessToDialogueOutDto +{ + public string CreateUserName { get; set; } + + public string TalkContent { get; set; } + + public DateTime CreateTime { get; set; } + + public bool IsTitle { get; set; } +} + +public enum AccessToDialogueEnum +{ + /// + /// + /// + Question = 0, + + /// + /// һԺ˲ + /// + Consistency = 1, +} + +/// +/// +/// +public class CopyFrontAuditConfigItemDto +{ + public Guid ParentId { get; set; } + + public Guid ChildId { get; set; } +} + + + + diff --git a/IRaCIS.Core.Application/Service/Inspection/FrontAuditConfigService.cs b/IRaCIS.Core.Application/Service/Inspection/FrontAuditConfigService.cs index e48d7d026..8f9b8b527 100644 --- a/IRaCIS.Core.Application/Service/Inspection/FrontAuditConfigService.cs +++ b/IRaCIS.Core.Application/Service/Inspection/FrontAuditConfigService.cs @@ -8,7 +8,6 @@ using Microsoft.AspNetCore.Mvc; using IRaCIS.Core.Application.Interfaces; using IRaCIS.Core.Application.ViewModel; using MassTransit; -using IRaCIS.Core.Infra.EFCore.Common.Dto; using Microsoft.Data.SqlClient; using Newtonsoft.Json; using Newtonsoft.Json.Linq; @@ -19,6 +18,7 @@ using IRaCIS.Application.Contracts; using IRaCIS.Core.Infrastructure.Extention; using Microsoft.EntityFrameworkCore; using Npgsql; +using IRaCIS.Core.Infra.EFCore.Common; namespace IRaCIS.Core.Application.Service { diff --git a/IRaCIS.Core.Infra.EFCore/Common/AuditingData.cs b/IRaCIS.Core.Infra.EFCore/Common/AuditingData.cs index 446560df0..6a211b97c 100644 --- a/IRaCIS.Core.Infra.EFCore/Common/AuditingData.cs +++ b/IRaCIS.Core.Infra.EFCore/Common/AuditingData.cs @@ -1,6 +1,5 @@ using IRaCIS.Core.Domain.Models; using IRaCIS.Core.Domain.Share; -using IRaCIS.Core.Infra.EFCore.Common.Dto; using IRaCIS.Core.Infrastructure; using IRaCIS.Core.Infrastructure.Extention; using MassTransit; diff --git a/IRaCIS.Core.Infra.EFCore/Common/Dto/SetDictionaryValueDto.cs b/IRaCIS.Core.Infra.EFCore/Common/AuditingDto.cs similarity index 65% rename from IRaCIS.Core.Infra.EFCore/Common/Dto/SetDictionaryValueDto.cs rename to IRaCIS.Core.Infra.EFCore/Common/AuditingDto.cs index 627e7e891..ced7f0951 100644 --- a/IRaCIS.Core.Infra.EFCore/Common/Dto/SetDictionaryValueDto.cs +++ b/IRaCIS.Core.Infra.EFCore/Common/AuditingDto.cs @@ -7,20 +7,8 @@ using System.ComponentModel.DataAnnotations; using IRaCIS.Core.Domain.Models; using IRaCIS.Core.Domain.Share; -namespace IRaCIS.Core.Infra.EFCore.Common.Dto +namespace IRaCIS.Core.Infra.EFCore.Common { - public class SetInspectionEnumValueDto - { - [NotDefault] - public Guid TrialId { get; set; } - - [NotDefault] - public List AuditDataIds { get; set; } - - - - } - public class SetInspectionEnumDataDto { public Guid Id { get; set; } @@ -34,8 +22,6 @@ namespace IRaCIS.Core.Infra.EFCore.Common.Dto public Guid? ObjectRelationParentId2 { get; set; } public Guid? ObjectRelationParentId3 { get; set; } - - /// /// 批次Id /// @@ -46,69 +32,6 @@ namespace IRaCIS.Core.Infra.EFCore.Common.Dto - - public class AddInterface - { - public Guid ParentId { get; set; } - - public List Names { get; set; } - } - - public class AccessToDialogueInDto - { - public Guid Id { get; set; } - - public AccessToDialogueEnum Type { get; set; } - - public DateTime Createtime { get; set; } - } - - - public class AccessToDialogueOutDto - { - public string CreateUserName { get; set; } - - public string TalkContent { get; set; } - - public DateTime CreateTime { get; set; } - - public bool IsTitle { get; set; } - } - - public enum AccessToDialogueEnum - { - /// - /// 质疑 - /// - Question = 0, - - /// - /// 一致性核查 - /// - Consistency = 1, - } - - /// - /// 复制 - /// - public class CopyFrontAuditConfigItemDto - { - public Guid ParentId { get; set; } - - public Guid ChildId { get; set; } - } - - - public class UnitData - { - /// - /// 单位 - /// - public ValueUnit? Unit { get; set; } - - public string UnitName { get; set; } - } - /// /// 稽查数据 /// @@ -120,20 +43,32 @@ namespace IRaCIS.Core.Infra.EFCore.Common.Dto public object CommonData { get; set; } } + + public class UnitData + { + /// + /// 单位 + /// + public ValueUnit? Unit { get; set; } + + public string UnitName { get; set; } + } + + public class VisitTaskAuditingDto { - public string UserRealName { get; set; } + public string UserRealName { get; set; } - public string SubjectCode { get; set; } + public string SubjectCode { get; set; } - public string R1 { get; set; } + public string R1 { get; set; } - public string R2 { get; set; } + public string R2 { get; set; } - public string CutOffVisitName { get; set; } + public string CutOffVisitName { get; set; } - public string SelectResult { get; set; } - } + public string SelectResult { get; set; } + } public class InspectionConvertDTO : DataInspection { /// @@ -172,10 +107,10 @@ namespace IRaCIS.Core.Infra.EFCore.Common.Dto public string BlindName { get; set; } = string.Empty; - /// - /// 标识操作 是否区分接口 - /// - public bool IsDistinctionInterface=true; + /// + /// 标识操作 是否区分接口 + /// + public bool IsDistinctionInterface = true; public bool IsSelfDefine = false; @@ -195,9 +130,7 @@ namespace IRaCIS.Core.Infra.EFCore.Common.Dto /// public Guid? TrialId { get; set; } - public Guid? TrialSiteId { get;set; } - - + public Guid? TrialSiteId { get; set; } /// /// 受试者 @@ -238,20 +171,6 @@ namespace IRaCIS.Core.Infra.EFCore.Common.Dto /// public string SubjectVisitName { get; set; } - - - // /// - ///// 创建人名称 - ///// - //public string CreateUserName { get; set; } - - - // /// - // /// 角色名称 - // /// - // public string RoleName { get; set; } - - } public class SetInspectionEnum @@ -268,9 +187,4 @@ namespace IRaCIS.Core.Infra.EFCore.Common.Dto public string Remake { get; set; } } - - - - - } diff --git a/IRaCIS.Core.Infra.EFCore/Common/Dto/DateDto.cs b/IRaCIS.Core.Infra.EFCore/Common/Dto/DateDto.cs deleted file mode 100644 index b102f4bf1..000000000 --- a/IRaCIS.Core.Infra.EFCore/Common/Dto/DateDto.cs +++ /dev/null @@ -1,23 +0,0 @@ -using IRaCIS.Core.Domain.Models; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Linq.Expressions; -using System.Text; -using System.Threading.Tasks; - -namespace IRaCIS.Core.Infra.EFCore.Common.Dto -{ - public class DateDto - { - public string Code { get; set; } - - public string DateType { get; set; } - - public string Identification { get; set; } - } - public class ForeignKey - { - public string Text { get; set; } - } -} diff --git a/IRaCIS.Core.Infra.EFCore/Context/IRaCISDBContext.cs b/IRaCIS.Core.Infra.EFCore/Context/IRaCISDBContext.cs index bdf501aa4..47b7795e9 100644 --- a/IRaCIS.Core.Infra.EFCore/Context/IRaCISDBContext.cs +++ b/IRaCIS.Core.Infra.EFCore/Context/IRaCISDBContext.cs @@ -16,7 +16,6 @@ using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.ValueGeneration; using UserTypeGroup = IRaCIS.Core.Domain.Models.UserTypeGroup; using IRaCIS.Core.Infra.EFCore.Common; -using IRaCIS.Core.Infra.EFCore.Common.Dto; using Microsoft.Identity.Client; using EntityFramework.Exceptions.Common; using System.Data; diff --git a/IRaCIS.Core.Test/LiquidTemplate/EntityService.liquid b/IRaCIS.Core.Test/LiquidTemplate/EntityService.liquid index 479a9dc62..420282f76 100644 --- a/IRaCIS.Core.Test/LiquidTemplate/EntityService.liquid +++ b/IRaCIS.Core.Test/LiquidTemplate/EntityService.liquid @@ -11,62 +11,61 @@ using IRaCIS.Core.Application.ViewModel; using IRaCIS.Core.Infrastructure.Extention; using System.Threading.Tasks; using IRaCIS.Core.Infra.EFCore; -namespace IRaCIS.Core.Application.Service -{ +namespace IRaCIS.Core.Application.Service; + +[ ApiExplorerSettings(GroupName = "Test")] +public class {{TableName}}Service(IRepository<{{TableName}}> {{LowercaseRepositoryName}}): BaseService, I{{TableName}}Service +{ - [ ApiExplorerSettings(GroupName = "Test")] - public class {{TableName}}Service(IRepository<{{TableName}}> {{LowercaseRepositoryName}}): BaseService, I{{TableName}}Service - { - - {% if IsPaged %} - [HttpPost] - public async Task> Get{{TableName}}List({{TableNameQuery}} inQuery) - { + {% if IsPaged %} + [HttpPost] + public async Task> Get{{TableName}}List({{TableNameQuery}} inQuery) + { - var {{LowercaseQueryableName}} ={{LowercaseRepositoryName}} - .ProjectTo<{{TableNameView}}>(_mapper.ConfigurationProvider); + var {{LowercaseQueryableName}} ={{LowercaseRepositoryName}} + .ProjectTo<{{TableNameView}}>(_mapper.ConfigurationProvider); - var pageList= await {{LowercaseQueryableName}}.ToPagedListAsync(inQuery); + var pageList= await {{LowercaseQueryableName}}.ToPagedListAsync(inQuery); - return pageList; - } - {% else %} - [HttpPost] - public async Task> Get{{TableName}}List({{TableNameQuery}} inQuery) - { + return pageList; + } + {% else %} + [HttpPost] + public async Task> Get{{TableName}}List({{TableNameQuery}} inQuery) + { - var {{LowercaseQueryableName}} ={{LowercaseRepositoryName}} - .ProjectTo<{{TableNameView}}>(_mapper.ConfigurationProvider); + var {{LowercaseQueryableName}} ={{LowercaseRepositoryName}} + .ProjectTo<{{TableNameView}}>(_mapper.ConfigurationProvider); - return await {{LowercaseQueryableName}}.ToListAsync(); - } - {% endif %} + return await {{LowercaseQueryableName}}.ToListAsync(); + } + {% endif %} - public async Task AddOrUpdate{{TableName}}({{TableName}}AddOrEdit addOrEdit{{TableName}}) - { - // 在此处拷贝automapper 映射 + public async Task AddOrUpdate{{TableName}}({{TableName}}AddOrEdit addOrEdit{{TableName}}) + { + // 在此处拷贝automapper 映射 - CreateMap<{{TableName}}, {{TableNameView}}>(); - CreateMap<{{TableName}},{{TableNameAddOrEdit}}>().ReverseMap(); + CreateMap<{{TableName}}, {{TableNameView}}>(); + CreateMap<{{TableName}},{{TableNameAddOrEdit}}>().ReverseMap(); - var entity = await {{LowercaseRepositoryName}}.InsertOrUpdateAsync(addOrEdit{{TableName}}, true); + var entity = await {{LowercaseRepositoryName}}.InsertOrUpdateAsync(addOrEdit{{TableName}}, true); - return ResponseOutput.Ok(entity.Id.ToString()); + return ResponseOutput.Ok(entity.Id.ToString()); - } + } - [HttpDelete("{{ '{' }}{{LowercaseTableNameId}}:guid{{ '}' }}")] - public async Task Delete{{TableName}}(Guid {{LowercaseTableNameId}}) - { - var success = await _<#=char.ToLower(tableName[0]) + tableName.Substring(1)#>Repository.DeleteFromQueryAsync(t => t.Id == {{LowercaseTableNameId}},true); - return ResponseOutput.Ok(); - } + [HttpDelete("{{ '{' }}{{LowercaseTableNameId}}:guid{{ '}' }}")] + public async Task Delete{{TableName}}(Guid {{LowercaseTableNameId}}) + { + var success = await _<#=char.ToLower(tableName[0]) + tableName.Substring(1)#>Repository.DeleteFromQueryAsync(t => t.Id == {{LowercaseTableNameId}},true); + return ResponseOutput.Ok(); + } + +} + - - } -} diff --git a/IRaCIS.Core.Test/LiquidTemplate/EntityViewModel.liquid b/IRaCIS.Core.Test/LiquidTemplate/EntityViewModel.liquid index 0a5902e97..87f4d4f2d 100644 --- a/IRaCIS.Core.Test/LiquidTemplate/EntityViewModel.liquid +++ b/IRaCIS.Core.Test/LiquidTemplate/EntityViewModel.liquid @@ -7,38 +7,38 @@ using System; using IRaCIS.Core.Domain.Share; using System.Collections.Generic; -namespace IRaCIS.Core.Application.ViewModel +namespace IRaCIS.Core.Application.ViewModel; + +public class {{ TableNameView }} : {{ TableNameAddOrEdit }} { - public class {{ TableNameView }} : {{ TableNameAddOrEdit }} - { - {% for field in ViewListFieldList %} - public {{ field.CSharpType }} {{ field.FieldName }} { get; set; } - {% endfor %} - } + {% for field in ViewListFieldList %} + public {{ field.CSharpType }} {{ field.FieldName }} { get; set; } + {% endfor %} +} - public class {{ TableNameAddOrEdit }} - { - {%- for field in AddOrUpdateFieldList -%} - {% if field.IsPrimarykey %} - public {{ field.CSharpType }}? {{ field.FieldName }} { get; set; } - {% else %} - public {{ field.CSharpType }} {{ field.FieldName }} { get; set; } - {% endif %} - {%- endfor -%} - } +public class {{ TableNameAddOrEdit }} +{ + {%- for field in AddOrUpdateFieldList -%} + {% if field.IsPrimarykey %} + public {{ field.CSharpType }}? {{ field.FieldName }} { get; set; } + {% else %} + public {{ field.CSharpType }} {{ field.FieldName }} { get; set; } + {% endif %} + {%- endfor -%} +} - public class {{ TableNameQuery }} - { - {%- for field in QueryListFieldList -%} - {% if field.IsNullable and field.IsCSharpString == false %} - public {{ field.CSharpType }} {{ field.FieldName }} { get; set; } - {% else %} - public {{ field.CSharpType }}? {{ field.FieldName }} { get; set; } - {% endif %} - {%- endfor -%} - } +public class {{ TableNameQuery }} +{ + {%- for field in QueryListFieldList -%} + {% if field.IsNullable and field.IsCSharpString == false %} + public {{ field.CSharpType }} {{ field.FieldName }} { get; set; } + {% else %} + public {{ field.CSharpType }}? {{ field.FieldName }} { get; set; } + {% endif %} + {%- endfor -%} } + diff --git a/IRaCIS.Core.Test/LiquidTemplate/IEntityService.liquid b/IRaCIS.Core.Test/LiquidTemplate/IEntityService.liquid index 9b22f711c..cd38ad0fc 100644 --- a/IRaCIS.Core.Test/LiquidTemplate/IEntityService.liquid +++ b/IRaCIS.Core.Test/LiquidTemplate/IEntityService.liquid @@ -8,18 +8,18 @@ using System; using IRaCIS.Core.Infrastructure.Extention; using System.Threading.Tasks; using IRaCIS.Core.Application.ViewModel; -namespace IRaCIS.Core.Application.Interfaces -{ - public interface I{{TableName}}Service - { - {% if IsPaged %} - Task> Get{{TableName}}List({{TableNameQuery}} inQuery); - {% else %} - Task> Get{{TableName}}List({{TableNameQuery}} inQuery); - {% endif %} - Task AddOrUpdate{{TableName}}({{TableNameAddOrEdit}} addOrEdit{{TableName}}); +namespace IRaCIS.Core.Application.Interfaces; - Task Delete{{TableNameView}}(Guid {{LowercaseTableNameId}}); - } +public interface I{{TableName}}Service +{ + {% if IsPaged %} + Task> Get{{TableName}}List({{TableNameQuery}} inQuery); + {% else %} + Task> Get{{TableName}}List({{TableNameQuery}} inQuery); + {% endif %} + Task AddOrUpdate{{TableName}}({{TableNameAddOrEdit}} addOrEdit{{TableName}}); + + Task Delete{{TableNameView}}(Guid {{LowercaseTableNameId}}); } +