@@ -85,17 +85,17 @@ namespace IRaCIS.Core.Application.Service
/// </summary>
/// <param name="queryVisitTask"></param>
/// <returns></returns>
[HttpPost]
[HttpPost]
public async Task < PageOutput < JudgeVisitTaskView > /*, object)*/ > GetJudgeVisitTaskList ( VisitTaskQuery queryVisitTask )
{
var visitTaskQueryable = _visitTaskRepository . Where ( t = > t . TrialId = = queryVisitTask . TrialId )
var visitTaskQueryable = _visitTaskRepository . Where ( t = > t . TrialId = = queryVisitTask . TrialId )
. 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 . ReadingCategory = = null , t = > t . ReadingCategory ! = ReadingCategory . Judge )
. WhereIf ( queryVisitTask . ReadingCategory = = null , t = > t . ReadingCategory ! = ReadingCategory . Judge )
. WhereIf ( queryVisitTask . TaskState ! = null , t = > t . TaskState = = queryVisitTask . TaskState )
. 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 ) )
@@ -114,6 +114,41 @@ namespace IRaCIS.Core.Application.Service
}
/// <summary>
/// 获取影像阅片列表 相比而言多了几个字段 和配置信息
/// </summary>
/// <param name="queryVisitTask"></param>
/// <returns></returns>
[HttpPost]
public async Task < ( PageOutput < ReadingTaskView > , object ) > GetReadingTaskList ( VisitTaskQuery queryVisitTask )
{
var visitTaskQueryable = _visitTaskRepository . Where ( t = > t . TrialId = = queryVisitTask . TrialId )
. 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 . ReadingCategory = = null , t = > t . ReadingCategory ! = ReadingCategory . Judge )
. WhereIf ( queryVisitTask . TaskState ! = null , t = > t . TaskState = = queryVisitTask . TaskState )
. 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 ) )
. WhereIf ( queryVisitTask . BeginAllocateDate ! = null , t = > t . AllocateTime > queryVisitTask . BeginAllocateDate )
. WhereIf ( queryVisitTask . EndAllocateDate ! = null , t = > t . AllocateTime < queryVisitTask . EndAllocateDate . Value . AddDays ( 1 ) )
. ProjectTo < ReadingTaskView > ( _mapper . ConfigurationProvider ) ;
var defalutSortArray = new string [ ] { nameof ( VisitTask . IsUrgent ) + " desc" , nameof ( VisitTask . SubjectId ) } ;
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 < TrialTaskConfig > ( _mapper . ConfigurationProvider ) . FirstOrDefault ( ) ;
return ( pageList , trialTaskConfig ) ;
}
/// <summary>
/// 获取手动分配 未分配的Subject列表(IsHaveAssigned 传递false)
/// </summary>
@@ -121,7 +156,7 @@ namespace IRaCIS.Core.Application.Service
[HttpPost]
public async Task < PageOutput < SubjectAssignView > > GetSubjectAssignList ( SubjectAssignQuery querySubjectAssign )
{
var subjectQuery = _subjectRepository . Where ( t = > t . TrialId = = querySubjectAssign . TrialId )
var subjectQuery = _subjectRepository . Where ( t = > t . TrialId = = querySubjectAssign . TrialId )
. 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 , t = > t . SubjectDoctorList . Count ( ) > 0 )
@@ -160,7 +195,7 @@ namespace IRaCIS.Core.Application.Service
var armEnum = assginSubjectDoctorCommand . DoctorUserIdArmList . Where ( t = > t . DoctorUserId = = doctorUserId ) . First ( ) . ArmEnum ;
await _subjectUserRepository . AddAsync ( new SubjectUser ( ) { TrialId = assginSubjectDoctorCommand . TrialId , SubjectId = subjectId , DoctorUserId = doctorUserId , ArmEnum = armEnum , AssignTime = DateTime . Now } ) ;
await _subjectUserRepository . AddAsync ( new SubjectUser ( ) { TrialId = assginSubjectDoctorCommand . TrialId , SubjectId = subjectId , DoctorUserId = doctorUserId , ArmEnum = armEnum , AssignTime = DateTime . Now } ) ;
}
//await _subjectRepository.BatchUpdateNoTrackingAsync(t => t.Id == subjectId, u => new Subject() { IsAssignDoctorUser = true });
@@ -200,13 +235,13 @@ namespace IRaCIS.Core.Application.Service
[UnitOfWork]
public async Task < IResponseOutput > ManualAssignDoctorApplyTask ( AssignConfirmCommand assignConfirmCommand )
{
var trialId = assignConfirmCommand . TrialId ;
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 ( ) ;
@@ -224,7 +259,7 @@ namespace IRaCIS.Core.Application.Service
if ( assignConfirmCommand . SubjectDoctorUserList . Count = = 0 )
{
subjectDoctorIdList = _subjectUserRepository . Where ( t = > t . SubjectId = = subjectId ) . Select ( t = > t . DoctorUserId ) . ToList ( ) ;
}
else
@@ -284,41 +319,41 @@ 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 , DoctorUserIdList = t . SubjectDoctorList . Select ( t = > t . DoctorUserId ) } ) . ToList ( ) ;
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 ( ) ;
//受试者总数
var subjectCount = subjectList . Count ( ) ;
//获取待分配的医生列表 指导分配医生的数量
var waitAllocationDoctorList = _taskAllocationRuleRepository . Where ( t = > t . TrialId = = trialId & & t . IsEnable )
. Select ( t = > new { t . DoctorUserId , t . PlanReadingRatio , Weight = ( double ) ( subjectCount * t . PlanReadingRatio ) % 100 } )
. 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 . DoctorUserIdList . Select ( c = > new { t . SubjectId , DoctorUserId = c } ) ) . ToList ( ) ;
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 ) . ToList ( ) ;
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 ( ) . DoctorUserIdList . Count ( ) ;
var hasAssignDoctorCount = subjectList . Where ( t = > t . SubjectId = = subjectId ) . FirstOrDefault ( ) . DoctorUserList . Count ( ) ;
//分配两个医生
if ( trialConfig . ReadingType = = ReadingMethod . Double )
@@ -343,136 +378,241 @@ namespace IRaCIS.Core.Application.Service
//验证通过 给医生开始分配
//eg : 10个Sujbect 都是1/4 先分配整数 再分配 10%4=2个
//不够分的subject数量 适用于 2个Subject 4个医生 这种
var specialSubjectCount = subjectCount % waitAllocationDoctorList . Count ( ) ;
foreach ( var doctor in waitAllocationDoctorList )
if ( trialConfig . ReadingType = = ReadingMethod . Single )
{
//eg : 10个Sujbect 都是1/4 先分配整数 再分配 10%4=2个
//特殊: 不够分的subject数量 适用于 2个Subject 4个医生 这种
var specialSubjectCount = subjectCount % waitAllocationDoctorList . Count ( ) ;
//该医生的目前已分配到的受试者
var hasAssignedSubjectIdList = assignedSubjectDoctorList . Where ( t = > t . DoctorUserId = = doctor . DoctorUserId ) . Select ( t = > t . SubjectId ) . ToList ( ) ;
//已分配的Subject 数量
var hasAssignedSubjectCount = hasAssignedSubjectIdList . Count ( ) ;
//该医生计划分配到的Subject 最接近的整数数量
var planSubjectCount = ( int ) Math . Ceiling ( ( double ) ( subjectCount * doctor . PlanReadingRatio ) / 100 ) ;
//权重大的,将特殊的分配
if ( doctor . Weight > = 50 )
{
if ( specialSubjectCount > 0 )
{
specialSubjectCount - - ;
planSubjectCount + + ;
}
}
//如果计划的数量 大于已经分配的数量 那么该医生 可以分配新的Subject
if ( planSubjectCount > hasAssignedSubjectCount )
//按照医生维度 分配Subject
foreach ( var doctor in waitAllocationDoctorList )
{
//从未分配的Subjct找到可以分配的分配给该医生
var allAssignedSubjectIdList = assignedSubjectDoctorList . Select ( t = > t . SubjectId ) . ToList ( ) ;
//该医生的目前已分配到的受试者
var hasAssignedSubjectIdList = assignedSubjectDoctorList . Where ( t = > t . DoctorUserId = = doctor . DoctorUserId ) . Select ( t = > t . SubjectId ) . Distinct ( ) . ToList ( ) ;
//取需要分配的数量 并且没有分配给其他医生的包括自己
var assignSubjectIdList = subjectList . Where ( t = > ! allAssignedSubjectIdList . Contains ( t . SubjectId ) ) . Select ( t = > t . SubjectId ) . Take ( planSubjectCount - hasAssignedSubjectCount ) . ToList ( ) ;
//已分配的Subject 数量
var hasAssignedSubjectCount = hasAssignedSubjectIdList . Count ( ) ;
foreach ( var assignSubjectId in assignSubjectIdList )
//该医生计划分配到的Subject 最接近的整数数量
var planSubjectCount = ( int ) Math . Ceiling ( ( double ) ( subjectCount * doctor . PlanReadingRatio ) / 100 ) ;
//权重大的,将特殊的分配
if ( doctor . Weight > = 50 )
{
//将分配结果记录
assignedSubjectDoctorList . Add ( new { SubjectId = assignSubjectId , DoctorUserId = doctor . DoctorUserId } ) ;
await _subjectUserRepository . AddAsync ( new SubjectUser ( ) { TrialId = trialId , SubjectId = assignSubjectId , DoctorUserId = doctor . DoctorUserId , AssignTime = DateTime . Now } ) ;
if ( specialSubjectCount > 0 )
{
specialSubjectCount - - ;
planSubjectCount + + ;
}
}
//如果计划的数量 大于已经分配的数量 那么该医生 可以分配新的Subject
if ( planSubjectCount > hasAssignedSubjectCount )
{
//从未分配的Subjct找到可以分配的分配给该医生
var allAssignedSubjectIdList = assignedSubjectDoctorList . Select ( t = > t . SubjectId ) . Distinct ( ) . ToList ( ) ;
//取需要分配的数量 并且没有分配给其他医生的包括自己
var assignSubjectIdList = subjectList . Where ( t = > ! allAssignedSubjectIdList . Contains ( t . SubjectId ) ) . Select ( t = > t . SubjectId ) . Take ( planSubjectCount - hasAssignedSubjectCount ) . ToList ( ) ;
foreach ( var assignSubjectId in assignSubjectIdList )
{
//将分配结果记录
assignedSubjectDoctorList . Add ( new { SubjectId = assignSubjectId , DoctorUserId = doctor . DoctorUserId , ArmEnum = 0 } ) ;
await _subjectUserRepository . AddAsync ( new SubjectUser ( ) { TrialId = trialId , SubjectId = assignSubjectId , DoctorUserId = doctor . DoctorUserId , AssignTime = DateTime . Now } ) ;
}
}
else
{
throw new BusinessValidationFailedException ( "当前有医生已分配的Subject 数量,超过了计划分配Subject数量,不支持自动分配" ) ;
}
}
}
if ( trialConfig . ReadingType = = ReadingMethod . Double )
{
var specialSubjectCount = subjectCount % waitAllocationDoctorList . Count ( ) ;
//按照医生维度 分配Subject
foreach ( var doctor in waitAllocationDoctorList )
{
//该医生的目前已分配到的受试者
var hasAssignedSubjectIdList = assignedSubjectDoctorList . Where ( t = > t . DoctorUserId = = doctor . DoctorUserId ) . Select ( t = > t . SubjectId ) . ToList ( ) ;
//已分配的Subject 数量
var hasAssignedSubjectCount = hasAssignedSubjectIdList . Count ( ) ;
//该医生计划分配到的Subject 最接近的整数数量
var planSubjectCount = ( int ) Math . Floor ( ( double ) ( subjectCount * doctor . PlanReadingRatio * 2 ) / 100 ) ;
//权重大的,将特殊的分配
if ( doctor . Weight > = 50 )
{
if ( specialSubjectCount > 0 )
{
specialSubjectCount - - ;
planSubjectCount + + ;
}
else
{
planSubjectCount + + ;
}
}
//如果计划的数量 大于已经分配的数量 那么该医生 可以分配新的Subject
if ( planSubjectCount > hasAssignedSubjectCount )
{
//分配给其他医生 已经满了的
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 assignSubjectIdList = subjectList . Where ( t = > ! hasAssignedSubjectIdList . Contains ( t . SubjectId ) & & ! otherExceptDoctorIdList . Contains ( t . SubjectId ) )
. Select ( t = > t . SubjectId ) . Take ( ( planSubjectCount - hasAssignedSubjectCount ) * 2 ) . ToList ( ) ;
foreach ( var assignSubjectId in assignSubjectIdList )
{
var otherHaveAssignedSubject = assignedSubjectDoctorList . Where ( t = > t . SubjectId = = assignSubjectId ) . FirstOrDefault ( ) ;
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 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 } ) ;
}
}
}
else
{
throw new BusinessValidationFailedException ( "当前有医生已分配的Subject 数量,超过了计划分配Subject数量,不支持自动分配" ) ;
}
}
//如果是2个Subject 3个医生 这种 都是百分之33的比率
// 10 3
#region 完 全 按 照 Subject 遍 历 去 分
//foreach (var subject in subjectList)
//{
// //该Subject 已经分配的医生数量
// var hasAssignDoctorCount = subject.DoctorUserIdList.Count();
// //分配两个医生
// if (trialConfig.ReadingType == ReadingMethod.Double)
// {
// //await _subjectUserRepository.AddAsync(new SubjectUser() { TrialId = trialId, SubjectId = subject.SubjectId, DoctorUserId = doctorUserId, AssignTime = DateTime.Now });
// if (hasAssignDoctorCount == 0)
// {
// }
// else if (hasAssignDoctorCount == 1)
// {
// }
// else if (hasAssignDoctorCount == 2)
// {
// }
// else
// {
// throw new BusinessValidationFailedException("当前有Subject绑定医生数量大于2");
// }
// }
// else if (trialConfig.ReadingType == ReadingMethod.Single)
// {
// if (hasAssignDoctorCount == 0)
// {
// }
// else if (hasAssignDoctorCount == 1)
// {
// }
// else
// {
// throw new BusinessValidationFailedException("当前有Subject绑定医生数量大于1");
// }
// }
//}
#endregion
}
//验证是否所有Subject 是否分配好
if ( assignedSubjectDoctorList . Select ( t = > t . SubjectId ) . Count ( ) ! = subjectCount )
if ( assignedSubjectDoctorList . Select ( t = > t . SubjectId ) . Distinct ( ) . Count ( ) ! = subjectCount )
{
throw new BusinessValidationFailedException ( "分配算法有问题,有Subject 未分配" ) ;
}
await _subjectUserRepository . SaveChangesAsync ( ) ;
//如果是2个Subject 3个医生 这种 都是百分之33的比率
// 10 3
#region 按 照 Subject 遍 历 去 分
//foreach (var subject in subjectList)
//{
// //该Subject 已经分配的医生数量
// var hasAssignDoctorCount = subject.DoctorUserIdList.Count();
// //分配两个医生
// if (trialConfig.ReadingType == ReadingMethod.Double)
// {
// //await _subjectUserRepository.AddAsync(new SubjectUser() { TrialId = trialId, SubjectId = subject.SubjectId, DoctorUserId = doctorUserId, AssignTime = DateTime.Now });
// if (hasAssignDoctorCount == 0)
// {
// }
// else if (hasAssignDoctorCount == 1)
// {
// }
// else if (hasAssignDoctorCount == 2)
// {
// }
// else
// {
// throw new BusinessValidationFailedException("当前有Subject绑定医生数量大于2");
// }
// }
// else if (trialConfig.ReadingType == ReadingMethod.Single)
// {
// if (hasAssignDoctorCount == 0)
// {
// }
// else if (hasAssignDoctorCount == 1)
// {
// }
// else
// {
// throw new BusinessValidationFailedException("当前有Subject绑定医生数量大于1");
// }
// }
//}
#endregion
return ResponseOutput . Ok ( ) ;
}
/// <summary>
/// 任务 手动分配 重新分配 确认 取消分配
/// </summary>分配