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