//-------------------------------------------------------------------- // 此代码由T4模板自动生成 byzhouhang 20210918 // 生成时间 2022-06-07 14:10:49 // 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。 //-------------------------------------------------------------------- using IRaCIS.Core.Domain.Models; using Microsoft.AspNetCore.Mvc; using IRaCIS.Core.Application.Interfaces; using IRaCIS.Core.Application.ViewModel; using IRaCIS.Core.Domain.Share; using IRaCIS.Core.Infrastructure; using IRaCIS.Core.Application.Contracts; using IRaCIS.Core.Infra.EFCore.Common; using System.Linq.Expressions; using IRaCIS.Application.Contracts; using IRaCIS.Core.Application.Filter; using DocumentFormat.OpenXml.Office2010.Word; using System.Linq.Dynamic.Core; using System.Linq; using DocumentFormat.OpenXml.Bibliography; using Org.BouncyCastle.Crypto; using IRaCIS.Core.Domain.Share.Reading; namespace IRaCIS.Core.Application.Service.Allocation { /// /// 检查批次读片任务 /// [ApiExplorerSettings(GroupName = "Trial")] public class VisitTaskService : BaseService, IVisitTaskService { private readonly IRepository _visitTaskRepository; private readonly IRepository _trialRepository; private readonly IRepository _subjectVisitRepository; private readonly IRepository _taskAllocationRuleRepository; private readonly IRepository _subjectRepository; private readonly IRepository _subjectUserRepository; private readonly IRepository _readModuleRepository; private readonly IRepository _visitTaskReReadingRepository; private readonly IRepository _taskMedicalReviewRepository; private readonly IRepository _readingTaskQuestionAnswerRepository; private readonly IRepository _trialReadingCriterionRepository; private readonly IRepository _readingClinicalDataReposiotry; public VisitTaskService(IRepository subjectVisitRepository, IRepository visitTaskRepository, IRepository trialRepository, IRepository subjectRepository, IRepository subjectUserRepository, IRepository taskAllocationRuleRepository, IRepository readModuleRepository, IRepository visitTaskReReadingRepository, IRepository taskMedicalReviewRepository, IRepository readingTaskQuestionAnswerRepository , IRepository trialReadingCriterionRepository, IRepository readingClinicalDataReposiotry ) { _readingClinicalDataReposiotry = readingClinicalDataReposiotry; _taskAllocationRuleRepository = taskAllocationRuleRepository; _visitTaskRepository = visitTaskRepository; _trialRepository = trialRepository; _subjectVisitRepository = subjectVisitRepository; _subjectRepository = subjectRepository; _subjectUserRepository = subjectUserRepository; _readModuleRepository = readModuleRepository; _visitTaskReReadingRepository = visitTaskReReadingRepository; _taskMedicalReviewRepository = taskMedicalReviewRepository; _readingTaskQuestionAnswerRepository = readingTaskQuestionAnswerRepository; _trialReadingCriterionRepository = trialReadingCriterionRepository; } /// /// 设置任务加急 /// /// /// [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) { var list = await _repository.Where(t => t.TrialId == trialId && t.IsConfirm) .OrderBy(t => t.ShowOrder) .Select(t => new TrialReadingCriterionDto() { TrialReadingCriterionId = t.Id, TrialReadingCriterionName = t.CriterionName, CriterionType = t.CriterionType, ReadingType = t.ReadingType, ReadingInfoSignTime = t.ReadingInfoSignTime }) .ToListAsync(); if (list.Count == 0) { throw new BusinessValidationFailedException("该项目还未确认任何一个阅片标准"); } return list.AsQueryable().WhereIf(isHaveSigned == true, t => t.ReadingInfoSignTime != null).ToList(); } /// /// Subject 任务类型 统计 +分配情况 /// /// [HttpPost] public async Task<(PageOutput, object?)> GetSubjectAssignAndTaskStatList(SubjectAssignStatQuery querySubjectAssign) { var subjectQuery = _subjectRepository.Where(t => t.TrialId == querySubjectAssign.TrialId && t.SubjectVisitTaskList.Any()) .WhereIf(querySubjectAssign.SiteId != null, t => t.SiteId == querySubjectAssign.SiteId) .WhereIf(querySubjectAssign.SubjectId != null, t => t.Id == querySubjectAssign.SubjectId) .WhereIf(querySubjectAssign.DoctorUserId != null, t => t.SubjectDoctorList.Any(t => t.DoctorUserId == querySubjectAssign.DoctorUserId && t.TrialReadingCriterionId == querySubjectAssign.TrialReadingCriterionId)) .WhereIf(!string.IsNullOrEmpty(querySubjectAssign.SubjectCode), t => t.Code.Contains(querySubjectAssign.SubjectCode)) .ProjectTo(_mapper.ConfigurationProvider, new { trialReadingCriterionId = querySubjectAssign.TrialReadingCriterionId }); var pageList = await subjectQuery.ToPagedListAsync(querySubjectAssign.PageIndex, querySubjectAssign.PageSize, string.IsNullOrWhiteSpace(querySubjectAssign.SortField) ? nameof(querySubjectAssign.SubjectId) : querySubjectAssign.SortField, querySubjectAssign.Asc); var criterionConfig = (await _trialReadingCriterionRepository.Where(x => x.Id == querySubjectAssign.TrialReadingCriterionId).Select(x => new { x.ReadingTool, x.IsReadingTaskViewInOrder, x.ReadingType, x.IsArbitrationReading, x.IsOncologyReading, x.IsGlobalReading }).FirstOrDefaultAsync()).IfNullThrowException(); return (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.OrignalSubjectUserId == 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.OrignalSubjectUserId == 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.TrialReadingCriterionId == cancelCommand.TrialReadingCriterionId && t.SubjectId == command.SubjectId && t.DoctorUserId == command.DoctorUserId && t.ArmEnum == command.ArmEnum && t.ReadingTaskState != ReadingTaskState.WaitReading)) { throw new BusinessValidationFailedException("当前医生已开始做该Subject 该标准的任务,不允许取消分配"); } 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 _repository.AddAsync(new SubjectCanceDoctor() { SubjectId = subjectId, Note = cancelCommand.Note }); 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("其中一个任务已分配给该医生,不允许分配"); } } 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("其中一个任务已分配给该医生,不允许分配"); } } else { throw new BusinessValidationFailedException("出现脏数据 任务来源字段没有值"); } //PM 回退了 但是还没生成任务 当前任务编号前有检查批次进行了回退就不允许分配 if (await _subjectVisitRepository.AnyAsync(t => t.SubjectId == visitTask.SubjectId && t.IsPMBackOrReReading && t.VisitNum <= visitTask.VisitTaskNum)) { return ResponseOutput.NotOk("该患者有检查批次进入了退回流程,还未经过一致性核查通过,不允许分配"); } 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 querySubjectAssign) { var subjectQuery = _subjectRepository.Where(t => t.TrialId == querySubjectAssign.TrialId) .WhereIf(querySubjectAssign.IsJudgeDoctor == false, t => t.SubjectVisitTaskList.Where(t => t.ArmEnum != Arm.JudgeArm).Any()) .WhereIf(querySubjectAssign.IsJudgeDoctor, t => t.SubjectVisitTaskList.Where(t => t.ArmEnum == Arm.JudgeArm).Any()) .WhereIf(querySubjectAssign.SiteId != null, t => t.SiteId == querySubjectAssign.SiteId) .WhereIf(querySubjectAssign.SubjectId != null, t => t.Id == querySubjectAssign.SubjectId) .WhereIf(querySubjectAssign.IsHaveAssigned != null && querySubjectAssign.IsHaveAssigned == true && querySubjectAssign.IsJudgeDoctor == false, t => t.SubjectDoctorList.Where(t => t.ArmEnum != Arm.JudgeArm).Any()) .WhereIf(querySubjectAssign.IsHaveAssigned != null && querySubjectAssign.IsHaveAssigned == true && querySubjectAssign.IsJudgeDoctor, t => t.SubjectDoctorList.Where(t => t.ArmEnum == Arm.JudgeArm).Any()) .WhereIf(querySubjectAssign.IsHaveAssigned != null && querySubjectAssign.IsHaveAssigned == false && querySubjectAssign.IsJudgeDoctor == false, t => !t.SubjectDoctorList.Where(t => t.ArmEnum != Arm.JudgeArm).Any()) .WhereIf(querySubjectAssign.IsHaveAssigned != null && querySubjectAssign.IsHaveAssigned == false && querySubjectAssign.IsJudgeDoctor, t => !t.SubjectDoctorList.Where(t => t.ArmEnum == Arm.JudgeArm).Any()) .WhereIf(querySubjectAssign.IsAssignConfirmed != null && querySubjectAssign.IsAssignConfirmed == true && querySubjectAssign.IsJudgeDoctor == false, t => t.SubjectDoctorList.Where(t => t.ArmEnum != Arm.JudgeArm).All(u => u.IsConfirmed)) .WhereIf(querySubjectAssign.IsAssignConfirmed != null && querySubjectAssign.IsAssignConfirmed == true && querySubjectAssign.IsJudgeDoctor, t => t.SubjectDoctorList.Where(t => t.ArmEnum == Arm.JudgeArm).All(u => u.IsConfirmed)) .WhereIf(querySubjectAssign.IsAssignConfirmed != null && querySubjectAssign.IsAssignConfirmed == false && querySubjectAssign.IsJudgeDoctor == false, t => t.SubjectDoctorList.Where(t => t.ArmEnum != Arm.JudgeArm).Any(u => u.IsConfirmed == false)) .WhereIf(querySubjectAssign.IsAssignConfirmed != null && querySubjectAssign.IsAssignConfirmed == false && querySubjectAssign.IsJudgeDoctor, t => t.SubjectDoctorList.Where(t => t.ArmEnum == Arm.JudgeArm).Any(u => u.IsConfirmed == false)) .WhereIf(querySubjectAssign.DoctorUserId != null && querySubjectAssign.IsJudgeDoctor == false, t => t.SubjectDoctorList.Where(t => t.ArmEnum != Arm.JudgeArm).Any(t => t.DoctorUserId == querySubjectAssign.DoctorUserId)) .WhereIf(querySubjectAssign.DoctorUserId != null && querySubjectAssign.IsJudgeDoctor, t => t.SubjectDoctorList.Where(t => t.ArmEnum == Arm.JudgeArm).Any(t => t.DoctorUserId == querySubjectAssign.DoctorUserId)) .ProjectTo(_mapper.ConfigurationProvider, new { isJudgeDoctor = querySubjectAssign.IsJudgeDoctor }); var pageList = await subjectQuery.ToPagedListAsync(querySubjectAssign.PageIndex, querySubjectAssign.PageSize, string.IsNullOrWhiteSpace(querySubjectAssign.SortField) ? nameof(querySubjectAssign.SubjectId) : querySubjectAssign.SortField, querySubjectAssign.Asc); 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.OrignalSubjectUserId == null)) { throw new BusinessValidationFailedException("有Subject 在其他Arm组已有该医生,不允许在新的组添加该医生"); } if (await _subjectUserRepository.AnyAsync(t => t.TrialId == trialId && t.SubjectId == subjectId && t.DoctorUserId == doctorUserId && t.ArmEnum == armEnum && t.OrignalSubjectUserId == null)) { throw new BusinessValidationFailedException("有Subject 已有该Arm组的医生,不允许继续分配,请刷新页面,确认页面数据是否过期"); } 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)) { throw new BusinessValidationFailedException("有Subject任务已应用,不允许取消分配"); } 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)) { throw new BusinessValidationFailedException("有Subject任务已应用,不允许取消分配"); } 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.OrignalSubjectUserId == null, u => new SubjectUser() { IsConfirmed = true }); } else { await _subjectUserRepository.BatchUpdateNoTrackingAsync(t => t.TrialId == trialId && t.IsConfirmed == false && t.OrignalSubjectUserId == 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.OrignalSubjectUserId == 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("在配置表中未找到配置的医生,无法应用绑定,请核对数据"); } } } await _visitTaskRepository.SaveChangesAsync(); return ResponseOutput.Ok(); } /// /// 检查批次任务 /// /// /// /// [HttpPost] public async Task> GetVisitTaskList(VisitTaskQuery queryVisitTask, [FromServices] IVisitTaskHelpeService _visitTaskCommonService) { //以前检查批次未产生任务的,在查询这里要产生 var svIdList = await _subjectVisitRepository.Where(t => t.TrialId == queryVisitTask.TrialId && t.CheckState == CheckStateEnum.CVPassed && t.IsVisitTaskGenerated == false).Select(t => t.Id).ToListAsync(); //之前没有生成任务的逻辑 但是现在加了,任务要自动生成 await _visitTaskCommonService.GenerateVisitTaskAsync(queryVisitTask.TrialId, svIdList); var visitTaskQueryable = _visitTaskRepository.Where(t => t.TrialId == queryVisitTask.TrialId && t.IsAnalysisCreate == false) .WhereIf(queryVisitTask.ReadingCategory != null, t => t.ReadingCategory == queryVisitTask.ReadingCategory) .WhereIf(queryVisitTask.ReadingCategory == null, t => t.ReadingCategory != ReadingCategory.Judge) .WhereIf(queryVisitTask.TaskState != null, t => t.TaskState == queryVisitTask.TaskState) .WhereIf(queryVisitTask.SiteId != null, t => t.Subject.SiteId == queryVisitTask.SiteId) .WhereIf(queryVisitTask.SubjectId != null, t => t.SubjectId == queryVisitTask.SubjectId) .WhereIf(queryVisitTask.IsUrgent != null, t => t.IsUrgent == queryVisitTask.IsUrgent) .WhereIf(queryVisitTask.DoctorUserId != null, t => t.DoctorUserId == queryVisitTask.DoctorUserId) .WhereIf(queryVisitTask.ReadingCategory != null, t => t.ReadingCategory == queryVisitTask.ReadingCategory) .WhereIf(queryVisitTask.TaskAllocationState != null, t => t.TaskAllocationState == queryVisitTask.TaskAllocationState) .WhereIf(queryVisitTask.TrialReadingCriterionId != null, t => t.TrialReadingCriterionId == queryVisitTask.TrialReadingCriterionId) .WhereIf(!string.IsNullOrEmpty(queryVisitTask.TrialSiteCode), t => (t.BlindTrialSiteCode.Contains(queryVisitTask.TrialSiteCode!) && t.IsAnalysisCreate) || (t.Subject.TrialSite.TrialSiteCode.Contains(queryVisitTask.TrialSiteCode!) && t.IsAnalysisCreate == false)) .WhereIf(!string.IsNullOrEmpty(queryVisitTask.TaskName), t => t.TaskName.Contains(queryVisitTask.TaskName) || t.TaskBlindName.Contains(queryVisitTask.TaskName)) .WhereIf(!string.IsNullOrEmpty(queryVisitTask.SubjectCode), t => (t.Subject.Code.Contains(queryVisitTask.SubjectCode) && t.IsAnalysisCreate == false) || (t.BlindSubjectCode.Contains(queryVisitTask.SubjectCode) && t.IsAnalysisCreate)) .WhereIf(queryVisitTask.BeginAllocateDate != null, t => t.AllocateTime > queryVisitTask.BeginAllocateDate) .WhereIf(queryVisitTask.EndAllocateDate != null, t => t.AllocateTime < queryVisitTask.EndAllocateDate!.Value.AddDays(1)) .ProjectTo(_mapper.ConfigurationProvider); var defalutSortArray = new string[] { nameof(VisitTask.IsUrgent) + " desc", nameof(VisitTask.SubjectId), nameof(VisitTask.VisitTaskNum) }; var pageList = await visitTaskQueryable.ToPagedListAsync(queryVisitTask.PageIndex, queryVisitTask.PageSize, queryVisitTask.SortField, queryVisitTask.Asc, string.IsNullOrWhiteSpace(queryVisitTask.SortField), defalutSortArray); //var trialTaskConfig = _trialRepository.Where(t => t.Id == queryVisitTask.TrialId).ProjectTo(_mapper.ConfigurationProvider).FirstOrDefault(); return pageList; } /// /// 裁判任务 /// /// /// [HttpPost] public async Task/*, object)*/> GetJudgeVisitTaskList(VisitTaskQuery queryVisitTask) { var visitTaskQueryable = _visitTaskRepository.Where(t => t.TrialId == queryVisitTask.TrialId && t.IsAnalysisCreate == false) .Where(t => t.ReadingCategory == ReadingCategory.Judge) .WhereIf(queryVisitTask.TaskState != null, t => t.TaskState == queryVisitTask.TaskState) .WhereIf(queryVisitTask.ReadingCategory != null, t => t.ReadingCategory == queryVisitTask.ReadingCategory) .WhereIf(queryVisitTask.SiteId != null, t => t.Subject.SiteId == queryVisitTask.SiteId) .WhereIf(queryVisitTask.SubjectId != null, t => t.SubjectId == queryVisitTask.SubjectId) .WhereIf(queryVisitTask.IsUrgent != null, t => t.IsUrgent == queryVisitTask.IsUrgent) .WhereIf(queryVisitTask.DoctorUserId != null, t => t.DoctorUserId == queryVisitTask.DoctorUserId) .WhereIf(queryVisitTask.TaskAllocationState != null, t => t.TaskAllocationState == queryVisitTask.TaskAllocationState) .WhereIf(queryVisitTask.ReadingTaskState != null, t => t.ReadingTaskState == queryVisitTask.ReadingTaskState) .WhereIf(queryVisitTask.TrialReadingCriterionId != null, t => t.TrialReadingCriterionId == queryVisitTask.TrialReadingCriterionId) .WhereIf(!string.IsNullOrEmpty(queryVisitTask.TrialSiteCode), t => (t.BlindTrialSiteCode.Contains(queryVisitTask.TrialSiteCode!) && t.IsAnalysisCreate) || (t.Subject.TrialSite.TrialSiteCode.Contains(queryVisitTask.TrialSiteCode!) && t.IsAnalysisCreate == false)) .WhereIf(!string.IsNullOrEmpty(queryVisitTask.TaskName), t => t.TaskName.Contains(queryVisitTask.TaskName) || t.TaskBlindName.Contains(queryVisitTask.TaskName)) .WhereIf(!string.IsNullOrEmpty(queryVisitTask.SubjectCode), t => (t.Subject.Code.Contains(queryVisitTask.SubjectCode) && t.IsAnalysisCreate == false) || (t.BlindSubjectCode.Contains(queryVisitTask.SubjectCode) && t.IsAnalysisCreate)) .WhereIf(queryVisitTask.BeginAllocateDate != null, t => t.AllocateTime > queryVisitTask.BeginAllocateDate) .WhereIf(queryVisitTask.EndAllocateDate != null, t => t.AllocateTime < queryVisitTask.EndAllocateDate!.Value.AddDays(1)) .ProjectTo(_mapper.ConfigurationProvider); var defalutSortArray = new string[] { nameof(VisitTask.IsUrgent) + " desc", nameof(VisitTask.SubjectId), nameof(VisitTaskView.VisitTaskNum) }; var pageList = await visitTaskQueryable.ToPagedListAsync(queryVisitTask.PageIndex, queryVisitTask.PageSize, queryVisitTask.SortField, queryVisitTask.Asc, string.IsNullOrWhiteSpace(queryVisitTask.SortField), defalutSortArray); return pageList; //var trialTaskConfig = _trialRepository.Where(t => t.Id == queryVisitTask.TrialId).ProjectTo(_mapper.ConfigurationProvider).FirstOrDefault(); //return (pageList, trialTaskConfig); } /// /// PM阅片跟踪 /// /// /// [HttpPost] public async Task<(PageOutput, object?)> GetReadingTaskList(VisitTaskQuery queryVisitTask) { var visitTaskQueryable = _visitTaskRepository.Where(t => t.TrialId == queryVisitTask.TrialId && t.IsAnalysisCreate == false) //.Where(t => t.IsAnalysisCreate == false && t.DoctorUserId != null) .WhereIf(queryVisitTask.TaskState != null, t => t.TaskState == queryVisitTask.TaskState) .WhereIf(queryVisitTask.SiteId != null, t => t.Subject.SiteId == queryVisitTask.SiteId) .WhereIf(queryVisitTask.SubjectId != null, t => t.SubjectId == queryVisitTask.SubjectId) .WhereIf(queryVisitTask.IsUrgent != null, t => t.IsUrgent == queryVisitTask.IsUrgent) .WhereIf(queryVisitTask.DoctorUserId != null, t => t.DoctorUserId == queryVisitTask.DoctorUserId) .WhereIf(queryVisitTask.ReadingCategory != null, t => t.ReadingCategory == queryVisitTask.ReadingCategory) .WhereIf(queryVisitTask.ReadingTaskState != null, t => t.ReadingTaskState == queryVisitTask.ReadingTaskState) .WhereIf(queryVisitTask.TaskAllocationState != null, t => t.TaskAllocationState == queryVisitTask.TaskAllocationState) .WhereIf(queryVisitTask.TrialReadingCriterionId != null, t => t.TrialReadingCriterionId == queryVisitTask.TrialReadingCriterionId) .WhereIf(queryVisitTask.ReReadingApplyState != null, t => t.ReReadingApplyState == queryVisitTask.ReReadingApplyState) .WhereIf(queryVisitTask.CompleteClinicalDataEnum == CompleteClinicalDataEnum.Complete, t => t.IsClinicalDataSign && t.IsNeedClinicalDataSign == true) .WhereIf(queryVisitTask.CompleteClinicalDataEnum == CompleteClinicalDataEnum.NotComplete, t => t.IsClinicalDataSign == false && t.IsNeedClinicalDataSign == true) .WhereIf(queryVisitTask.CompleteClinicalDataEnum == CompleteClinicalDataEnum.NA, t => t.IsNeedClinicalDataSign == false) .WhereIf(!string.IsNullOrEmpty(queryVisitTask.TrialSiteCode), t => (t.BlindTrialSiteCode.Contains(queryVisitTask.TrialSiteCode!) && t.IsAnalysisCreate) || (t.Subject.TrialSite.TrialSiteCode.Contains(queryVisitTask.TrialSiteCode!) && t.IsAnalysisCreate == false)) .WhereIf(!string.IsNullOrEmpty(queryVisitTask.TaskName), t => t.TaskName.Contains(queryVisitTask.TaskName) || t.TaskBlindName.Contains(queryVisitTask.TaskName)) .WhereIf(!string.IsNullOrEmpty(queryVisitTask.SubjectCode), t => (t.Subject.Code.Contains(queryVisitTask.SubjectCode) && t.IsAnalysisCreate == false) || (t.BlindSubjectCode.Contains(queryVisitTask.SubjectCode) && t.IsAnalysisCreate)) .WhereIf(queryVisitTask.BeginAllocateDate != null, t => t.AllocateTime >= queryVisitTask.BeginAllocateDate) .WhereIf(queryVisitTask.EndAllocateDate != null, t => t.AllocateTime <= queryVisitTask.EndAllocateDate) .WhereIf(queryVisitTask.TaskCode != null, t => t.TaskCode.Contains(queryVisitTask.TaskCode) ) .WhereIf(queryVisitTask.BeginSignTime != null, t => t.SignTime >= queryVisitTask.BeginSignTime) .WhereIf(queryVisitTask.EndSignTime != null, t => t.SignTime <= queryVisitTask.EndSignTime) .ProjectTo(_mapper.ConfigurationProvider); var defalutSortArray = new string[] { nameof(VisitTask.IsUrgent) + " desc", nameof(VisitTask.SubjectId), nameof(VisitTask.VisitTaskNum) }; var pageList = await visitTaskQueryable.ToPagedListAsync(queryVisitTask.PageIndex, queryVisitTask.PageSize, queryVisitTask.SortField, queryVisitTask.Asc, string.IsNullOrWhiteSpace(queryVisitTask.SortField), defalutSortArray); var trialTaskConfig = _trialRepository.Where(t => t.Id == queryVisitTask.TrialId).ProjectTo(_mapper.ConfigurationProvider).FirstOrDefault(); return (pageList,trialTaskConfig); } /// /// PM 重阅追踪 /// /// /// [HttpPost] public async Task> GetReReadingTaskList(VisitTaskQuery queryVisitTask) { var visitTaskQueryable = _visitTaskReReadingRepository .Where(t => t.OriginalReReadingTask.TrialId == queryVisitTask.TrialId /*&& t.OriginalReReadingTask.IsAnalysisCreate == false*/) .WhereIf(queryVisitTask.RootReReadingTaskId != null, t => t.RootReReadingTaskId == queryVisitTask.RootReReadingTaskId || t.OriginalReReadingTaskId == queryVisitTask.RootReReadingTaskId) .WhereIf(!string.IsNullOrEmpty(queryVisitTask.TaskCode), t => t.OriginalReReadingTask.TaskCode.Contains(queryVisitTask.TaskCode!) || t.RootReReadingTask.TaskCode.Contains(queryVisitTask.TaskCode!)) .WhereIf(queryVisitTask.SiteId != null, t => t.OriginalReReadingTask.Subject.SiteId == queryVisitTask.SiteId) .WhereIf(queryVisitTask.TaskState != null, t => t.OriginalReReadingTask.TaskState == queryVisitTask.TaskState) .WhereIf(queryVisitTask.ReReadingApplyState != null, t => t.OriginalReReadingTask.ReReadingApplyState == queryVisitTask.ReReadingApplyState) .WhereIf(queryVisitTask.RequestReReadingType != null, t => t.RequestReReadingType == queryVisitTask.RequestReReadingType) .WhereIf(queryVisitTask.SubjectId != null, t => t.OriginalReReadingTask.SubjectId == queryVisitTask.SubjectId) .WhereIf(queryVisitTask.IsUrgent != null, t => t.OriginalReReadingTask.IsUrgent == queryVisitTask.IsUrgent) .WhereIf(queryVisitTask.DoctorUserId != null, t => t.OriginalReReadingTask.DoctorUserId == queryVisitTask.DoctorUserId) .WhereIf(queryVisitTask.ReadingTaskState != null, t => t.OriginalReReadingTask.ReadingTaskState == queryVisitTask.ReadingTaskState) .WhereIf(queryVisitTask.TaskAllocationState != null, t => t.OriginalReReadingTask.TaskAllocationState == queryVisitTask.TaskAllocationState) .WhereIf(queryVisitTask.TrialReadingCriterionId != null, t => t.OriginalReReadingTask.TrialReadingCriterionId == queryVisitTask.TrialReadingCriterionId) .WhereIf(queryVisitTask.ReadingCategory != null, t => t.OriginalReReadingTask.ReadingCategory == queryVisitTask.ReadingCategory) .WhereIf(queryVisitTask.RequestReReadingResultEnum != null, t => t.RequestReReadingResultEnum == queryVisitTask.RequestReReadingResultEnum) .WhereIf(!string.IsNullOrEmpty(queryVisitTask.TrialSiteCode), t => (t.OriginalReReadingTask.BlindTrialSiteCode.Contains(queryVisitTask.TrialSiteCode!) && t.OriginalReReadingTask.IsAnalysisCreate) || (t.OriginalReReadingTask.Subject.TrialSite.TrialSiteCode.Contains(queryVisitTask.TrialSiteCode!) && t.OriginalReReadingTask.IsAnalysisCreate == false)) .WhereIf(!string.IsNullOrEmpty(queryVisitTask.TaskName), t => t.OriginalReReadingTask.TaskName.Contains(queryVisitTask.TaskName) || t.OriginalReReadingTask.TaskBlindName.Contains(queryVisitTask.TaskName)) .WhereIf(!string.IsNullOrEmpty(queryVisitTask.SubjectCode), t => (t.OriginalReReadingTask.Subject.Code.Contains(queryVisitTask.SubjectCode) && t.OriginalReReadingTask.IsAnalysisCreate == false) || (t.OriginalReReadingTask.BlindSubjectCode.Contains(queryVisitTask.SubjectCode) && t.OriginalReReadingTask.IsAnalysisCreate)) .WhereIf(queryVisitTask.BeginAllocateDate != null, t => t.OriginalReReadingTask.AllocateTime > queryVisitTask.BeginAllocateDate) .WhereIf(queryVisitTask.EndAllocateDate != null, t => t.OriginalReReadingTask.AllocateTime < queryVisitTask.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.SubjectId), nameof(ReReadingTaskView.OriginalReReadingTask) + "." + nameof(ReReadingTaskView.OriginalReReadingTask.VisitTaskNum) }; var defalutSortArray = new string[] { nameof(ReReadingTaskView.OriginalReReadingTask) + "." + nameof(ReReadingTaskView.OriginalReReadingTask.TaskState), nameof(ReReadingTaskView.RequestReReadingResultEnum) , 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(queryVisitTask.PageIndex, queryVisitTask.PageSize, queryVisitTask.SortField, queryVisitTask.Asc, string.IsNullOrWhiteSpace(queryVisitTask.SortField), defalutSortArray); return pageList; } /// /// 获取IR 重阅影像阅片列表 /// /// /// [HttpPost] public async Task> GetIRReReadingTaskList(VisitTaskQuery queryVisitTask) { var visitTaskQueryable = _visitTaskReReadingRepository .Where(t => t.RequestReReadingType == RequestReReadingType.DocotorApply) .Where(t => t.OriginalReReadingTask.DoctorUserId == _userInfo.Id) .Where(t => t.OriginalReReadingTask.TrialId == queryVisitTask.TrialId) .WhereIf(queryVisitTask.RootReReadingTaskId != null, t => t.RootReReadingTaskId == queryVisitTask.RootReReadingTaskId || t.OriginalReReadingTaskId == queryVisitTask.RootReReadingTaskId) .WhereIf(!string.IsNullOrEmpty(queryVisitTask.TaskCode), t => t.OriginalReReadingTask.TaskCode.Contains(queryVisitTask.TaskCode!) || t.RootReReadingTask.TaskCode.Contains(queryVisitTask.TaskCode!)) .WhereIf(queryVisitTask.TaskState != null, t => t.OriginalReReadingTask.TaskState == queryVisitTask.TaskState) .WhereIf(queryVisitTask.ReReadingApplyState != null, t => t.OriginalReReadingTask.ReReadingApplyState == queryVisitTask.ReReadingApplyState) .WhereIf(queryVisitTask.SiteId != null, t => t.OriginalReReadingTask.Subject.SiteId == queryVisitTask.SiteId) .WhereIf(queryVisitTask.SubjectId != null, t => t.OriginalReReadingTask.SubjectId == queryVisitTask.SubjectId) .WhereIf(queryVisitTask.IsUrgent != null, t => t.OriginalReReadingTask.IsUrgent == queryVisitTask.IsUrgent) .WhereIf(queryVisitTask.DoctorUserId != null, t => t.OriginalReReadingTask.DoctorUserId == queryVisitTask.DoctorUserId) .WhereIf(queryVisitTask.ReadingTaskState != null, t => t.OriginalReReadingTask.ReadingTaskState == queryVisitTask.ReadingTaskState) .WhereIf(queryVisitTask.TaskAllocationState != null, t => t.OriginalReReadingTask.TaskAllocationState == queryVisitTask.TaskAllocationState) .WhereIf(queryVisitTask.TrialReadingCriterionId != null, t => t.OriginalReReadingTask.TrialReadingCriterionId == queryVisitTask.TrialReadingCriterionId) .WhereIf(!string.IsNullOrEmpty(queryVisitTask.TrialSiteCode), t => (t.OriginalReReadingTask.BlindTrialSiteCode.Contains(queryVisitTask.TrialSiteCode!) && t.OriginalReReadingTask.IsAnalysisCreate) || (t.OriginalReReadingTask.Subject.TrialSite.TrialSiteCode.Contains(queryVisitTask.TrialSiteCode!) && t.OriginalReReadingTask.IsAnalysisCreate == false)) .WhereIf(!string.IsNullOrEmpty(queryVisitTask.TaskName), t => t.OriginalReReadingTask.TaskName.Contains(queryVisitTask.TaskName) || t.NewReReadingTask.TaskBlindName.Contains(queryVisitTask.TaskName)) .WhereIf(!string.IsNullOrEmpty(queryVisitTask.SubjectCode), t => (t.OriginalReReadingTask.Subject.Code.Contains(queryVisitTask.SubjectCode) && t.OriginalReReadingTask.IsAnalysisCreate == false) || (t.OriginalReReadingTask.BlindSubjectCode.Contains(queryVisitTask.SubjectCode) && t.OriginalReReadingTask.IsAnalysisCreate)) .WhereIf(queryVisitTask.BeginAllocateDate != null, t => t.OriginalReReadingTask.AllocateTime > queryVisitTask.BeginAllocateDate) .WhereIf(queryVisitTask.EndAllocateDate != null, t => t.OriginalReReadingTask.AllocateTime < queryVisitTask.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.SubjectId), nameof(ReReadingTaskView.OriginalReReadingTask) + "." + nameof(ReReadingTaskView.OriginalReReadingTask.VisitTaskNum) }; var pageList = await visitTaskQueryable.ToPagedListAsync(queryVisitTask.PageIndex, queryVisitTask.PageSize, queryVisitTask.SortField, queryVisitTask.Asc, string.IsNullOrWhiteSpace(queryVisitTask.SortField), defalutSortArray); return pageList; } //SPM 能看到项目组申请记录 [HttpPost] public async Task> GetSPMReReadingTaskList(VisitTaskQuery queryVisitTask) { var visitTaskQueryable = _visitTaskReReadingRepository.Where(t => t.RequestReReadingType == RequestReReadingType.TrialGroupApply && t.OriginalReReadingTask.IsAnalysisCreate == false) .Where(t => t.OriginalReReadingTask.TrialId == queryVisitTask.TrialId) .WhereIf(queryVisitTask.RootReReadingTaskId != null, t => t.RootReReadingTaskId == queryVisitTask.RootReReadingTaskId || t.OriginalReReadingTaskId == queryVisitTask.RootReReadingTaskId) .WhereIf(!string.IsNullOrEmpty(queryVisitTask.TaskCode), t => t.OriginalReReadingTask.TaskCode.Contains(queryVisitTask.TaskCode!) || t.RootReReadingTask.TaskCode.Contains(queryVisitTask.TaskCode!)) .WhereIf(queryVisitTask.TaskState != null, t => t.OriginalReReadingTask.TaskState == queryVisitTask.TaskState) .WhereIf(queryVisitTask.SiteId != null, t => t.OriginalReReadingTask.Subject.SiteId == queryVisitTask.SiteId) .WhereIf(queryVisitTask.SubjectId != null, t => t.OriginalReReadingTask.SubjectId == queryVisitTask.SubjectId) .WhereIf(queryVisitTask.IsUrgent != null, t => t.OriginalReReadingTask.IsUrgent == queryVisitTask.IsUrgent) .WhereIf(queryVisitTask.DoctorUserId != null, t => t.OriginalReReadingTask.DoctorUserId == queryVisitTask.DoctorUserId) .WhereIf(queryVisitTask.ReadingTaskState != null, t => t.OriginalReReadingTask.ReadingTaskState == queryVisitTask.ReadingTaskState) .WhereIf(queryVisitTask.TaskAllocationState != null, t => t.OriginalReReadingTask.TaskAllocationState == queryVisitTask.TaskAllocationState) .WhereIf(queryVisitTask.TrialReadingCriterionId != null, t => t.OriginalReReadingTask.TrialReadingCriterionId == queryVisitTask.TrialReadingCriterionId) .WhereIf(!string.IsNullOrEmpty(queryVisitTask.TrialSiteCode), t => (t.OriginalReReadingTask.BlindTrialSiteCode.Contains(queryVisitTask.TrialSiteCode!) && t.OriginalReReadingTask.IsAnalysisCreate) || (t.OriginalReReadingTask.Subject.TrialSite.TrialSiteCode.Contains(queryVisitTask.TrialSiteCode!) && t.OriginalReReadingTask.IsAnalysisCreate == false)) .WhereIf(!string.IsNullOrEmpty(queryVisitTask.TaskName), t => t.OriginalReReadingTask.TaskName.Contains(queryVisitTask.TaskName) || t.NewReReadingTask.TaskBlindName.Contains(queryVisitTask.TaskName)) .WhereIf(!string.IsNullOrEmpty(queryVisitTask.SubjectCode), t => (t.OriginalReReadingTask.Subject.Code.Contains(queryVisitTask.SubjectCode) && t.OriginalReReadingTask.IsAnalysisCreate == false) || (t.OriginalReReadingTask.BlindSubjectCode.Contains(queryVisitTask.SubjectCode) && t.OriginalReReadingTask.IsAnalysisCreate)) .WhereIf(queryVisitTask.BeginAllocateDate != null, t => t.OriginalReReadingTask.AllocateTime > queryVisitTask.BeginAllocateDate) .WhereIf(queryVisitTask.EndAllocateDate != null, t => t.OriginalReReadingTask.AllocateTime < queryVisitTask.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(queryVisitTask.PageIndex, queryVisitTask.PageSize, queryVisitTask.SortField, queryVisitTask.Asc, string.IsNullOrWhiteSpace(queryVisitTask.SortField), defalutSortArray); return pageList; } /// /// IR 待阅片任务列表 /// /// [HttpPost] public async Task<(PageOutput, object)> GetIRUnReadSubjectTaskList(IRUnReadSubjectQuery iRUnReadSubjectQuery) { var trialId = iRUnReadSubjectQuery.TrialId; var trialReadingCriterionId = iRUnReadSubjectQuery.TrialReadingCriterionId; var criterionConfig = await _trialReadingCriterionRepository.Where(x => x.Id == iRUnReadSubjectQuery.TrialReadingCriterionId).FirstNotNullAsync(); var readingTool = criterionConfig.ReadingTool; var isReadingTaskViewInOrder = criterionConfig.IsReadingTaskViewInOrder; var visitTaskListInfo = await GetOrderReadingIQueryable(new GetOrderReadingIQueryableInDto() { TrialId = trialId, TrialReadingCriterionId = trialReadingCriterionId, SubjectCode = iRUnReadSubjectQuery.SubjectCode, Page = new PageInput() { PageIndex = iRUnReadSubjectQuery.PageIndex, PageSize = iRUnReadSubjectQuery.PageSize, Asc = iRUnReadSubjectQuery.Asc, SortField = iRUnReadSubjectQuery.SortField, } }); var totalCount = visitTaskListInfo.Item1; var currentPageData = visitTaskListInfo.Item2; var result = new PageOutput() { PageSize = iRUnReadSubjectQuery.PageSize, PageIndex = iRUnReadSubjectQuery.PageIndex, TotalCount = totalCount, CurrentPageData = currentPageData, }; #region 按照Subject 维度 if (isReadingTaskViewInOrder) { // 封装的方法有问题 //var result = await visitQuery.ToPagedListAsync(iRUnReadSubjectQuery.PageIndex, iRUnReadSubjectQuery.PageSize, String.IsNullOrEmpty(iRUnReadSubjectQuery.SortField) ? nameof(IRUnReadSubjectView.SubjectId) : iRUnReadSubjectQuery.SortField, iRUnReadSubjectQuery.Asc); return (result, new { RandomReadInfo = new IRUnReadOutDto(), IsReadingTaskViewInOrder = isReadingTaskViewInOrder, ReadingTool = readingTool, IseCRFShowInDicomReading = criterionConfig.IseCRFShowInDicomReading, IsReadingShowSubjectInfo = criterionConfig.IsReadingShowSubjectInfo, IsReadingShowPreviousResults = criterionConfig.IsReadingShowPreviousResults, DigitPlaces = criterionConfig.DigitPlaces, CriterionType = criterionConfig.CriterionType, }); } else { var taskQuery = _visitTaskRepository.Where(x => x.TrialId == iRUnReadSubjectQuery.TrialId && x.DoctorUserId == _userInfo.Id && x.TaskState == TaskState.Effect && x.TrialReadingCriterionId == trialReadingCriterionId) // .Where(x=>x.Subject.ClinicalDataList.Any(c => c.IsSign && (c.ReadingId == x.SouceReadModuleId || c.ReadingId == x.SourceSubjectVisitId))) .Where(x => !x.Subject.IsDeleted); IRUnReadOutDto 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 (result, new { IsReadingTaskViewInOrder = isReadingTaskViewInOrder, RandomReadInfo = iRUnReadOut, ReadingTool = readingTool, IseCRFShowInDicomReading = criterionConfig.IseCRFShowInDicomReading, IsReadingShowSubjectInfo = criterionConfig.IsReadingShowSubjectInfo, IsReadingShowPreviousResults = criterionConfig.IsReadingShowPreviousResults, DigitPlaces = criterionConfig.DigitPlaces, CriterionType = criterionConfig.CriterionType, }); } #endregion } /// /// 获取有序阅片IQuery对象 /// /// /// public async Task<(int, List)> GetOrderReadingIQueryable(GetOrderReadingIQueryableInDto inDto) { var trialReadingCriterionId = inDto.TrialReadingCriterionId; //Expression> visitTaskLambda = x => x.DoctorUserId == _userInfo.Id && x.TaskState == TaskState.Effect && x.TrialReadingCriterionId == inDto.TrialReadingCriterionId; var visitQuery = _visitTaskRepository.Where(x => x.TrialId == inDto.TrialId && x.DoctorUserId == _userInfo.Id && x.TaskState == TaskState.Effect /*&& x.TrialReadingCriterionId== inDto.TrialReadingCriterionId*/) //.Where(t => t.VisitTaskNum < t.Subject.SubjectVisitList.Where(t => t.CheckState != CheckStateEnum.CVPassed).Min(t => t.VisitNum) ) .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(inDto.SubjectCode), t => (t.Subject.Code.Contains(inDto.SubjectCode) && t.IsAnalysisCreate == false) || (t.BlindSubjectCode.Contains(inDto.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).Count(), ExistReadingApply = x.Any(y => y.ReReadingApplyState == ReReadingApplyState.DocotorHaveApplyed || 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(inDto.Page.SortField) ? "UnReadCanReadTaskCount" : inDto.Page.SortField; var visitTaskOrderQuery = inDto.Page.Asc ? visitTaskQuery.OrderBy(propName) : visitTaskQuery.OrderBy(propName + " desc"); if (inDto.Page != null) { result = await visitTaskOrderQuery .Skip((inDto.Page.PageIndex - 1) * inDto.Page.PageSize) .Take(inDto.Page.PageSize).ToListAsync(); } else { result = await visitTaskOrderQuery.ToListAsync(); } return (count, result); } /// /// IR 已阅片任务 /// /// /// [HttpPost] public async Task> GetIRHaveReadTaskList(VisitTaskQuery queryVisitTask) { var visitTaskQueryable = _visitTaskRepository.Where(t => t.TrialId == queryVisitTask.TrialId) .Where(t => t.DoctorUserId == _userInfo.Id && t.ReadingTaskState == ReadingTaskState.HaveSigned)//该医生 已经签名的数据 .WhereIf(queryVisitTask.SiteId != null, t => t.Subject.SiteId == queryVisitTask.SiteId) .WhereIf(queryVisitTask.SubjectId != null, t => t.SubjectId == queryVisitTask.SubjectId) .WhereIf(queryVisitTask.IsUrgent != null, t => t.IsUrgent == queryVisitTask.IsUrgent) .WhereIf(queryVisitTask.ReadingCategory != null, t => t.ReadingCategory == queryVisitTask.ReadingCategory) .WhereIf(queryVisitTask.TaskAllocationState != null, t => t.TaskAllocationState == queryVisitTask.TaskAllocationState) .WhereIf(queryVisitTask.TrialReadingCriterionId != null, t => t.TrialReadingCriterionId == queryVisitTask.TrialReadingCriterionId) .WhereIf(queryVisitTask.TaskState != null, t => t.TaskState == queryVisitTask.TaskState) .WhereIf(!string.IsNullOrEmpty(queryVisitTask.TrialSiteCode), t => (t.BlindTrialSiteCode.Contains(queryVisitTask.TrialSiteCode!) && t.IsAnalysisCreate) || (t.Subject.TrialSite.TrialSiteCode.Contains(queryVisitTask.TrialSiteCode!) && t.IsAnalysisCreate == false)) .WhereIf(!string.IsNullOrEmpty(queryVisitTask.TaskName), t => t.TaskName.Contains(queryVisitTask.TaskName) || t.TaskBlindName.Contains(queryVisitTask.TaskName)) .WhereIf(!string.IsNullOrEmpty(queryVisitTask.SubjectCode), t => (t.Subject.Code.Contains(queryVisitTask.SubjectCode) && t.IsAnalysisCreate == false) || (t.BlindSubjectCode.Contains(queryVisitTask.SubjectCode) && t.IsAnalysisCreate)) .WhereIf(queryVisitTask.BeginAllocateDate != null, t => t.AllocateTime > queryVisitTask.BeginAllocateDate) .WhereIf(queryVisitTask.EndAllocateDate != null, t => t.AllocateTime < queryVisitTask.EndAllocateDate!.Value.AddDays(1)) .ProjectTo(_mapper.ConfigurationProvider); var defalutSortArray = new string[] { nameof(VisitTask.IsUrgent) + " desc", nameof(VisitTask.SubjectId), nameof(VisitTask.VisitTaskNum) }; var pageList = await visitTaskQueryable.ToPagedListAsync(queryVisitTask.PageIndex, queryVisitTask.PageSize, queryVisitTask.SortField, queryVisitTask.Asc, string.IsNullOrWhiteSpace(queryVisitTask.SortField), 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 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("后台数据有错误"); } 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(); } /// /// 申请重阅 1:IR 2:PM /// /// /// [HttpPost] [UnitOfWork] [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })] public async Task ApplyReReading(ApplyReReadingCommand applyReReadingCommand) { 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.IsReadingTaskViewInOrder }).FirstOrDefaultAsync()).IfNullThrowException(); foreach (var task in taskList) { if (task.ReadingTaskState != ReadingTaskState.HaveSigned || task.TaskState != TaskState.Effect) { throw new BusinessValidationFailedException("未阅片完成,或者未生效的任务不允许申请重阅"); } if (task.ReReadingApplyState == ReReadingApplyState.DocotorHaveApplyed || task.ReReadingApplyState == ReReadingApplyState.TrialGroupHaveApplyed || task.ReReadingApplyState == ReReadingApplyState.Agree) { throw new BusinessValidationFailedException("重阅已申请,或者重阅已同意状态下不允许申请重阅"); } if (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ProjectManager) { if (task.IsAnalysisCreate) { throw new BusinessValidationFailedException("PM 不允许对一致性分析任务进行申请重阅"); } if (task.ReadingCategory != ReadingCategory.Visit) { throw new BusinessValidationFailedException("PM 仅仅允许对检查批次类型的任务申请重阅"); } // 有序 一个患者检查批次重阅未处理完,不能申请其他的 if (criterionConfig.IsReadingTaskViewInOrder) { 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("当前为有序阅片,该患者已有检查批次已申请重阅还未处理(项目组申请),暂不能继续申请重阅"); } } task.ReReadingApplyState = ReReadingApplyState.TrialGroupHaveApplyed; } if (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.IndependentReviewer) { task.ReReadingApplyState = ReReadingApplyState.DocotorHaveApplyed; // 有序 if (criterionConfig.IsReadingTaskViewInOrder) { 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.DocotorApply && t.RequestReReadingResultEnum == RequestReReadingResult.Default)) { return ResponseOutput.NotOk("当前为有序阅片,该患者已有检查批次已申请重阅还未处理,暂不能继续申请重阅"); } //在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 (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)) { return ResponseOutput.NotOk("当前为有序阅片,影像存在问题,项目组已申请回退,暂不能申请重阅"); } } 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("有序阅片,只允许申请该患者阅片人最后一次完成全局任务重阅"); } if (task.ReadingCategory == ReadingCategory.Oncology && await _visitTaskRepository.AnyAsync(filterExpression.And(t => t.ReadingCategory == ReadingCategory.Oncology))) { throw new BusinessValidationFailedException("有序阅片,只允许申请该患者阅片人最后一次完成肿瘤学任务重阅"); } if (task.ReadingCategory == ReadingCategory.Judge && await _visitTaskRepository.AnyAsync(filterExpression.And(t => t.ReadingCategory == ReadingCategory.Judge))) { throw new BusinessValidationFailedException("有序阅片,只允许申请该患者阅片人最后一次完成裁判的任务重阅"); } } else { if (task.ReadingCategory != ReadingCategory.Visit && task.ReadingCategory != ReadingCategory.Global) { throw new BusinessValidationFailedException("无序阅片,仅仅允许IR 申请 全局和检查批次类型类别的任务进行重阅"); } } } //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() { 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("当前重阅任务状态不为已申请状态,不允许进行处理,请刷新页面"); } } 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 SetReReadingOrBackInfluenceAnalysisAsync(Guid subjectId) { if (await _repository.AnyAsync(t => t.IsAnalysisCreate && t.SubjectId == subjectId)) { await _repository.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) { return ResponseOutput.NotOk("当前申请重阅任务的状态,已被其他任务重阅已影响,不允许对该状态下的任务进行重阅同意与否操作"); } var criterionConfig = await _trialReadingCriterionRepository.Where(x => x.Id == origenalTask.TrialReadingCriterionId).Select(x => new { x.ReadingTool, 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.TaskAllocationState == TaskAllocationState.Allocated; //是否是一致性分析任务 正常申请 会影响一致性分析任务 filterExpression = filterExpression.And(t => t.IsAnalysisCreate == origenalTask.IsAnalysisCreate); if (agreeReReadingCommand.RequestReReadingResultEnum == RequestReReadingResult.Agree) { //PM申请 SPM / CPM审批 回退检查批次,在此不生成检查批次任务 影响多个标准的任务 if (visitTaskReReadingAppply.RequestReReadingType == RequestReReadingType.TrialGroupApply && (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.SPM || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.CPM)) { #region PM 申请两个IR 同一检查批次,其他人的申请记录也设置为同意 不会出现,因为在未处理前 一个Subject只能申请一次 // await _visitTaskReReadingRepository.BatchUpdateNoTrackingAsync(t => t.OriginalReReadingTask.SubjectId == origenalTask.SubjectId && // t.OriginalReReadingTask.ReReadingApplyState == ReReadingApplyState.TrialGroupHaveApplyed && // t.RequestReReadingType == RequestReReadingType.TrialGroupApply && //t.OriginalReReadingTask.VisitTaskNum == origenalTask.VisitTaskNum && //t.Id != item.Id, u => new VisitTaskReReading() //{ // RequestReReadingConfirmUserId = _userInfo.Id, // RequestReReadingResultEnum = RequestReReadingResult.Agree, //}); // //只更新 PM 申请 同一检查批次的数据 // await _visitTaskRepository.BatchUpdateNoTrackingAsync(t => t.SubjectId == origenalTask.SubjectId && // t.ReReadingApplyState == ReReadingApplyState.TrialGroupHaveApplyed && // t.TrialReadingCriterionId == origenalTask.TrialReadingCriterionId && // t.IsAnalysisCreate == origenalTask.IsAnalysisCreate && // t.VisitTaskNum == origenalTask.VisitTaskNum && // t.Id != origenalTask.Id, u => new VisitTask() // { // ReReadingApplyState = ReReadingApplyState.Agree // }); #endregion // 不管有序 无序 都会 回退检查批次 if (origenalTask.ReadingCategory == ReadingCategory.Visit) { //执行类似一致性核查回退流程 await VisitBackAsync(origenalTask.SourceSubjectVisitId); } else { throw new BusinessValidationFailedException("仅允许同意检查批次类型的任务重阅"); } //有序阅片 if (criterionConfig.IsReadingTaskViewInOrder) { //检查批次影响当前以及当前之后的 两个阅片人的 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); //influenceTaskList.ForEach(t => //{ // //记录实际影像的任务 // influenceTask.TaskInfluenceList.Add(new TaskInfluence() { InfluenceTaskId = t.Id }); //}); await SetReReadingOrBackInfluenceAnalysisAsync(origenalTask.SubjectId); await SetMedicalReviewInvalidAsync(influenceTaskList); } //申请的检查批次 要不是重阅重置,要不就是失效 不会存在取消分配 if (influenceTask.ReadingCategory == ReadingCategory.Visit && influenceTask.VisitTaskNum != origenalTask.VisitTaskNum) { if (influenceTask.ReadingTaskState == ReadingTaskState.HaveSigned) { influenceTask.TaskState = TaskState.HaveReturned; trakingOrigenalTask?.TaskInfluenceList.Add(new TaskInfluence() { InfluenceTaskId = influenceTask.Id, OptType = ReReadingOrBackOptType.Return }); } else if (influenceTask.ReadingTaskState == ReadingTaskState.Reading) { influenceTask.TaskState = TaskState.Adbandon; trakingOrigenalTask?.TaskInfluenceList.Add(new TaskInfluence() { InfluenceTaskId = influenceTask.Id, OptType = ReReadingOrBackOptType.Abandon }); } else { influenceTask.DoctorUserId = null; influenceTask.AllocateTime = null; influenceTask.SuggesteFinishedTime = null; influenceTask.TaskAllocationState = TaskAllocationState.NotAllocate; trakingOrigenalTask?.TaskInfluenceList.Add(new TaskInfluence() { InfluenceTaskId = influenceTask.Id, OptType = ReReadingOrBackOptType.CancelAssign }); } } //当前检查批次 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 }); } } } #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); //influenceTaskList.ForEach(t => //{ // //记录实际影像的任务 // influenceTask.TaskInfluenceList.Add(new TaskInfluence() { InfluenceTaskId = t.Id }); //}); await SetReReadingOrBackInfluenceAnalysisAsync(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 && (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ProjectManager || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.AIR)) { #region 两个IR 申请同一检查批次,其他人的申请记录也设置为同意 await _visitTaskReReadingRepository.BatchUpdateNoTrackingAsync(t => t.OriginalReReadingTask.SubjectId == origenalTask.SubjectId && t.OriginalReReadingTask.ReReadingApplyState == ReReadingApplyState.DocotorHaveApplyed && t.RequestReReadingType == RequestReReadingType.DocotorApply && t.OriginalReReadingTask.VisitTaskNum == origenalTask.VisitTaskNum && t.Id != item.Id, u => new VisitTaskReReading() { RequestReReadingConfirmUserId = _userInfo.Id, RequestReReadingResultEnum = RequestReReadingResult.Agree, }); //await _visitTaskRepository.UpdatePartialFromQueryAsync(t => t.Id == origenalTask.Id, u => new VisitTask() //{ // ReReadingApplyState = ReReadingApplyState.Agree //}); #endregion //影响申请标准的任务 filterExpression = filterExpression.And(t => t.TrialReadingCriterionId == origenalTask.TrialReadingCriterionId); //有序阅片 if (criterionConfig.IsReadingTaskViewInOrder) { #region 有序 IR 申请 重阅 影响的其他检查批次查询 switch (origenalTask.ReadingCategory) { case ReadingCategory.Visit: //影响后续检查批次已经读完的,正在读的,未读的不做处理 以及其他类型任务 filterExpression = filterExpression.And(t => t.VisitTaskNum >= origenalTask.VisitTaskNum && ((t.DoctorUserId == origenalTask.DoctorUserId && ((t.ReadingCategory == ReadingCategory.Visit && t.ReadingTaskState != ReadingTaskState.WaitReading) || t.ReadingCategory == ReadingCategory.Global)) || 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("不支持重阅的任务类型"); } #endregion #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 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 }); } if (/*influenceTask.ReadingTaskState == ReadingTaskState.HaveSigned &&*/ influenceTask.ReadingCategory == ReadingCategory.Visit) { 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.IsCopyFollowForms && origenalTask.VisitTaskNum != influenceTask.VisitTaskNum) { if (origenalTask.ReadingCategory == ReadingCategory.Visit) { var list = _readingTaskQuestionAnswerRepository.Where(t => t.VisitTaskId == origenalTask.Id).ToList(); foreach (var item in list) { item.Id = Guid.Empty; item.VisitTaskId = newTask.Id; } _ = _readingTaskQuestionAnswerRepository.AddRangeAsync(list).Result; } //else if (origenalTask.ReadingCategory == ReadingCategory.Global) //{ // var list = _repository.Where(t => t.GlobalTaskId == origenalTask.Id).ToList(); // foreach (var item in list) // { // item.Id = Guid.Empty; // item.GlobalTaskId = newTask.Id; // } // _ = _repository.AddRangeAsync(list).Result; //} } } }); } } } #endregion } //无序阅片 只会申请检查批次类型和裁判类型的任务 注意这里有一致性分析的申请同意 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 申请任务 重新生成 拷贝表单 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) { if (origenalTask.ReadingCategory == ReadingCategory.Visit) { var list = _readingTaskQuestionAnswerRepository.Where(t => t.VisitTaskId == origenalTask.Id).ToList(); foreach (var item in list) { item.Id = Guid.Empty; item.VisitTaskId = newTask.Id; } _ = _readingTaskQuestionAnswerRepository.AddRangeAsync(list).Result; } //else if (origenalTask.ReadingCategory == ReadingCategory.Global) //{ // var list = _repository.Where(t => t.GlobalTaskId == origenalTask.Id).ToList(); // foreach (var item in list) // { // item.Id = Guid.Empty; // item.GlobalTaskId = newTask.Id; // } // _ = _repository.AddRangeAsync(list).Result; //} } } }); #endregion } else { throw new BusinessValidationFailedException("不符合 PM申请 SPM / CPM审批 | IR申请 PM 审批 "); } } 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("当前重阅任务状态不为已申请状态,不允许进行处理,请刷新页面"); } } } await _visitTaskRepository.SaveChangesAsync(); return ResponseOutput.Ok(); } /// /// 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.IsReadingTaskViewInOrder }).FirstOrDefaultAsync()).IfNullThrowException(); if (task.TaskState != TaskState.Effect || task.ReadingCategory != ReadingCategory.Visit || task.ReadingTaskState == ReadingTaskState.HaveSigned) { return ResponseOutput.NotOk("仅仅允许针对生效、未完成的检查批次任务进行退回操作,请刷新页面数据"); } if( await _subjectVisitRepository.AnyAsync(t=>t.Id==task.SourceSubjectVisitId && t.CheckState!= CheckStateEnum.CVPassed)) { return ResponseOutput.NotOk("当前检查批次已回退到影像上传,不允许继续回退!"); } if (task.IsAnalysisCreate) { return ResponseOutput.NotOk("一致性分析的任务,不允许设置退回"); } //PM 才允许操作 if (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ProjectManager) { #region 有序 无序公用流程 //执行类似一致性核查回退流程 回退检查批次到影像上传流程 await VisitBackAsync(task.SourceSubjectVisitId); #endregion //有序 if (criterionConfig.IsReadingTaskViewInOrder) { Expression> filterExpression = t => t.TrialId == trialId && t.SubjectId == task.SubjectId && t.TaskState == TaskState.Effect && t.IsAnalysisCreate == false && t.TaskAllocationState == TaskAllocationState.Allocated; //另一个阅片人的任务根据任务进度自动进入PM退回或PM申请重阅 filterExpression = filterExpression.And(t => t.VisitTaskNum >= task.VisitTaskNum); var influenceTaskList = await _visitTaskRepository.Where(filterExpression, true).ToListAsync(); #region 方式一 //foreach (var influenceTask in influenceTaskList) //{ // //申请任务的阅片人 后续任务肯定没做, 只有检查批次任务,没有其他任务 取消分配 // if (influenceTask.DoctorUserId == task.DoctorUserId) // { // switch (influenceTask.ReadingCategory) // { // case ReadingCategory.Visit: // influenceTask.DoctorUserId = null; // influenceTask.AllocateTime = null; // influenceTask.SuggesteFinishedTime = null; // influenceTask.TaskAllocationState = TaskAllocationState.NotAllocate; // break; // case ReadingCategory.Global: // case ReadingCategory.Judge: // case ReadingCategory.Oncology: // throw new BusinessValidationFailedException("不支持回退任务类型"); // } // } // //另外一个阅片人 // else // { // //另外一个阅片人 有序PM 申请重阅流程 // if (otherReviewerTask.ReadingTaskState == ReadingTaskState.HaveSigned) // { // switch (influenceTask.ReadingCategory) // { // case ReadingCategory.Visit: // if (influenceTask.ReadingTaskState == ReadingTaskState.HaveSigned) // { // influenceTask.TaskState = TaskState.HaveReturned; // } // else if (influenceTask.ReadingTaskState == ReadingTaskState.Reading) // { // influenceTask.TaskState = TaskState.Adbandon; // } // else // { // influenceTask.DoctorUserId = null; // influenceTask.AllocateTime = null; // influenceTask.SuggesteFinishedTime = null; // influenceTask.TaskAllocationState = TaskAllocationState.NotAllocate; // } // break; // case ReadingCategory.Global: // case ReadingCategory.Oncology: // if (influenceTask.ReadingTaskState == ReadingTaskState.HaveSigned) // { // influenceTask.TaskState = TaskState.HaveReturned; // } // else // { // influenceTask.TaskState = TaskState.Adbandon; // } // break; // case ReadingCategory.Judge: // default: // throw new BusinessValidationFailedException("不支持回退任务类型"); // } // } // //另外一个阅片人 有序 PM 回退流程 // else // { // switch (influenceTask.ReadingCategory) // { // case ReadingCategory.Visit: // influenceTask.DoctorUserId = null; // influenceTask.AllocateTime = null; // influenceTask.SuggesteFinishedTime = null; // influenceTask.TaskAllocationState = TaskAllocationState.NotAllocate; // break; // case ReadingCategory.Global: // case ReadingCategory.Judge: // case ReadingCategory.Oncology: // throw new BusinessValidationFailedException("不支持回退任务类型"); // } // } // } //} #endregion #region 方式二 var origenalTask = influenceTaskList.Where(t => t.Id == task.Id).FirstOrDefault(); foreach (var influenceTask in influenceTaskList) { //同意的检查批次 因为要记录具体的操作,所以废弃 if (influenceTask.Id == task.Id) { //influenceTaskList.ForEach(t => //{ // //记录实际影像的任务 // influenceTask.TaskInfluenceList.Add(new TaskInfluence() { InfluenceTaskId = t.Id }); //}); await SetReReadingOrBackInfluenceAnalysisAsync(influenceTask.SubjectId); await SetMedicalReviewInvalidAsync(influenceTaskList); influenceTask.IsPMSetBack = true; } //申请的检查批次 要不是重阅重置,要不就是失效 不会存在取消分配 if (influenceTask.ReadingCategory == ReadingCategory.Visit && influenceTask.VisitTaskNum != task.VisitTaskNum) { //后续检查批次处理检查批次 if (influenceTask.ReadingTaskState == ReadingTaskState.HaveSigned) { influenceTask.TaskState = TaskState.HaveReturned; origenalTask.TaskInfluenceList.Add(new TaskInfluence() { InfluenceTaskId = influenceTask.Id, OptType = ReReadingOrBackOptType.Return }); } else if (influenceTask.ReadingTaskState == ReadingTaskState.Reading) { influenceTask.TaskState = TaskState.Adbandon; origenalTask.TaskInfluenceList.Add(new TaskInfluence() { InfluenceTaskId = influenceTask.Id, OptType = ReReadingOrBackOptType.Abandon }); } else { influenceTask.DoctorUserId = null; influenceTask.AllocateTime = null; influenceTask.SuggesteFinishedTime = null; influenceTask.TaskAllocationState = TaskAllocationState.NotAllocate; origenalTask.TaskInfluenceList.Add(new TaskInfluence() { InfluenceTaskId = influenceTask.Id, OptType = ReReadingOrBackOptType.CancelAssign }); } } else { //申请的检查批次 全局肿瘤学 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 { //无序 无序阅片没有 全局 肿瘤学 //// 当前任务标为失效 //task.TaskState = TaskState.Adbandon; ////考虑该检查批次 另外一个阅片人的任务 //var otherReviewerTask = await _visitTaskRepository.FirstOrDefaultAsync(t => t.SourceSubjectVisitId == task.SourceSubjectVisitId && t.Id != task.Id && t.TaskState == TaskState.Effect); //if (otherReviewerTask.ReadingTaskState == ReadingTaskState.HaveSigned) //{ // //另外阅片人完成阅片了 就设置为重阅重置 // otherReviewerTask.TaskState = TaskState.HaveReturned; //} //else //{ // otherReviewerTask.TaskState = TaskState.Adbandon; //} // 申请该检查批次的任务 申请人失效 另外一个人重阅重置或者失效 var currentVisitList = await _visitTaskRepository.Where(t => t.SourceSubjectVisitId == task.SourceSubjectVisitId && t.ReadingCategory == ReadingCategory.Visit && t.TaskState == TaskState.Effect && t.VisitTaskNum == task.VisitTaskNum, true).ToListAsync(); await SetMedicalReviewInvalidAsync(currentVisitList); var origenalTask = currentVisitList.Where(t => t.Id == task.Id).First(); 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 }); } ////同意的检查批次 //if (influenceTask.Id == task.Id) //{ // currentVisitList.ForEach(t => // { // //记录实际影像的任务 // influenceTask.TaskInfluenceList.Add(new TaskInfluence() { InfluenceTaskId = t.Id }); // }); //} } } } else { return ResponseOutput.NotOk("仅PM 可以进行回退操作"); } await _visitTaskRepository.SaveChangesAsync(); return ResponseOutput.Ok(); } //包括临床数据签名状态 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 _repository.BatchDeleteAsync(t => t.SubjectVisitId == subjectVisitId); await _repository.BatchDeleteAsync(t => t.DicomSerie.IsDeleted); await _repository.BatchDeleteAsync(t => t.IsDeleted); var success = await _subjectVisitRepository.SaveChangesAsync(); } /// /// 影响提示列表 重阅仅仅针对已完成的任务申请 退回针对的是未完成的(退回仅仅针对是检查批次类型的) /// /// /// 重阅还是直接回退 /// 申请记录的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 trialConfig = (await _trialRepository.Where(t => t.Id == trialId).Select(t => new { TrialId = t.Id, t.IsReadingTaskViewInOrder, t.ReadingType }).FirstOrDefaultAsync()).IfNullThrowException(); var criterionConfig = (await _trialReadingCriterionRepository.Where(x => x.Id == filterObj.TrialReadingCriterionId).Select(x => new { x.ReadingTool, x.IsReadingTaskViewInOrder }).FirstOrDefaultAsync()).IfNullThrowException(); Expression> filterExpression = t => t.TrialId == trialId && t.SubjectId == filterObj.SubjectId && t.TaskState == TaskState.Effect && t.TaskAllocationState == TaskAllocationState.Allocated; //是否是一致性分析任务 (一致性分析的任务 不会产生裁判 肿瘤学 仅仅有生成的检查批次和全局) filterExpression = filterExpression.And(t => t.IsAnalysisCreate == filterObj.IsAnalysisCreate); //重阅影响 if (isReReading) { //IR 申请 PM 同意 仅仅影响自己 if ((_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ProjectManager && applyId != null && await _visitTaskReReadingRepository.AnyAsync(t => t.Id == applyId && t.CreateUser.UserTypeEnum == UserTypeEnum.IndependentReviewer)) || (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.IndependentReviewer && applyId == null)) { filterExpression = filterExpression.And(t => t.TrialReadingCriterionId == filterObj.TrialReadingCriterionId); //当前任务及其之后的所有检查批次任务、全局任务、裁判任务、肿瘤学阅片任务 //有序 if (criterionConfig.IsReadingTaskViewInOrder) { switch (filterObj.ReadingCategory) { case ReadingCategory.Visit: //影响当前医生 以及当前医生之后的 1、检查批次任务 已经读完的 //2、后续任务如果是全局、肿瘤学阅片任务,状态为阅片完成标记为重阅重置;若在阅片中,则标记为失效;若为待阅片,则标记为失效; //3、当前任务、后续检查批次任务或者全局任务触发了裁判任务,若裁判任务状态为阅片完成,则标记为重阅重置;若在阅片中或待阅片,则标记为失效 // 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.Judge || t.ReadingCategory == ReadingCategory.Oncology) // ); filterExpression = filterExpression.And(t => t.VisitTaskNum >= filterObj.VisitTaskNum && ( (((t.ReadingCategory == ReadingCategory.Visit && t.ReadingTaskState != ReadingTaskState.WaitReading) || 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("不支持重阅的任务类型"); } } //无序 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 (((_userInfo.UserTypeEnumInt == (int)UserTypeEnum.SPM || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.CPM) && applyId != null && await _visitTaskReReadingRepository.AnyAsync(t => t.Id == applyId && t.CreateUser.UserTypeEnum == UserTypeEnum.ProjectManager) && filterObj.IsAnalysisCreate == false && filterObj.ReadingCategory == ReadingCategory.Visit) || (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ProjectManager && applyId == null)) { //有序 if (criterionConfig.IsReadingTaskViewInOrder) { switch (filterObj.ReadingCategory) { case ReadingCategory.Visit: //检查批次影响当前以及当前之后的 两个阅片人的 filterExpression = filterExpression.And(t => t.VisitTaskNum >= filterObj.VisitTaskNum); break; default: throw new BusinessValidationFailedException("不支持重阅的任务类型"); } 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("当前用户查看列表未定义"); } } //退回影响 仅仅针对是检查批次类型的 影响多个标准的任务 else { if (filterObj.IsAnalysisCreate) { throw new BusinessValidationFailedException("不允许退回一致性分析任务"); } if (filterObj.ReadingCategory == ReadingCategory.Visit && _userInfo.UserTypeEnumInt == (int)UserTypeEnum.ProjectManager) { //有序 if (criterionConfig.IsReadingTaskViewInOrder) { // 当前任务及其之后的所有检查批次任务 两个阅片人的 // 1.后续检查批次不处理 //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 { throw new BusinessValidationFailedException("仅仅检查批次类型的任务支持PM退回"); } } 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) { if (isReReading) { if ((_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ProjectManager && applyId != null) || (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.IndependentReviewer && applyId == null)) { //有序 if (criterionConfig.IsReadingTaskViewInOrder) { if (influenceTask.ReadingTaskState == ReadingTaskState.HaveSigned) { influenceTask.OptType = ReReadingOrBackOptType.Return; } else { influenceTask.OptType = ReReadingOrBackOptType.Abandon; } //else if (influenceTask.ReadingTaskState == ReadingTaskState.Reading) //{ // influenceTask.OptType = ReReadingOrBackOptType.Abandon; //} //else //{ // throw new BusinessValidationFailedException("IR 申请重阅,不会影响到后续未读的任务,当前影响列表有未读的任务,请核查"); //} } else { if (influenceTask.ReadingTaskState == ReadingTaskState.HaveSigned) { influenceTask.OptType = ReReadingOrBackOptType.Return; } else { influenceTask.OptType = ReReadingOrBackOptType.Abandon; } } } if (((_userInfo.UserTypeEnumInt == (int)UserTypeEnum.SPM || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.CPM) && applyId != null) || (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ProjectManager && applyId == null)) { //有序 if (criterionConfig.IsReadingTaskViewInOrder) { //申请的检查批次 要不是重阅重置,要不就是失效 不会存在取消分配 if (influenceTask.ReadingCategory == ReadingCategory.Visit && influenceTask.VisitTaskNum != filterObj.VisitTaskNum) { if (influenceTask.ReadingTaskState == ReadingTaskState.HaveSigned) { influenceTask.OptType = ReReadingOrBackOptType.Return; } else if (influenceTask.ReadingTaskState == ReadingTaskState.Reading) { influenceTask.OptType = ReReadingOrBackOptType.Abandon; } else { influenceTask.OptType = ReReadingOrBackOptType.CancelAssign; } } else { if (influenceTask.ReadingTaskState == ReadingTaskState.HaveSigned) { influenceTask.OptType = ReReadingOrBackOptType.Return; } else { influenceTask.OptType = ReReadingOrBackOptType.Abandon; } } } else { if (influenceTask.ReadingTaskState == ReadingTaskState.HaveSigned) { influenceTask.OptType = ReReadingOrBackOptType.Return; } else { influenceTask.OptType = ReReadingOrBackOptType.Abandon; } } } } //PM退回 else { //有序 if (criterionConfig.IsReadingTaskViewInOrder) { //申请的检查批次 要不是重阅重置,要不就是失效 不会存在取消分配 if (influenceTask.ReadingCategory == ReadingCategory.Visit && influenceTask.VisitTaskNum != filterObj.VisitTaskNum) { //后续检查批次处理检查批次 if (influenceTask.ReadingTaskState == ReadingTaskState.HaveSigned) { influenceTask.OptType = ReReadingOrBackOptType.Return; } else if (influenceTask.ReadingTaskState == ReadingTaskState.Reading) { influenceTask.OptType = ReReadingOrBackOptType.Abandon; } else { influenceTask.OptType = ReReadingOrBackOptType.CancelAssign; } } else { //申请的检查批次 全局肿瘤学 if (influenceTask.ReadingTaskState == ReadingTaskState.HaveSigned) { influenceTask.OptType = ReReadingOrBackOptType.Return; } else { influenceTask.OptType = ReReadingOrBackOptType.Abandon; } } } //无序 else { //重阅重置或者失效 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 _repository.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 } }