diff --git a/IRaCIS.Core.Application/Service/Allocation/DTO/TaskAllocationRuleViewModel.cs b/IRaCIS.Core.Application/Service/Allocation/DTO/TaskAllocationRuleViewModel.cs index 3b9f66cf3..98914c371 100644 --- a/IRaCIS.Core.Application/Service/Allocation/DTO/TaskAllocationRuleViewModel.cs +++ b/IRaCIS.Core.Application/Service/Allocation/DTO/TaskAllocationRuleViewModel.cs @@ -51,6 +51,11 @@ namespace IRaCIS.Core.Application.ViewModel } + + + + + public class AllocateInfo { public int? TotalTaskCount { get; set; } diff --git a/IRaCIS.Core.Application/Service/Allocation/DTO/VisitTaskViewModel.cs b/IRaCIS.Core.Application/Service/Allocation/DTO/VisitTaskViewModel.cs index ee1e624af..a0349764a 100644 --- a/IRaCIS.Core.Application/Service/Allocation/DTO/VisitTaskViewModel.cs +++ b/IRaCIS.Core.Application/Service/Allocation/DTO/VisitTaskViewModel.cs @@ -282,6 +282,27 @@ namespace IRaCIS.Core.Application.ViewModel public List SubjectIdList { get; set; } } + public class AutoAssignResultDTO + { + public Guid DoctorUserId { get; set; } + + public int PlanReadingRatio { get; set; } + + public List SubjectArmList { get; set; } = new List(); + + public int SubjectCount { get; set; } + + public int Weight => (SubjectCount - SubjectArmList.Count) * PlanReadingRatio; + + } + + public class SubjectArm + { + public Guid SubjectId { get; set; } + + public int ArmEnum { get; set; } + } + public class AssignConfirmCommand { diff --git a/IRaCIS.Core.Application/Service/Allocation/TaskAllocationRuleService.cs b/IRaCIS.Core.Application/Service/Allocation/TaskAllocationRuleService.cs index ddfd69b87..612fbf7a0 100644 --- a/IRaCIS.Core.Application/Service/Allocation/TaskAllocationRuleService.cs +++ b/IRaCIS.Core.Application/Service/Allocation/TaskAllocationRuleService.cs @@ -41,6 +41,7 @@ namespace IRaCIS.Core.Application.Service var trialTaskConfig= _trialRepository.Where(t=>t.Id==queryTaskAllocationRule.TrialId).ProjectTo(_mapper.ConfigurationProvider).FirstOrDefault(); + return (await taskAllocationRuleQueryable.ToListAsync(), trialTaskConfig); } diff --git a/IRaCIS.Core.Application/Service/Allocation/VisitTaskService.cs b/IRaCIS.Core.Application/Service/Allocation/VisitTaskService.cs index b65f00a2a..2b7fa419a 100644 --- a/IRaCIS.Core.Application/Service/Allocation/VisitTaskService.cs +++ b/IRaCIS.Core.Application/Service/Allocation/VisitTaskService.cs @@ -217,16 +217,16 @@ namespace IRaCIS.Core.Application.Service .Where(t => t.SubjectDoctorList.Any(t => t.DoctorUserId == _userInfo.Id)) .WhereIf(!string.IsNullOrEmpty(iRUnReadSubjectQuery.SubjectCode), t => t.Code.Contains(iRUnReadSubjectQuery.SubjectCode)) .Select(s => new IRUnReadSubjectView() - { - SubjectId = s.Id, - SubjectCode = s.Code, - UnReadTaskCount = s.SubjectVisitTaskList.Count(t => t.ReadingTaskState != ReadingTaskState.HaveSigned && t.DoctorUserId == _userInfo.Id), - UnReadTaskList = s.SubjectVisitTaskList.Where(t => t.ReadingTaskState != ReadingTaskState.HaveSigned && t.DoctorUserId == _userInfo.Id).Select(u => new IRUnreadTaskView() { Id = u.Id, IsUrgent = u.IsUrgent, SuggesteFinishedTime = u.SuggesteFinishedTime }).ToList(), - }) - .Where(t=>t.UnReadTaskCount>0); + { + SubjectId = s.Id, + SubjectCode = s.Code, + UnReadTaskCount = s.SubjectVisitTaskList.Count(t => t.ReadingTaskState != ReadingTaskState.HaveSigned && t.DoctorUserId == _userInfo.Id), + UnReadTaskList = s.SubjectVisitTaskList.Where(t => t.ReadingTaskState != ReadingTaskState.HaveSigned && t.DoctorUserId == _userInfo.Id).Select(u => new IRUnreadTaskView() { Id = u.Id, IsUrgent = u.IsUrgent, SuggesteFinishedTime = u.SuggesteFinishedTime }).ToList(), + }) + .Where(t => t.UnReadTaskCount > 0); - return await subjectQuery.ToPagedListAsync(iRUnReadSubjectQuery.PageIndex, iRUnReadSubjectQuery.PageSize, String.IsNullOrEmpty(iRUnReadSubjectQuery.SortField)?nameof(IRUnReadSubjectView.SubjectId): iRUnReadSubjectQuery.SortField, iRUnReadSubjectQuery.Asc); + return await subjectQuery.ToPagedListAsync(iRUnReadSubjectQuery.PageIndex, iRUnReadSubjectQuery.PageSize, String.IsNullOrEmpty(iRUnReadSubjectQuery.SortField) ? nameof(IRUnReadSubjectView.SubjectId) : iRUnReadSubjectQuery.SortField, iRUnReadSubjectQuery.Asc); #endregion @@ -345,7 +345,7 @@ namespace IRaCIS.Core.Application.Service if (assginSubjectDoctorCommand.IsReAssign) { - if (await _visitTaskRepository.AnyAsync(t => assginSubjectDoctorCommand.SubjectIdList.Contains(t.SubjectId)&& t.DoctorUserId != null)) + if (await _visitTaskRepository.AnyAsync(t => assginSubjectDoctorCommand.SubjectIdList.Contains(t.SubjectId) && t.DoctorUserId != null)) { throw new BusinessValidationFailedException("有Subject任务已应用,不允许重新分配"); } @@ -381,7 +381,7 @@ namespace IRaCIS.Core.Application.Service { foreach (var subjectId in cancelSubjectAssignCommand.SubjectIdList) { - if(await _visitTaskRepository.AnyAsync(t=>t.SubjectId==subjectId && t.DoctorUserId != null)) + if (await _visitTaskRepository.AnyAsync(t => t.SubjectId == subjectId && t.DoctorUserId != null)) { throw new BusinessValidationFailedException("有Subject任务已应用,不允许取消分配"); } @@ -430,7 +430,7 @@ namespace IRaCIS.Core.Application.Service if (assignConfirmCommand.SubjectDoctorUserList.Count == 0) { - subjectDoctorIdArmList = _subjectUserRepository.Where(t => t.SubjectId == subjectId).Select(t => new DoctorArm() { DoctorUserId=t.DoctorUserId, ArmEnum=t.ArmEnum } ).ToList(); + subjectDoctorIdArmList = _subjectUserRepository.Where(t => t.SubjectId == subjectId).Select(t => new DoctorArm() { DoctorUserId = t.DoctorUserId, ArmEnum = t.ArmEnum }).ToList(); } else { @@ -444,7 +444,7 @@ namespace IRaCIS.Core.Application.Service var subjectDoctorArm = subjectDoctorIdArmList.Where(t => t.ArmEnum == task.ArmEnum).FirstOrDefault(); - if(subjectDoctorArm != null) + if (subjectDoctorArm != null) { task.DoctorUserId = subjectDoctorArm.DoctorUserId; task.AllocateTime = DateTime.Now; @@ -477,320 +477,392 @@ namespace IRaCIS.Core.Application.Service { //自动分配的话,需要把手动分配的给删掉 - //throw new BusinessValidationFailedException("自动分配算法正在开发,还未完成"); var trialId = autoSubjectAssignCommand.TrialId; - //获取所有的Subject 目前的分配情况 - var subjectList = _subjectRepository.Where(t => t.TrialId == trialId).Select(t => new { SubjectId = t.Id, DoctorUserList = t.SubjectDoctorList.Select(t => new { t.DoctorUserId, t.ArmEnum }) }).ToList(); + //获取 已产生任务的Subject 目前分配情况 + var subjectList = _subjectRepository.Where(t => t.TrialId == trialId).Where(t => t.SubjectVisitTaskList.Any()) + .Select(t => new { SubjectId = t.Id, DoctorUserList = t.SubjectDoctorList.Select(t => new { t.DoctorUserId, t.ArmEnum }), IsApplyed = t.SubjectVisitTaskList.Any(c => c.DoctorUserId != null) }).ToList(); - //受试者总数 - var subjectCount = subjectList.Count(); - //获取待分配的医生列表 指导分配医生的数量 - var waitAllocationDoctorList = _taskAllocationRuleRepository.Where(t => t.TrialId == trialId && t.IsEnable) - .Select(t => new { t.DoctorUserId, t.PlanReadingRatio, Weight = (subjectCount * t.PlanReadingRatio) % 100 }) - .OrderByDescending(t => t.PlanReadingRatio).ThenByDescending(t => t.Weight).ToList(); //获取项目配置 判断应该分配几个医生 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 assignedSubjectDoctorList = subjectList.Clone().SelectMany(t => t.DoctorUserList.Select(c => new { t.SubjectId, DoctorUserId = c.DoctorUserId, c.ArmEnum })).ToList(); - - //给医生分配Subject 前验证 已经分配的数据是否符合分配的规范 - foreach (var doctor in waitAllocationDoctorList) - { - - //该医生的目前已分配到的受试者 - var hasAssignedSubjectIdList = assignedSubjectDoctorList.Where(t => t.DoctorUserId == doctor.DoctorUserId).Select(t => t.SubjectId).Distinct().ToList(); - //验证已经分配的Subject 是否 符合项目配置规范 - foreach (var subjectId in hasAssignedSubjectIdList) - { - var hasAssignDoctorCount = subjectList.Where(t => t.SubjectId == subjectId).FirstOrDefault().DoctorUserList.Count(); - - //分配两个医生 - if (trialConfig.ReadingType == ReadingMethod.Double) - { - - if (hasAssignDoctorCount > 2) - { - throw new BusinessValidationFailedException("双重阅片当前有Subject绑定医生数量大于2"); - } - - } - else if (trialConfig.ReadingType == ReadingMethod.Single) - { - if (hasAssignDoctorCount > 1) - { - throw new BusinessValidationFailedException("单重阅片当前有Subject绑定医生数量大于1"); - } - } - } - - } - - //验证通过 给医生开始分配 #region 按照医生维度分配Subject - if (trialConfig.ReadingType == ReadingMethod.Single) - { - //eg : 10个Sujbect 都是1/4 先分配整数 再分配 10%4=2个 + ////受试者总数 + //var subjectCount = subjectList.Count(); - //特殊: 不够分的subject数量 适用于 2个Subject 4个医生 这种 + ////获取待分配的医生列表 指导分配医生的数量 + //var waitAllocationDoctorList = _taskAllocationRuleRepository.Where(t => t.TrialId == trialId && t.IsEnable) + // .Select(t => new { t.DoctorUserId, t.PlanReadingRatio, Weight = (subjectCount * t.PlanReadingRatio) % 100 }) + // .OrderByDescending(t => t.PlanReadingRatio).ThenByDescending(t => t.Weight).ToList(); + ////给医生分配Subject 前验证 已经分配的数据是否符合分配的规范 + //foreach (var subject in subjectList) + //{ + // var doctorCount = subject.DoctorUserList.Count(); + // //分配两个医生 + // if (trialConfig.ReadingType == ReadingMethod.Double) + // { - var integerPlan = 0; + // if (doctorCount > 2) + // { + // throw new BusinessValidationFailedException("双重阅片当前有Subject绑定医生数量大于2"); + // } - waitAllocationDoctorList.ForEach(doctor => - { + // } + // else if (trialConfig.ReadingType == ReadingMethod.Single) + // { + // if (doctorCount > 1) + // { + // throw new BusinessValidationFailedException("单重阅片当前有Subject绑定医生数量大于1"); + // } + // } + //} - integerPlan += (int)Math.Floor((double)(subjectCount * doctor.PlanReadingRatio) / 100); + ////存放分配后Subject 医生的情况 + //var assignedSubjectDoctorList = subjectList.Clone().SelectMany(t => t.DoctorUserList.Select(c => new { t.SubjectId, DoctorUserId = c.DoctorUserId, c.ArmEnum })).ToList(); - }); + //if (trialConfig.ReadingType == ReadingMethod.Single) + //{ + // //eg : 10个Sujbect 都是1/4 先分配整数 再分配 10%4=2个 + // //特殊: 不够分的subject数量 适用于 2个Subject 4个医生 这种 - var specialSubjectCount = subjectCount - integerPlan; - //按照医生维度 分配Subject - foreach (var doctor in waitAllocationDoctorList) - { + // var integerPlan = 0; + // waitAllocationDoctorList.ForEach(doctor => + // { - //该医生的目前已分配到的受试者 - var hasAssignedSubjectIdList = assignedSubjectDoctorList.Where(t => t.DoctorUserId == doctor.DoctorUserId).Select(t => t.SubjectId).Distinct().ToList(); + // integerPlan += (int)Math.Floor((double)(subjectCount * doctor.PlanReadingRatio) / 100); - //已分配的Subject 数量 - var hasAssignedSubjectCount = hasAssignedSubjectIdList.Count(); + // }); - //该医生计划分配到的Subject 最接近的整数数量 - var planSubjectCount = (int)Math.Ceiling((double)(subjectCount * doctor.PlanReadingRatio) / 100); - //权重大的,将特殊的分配 - if (doctor.Weight != 50) - { - if (specialSubjectCount > 0) - { - specialSubjectCount--; + // var specialSubjectCount = subjectCount - integerPlan; - planSubjectCount++; - } + // //按照医生维度 分配Subject + // foreach (var doctor in waitAllocationDoctorList) + // { - } - //如果计划的数量 大于已经分配的数量 那么该医生 可以分配新的Subject - if (planSubjectCount > hasAssignedSubjectCount) - { + // //该医生的目前已分配到的受试者 + // var hasAssignedSubjectIdList = assignedSubjectDoctorList.Where(t => t.DoctorUserId == doctor.DoctorUserId).Select(t => t.SubjectId).Distinct().ToList(); - //从未分配的Subjct找到可以分配的分配给该医生 + // //已分配的Subject 数量 + // var hasAssignedSubjectCount = hasAssignedSubjectIdList.Count(); - var allAssignedSubjectIdList = assignedSubjectDoctorList.Select(t => t.SubjectId).Distinct().ToList(); + // //该医生计划分配到的Subject 最接近的整数数量 + // var planSubjectCount = (int)Math.Ceiling((double)(subjectCount * doctor.PlanReadingRatio) / 100); - //取需要分配的数量 并且没有分配给其他医生的包括自己 - var assignSubjectIdList = subjectList.Where(t => !allAssignedSubjectIdList.Contains(t.SubjectId)).Select(t => t.SubjectId).Take(planSubjectCount - hasAssignedSubjectCount).ToList(); + // //权重大的,将特殊的分配 + // if (doctor.Weight != 50) + // { + // if (specialSubjectCount > 0) + // { + // specialSubjectCount--; - foreach (var assignSubjectId in assignSubjectIdList) - { - //将分配结果记录 - assignedSubjectDoctorList.Add(new { SubjectId = assignSubjectId, DoctorUserId = doctor.DoctorUserId, ArmEnum = 0 }); + // planSubjectCount++; + // } - await _subjectUserRepository.AddAsync(new SubjectUser() { TrialId = trialId, SubjectId = assignSubjectId, DoctorUserId = doctor.DoctorUserId, AssignTime = DateTime.Now }); + // } + // //如果计划的数量 大于已经分配的数量 那么该医生 可以分配新的Subject + // if (planSubjectCount > hasAssignedSubjectCount) + // { - } - } - else - { - throw new BusinessValidationFailedException("当前有医生已分配的Subject 数量,超过了计划分配Subject数量,不支持自动分配"); - } + // //从未分配的Subjct找到可以分配的分配给该医生 - } + // var allAssignedSubjectIdList = assignedSubjectDoctorList.Select(t => t.SubjectId).Distinct().ToList(); - } - if (trialConfig.ReadingType == ReadingMethod.Double) - { - var integerPlan = 0; + // //取需要分配的数量 并且没有分配给其他医生的包括自己 + // var assignSubjectIdList = subjectList.Where(t => !allAssignedSubjectIdList.Contains(t.SubjectId)).Select(t => t.SubjectId).Take(planSubjectCount - hasAssignedSubjectCount).ToList(); - waitAllocationDoctorList.ForEach(doctor => - { + // foreach (var assignSubjectId in assignSubjectIdList) + // { + // //将分配结果记录 + // assignedSubjectDoctorList.Add(new { SubjectId = assignSubjectId, DoctorUserId = doctor.DoctorUserId, ArmEnum = 0 }); - integerPlan += (int)Math.Floor((double)(subjectCount * doctor.PlanReadingRatio * 2) / 100); + // await _subjectUserRepository.AddAsync(new SubjectUser() { TrialId = trialId, SubjectId = assignSubjectId, DoctorUserId = doctor.DoctorUserId, AssignTime = DateTime.Now }); - }); + // } + // } + // else + // { + // throw new BusinessValidationFailedException("当前有医生已分配的Subject 数量,超过了计划分配Subject数量,不支持自动分配"); + // } - var specialSubjectCount = (subjectCount * 2) - integerPlan; + // } - //按照医生维度 分配Subject - foreach (var doctor in waitAllocationDoctorList) - { + //} + //if (trialConfig.ReadingType == ReadingMethod.Double) + //{ + // var integerPlan = 0; + // waitAllocationDoctorList.ForEach(doctor => + // { - //该医生的目前已分配到的受试者 - var hasAssignedSubjectIdList = assignedSubjectDoctorList.Where(t => t.DoctorUserId == doctor.DoctorUserId).Select(t => t.SubjectId).ToList(); + // integerPlan += (int)Math.Floor((double)(subjectCount * doctor.PlanReadingRatio * 2) / 100); - //已分配的Subject 数量 - var hasAssignedSubjectCount = hasAssignedSubjectIdList.Count(); + // }); - //该医生计划分配到的Subject 最接近的整数数量 - var planSubjectCount = (int)Math.Floor((double)(subjectCount * doctor.PlanReadingRatio * 2) / 100); - //判断是否能整除 + // var specialSubjectCount = (subjectCount * 2) - integerPlan; - var yuShu = (subjectCount * doctor.PlanReadingRatio * 2) % 100; + // //按照医生维度 分配Subject + // foreach (var doctor in waitAllocationDoctorList) + // { - if (yuShu != 0) - { - if (specialSubjectCount > 0) - { - specialSubjectCount--; - planSubjectCount++; - } - } + // //该医生的目前已分配到的受试者 + // var hasAssignedSubjectIdList = assignedSubjectDoctorList.Where(t => t.DoctorUserId == doctor.DoctorUserId).Select(t => t.SubjectId).ToList(); + // //已分配的Subject 数量 + // var hasAssignedSubjectCount = hasAssignedSubjectIdList.Count(); - //如果计划的数量 大于已经分配的数量 那么该医生 可以分配新的Subject - if (planSubjectCount > hasAssignedSubjectCount) - { + // //该医生计划分配到的Subject 最接近的整数数量 + // var planSubjectCount = (int)Math.Floor((double)(subjectCount * doctor.PlanReadingRatio * 2) / 100); - //分配给其他医生 已经满了的 - var otherExceptDoctorIdList = assignedSubjectDoctorList.Where(t => t.DoctorUserId != doctor.DoctorUserId).GroupBy(t => t.SubjectId) - .Select(g => new { SubjectId = g.Key, DoctorCount = g.Count() }).Where(c => c.DoctorCount == 2).Select(t => t.SubjectId).ToList(); + // //判断是否能整除 + // var yuShu = (subjectCount * doctor.PlanReadingRatio * 2) % 100; - //取需要分配的数量 并且没有分配给其他医生的包括自己 - var assignSubjectIdList = subjectList.Where(t => !hasAssignedSubjectIdList.Contains(t.SubjectId) && !otherExceptDoctorIdList.Contains(t.SubjectId)) - .Select(t => t.SubjectId).Take((planSubjectCount - hasAssignedSubjectCount)).ToList(); + // if (yuShu != 0) + // { + // if (specialSubjectCount > 0) + // { + // specialSubjectCount--; + // planSubjectCount++; - foreach (var assignSubjectId in assignSubjectIdList) - { + // } + // } - var otherHaveAssignedSubject = assignedSubjectDoctorList.Where(t => t.SubjectId == assignSubjectId).FirstOrDefault(); + // //如果计划的数量 大于已经分配的数量 那么该医生 可以分配新的Subject + // if (planSubjectCount > hasAssignedSubjectCount) + // { - if (otherHaveAssignedSubject != null) - { + // //分配给其他医生 已经满了的 + // var otherExceptDoctorIdList = assignedSubjectDoctorList.Where(t => t.DoctorUserId != doctor.DoctorUserId).GroupBy(t => t.SubjectId) + // .Select(g => new { SubjectId = g.Key, DoctorCount = g.Count() }).Where(c => c.DoctorCount == 2).Select(t => t.SubjectId).ToList(); - if (otherHaveAssignedSubject.ArmEnum == 1) - { - assignedSubjectDoctorList.Add(new { SubjectId = assignSubjectId, DoctorUserId = doctor.DoctorUserId, ArmEnum = 2 }); - await _subjectUserRepository.AddAsync(new SubjectUser() { TrialId = trialId, SubjectId = assignSubjectId, DoctorUserId = doctor.DoctorUserId, ArmEnum = 2, AssignTime = DateTime.Now }); + // //取需要分配的数量 并且没有分配给其他医生的包括自己 + // var assignSubjectIdList = subjectList.Where(t => !hasAssignedSubjectIdList.Contains(t.SubjectId) && !otherExceptDoctorIdList.Contains(t.SubjectId)) + // .Select(t => t.SubjectId).Take((planSubjectCount - hasAssignedSubjectCount)).ToList(); - } - else if (otherHaveAssignedSubject.ArmEnum == 2) - { - assignedSubjectDoctorList.Add(new { SubjectId = assignSubjectId, DoctorUserId = doctor.DoctorUserId, ArmEnum = 1 }); + // foreach (var assignSubjectId in assignSubjectIdList) + // { - await _subjectUserRepository.AddAsync(new SubjectUser() { TrialId = trialId, SubjectId = assignSubjectId, DoctorUserId = doctor.DoctorUserId, ArmEnum = 1, AssignTime = DateTime.Now }); - } - } - else - { - assignedSubjectDoctorList.Add(new { SubjectId = assignSubjectId, DoctorUserId = doctor.DoctorUserId, ArmEnum = 1 }); + // var otherHaveAssignedSubject = assignedSubjectDoctorList.Where(t => t.SubjectId == assignSubjectId).FirstOrDefault(); - await _subjectUserRepository.AddAsync(new SubjectUser() { TrialId = trialId, SubjectId = assignSubjectId, DoctorUserId = doctor.DoctorUserId, ArmEnum = 1, AssignTime = DateTime.Now }); + // if (otherHaveAssignedSubject != null) + // { - } + // if (otherHaveAssignedSubject.ArmEnum == 1) + // { + // assignedSubjectDoctorList.Add(new { SubjectId = assignSubjectId, DoctorUserId = doctor.DoctorUserId, ArmEnum = 2 }); + // await _subjectUserRepository.AddAsync(new SubjectUser() { TrialId = trialId, SubjectId = assignSubjectId, DoctorUserId = doctor.DoctorUserId, ArmEnum = 2, AssignTime = DateTime.Now }); - } - } - else - { - throw new BusinessValidationFailedException("当前有医生已分配的Subject 数量,超过了计划分配Subject数量,不支持自动分配"); - } + // } + // else if (otherHaveAssignedSubject.ArmEnum == 2) + // { + // assignedSubjectDoctorList.Add(new { SubjectId = assignSubjectId, DoctorUserId = doctor.DoctorUserId, ArmEnum = 1 }); + // await _subjectUserRepository.AddAsync(new SubjectUser() { TrialId = trialId, SubjectId = assignSubjectId, DoctorUserId = doctor.DoctorUserId, ArmEnum = 1, AssignTime = DateTime.Now }); + // } + // } + // else + // { + // assignedSubjectDoctorList.Add(new { SubjectId = assignSubjectId, DoctorUserId = doctor.DoctorUserId, ArmEnum = 1 }); - } + // await _subjectUserRepository.AddAsync(new SubjectUser() { TrialId = trialId, SubjectId = assignSubjectId, DoctorUserId = doctor.DoctorUserId, ArmEnum = 1, AssignTime = DateTime.Now }); + // } - //如果是2个Subject 3个医生 这种 都是百分之33的比率 - // 10 3 + // } + // } + // else + // { + // throw new BusinessValidationFailedException("当前有医生已分配的Subject 数量,超过了计划分配Subject数量,不支持自动分配"); + // } + // } + // //如果是2个Subject 3个医生 这种 都是百分之33的比率 + // // 10 3 - } + + + + //} + + ////验证是否所有Subject 是否分配好 + + //if (assignedSubjectDoctorList.Select(t => t.SubjectId).Distinct().Count() != subjectCount) + //{ + // throw new BusinessValidationFailedException("分配算法有问题,有Subject 未分配"); + //} + #endregion #region 完全按照Subject 遍历去分 - //foreach (var subject in subjectList) - //{ - // //该Subject 已经分配的医生数量 - // var hasAssignDoctorCount = subject.DoctorUserIdList.Count(); + var subjectCount = subjectList.Count; - // //分配两个医生 - // if (trialConfig.ReadingType == ReadingMethod.Double) - // { - // //await _subjectUserRepository.AddAsync(new SubjectUser() { TrialId = trialId, SubjectId = subject.SubjectId, DoctorUserId = doctorUserId, AssignTime = DateTime.Now }); + var waitAllocationDoctorList = _taskAllocationRuleRepository.Where(t => t.TrialId == trialId && t.IsEnable) + .Select(t => new AutoAssignResultDTO() { DoctorUserId = t.DoctorUserId, PlanReadingRatio = t.PlanReadingRatio, SubjectCount = subjectCount }) + .ToList(); + + //已分配的 医生的情况 + var haveAssignedSubjectDoctorList = subjectList.Clone().SelectMany(t => t.DoctorUserList.Select(c => new { t.SubjectId, DoctorUserId = c.DoctorUserId, c.ArmEnum })).ToList(); - // if (hasAssignDoctorCount == 0) - // { + 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(); + } + + + //仅仅分配未应用的 + foreach (var subject in subjectList.Where(t => t.IsApplyed == false)) + { + //该Subject 已经分配的医生数量 + var hasAssignDoctorCount = subject.DoctorUserList.Count(); + + //分配两个医生 + 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(); + + + //将分配结果记录 + + + //看阅片人之前在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 = 1; + var doctor2Arm = 2; + + if ((preferredDoctor1Arm == null && preferredDoctor2Arm == null) || + (preferredDoctor1Arm == null && preferredDoctor2Arm == 2) || + (preferredDoctor1Arm == 1 && preferredDoctor2Arm == null) || + (preferredDoctor1Arm == 1 && preferredDoctor2Arm == 2) + ) + { + doctor1Arm = 1; + doctor2Arm = 2; + } + else if ( (preferredDoctor1Arm == null && preferredDoctor2Arm == 1)|| + (preferredDoctor1Arm == 2 && preferredDoctor2Arm == 1)|| + (preferredDoctor1Arm == 2 && preferredDoctor2Arm == null)) + { + doctor1Arm = 2; + doctor2Arm = 1; + } + + else if (preferredDoctor1Arm == 1 && preferredDoctor2Arm == 1) + { + doctor1Arm = 1; + doctor2Arm = 2; + } + else if (preferredDoctor1Arm == 2 && preferredDoctor2Arm == 2) + { + doctor1Arm = 2; + doctor2Arm = 1; + } + + + await _subjectUserRepository.AddAsync(new SubjectUser() { TrialId = trialId, SubjectId = subject.SubjectId, DoctorUserId = allocateDoctorList[0].DoctorUserId, ArmEnum = doctor1Arm, AssignTime = DateTime.Now }); + + await _subjectUserRepository.AddAsync(new SubjectUser() { TrialId = trialId, SubjectId = subject.SubjectId, DoctorUserId = allocateDoctorList[1].DoctorUserId, ArmEnum = doctor2Arm, AssignTime = DateTime.Now }); - // } - // else if (hasAssignDoctorCount == 1) - // { + waitAllocationDoctorList.FirstOrDefault(t => t.DoctorUserId == allocateDoctorList[0].DoctorUserId).SubjectArmList.Add(new SubjectArm() + { + SubjectId = subject.SubjectId, + ArmEnum = doctor1Arm + }); - // } - // else if (hasAssignDoctorCount == 2) - // { + waitAllocationDoctorList.FirstOrDefault(t => t.DoctorUserId == allocateDoctorList[1].DoctorUserId).SubjectArmList.Add(new SubjectArm() + { + SubjectId = subject.SubjectId, + ArmEnum = doctor2Arm + }); - // } - // else - // { - // throw new BusinessValidationFailedException("当前有Subject绑定医生数量大于2"); - // } - // } - // else if (trialConfig.ReadingType == ReadingMethod.Single) - // { - // if (hasAssignDoctorCount == 0) - // { + } + else if (trialConfig.ReadingType == ReadingMethod.Single) + { + if (hasAssignDoctorCount > 1) + { + throw new BusinessValidationFailedException("单重阅片当前有Subject绑定医生数量大于1"); + } - // } - // else if (hasAssignDoctorCount == 1) - // { + var allocateDoctor = waitAllocationDoctorList.OrderByDescending(t => t.Weight).ThenByDescending(t => t.PlanReadingRatio).FirstOrDefault(); - // } - // else - // { - // throw new BusinessValidationFailedException("当前有Subject绑定医生数量大于1"); - // } - // } + waitAllocationDoctorList.FirstOrDefault(t => t.DoctorUserId == allocateDoctor.DoctorUserId).SubjectArmList.Add(new SubjectArm() + { + SubjectId = subject.SubjectId, + ArmEnum = 0 + }); - //} + await _subjectUserRepository.AddAsync(new SubjectUser() { TrialId = trialId, SubjectId = subject.SubjectId, DoctorUserId = allocateDoctor.DoctorUserId, ArmEnum = 0, AssignTime = DateTime.Now }); + + } + + } #endregion - //验证是否所有Subject 是否分配好 - if (assignedSubjectDoctorList.Select(t => t.SubjectId).Distinct().Count() != subjectCount) - { - throw new BusinessValidationFailedException("分配算法有问题,有Subject 未分配"); - } await _subjectUserRepository.SaveChangesAsync(); diff --git a/IRaCIS.Core.Domain.Share/Allocation/AllocationRelation.cs b/IRaCIS.Core.Domain.Share/Allocation/AllocationRelation.cs index 478e2a993..b0bbb4601 100644 --- a/IRaCIS.Core.Domain.Share/Allocation/AllocationRelation.cs +++ b/IRaCIS.Core.Domain.Share/Allocation/AllocationRelation.cs @@ -71,6 +71,7 @@ namespace IRaCIS.Core.Domain.Share } + //阅片状态 public enum ReadingTaskState { WaitReading=0, @@ -80,6 +81,7 @@ namespace IRaCIS.Core.Domain.Share HaveSigned=2 } + // public enum RequestReReadingType { Default = 0, @@ -89,6 +91,8 @@ namespace IRaCIS.Core.Domain.Share TrialGroupApply = 2 } + //重阅申请结果 + public enum RequestReReadingResult { Default = 0,