PM阅片跟踪列表
parent
09fc253d67
commit
2d8f739f12
|
@ -72,6 +72,13 @@
|
||||||
<param name="queryVisitTask"></param>
|
<param name="queryVisitTask"></param>
|
||||||
<returns></returns>
|
<returns></returns>
|
||||||
</member>
|
</member>
|
||||||
|
<member name="M:IRaCIS.Core.Application.Service.VisitTaskService.GetReadingTaskList(IRaCIS.Core.Application.ViewModel.VisitTaskQuery)">
|
||||||
|
<summary>
|
||||||
|
获取影像阅片列表 相比而言多了几个字段 和配置信息
|
||||||
|
</summary>
|
||||||
|
<param name="queryVisitTask"></param>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
<member name="M:IRaCIS.Core.Application.Service.VisitTaskService.GetSubjectAssignList(IRaCIS.Core.Application.ViewModel.SubjectAssignQuery)">
|
<member name="M:IRaCIS.Core.Application.Service.VisitTaskService.GetSubjectAssignList(IRaCIS.Core.Application.ViewModel.SubjectAssignQuery)">
|
||||||
<summary>
|
<summary>
|
||||||
获取手动分配 未分配的Subject列表(IsHaveAssigned 传递false)
|
获取手动分配 未分配的Subject列表(IsHaveAssigned 传递false)
|
||||||
|
@ -3257,6 +3264,13 @@
|
||||||
<param name="trialConfig"></param>
|
<param name="trialConfig"></param>
|
||||||
<returns></returns>
|
<returns></returns>
|
||||||
</member>
|
</member>
|
||||||
|
<member name="M:IRaCIS.Core.Application.TrialConfigService.ConfigTrialReadingTaskViewRule(IRaCIS.Core.Application.Contracts.TrialReadingTaskViewConfig)">
|
||||||
|
<summary>
|
||||||
|
配置项目赌片规则信息
|
||||||
|
</summary>
|
||||||
|
<param name="trialConfig"></param>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
<member name="T:IRaCIS.Core.Application.Triggers.AddVisitPlanTrigger">
|
<member name="T:IRaCIS.Core.Application.Triggers.AddVisitPlanTrigger">
|
||||||
<summary>
|
<summary>
|
||||||
添加访视计划 要给改项目下的所有Subject 添加该访视
|
添加访视计划 要给改项目下的所有Subject 添加该访视
|
||||||
|
|
|
@ -64,6 +64,21 @@ namespace IRaCIS.Core.Application.ViewModel
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public class ReadingTaskView: VisitTaskView
|
||||||
|
{
|
||||||
|
|
||||||
|
//建议完成时间
|
||||||
|
public int SuggesteDays { get; set; }
|
||||||
|
|
||||||
|
public ReadingTaskState ReadingTaskState { get; set; }
|
||||||
|
|
||||||
|
public DateTime? SignTime { get; set; }
|
||||||
|
|
||||||
|
//是否回退过
|
||||||
|
public bool IsReturned { get; set; }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public class HistoryReadingDoctorUser
|
public class HistoryReadingDoctorUser
|
||||||
{
|
{
|
||||||
|
|
|
@ -89,13 +89,13 @@ namespace IRaCIS.Core.Application.Service
|
||||||
public async Task<PageOutput<JudgeVisitTaskView>/*, object)*/> GetJudgeVisitTaskList(VisitTaskQuery queryVisitTask)
|
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.SiteId != null, t => t.Subject.SiteId == queryVisitTask.SiteId)
|
||||||
.WhereIf(queryVisitTask.SubjectId != null, t => t.SubjectId == queryVisitTask.SubjectId)
|
.WhereIf(queryVisitTask.SubjectId != null, t => t.SubjectId == queryVisitTask.SubjectId)
|
||||||
.WhereIf(queryVisitTask.IsUrgent != null, t => t.IsUrgent == queryVisitTask.IsUrgent)
|
.WhereIf(queryVisitTask.IsUrgent != null, t => t.IsUrgent == queryVisitTask.IsUrgent)
|
||||||
.WhereIf(queryVisitTask.DoctorUserId != null, t => t.DoctorUserId == queryVisitTask.DoctorUserId)
|
.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 == 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(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.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(!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>
|
/// <summary>
|
||||||
/// 获取手动分配 未分配的Subject列表(IsHaveAssigned 传递false)
|
/// 获取手动分配 未分配的Subject列表(IsHaveAssigned 传递false)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -121,7 +156,7 @@ namespace IRaCIS.Core.Application.Service
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
public async Task<PageOutput<SubjectAssignView>> GetSubjectAssignList(SubjectAssignQuery querySubjectAssign)
|
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.SiteId != null, t => t.SiteId == querySubjectAssign.SiteId)
|
||||||
.WhereIf(querySubjectAssign.SubjectId != null, t => t.Id == querySubjectAssign.SubjectId)
|
.WhereIf(querySubjectAssign.SubjectId != null, t => t.Id == querySubjectAssign.SubjectId)
|
||||||
.WhereIf(querySubjectAssign.IsHaveAssigned != null && querySubjectAssign.IsHaveAssigned == true, t => t.SubjectDoctorList.Count() > 0)
|
.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;
|
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 });
|
//await _subjectRepository.BatchUpdateNoTrackingAsync(t => t.Id == subjectId, u => new Subject() { IsAssignDoctorUser = true });
|
||||||
|
|
||||||
|
@ -200,7 +235,7 @@ namespace IRaCIS.Core.Application.Service
|
||||||
[UnitOfWork]
|
[UnitOfWork]
|
||||||
public async Task<IResponseOutput> ManualAssignDoctorApplyTask(AssignConfirmCommand assignConfirmCommand)
|
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();
|
//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();
|
||||||
|
@ -284,41 +319,41 @@ namespace IRaCIS.Core.Application.Service
|
||||||
{
|
{
|
||||||
//自动分配的话,需要把手动分配的给删掉
|
//自动分配的话,需要把手动分配的给删掉
|
||||||
|
|
||||||
|
throw new BusinessValidationFailedException("自动分配算法正在开发,还未完成");
|
||||||
|
|
||||||
var trialId = autoSubjectAssignCommand.TrialId;
|
var trialId = autoSubjectAssignCommand.TrialId;
|
||||||
|
|
||||||
|
|
||||||
//获取所有的Subject 目前的分配情况
|
//获取所有的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 subjectCount = subjectList.Count();
|
||||||
|
|
||||||
//获取待分配的医生列表 指导分配医生的数量
|
//获取待分配的医生列表 指导分配医生的数量
|
||||||
var waitAllocationDoctorList = _taskAllocationRuleRepository.Where(t => t.TrialId == trialId && t.IsEnable)
|
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();
|
.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();
|
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 医生的情况
|
//存放分配后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 前验证 已经分配的数据是否符合分配的规范
|
//给医生分配Subject 前验证 已经分配的数据是否符合分配的规范
|
||||||
foreach (var doctor in waitAllocationDoctorList)
|
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 是否 符合项目配置规范
|
//验证已经分配的Subject 是否 符合项目配置规范
|
||||||
|
|
||||||
foreach (var subjectId in hasAssignedSubjectIdList)
|
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)
|
if (trialConfig.ReadingType == ReadingMethod.Double)
|
||||||
|
@ -343,17 +378,21 @@ namespace IRaCIS.Core.Application.Service
|
||||||
|
|
||||||
//验证通过 给医生开始分配
|
//验证通过 给医生开始分配
|
||||||
|
|
||||||
|
|
||||||
|
if (trialConfig.ReadingType == ReadingMethod.Single)
|
||||||
|
{
|
||||||
//eg : 10个Sujbect 都是1/4 先分配整数 再分配 10%4=2个
|
//eg : 10个Sujbect 都是1/4 先分配整数 再分配 10%4=2个
|
||||||
|
|
||||||
//不够分的subject数量 适用于 2个Subject 4个医生 这种
|
//特殊: 不够分的subject数量 适用于 2个Subject 4个医生 这种
|
||||||
var specialSubjectCount = subjectCount % waitAllocationDoctorList.Count();
|
var specialSubjectCount = subjectCount % waitAllocationDoctorList.Count();
|
||||||
|
|
||||||
|
//按照医生维度 分配Subject
|
||||||
foreach (var doctor in waitAllocationDoctorList)
|
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 数量
|
//已分配的Subject 数量
|
||||||
var hasAssignedSubjectCount = hasAssignedSubjectIdList.Count();
|
var hasAssignedSubjectCount = hasAssignedSubjectIdList.Count();
|
||||||
|
@ -379,7 +418,7 @@ namespace IRaCIS.Core.Application.Service
|
||||||
|
|
||||||
//从未分配的Subjct找到可以分配的分配给该医生
|
//从未分配的Subjct找到可以分配的分配给该医生
|
||||||
|
|
||||||
var allAssignedSubjectIdList = assignedSubjectDoctorList.Select(t => t.SubjectId).ToList();
|
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();
|
var assignSubjectIdList = subjectList.Where(t => !allAssignedSubjectIdList.Contains(t.SubjectId)).Select(t => t.SubjectId).Take(planSubjectCount - hasAssignedSubjectCount).ToList();
|
||||||
|
@ -387,25 +426,115 @@ namespace IRaCIS.Core.Application.Service
|
||||||
foreach (var assignSubjectId in assignSubjectIdList)
|
foreach (var assignSubjectId in assignSubjectIdList)
|
||||||
{
|
{
|
||||||
//将分配结果记录
|
//将分配结果记录
|
||||||
assignedSubjectDoctorList.Add(new { SubjectId = assignSubjectId, DoctorUserId = doctor.DoctorUserId });
|
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 });
|
await _subjectUserRepository.AddAsync(new SubjectUser() { TrialId = trialId, SubjectId = assignSubjectId, DoctorUserId = doctor.DoctorUserId, AssignTime = DateTime.Now });
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
}
|
|
||||||
|
|
||||||
//验证是否所有Subject 是否分配好
|
|
||||||
|
|
||||||
if (assignedSubjectDoctorList.Select(t => t.SubjectId).Count() != subjectCount)
|
|
||||||
{
|
{
|
||||||
throw new BusinessValidationFailedException("分配算法有问题,有Subject 未分配");
|
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数量,不支持自动分配");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
await _subjectUserRepository.SaveChangesAsync();
|
|
||||||
|
|
||||||
//如果是2个Subject 3个医生 这种 都是百分之33的比率
|
//如果是2个Subject 3个医生 这种 都是百分之33的比率
|
||||||
// 10 3
|
// 10 3
|
||||||
|
@ -414,7 +543,7 @@ namespace IRaCIS.Core.Application.Service
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#region 按照Subject 遍历去分
|
#region 完全按照Subject 遍历去分
|
||||||
|
|
||||||
//foreach (var subject in subjectList)
|
//foreach (var subject in subjectList)
|
||||||
//{
|
//{
|
||||||
|
@ -469,10 +598,21 @@ namespace IRaCIS.Core.Application.Service
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
return ResponseOutput.Ok();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//验证是否所有Subject 是否分配好
|
||||||
|
|
||||||
|
if (assignedSubjectDoctorList.Select(t => t.SubjectId).Distinct().Count() != subjectCount)
|
||||||
|
{
|
||||||
|
throw new BusinessValidationFailedException("分配算法有问题,有Subject 未分配");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
await _subjectUserRepository.SaveChangesAsync();
|
||||||
|
return ResponseOutput.Ok();
|
||||||
|
|
||||||
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 任务 手动分配 重新分配 确认 取消分配
|
/// 任务 手动分配 重新分配 确认 取消分配
|
||||||
/// </summary>分配
|
/// </summary>分配
|
||||||
|
|
|
@ -40,6 +40,9 @@ namespace IRaCIS.Core.Application.Service
|
||||||
.ForMember(o => o.FullName, t => t.MapFrom(u => u.DoctorUser.FullName))
|
.ForMember(o => o.FullName, t => t.MapFrom(u => u.DoctorUser.FullName))
|
||||||
.ForMember(o => o.UserTypeShortName, t => t.MapFrom(u => u.DoctorUser.UserTypeRole.UserTypeShortName));
|
.ForMember(o => o.UserTypeShortName, t => t.MapFrom(u => u.DoctorUser.UserTypeRole.UserTypeShortName));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
CreateMap<VisitTask, JudgeVisitTaskView>()
|
CreateMap<VisitTask, JudgeVisitTaskView>()
|
||||||
.ForMember(o => o.SiteId, t => t.MapFrom(u => u.Subject.SiteId))
|
.ForMember(o => o.SiteId, t => t.MapFrom(u => u.Subject.SiteId))
|
||||||
.ForMember(o => o.TrialSiteCode, t => t.MapFrom(u => u.Subject.TrialSite.TrialSiteCode))
|
.ForMember(o => o.TrialSiteCode, t => t.MapFrom(u => u.Subject.TrialSite.TrialSiteCode))
|
||||||
|
@ -51,6 +54,18 @@ namespace IRaCIS.Core.Application.Service
|
||||||
|
|
||||||
.ForMember(o => o.HistoryReadingDoctorUserList, t => t.MapFrom(u => u.JudgeVisitList));
|
.ForMember(o => o.HistoryReadingDoctorUserList, t => t.MapFrom(u => u.JudgeVisitList));
|
||||||
|
|
||||||
|
CreateMap<VisitTask, ReadingTaskView>()
|
||||||
|
.ForMember(o => o.SiteId, t => t.MapFrom(u => u.Subject.SiteId))
|
||||||
|
.ForMember(o => o.TrialSiteCode, t => t.MapFrom(u => u.Subject.TrialSite.TrialSiteCode))
|
||||||
|
.ForMember(o => o.SubjectCode, t => t.MapFrom(u => u.Subject.Code))
|
||||||
|
.ForMember(o => o.UserCode, t => t.MapFrom(u => u.DoctorUser.UserCode))
|
||||||
|
.ForMember(o => o.UserName, t => t.MapFrom(u => u.DoctorUser.UserName))
|
||||||
|
.ForMember(o => o.FullName, t => t.MapFrom(u => u.DoctorUser.FullName))
|
||||||
|
.ForMember(o => o.UserTypeShortName, t => t.MapFrom(u => u.DoctorUser.UserTypeRole.UserTypeShortName));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
CreateMap<VisitTask, HistoryReadingDoctorUser>()
|
CreateMap<VisitTask, HistoryReadingDoctorUser>()
|
||||||
.ForMember(o => o.UserCode, t => t.MapFrom(u => u.DoctorUser.UserCode))
|
.ForMember(o => o.UserCode, t => t.MapFrom(u => u.DoctorUser.UserCode))
|
||||||
.ForMember(o => o.UserName, t => t.MapFrom(u => u.DoctorUser.UserName))
|
.ForMember(o => o.UserName, t => t.MapFrom(u => u.DoctorUser.UserName))
|
||||||
|
|
|
@ -142,6 +142,15 @@ namespace IRaCIS.Core.Application.Contracts
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class TrialReadingTaskViewConfig
|
||||||
|
{
|
||||||
|
public Guid TrialId { get; set; }
|
||||||
|
|
||||||
|
public ReadingTaskViewMethod ReadingTaskViewEnum { get; set; }
|
||||||
|
|
||||||
|
public bool IsReadingTaskViewInOrder { get; set; } = true;
|
||||||
|
}
|
||||||
|
|
||||||
public class TrialUrgentConfig
|
public class TrialUrgentConfig
|
||||||
{
|
{
|
||||||
public Guid TrialId { get; set; }
|
public Guid TrialId { get; set; }
|
||||||
|
|
|
@ -393,5 +393,23 @@ namespace IRaCIS.Core.Application
|
||||||
return ResponseOutput.Ok(await _trialRepository.SaveChangesAsync());
|
return ResponseOutput.Ok(await _trialRepository.SaveChangesAsync());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 配置项目赌片规则信息
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="trialConfig"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpPut]
|
||||||
|
public async Task<IResponseOutput> ConfigTrialReadingTaskViewRule(TrialReadingTaskViewConfig trialConfig)
|
||||||
|
{
|
||||||
|
var trialInfo = (await _trialRepository.FirstOrDefaultAsync(t => t.Id == trialConfig.TrialId)).IfNullThrowException();
|
||||||
|
|
||||||
|
_mapper.Map(trialConfig, trialInfo);
|
||||||
|
|
||||||
|
return ResponseOutput.Ok(await _trialRepository.SaveChangesAsync());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,9 @@ namespace IRaCIS.Core.Application.Service
|
||||||
|
|
||||||
CreateMap<TrialTaskConfig, Trial>().ForMember(d => d.Id, u => u.MapFrom(s => s.TrialId)).ReverseMap();
|
CreateMap<TrialTaskConfig, Trial>().ForMember(d => d.Id, u => u.MapFrom(s => s.TrialId)).ReverseMap();
|
||||||
|
|
||||||
|
CreateMap<TrialReadingTaskViewConfig, Trial>().ForMember(d => d.Id, u => u.MapFrom(s => s.TrialId)).ReverseMap();
|
||||||
|
|
||||||
|
|
||||||
CreateMap<UserTrialCommand, TrialUser>();
|
CreateMap<UserTrialCommand, TrialUser>();
|
||||||
|
|
||||||
CreateMap<TrialSiteCommand, TrialSite>()
|
CreateMap<TrialSiteCommand, TrialSite>()
|
||||||
|
|
|
@ -61,4 +61,26 @@ namespace IRaCIS.Core.Domain.Share
|
||||||
Special=3
|
Special=3
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public enum ReadingTaskViewMethod
|
||||||
|
{
|
||||||
|
//受试者
|
||||||
|
Subject = 0,
|
||||||
|
|
||||||
|
//访视/阅片期
|
||||||
|
ReadingPeriodOrVisit = 2,
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum ReadingTaskState
|
||||||
|
{
|
||||||
|
WaitReading=0,
|
||||||
|
|
||||||
|
Reading=1,
|
||||||
|
|
||||||
|
HaveSigned=2
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -132,7 +132,7 @@ namespace IRaCIS.Core.Domain.Models
|
||||||
//建议完成时间
|
//建议完成时间
|
||||||
public int SuggesteDays { get; set; }
|
public int SuggesteDays { get; set; }
|
||||||
|
|
||||||
public int ReadingTaskState { get; set; }
|
public ReadingTaskState ReadingTaskState { get; set; }
|
||||||
|
|
||||||
public DateTime? SignTime { get; set; }
|
public DateTime? SignTime { get; set; }
|
||||||
|
|
||||||
|
|
|
@ -327,6 +327,11 @@ namespace IRaCIS.Core.Domain.Models
|
||||||
public TaskAllocateDefaultState FollowGlobalVisitAutoAssignDefaultState { get; set; }
|
public TaskAllocateDefaultState FollowGlobalVisitAutoAssignDefaultState { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
public ReadingTaskViewMethod ReadingTaskViewEnum { get; set; }
|
||||||
|
|
||||||
|
public bool IsReadingTaskViewInOrder { get; set; } = true;
|
||||||
|
|
||||||
|
|
||||||
//public Guid? ReviewTypeId { get; set; } = Guid.Empty;
|
//public Guid? ReviewTypeId { get; set; } = Guid.Empty;
|
||||||
|
|
||||||
//[ForeignKey("ReviewTypeId")]
|
//[ForeignKey("ReviewTypeId")]
|
||||||
|
|
Loading…
Reference in New Issue