irc-netcore-api/IRaCIS.Core.Application/Service/Allocation/VisitTaskService.cs

932 lines
48 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

//--------------------------------------------------------------------
// 此代码由T4模板自动生成 byzhouhang 20210918
// 生成时间 2022-06-07 14:10:49
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
//--------------------------------------------------------------------
using IRaCIS.Core.Domain.Models;
using Microsoft.AspNetCore.Mvc;
using IRaCIS.Core.Application.Interfaces;
using IRaCIS.Core.Application.ViewModel;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Infrastructure;
using IRaCIS.Core.Application.Contracts;
namespace IRaCIS.Core.Application.Service
{
/// <summary>
/// 访视读片任务
/// </summary>
[ApiExplorerSettings(GroupName = "Trial")]
public class VisitTaskService : BaseService
{
private readonly IRepository<VisitTask> _visitTaskRepository;
private readonly IRepository<Trial> _trialRepository;
private readonly IRepository<SubjectVisit> _subjectVisitRepository;
private readonly IRepository<TaskAllocationRule> _taskAllocationRuleRepository;
private readonly IRepository<Subject> _subjectRepository;
private readonly IRepository<SubjectUser> _subjectUserRepository;
private readonly IRepository<ReadModule> _readModuleRepository;
public VisitTaskService(IRepository<VisitTask> visitTaskRepository, IRepository<Trial> trialRepository, IRepository<SubjectVisit> subjectVisitRepository,
IRepository<Subject> subjectRepository, IRepository<SubjectUser> subjectUserRepository, IRepository<TaskAllocationRule> taskAllocationRuleRepository, IRepository<ReadModule> readModuleRepository
)
{
_taskAllocationRuleRepository = taskAllocationRuleRepository;
_visitTaskRepository = visitTaskRepository;
_trialRepository = trialRepository;
_subjectVisitRepository = subjectVisitRepository;
_subjectRepository = subjectRepository;
_subjectUserRepository = subjectUserRepository;
_readModuleRepository = readModuleRepository;
}
/// <summary>
/// 获取随访 阅片期 全局 任务列表
/// </summary>
/// <param name="queryVisitTask"></param>
/// <param name="_visitTaskCommonService"></param>
/// <returns></returns>
[HttpPost]
public async Task<(PageOutput<VisitTaskView>, object)> GetVisitTaskList(VisitTaskQuery queryVisitTask, [FromServices] IVisitTaskHelpeService _visitTaskCommonService)
{
//以前访视未产生任务的,在查询这里要产生
var svIdList = await _subjectVisitRepository.Where(t => t.TrialId == queryVisitTask.TrialId && t.CheckState == CheckStateEnum.CVPassed && t.IsVisitTaskGenerated == false).Select(t => t.Id).ToListAsync();
await _visitTaskCommonService.GenerateVisitTaskAsync(queryVisitTask.TrialId, svIdList);
var visitTaskQueryable = _visitTaskRepository.Where(t => t.TrialId == queryVisitTask.TrialId)
.WhereIf(queryVisitTask.ReadingCategory != null, t => t.ReadingCategory == queryVisitTask.ReadingCategory)
.WhereIf(queryVisitTask.ReadingCategory == null, t => t.ReadingCategory != ReadingCategory.Judge)
.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.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<VisitTaskView>(_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<TrialTaskConfigView>(_mapper.ConfigurationProvider).FirstOrDefault();
return (pageList, trialTaskConfig);
}
/// <summary>
/// 获取裁判访视任务列表
/// </summary>
/// <param name="queryVisitTask"></param>
/// <returns></returns>
[HttpPost]
public async Task<PageOutput<JudgeVisitTaskView>/*, object)*/> GetJudgeVisitTaskList(VisitTaskQuery queryVisitTask)
{
var visitTaskQueryable = _visitTaskRepository.Where(t => t.TrialId == queryVisitTask.TrialId)
.Where(t => t.ReadingCategory == ReadingCategory.Judge)
.WhereIf(queryVisitTask.ReadingCategory != null, t => t.ReadingCategory == queryVisitTask.ReadingCategory)
.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.TaskState != null, t => t.TaskState == queryVisitTask.TaskState)
.WhereIf(queryVisitTask.ReadingTaskState != null, t => t.ReadingTaskState == queryVisitTask.ReadingTaskState)
.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<JudgeVisitTaskView>(_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);
return pageList;
//var trialTaskConfig = _trialRepository.Where(t => t.Id == queryVisitTask.TrialId).ProjectTo<TrialTaskConfig>(_mapper.ConfigurationProvider).FirstOrDefault();
//return (pageList, trialTaskConfig);
}
/// <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)
.Where(t => t.OriginalReReadingId == null && t.DoctorUserId != null)
.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.ReadingTaskState != null, t => t.ReadingTaskState == queryVisitTask.ReadingTaskState)
.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>
/// <param name="queryVisitTask"></param>
/// <returns></returns>
[HttpPost]
public async Task<PageOutput<ReReadingTaskView>> GetReReadingTaskList(VisitTaskQuery queryVisitTask)
{
var visitTaskQueryable = _visitTaskRepository.Where(t => t.TrialId == queryVisitTask.TrialId)
.WhereIf(queryVisitTask.OriginalReReadingId != null, t => t.OriginalReReadingId == queryVisitTask.OriginalReReadingId)
.WhereIf(queryVisitTask.OriginalReReadingId == null, t => t.OriginalReReadingId != null)
.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.ReadingTaskState != null, t => t.ReadingTaskState == queryVisitTask.ReadingTaskState)
.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<ReReadingTaskView>(_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);
return pageList;
}
/// <summary>
/// IR 待阅片任务列表Subject 维度统计)
/// </summary>
/// <returns></returns>
[HttpPost]
public async Task<PageOutput<IRUnReadSubjectView>> GetIRUnReadSubjectTaskList(IRUnReadSubjectQuery iRUnReadSubjectQuery)
{
var trialId = iRUnReadSubjectQuery.TrialId;
#region 按照任务的维度统计分组
//var query = _visitTaskRepository.Where(t => t.TrialId == trialId)
// .Where(t => t.DoctorUserId == _userInfo.Id && t.ReadingTaskState != ReadingTaskState.HaveSigned)
// .GroupBy(t => new { t.SubjectId, t.Subject.Code })
// .Select(g => new IRUnReadSubjectView()
// {
// SubjectCode = g.Key.Code,
// SubjectId = g.Key.SubjectId,
// UnReadTaskCount = g.Count(),
// UnReadTaskList = g.AsQueryable().Select(c => new IRUnreadTaskView() { Id = c.Id, SuggesteFinishedTime = c.SuggesteFinishedTime, IsUrgent = c.IsUrgent }).ToList()
// });
//return query.ToList();
#endregion
#region 按照Subject 维度
var subjectQuery = _subjectRepository.Where(t => t.TrialId == trialId)
.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);
return await subjectQuery.ToPagedListAsync(iRUnReadSubjectQuery.PageIndex, iRUnReadSubjectQuery.PageSize, String.IsNullOrEmpty(iRUnReadSubjectQuery.SortField) ? nameof(IRUnReadSubjectView.SubjectId) : iRUnReadSubjectQuery.SortField, iRUnReadSubjectQuery.Asc);
#endregion
}
/// <summary>
/// IR 已阅片任务
/// </summary>
/// <param name="queryVisitTask"></param>
/// <returns></returns>
[HttpPost]
public async Task<PageOutput<IRHaveReadView>> GetIRHaveReadTaskList(VisitTaskQuery queryVisitTask)
{
var visitTaskQueryable = _visitTaskRepository.Where(t => t.TrialId == queryVisitTask.TrialId)
.Where(t => t.DoctorUserId == _userInfo.Id && t.ReadingTaskState == ReadingTaskState.HaveSigned)//该医生 已经签名的数据
.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.ReadingCategory != null, t => t.ReadingCategory == queryVisitTask.ReadingCategory)
.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<IRHaveReadView>(_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);
return pageList;
}
/// <summary>
/// 获取IR 重阅影像阅片列表
/// </summary>
/// <param name="queryVisitTask"></param>
/// <returns></returns>
[HttpPost]
public async Task<PageOutput<ReReadingTaskView>> GetIRReReadingTaskList(VisitTaskQuery queryVisitTask)
{
var visitTaskQueryable = _visitTaskRepository.Where(t => t.TrialId == queryVisitTask.TrialId)
.Where(t => t.DoctorUserId == _userInfo.Id)
.WhereIf(queryVisitTask.OriginalReReadingId != null, t => t.OriginalReReadingId == queryVisitTask.OriginalReReadingId)
.WhereIf(queryVisitTask.OriginalReReadingId == null, t => t.OriginalReReadingId != null)
.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.ReadingTaskState != null, t => t.ReadingTaskState == queryVisitTask.ReadingTaskState)
.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<ReReadingTaskView>(_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);
return pageList;
}
/// <summary>
/// 获取手动分配 未分配的Subject列表(IsHaveAssigned 传递false)
/// </summary>
/// <returns></returns>
[HttpPost]
public async Task<PageOutput<SubjectAssignView>> GetSubjectAssignList(SubjectAssignQuery querySubjectAssign)
{
var subjectQuery = _subjectRepository.Where(t => t.TrialId == querySubjectAssign.TrialId)
.Where(t => t.SubjectVisitTaskList.Any())
.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)
.WhereIf(querySubjectAssign.IsHaveAssigned != null && querySubjectAssign.IsHaveAssigned == false, t => !t.SubjectDoctorList.Any())
.WhereIf(querySubjectAssign.IsHaveApplyedTask != null && querySubjectAssign.IsHaveApplyedTask == true, t => t.SubjectDoctorList.SelectMany(t => t.Subject.SubjectVisitTaskList).All(u => u.DoctorUserId != null))
.WhereIf(querySubjectAssign.IsHaveApplyedTask != null && querySubjectAssign.IsHaveApplyedTask == false, t => t.SubjectDoctorList.SelectMany(t => t.Subject.SubjectVisitTaskList).Any(u => u.DoctorUserId == null))
.WhereIf(querySubjectAssign.DoctorUserId != null, t => t.SubjectDoctorList.Any(t => t.DoctorUserId == querySubjectAssign.DoctorUserId))
.ProjectTo<SubjectAssignView>(_mapper.ConfigurationProvider);
var pageList = await subjectQuery.ToPagedListAsync(querySubjectAssign.PageIndex, querySubjectAssign.PageSize, string.IsNullOrWhiteSpace(querySubjectAssign.SortField) ? nameof(querySubjectAssign.SubjectId) : querySubjectAssign.SortField, querySubjectAssign.Asc);
return pageList;
}
/// <summary>
/// 批量为 多个Subject 分配医生 手动分配 IsReAssign 为true 批量删除 重新分配
/// </summary>
/// <param name="assginSubjectDoctorCommand"></param>
/// <returns></returns>
[HttpPost]
public async Task<IResponseOutput> AssignSubjectDoctor(AssginSubjectDoctorCommand assginSubjectDoctorCommand)
{
var doctorUserIdList = assginSubjectDoctorCommand.DoctorUserIdArmList.Select(t => t.DoctorUserId).ToList();
if (assginSubjectDoctorCommand.IsReAssign)
{
if (await _visitTaskRepository.AnyAsync(t => assginSubjectDoctorCommand.SubjectIdList.Contains(t.SubjectId) && t.DoctorUserId != null))
{
throw new BusinessValidationFailedException("有Subject任务已应用不允许重新分配");
}
await _subjectUserRepository.BatchDeleteNoTrackingAsync(t => doctorUserIdList.Contains(t.DoctorUserId) && assginSubjectDoctorCommand.SubjectIdList.Contains(t.SubjectId));
}
foreach (var subjectId in assginSubjectDoctorCommand.SubjectIdList)
{
foreach (var doctorUserId in doctorUserIdList)
{
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 _subjectRepository.BatchUpdateNoTrackingAsync(t => t.Id == subjectId, u => new Subject() { IsAssignDoctorUser = true });
}
await _subjectUserRepository.SaveChangesAsync();
return ResponseOutput.Ok();
}
/// <summary>
/// 批量取消Subject 分配的医生
/// </summary>
/// <returns></returns> 数量
[HttpPost]
public async Task<IResponseOutput> CancelSubjectAssignDoctor(CancelSubjectAssignCommand cancelSubjectAssignCommand)
{
foreach (var subjectId in cancelSubjectAssignCommand.SubjectIdList)
{
if (await _visitTaskRepository.AnyAsync(t => t.SubjectId == subjectId && t.DoctorUserId != null))
{
throw new BusinessValidationFailedException("有Subject任务已应用不允许取消分配");
}
await _subjectUserRepository.DeleteFromQueryAsync(t => t.SubjectId == subjectId);
//await _subjectRepository.BatchUpdateNoTrackingAsync(t => t.Id == subjectId, u => new Subject() { IsAssignDoctorUser = false });
}
await _subjectUserRepository.SaveChangesAsync();
return ResponseOutput.Ok();
}
/// <summary>
/// 手动分配确认 绑定该Subject的已存在的任务给医生
/// </summary>
/// <param name="assignConfirmCommand"></param>
/// <returns></returns>
[HttpPost]
[UnitOfWork]
public async Task<IResponseOutput> ManualAssignDoctorApplyTask(AssignConfirmCommand assignConfirmCommand)
{
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();
var taskList = _visitTaskRepository.Where(t => t.TrialId == assignConfirmCommand.TrialId && t.DoctorUserId == null, true)
.WhereIf(subjectIdList.Count() > 0, t => subjectIdList.Contains(t.SubjectId) && t.Subject.SubjectDoctorList.Any())
.ToList();
foreach (var subjectTaskGroup in taskList.GroupBy(t => t.SubjectId))
{
var subjectId = subjectTaskGroup.Key;
//如果数据为空 那么就是确认所有已分配的
List<DoctorArm> subjectDoctorIdArmList = new List<DoctorArm>();
if (assignConfirmCommand.SubjectDoctorUserList.Count == 0)
{
subjectDoctorIdArmList = _subjectUserRepository.Where(t => t.SubjectId == subjectId).Select(t => new DoctorArm() { DoctorUserId = t.DoctorUserId, ArmEnum = t.ArmEnum }).ToList();
}
else
{
subjectDoctorIdArmList = assignConfirmCommand.SubjectDoctorUserList.Where(t => t.SubjectId == subjectId).First().DoctorUserIdArmList;
}
foreach (var task in subjectTaskGroup.OrderBy(t => t.ArmEnum).ToList())
{
var subjectDoctorArm = subjectDoctorIdArmList.Where(t => t.ArmEnum == task.ArmEnum).FirstOrDefault();
if (subjectDoctorArm != null)
{
task.DoctorUserId = subjectDoctorArm.DoctorUserId;
task.AllocateTime = DateTime.Now;
task.TaskState = TaskState.Allocated;
await _subjectVisitRepository.BatchUpdateNoTrackingAsync(t => t.Id == task.SourceSubjectVisitId, u => new SubjectVisit() { ReadingStatus = ReadingStatusEnum.ImageReading });
await _readModuleRepository.BatchUpdateNoTrackingAsync(t => t.Id == task.SouceReadModuleId, u => new ReadModule() { ReadingStatus = ReadingStatusEnum.ImageReading });
}
else
{
throw new BusinessValidationFailedException("当前提交 Subject 以及医生所在Arm 与任务的Arm不一致,无法绑定,请核对数据");
}
}
}
await _visitTaskRepository.SaveChangesAsync();
return ResponseOutput.Ok();
}
/// <summary>
/// 自动一次性分配所有未分配的 Subject 给医生
/// </summary>
/// <param name="autoSubjectAssignCommand"></param>
/// <returns></returns>
[HttpPost]
[UnitOfWork]
public async Task<IResponseOutput> AutoSubjectAssignDoctor(AutoSubjectAssignCommand autoSubjectAssignCommand)
{
//自动分配的话,需要把手动分配的给删掉
var trialId = autoSubjectAssignCommand.TrialId;
//获取 已产生任务的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 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();
#region 按照医生维度分配Subject
////受试者总数
//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();
////给医生分配Subject 前验证 已经分配的数据是否符合分配的规范
//foreach (var subject in subjectList)
//{
// var doctorCount = subject.DoctorUserList.Count();
// //分配两个医生
// if (trialConfig.ReadingType == ReadingMethod.Double)
// {
// if (doctorCount > 2)
// {
// throw new BusinessValidationFailedException("双重阅片当前有Subject绑定医生数量大于2");
// }
// }
// else if (trialConfig.ReadingType == ReadingMethod.Single)
// {
// if (doctorCount > 1)
// {
// throw new BusinessValidationFailedException("单重阅片当前有Subject绑定医生数量大于1");
// }
// }
//}
////存放分配后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 integerPlan = 0;
// waitAllocationDoctorList.ForEach(doctor =>
// {
// integerPlan += (int)Math.Floor((double)(subjectCount * doctor.PlanReadingRatio) / 100);
// });
// var specialSubjectCount = subjectCount - integerPlan;
// //按照医生维度 分配Subject
// foreach (var doctor in waitAllocationDoctorList)
// {
// //该医生的目前已分配到的受试者
// var hasAssignedSubjectIdList = assignedSubjectDoctorList.Where(t => t.DoctorUserId == doctor.DoctorUserId).Select(t => t.SubjectId).Distinct().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)
// {
// //从未分配的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 integerPlan = 0;
// waitAllocationDoctorList.ForEach(doctor =>
// {
// integerPlan += (int)Math.Floor((double)(subjectCount * doctor.PlanReadingRatio * 2) / 100);
// });
// var specialSubjectCount = (subjectCount * 2) - integerPlan;
// //按照医生维度 分配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);
// //判断是否能整除
// var yuShu = (subjectCount * doctor.PlanReadingRatio * 2) % 100;
// if (yuShu != 0)
// {
// if (specialSubjectCount > 0)
// {
// specialSubjectCount--;
// 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)).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
//}
////验证是否所有Subject 是否分配好
//if (assignedSubjectDoctorList.Select(t => t.SubjectId).Distinct().Count() != subjectCount)
//{
// throw new BusinessValidationFailedException("分配算法有问题有Subject 未分配");
//}
#endregion
#region 完全按照Subject 遍历去分
var subjectCount = subjectList.Count;
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();
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 && !t.DoctorUserList.Any()))
{
//该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 = Arm.DoubleReadingArm1;
var doctor2Arm = Arm.DoubleReadingArm2;
if ((preferredDoctor1Arm == null && preferredDoctor2Arm == null) ||
(preferredDoctor1Arm == null && preferredDoctor2Arm == Arm.DoubleReadingArm2) ||
(preferredDoctor1Arm == Arm.DoubleReadingArm1 && preferredDoctor2Arm == null) ||
(preferredDoctor1Arm == Arm.DoubleReadingArm1 && preferredDoctor2Arm == Arm.DoubleReadingArm2)
)
{
doctor1Arm = Arm.DoubleReadingArm1;
doctor2Arm = Arm.DoubleReadingArm2;
}
else if ((preferredDoctor1Arm == null && preferredDoctor2Arm == Arm.DoubleReadingArm1) ||
(preferredDoctor1Arm == Arm.DoubleReadingArm2 && preferredDoctor2Arm == Arm.DoubleReadingArm1) ||
(preferredDoctor1Arm == Arm.DoubleReadingArm2 && preferredDoctor2Arm == null))
{
doctor1Arm = Arm.DoubleReadingArm2;
doctor2Arm = Arm.DoubleReadingArm1;
}
else if (preferredDoctor1Arm == Arm.DoubleReadingArm1 && preferredDoctor2Arm == Arm.DoubleReadingArm1)
{
doctor1Arm = Arm.DoubleReadingArm1;
doctor2Arm = Arm.DoubleReadingArm2;
}
else if (preferredDoctor1Arm == Arm.DoubleReadingArm2 && preferredDoctor2Arm == Arm.DoubleReadingArm2)
{
doctor1Arm = Arm.DoubleReadingArm2;
doctor2Arm = Arm.DoubleReadingArm1;
}
//if(!waitAllocationDoctorList.Where(t=>t.DoctorUserId== allocateDoctorList[0].DoctorUserId).SelectMany(u => u.SubjectArmList).Any(t => t.SubjectId == subject.SubjectId))
//{
await _subjectUserRepository.AddAsync(new SubjectUser() { TrialId = trialId, SubjectId = subject.SubjectId, DoctorUserId = allocateDoctorList[0].DoctorUserId, ArmEnum = doctor1Arm, AssignTime = DateTime.Now });
waitAllocationDoctorList.FirstOrDefault(t => t.DoctorUserId == allocateDoctorList[0].DoctorUserId).SubjectArmList.Add(new SubjectArm()
{
SubjectId = subject.SubjectId,
ArmEnum = doctor1Arm
});
//}
//if (!waitAllocationDoctorList.Where(t => t.DoctorUserId == allocateDoctorList[1].DoctorUserId).SelectMany(u => u.SubjectArmList).Any(t => t.SubjectId == subject.SubjectId))
//{
await _subjectUserRepository.AddAsync(new SubjectUser() { TrialId = trialId, SubjectId = subject.SubjectId, DoctorUserId = allocateDoctorList[1].DoctorUserId, ArmEnum = doctor2Arm, AssignTime = DateTime.Now });
waitAllocationDoctorList.FirstOrDefault(t => t.DoctorUserId == allocateDoctorList[1].DoctorUserId).SubjectArmList.Add(new SubjectArm()
{
SubjectId = subject.SubjectId,
ArmEnum = doctor2Arm
});
//}
}
else if (trialConfig.ReadingType == ReadingMethod.Single)
{
if (hasAssignDoctorCount > 1)
{
throw new BusinessValidationFailedException("单重阅片当前有Subject绑定医生数量大于1");
}
var allocateDoctor = waitAllocationDoctorList.OrderByDescending(t => t.Weight).ThenByDescending(t => t.PlanReadingRatio).FirstOrDefault();
waitAllocationDoctorList.FirstOrDefault(t => t.DoctorUserId == allocateDoctor.DoctorUserId).SubjectArmList.Add(new SubjectArm()
{
SubjectId = subject.SubjectId,
ArmEnum = Arm.SingleReadingArm
});
await _subjectUserRepository.AddAsync(new SubjectUser() { TrialId = trialId, SubjectId = subject.SubjectId, DoctorUserId = allocateDoctor.DoctorUserId, ArmEnum = Arm.SingleReadingArm, AssignTime = DateTime.Now });
}
}
#endregion
await _subjectUserRepository.SaveChangesAsync();
return ResponseOutput.Ok();
}
/// <summary>
/// 任务 手动分配 重新分配 确认 取消分配
/// </summary>分配
/// <param name="assignSubjectTaskToDoctorCommand"></param>
/// <returns></returns>
[HttpPost]
[UnitOfWork]
public async Task<IResponseOutput> AssignSubjectTaskToDoctor(AssignSubjectTaskToDoctorCommand assignSubjectTaskToDoctorCommand)
{
var visitTask = await _visitTaskRepository.FirstOrDefaultAsync(t => t.Id == assignSubjectTaskToDoctorCommand.Id);
if (assignSubjectTaskToDoctorCommand.TaskOptType == TaskOptType.Assign || assignSubjectTaskToDoctorCommand.TaskOptType == TaskOptType.ReAssign)
{
visitTask.AllocateTime = DateTime.Now;
visitTask.DoctorUserId = assignSubjectTaskToDoctorCommand.DoctorUserId;
visitTask.TaskState = TaskState.Allocated;
}
else if (assignSubjectTaskToDoctorCommand.TaskOptType == TaskOptType.ReAssign)
{
//验证 是不是两个任务都给了同一个医生
//是否删除配置规则表里的 Subject 医生绑定关系 重新添加绑定关系
//是否其该Subject 其他访视 绑定的医生 也同时变更?
}
else if (assignSubjectTaskToDoctorCommand.TaskOptType == TaskOptType.Confirm)
{
visitTask.TaskState = TaskState.Allocated;
}
else if (assignSubjectTaskToDoctorCommand.TaskOptType == TaskOptType.CancelAssign)
{
visitTask.AllocateTime = null;
visitTask.DoctorUserId = null;
visitTask.TaskState = TaskState.NotAllocate;
}
await _visitTaskRepository.SaveChangesAsync();
return ResponseOutput.Ok();
}
}
}