修改分配算法

Uat_Study
hang 2022-06-16 17:25:43 +08:00
parent 2d3c73ccae
commit 63a9561e49
5 changed files with 316 additions and 213 deletions

View File

@ -51,6 +51,11 @@ namespace IRaCIS.Core.Application.ViewModel
}
public class AllocateInfo
{
public int? TotalTaskCount { get; set; }

View File

@ -282,6 +282,27 @@ namespace IRaCIS.Core.Application.ViewModel
public List<Guid> SubjectIdList { get; set; }
}
public class AutoAssignResultDTO
{
public Guid DoctorUserId { get; set; }
public int PlanReadingRatio { get; set; }
public List<SubjectArm> SubjectArmList { get; set; } = new List<SubjectArm>();
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
{

View File

@ -41,6 +41,7 @@ namespace IRaCIS.Core.Application.Service
var trialTaskConfig= _trialRepository.Where(t=>t.Id==queryTaskAllocationRule.TrialId).ProjectTo<TrialTaskConfig>(_mapper.ConfigurationProvider).FirstOrDefault();
return (await taskAllocationRuleQueryable.ToListAsync(), trialTaskConfig);
}

View File

@ -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();

View File

@ -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,