|
|
|
@ -16,6 +16,9 @@ using System.Linq;
|
|
|
|
|
using IRaCIS.Core.Application.Contracts;
|
|
|
|
|
using IRaCIS.Core.Application.Filter;
|
|
|
|
|
using Medallion.Threading;
|
|
|
|
|
using IRaCIS.Core.Infrastructure.Extention;
|
|
|
|
|
using System;
|
|
|
|
|
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
|
|
|
|
|
|
|
|
|
namespace IRaCIS.Core.Application.Service
|
|
|
|
|
{
|
|
|
|
@ -37,10 +40,11 @@ namespace IRaCIS.Core.Application.Service
|
|
|
|
|
|
|
|
|
|
private readonly IRepository<TrialVirtualSiteCodeUpdate> _trialVirtualSiteCodeUpdateRepository;
|
|
|
|
|
|
|
|
|
|
private readonly IVisitTaskHelpeService _visitTaskCommonService;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public TaskConsistentRuleService(IRepository<VisitTask> visitTaskRepository, IRepository<Enroll> enrollRepository, IRepository<TaskConsistentRule> taskConsistentRuleRepository, IRepository<SubjectUser> subjectUserRepository, IRepository<Subject> subjectRepository, IDistributedLockProvider distributedLockProvider,
|
|
|
|
|
IRepository<Trial> trialRepository, IRepository<TrialSite> trialSiteRepository, IRepository<TrialVirtualSiteCodeUpdate> trialVirtualSiteCodeUpdateRepository)
|
|
|
|
|
IRepository<Trial> trialRepository, IRepository<TrialSite> trialSiteRepository, IRepository<TrialVirtualSiteCodeUpdate> trialVirtualSiteCodeUpdateRepository, IVisitTaskHelpeService visitTaskCommonService)
|
|
|
|
|
{
|
|
|
|
|
_taskConsistentRuleRepository = taskConsistentRuleRepository;
|
|
|
|
|
_visitTaskRepository = visitTaskRepository;
|
|
|
|
@ -54,6 +58,8 @@ namespace IRaCIS.Core.Application.Service
|
|
|
|
|
_trialSiteRepository = trialSiteRepository;
|
|
|
|
|
|
|
|
|
|
_trialVirtualSiteCodeUpdateRepository = trialVirtualSiteCodeUpdateRepository;
|
|
|
|
|
|
|
|
|
|
_visitTaskCommonService = visitTaskCommonService;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
@ -136,13 +142,12 @@ namespace IRaCIS.Core.Application.Service
|
|
|
|
|
/// 确认生成自身一致性分析任务
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="inCommand"></param>
|
|
|
|
|
/// <param name="_visitTaskCommonService"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
[HttpPost]
|
|
|
|
|
[UnitOfWork]
|
|
|
|
|
//[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
|
|
|
|
|
|
|
|
|
|
public async Task<IResponseOutput> ConfirmGenerateSelfConsistentTask(ConsistentConfirmGenerateCommand inCommand, [FromServices] IVisitTaskHelpeService _visitTaskCommonService)
|
|
|
|
|
public async Task<IResponseOutput> ConfirmGenerateSelfConsistentTask(ConsistentConfirmGenerateCommand inCommand)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -150,6 +155,20 @@ namespace IRaCIS.Core.Application.Service
|
|
|
|
|
var doctorUserId = inCommand.DoctorUserId;
|
|
|
|
|
var trialReadingCriterionId = filterObj.TrialReadingCriterionId;
|
|
|
|
|
|
|
|
|
|
//随机分配
|
|
|
|
|
if (inCommand.IsAutoAllocateGenerateTask)
|
|
|
|
|
{
|
|
|
|
|
var subjectList = (await GetSelfConsistentRuleMatchSubjectIdListAsync(new SelfConsistentSimpleQuery() { TaskConsistentRuleId = inCommand.TaskConsistentRuleId, DoctorUserId = inCommand.DoctorUserId })).ToList();
|
|
|
|
|
|
|
|
|
|
if (subjectList.Any(t => t.IsHaveGeneratedTask))
|
|
|
|
|
{
|
|
|
|
|
//已手动分配,不允许自动分配
|
|
|
|
|
throw new BusinessValidationFailedException(_localizer["TaskConsistent_NotAllowedGenerate"]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
inCommand.SubejctIdList = GetRandomSubjectIdList(subjectList.Select(t => t.SubjectId).ToList(), filterObj.PlanSubjectCount);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var list = await GetIQueryableDoctorSelfConsistentSubjectView(filterObj, doctorUserId, inCommand.SubejctIdList).ToListAsync();
|
|
|
|
|
|
|
|
|
|
//var (group, query) = GetIQueryableDoctorSelfConsistentRuleSubjectView(filterObj, inCommand.SubejctIdList);
|
|
|
|
@ -284,20 +303,34 @@ namespace IRaCIS.Core.Application.Service
|
|
|
|
|
/// 确认生成组间一致性分析任务
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="inCommand"></param>
|
|
|
|
|
/// <param name="_visitTaskCommonService"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
[HttpPost]
|
|
|
|
|
[UnitOfWork]
|
|
|
|
|
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
|
|
|
|
|
|
|
|
|
|
public async Task<IResponseOutput> ConfirmGenerateGroupConsistentTask(GroupConsistentConfirmGenrateCommand inCommand, [FromServices] IVisitTaskHelpeService _visitTaskCommonService)
|
|
|
|
|
public async Task<IResponseOutput> ConfirmGenerateGroupConsistentTask(GroupConsistentConfirmGenrateCommand inCommand)
|
|
|
|
|
{
|
|
|
|
|
var trialId = inCommand.TrialId;
|
|
|
|
|
|
|
|
|
|
var filterObj = await _taskConsistentRuleRepository.FirstOrDefaultAsync(t => t.TrialId == trialId && t.IsSelfAnalysis == false);
|
|
|
|
|
var filterObj = await _taskConsistentRuleRepository.FirstOrDefaultAsync(t => t.TrialId == trialId && t.TrialReadingCriterionId == inCommand.TrialReadingCriterionId && t.IsSelfAnalysis == false);
|
|
|
|
|
|
|
|
|
|
var trialReadingCriterionId = filterObj.TrialReadingCriterionId;
|
|
|
|
|
|
|
|
|
|
//随机分配
|
|
|
|
|
if (inCommand.IsAutoAllocateGenerateTask)
|
|
|
|
|
{
|
|
|
|
|
var subjectSelectList = (await GetGroupConsistentRuleMatchSubjectIdListAsync(new GroupConsistentSimpleQuery() { TrialId = inCommand.TrialId, TrialReadingCriterionId = inCommand.TrialReadingCriterionId })).ToList();
|
|
|
|
|
|
|
|
|
|
if (subjectSelectList.Any(t => t.IsHaveGeneratedTask))
|
|
|
|
|
{
|
|
|
|
|
//已手动分配过,不允许自动分配
|
|
|
|
|
throw new BusinessValidationFailedException(_localizer["TaskConsistent_NotAllowedGenerate"]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
inCommand.SubejctIdList = GetRandomSubjectIdList(subjectSelectList.Select(t => t.SubjectId).ToList(), filterObj.PlanSubjectCount);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var query = await GetGroupConsistentQueryAsync(filterObj, inCommand.SubejctIdList);
|
|
|
|
|
|
|
|
|
@ -578,7 +611,12 @@ namespace IRaCIS.Core.Application.Service
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 组间一致性分析 满足条件的subject 筛选
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="filterObj"></param>
|
|
|
|
|
/// <param name="subejctIdList"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
private async Task<IQueryable<DoctorGroupConsistentSubjectView>> GetGroupConsistentQueryAsync(TaskConsistentRule filterObj, List<Guid>? subejctIdList = null)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
@ -638,6 +676,13 @@ namespace IRaCIS.Core.Application.Service
|
|
|
|
|
|
|
|
|
|
IsHaveGeneratedTask = t.SubjectVisitTaskList.Any(c => c.IsSelfAnalysis == false && c.TrialReadingCriterionId == trialReadingCriterionId),
|
|
|
|
|
|
|
|
|
|
DoctorUserList = t.SubjectDoctorList.Where(t => t.TrialReadingCriterionId == trialReadingCriterionId && t.IsConfirmed).Select(t => new UserSimpleInfo()
|
|
|
|
|
{
|
|
|
|
|
UserId = t.Id,
|
|
|
|
|
FullName = t.DoctorUser.FullName,
|
|
|
|
|
UserCode = t.DoctorUser.UserCode,
|
|
|
|
|
UserName = t.DoctorUser.UserName
|
|
|
|
|
}).ToList(),
|
|
|
|
|
|
|
|
|
|
ValidVisitCount = t.SubjectVisitTaskList.AsQueryable().Where(visitTaskFilter).GroupBy(t => new { t.SubjectId, t.VisitTaskNum }).Where(g => g.Count() == 2).Count(),
|
|
|
|
|
|
|
|
|
@ -686,11 +731,21 @@ namespace IRaCIS.Core.Application.Service
|
|
|
|
|
/// <param name="inQuery"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
[HttpPost]
|
|
|
|
|
public async Task<List<TaskConsistentRuleView>> GetSelfConsistentDoctorStatList(TaskConsistentRuleQuery inQuery)
|
|
|
|
|
public async Task<IResponseOutput<List<TaskConsistentRuleView>>> GetSelfConsistentDoctorStatList(TaskConsistentRuleQuery inQuery)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var trialId = inQuery.TrialId;
|
|
|
|
|
|
|
|
|
|
var taskConsistentRuleQueryable = from enroll in _repository.Where<Enroll>(t => t.TrialId == trialId && t.EnrollStatus == EnrollStatus.ConfirmIntoGroup)
|
|
|
|
|
Expression<Func<VisitTask, bool>> comonTaskFilter = u => u.TrialId == trialId && u.IsAnalysisCreate == false && u.TaskState == TaskState.Effect && u.ReadingTaskState == ReadingTaskState.HaveSigned && (u.ReReadingApplyState == ReReadingApplyState.Default || u.ReReadingApplyState == ReReadingApplyState.Reject);
|
|
|
|
|
|
|
|
|
|
//&& u.TrialReadingCriterionId == trialReadingCriterionId &&u.SignTime!.Value.AddDays(filterObj.IntervalWeeks * 7) < DateTime.Now && u.DoctorUserId == doctorUserId;
|
|
|
|
|
|
|
|
|
|
Expression<Func<VisitTask, bool>> visitTaskFilter = comonTaskFilter.And(t => t.ReadingCategory == ReadingCategory.Visit);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var taskConsistentRuleQueryable = from enroll in _repository.Where<Enroll>(t => t.TrialId == trialId && t.EnrollStatus == EnrollStatus.ConfirmIntoGroup
|
|
|
|
|
&& t.EnrollReadingCriteriaList.Any(c => c.TrialReadingCriterionId == inQuery.TrialReadingCriterionId && c.IsJoinAnalysis))
|
|
|
|
|
join user in _repository.Where<User>() on enroll.DoctorId equals user.DoctorId
|
|
|
|
|
join taskConsistentRule in _repository.Where<TaskConsistentRule>(t => t.TrialId == trialId && t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId && t.IsSelfAnalysis) on enroll.TrialId equals taskConsistentRule.TrialId
|
|
|
|
|
select new TaskConsistentRuleView()
|
|
|
|
@ -711,7 +766,26 @@ namespace IRaCIS.Core.Application.Service
|
|
|
|
|
IsHaveReadingPeriod = taskConsistentRule.IsHaveReadingPeriod,
|
|
|
|
|
PlanVisitCount = taskConsistentRule.PlanVisitCount,
|
|
|
|
|
|
|
|
|
|
GeneratedSubjectCount = taskConsistentRule.Trial.VisitTaskList.Where(t => t.IsAnalysisCreate && t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId && t.IsSelfAnalysis == true && t.DoctorUserId == user.Id).Select(t => t.SubjectId).Distinct().Count(),
|
|
|
|
|
GeneratedSubjectCount = taskConsistentRule.TrialReadingCriterion.VisitTaskList.Where(t => t.IsAnalysisCreate && t.IsSelfAnalysis == true && t.DoctorUserId == user.Id).Select(t => t.SubjectId).Distinct().Count(),
|
|
|
|
|
|
|
|
|
|
//MatchSubejctCount = taskConsistentRule.Trial.SubjectList.Where(t => t.SubjectVisitTaskList.AsQueryable().Where(visitTaskFilter)
|
|
|
|
|
//.Where(t => t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId && t.SignTime!.Value.AddDays(taskConsistentRule.IntervalWeeks * 7) < DateTime.Now && t.DoctorUserId == user.DoctorId)
|
|
|
|
|
//.Count() >= taskConsistentRule.PlanVisitCount)
|
|
|
|
|
//.WhereIf(taskConsistentRule.IsHaveReadingPeriod == true, u => u.SubjectVisitTaskList.AsQueryable().Where(comonTaskFilter)
|
|
|
|
|
//.Where(t => t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId && t.SignTime!.Value.AddDays(taskConsistentRule.IntervalWeeks * 7) < DateTime.Now && t.DoctorUserId == user.DoctorId)
|
|
|
|
|
//.Where(t => t.ReadingCategory == ReadingCategory.Visit || t.ReadingCategory == ReadingCategory.Global).OrderBy(t => t.VisitTaskNum).Take(taskConsistentRule.PlanVisitCount + 1).Any(t => t.ReadingCategory == ReadingCategory.Global))
|
|
|
|
|
//.Count(),
|
|
|
|
|
|
|
|
|
|
MatchSubejctCount = taskConsistentRule.Trial.SubjectList.AsQueryable()
|
|
|
|
|
.Where(t => taskConsistentRule.IsHaveReadingPeriod == false ? t.SubjectVisitTaskList.AsQueryable()
|
|
|
|
|
.Where(visitTaskFilter).Where(t => t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId && t.SignTime!.Value.AddDays(taskConsistentRule.IntervalWeeks * 7) < DateTime.Now && t.DoctorUserId == user.DoctorId)
|
|
|
|
|
.Count() >= taskConsistentRule.PlanVisitCount :
|
|
|
|
|
t.SubjectVisitTaskList.AsQueryable().Where(comonTaskFilter)
|
|
|
|
|
.Where(t => t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId && t.SignTime!.Value.AddDays(taskConsistentRule.IntervalWeeks * 7) < DateTime.Now && t.DoctorUserId == user.DoctorId)
|
|
|
|
|
.Where(t => t.ReadingCategory == ReadingCategory.Visit || t.ReadingCategory == ReadingCategory.Global).OrderBy(t => t.VisitTaskNum).Take(taskConsistentRule.PlanVisitCount + 1).Any(t => t.ReadingCategory == ReadingCategory.Global))
|
|
|
|
|
.Count(),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
AnalysisDoctorUser = new UserSimpleInfo()
|
|
|
|
|
{
|
|
|
|
@ -738,7 +812,10 @@ namespace IRaCIS.Core.Application.Service
|
|
|
|
|
//var taskConsistentRuleQueryable = _taskConsistentRuleRepository.Where(t => t.TrialId == inQuery.TrialId)
|
|
|
|
|
// .ProjectTo<TaskConsistentRuleView>(_mapper.ConfigurationProvider);
|
|
|
|
|
|
|
|
|
|
return await taskConsistentRuleQueryable.ToListAsync();
|
|
|
|
|
var list= await taskConsistentRuleQueryable.ToListAsync();
|
|
|
|
|
|
|
|
|
|
var rule= await _taskConsistentRuleRepository.Where(t => t.TrialId == inQuery.TrialId && t.IsSelfAnalysis == inQuery.IsSelfAnalysis && t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId).ProjectTo<TaskConsistentRuleBasic>(_mapper.ConfigurationProvider).FirstOrDefaultAsync();
|
|
|
|
|
return ResponseOutput.Ok(list, rule);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[HttpPost]
|
|
|
|
@ -831,8 +908,65 @@ namespace IRaCIS.Core.Application.Service
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 获取自身一致性分析 符合条件的subject 数组
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="inQuery"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public async Task<List<SubjectGeneratedTask>> GetSelfConsistentRuleMatchSubjectIdListAsync(SelfConsistentSimpleQuery inQuery)
|
|
|
|
|
{
|
|
|
|
|
var filterObj = await _taskConsistentRuleRepository.FirstOrDefaultAsync(t => t.Id == inQuery.TaskConsistentRuleId);
|
|
|
|
|
|
|
|
|
|
var subjectList = await GetIQueryableDoctorSelfConsistentSubjectView(filterObj, inQuery.DoctorUserId).Select(t => new SubjectGeneratedTask() { SubjectId = t.SubjectId, IsHaveGeneratedTask = t.IsHaveGeneratedTask }).ToListAsync();
|
|
|
|
|
|
|
|
|
|
return subjectList;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 获取组件一致性分析符合条件的subject 数组
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="inQuery"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public async Task<List<SubjectGeneratedTask>> GetGroupConsistentRuleMatchSubjectIdListAsync(GroupConsistentSimpleQuery inQuery)
|
|
|
|
|
{
|
|
|
|
|
var filterObj = await _taskConsistentRuleRepository.FirstOrDefaultAsync(t => t.TrialId == inQuery.TrialId && t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId && t.IsSelfAnalysis == false);
|
|
|
|
|
|
|
|
|
|
var subjectList = await (await GetGroupConsistentQueryAsync(filterObj)).Select(t => new SubjectGeneratedTask() { SubjectId = t.SubjectId, IsHaveGeneratedTask = t.IsHaveGeneratedTask }).ToListAsync();
|
|
|
|
|
|
|
|
|
|
return subjectList;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 随机算法,选择指定数量的 subject
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="matchSubjectIdList"></param>
|
|
|
|
|
/// <param name="countToSelect"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public List<Guid> GetRandomSubjectIdList(List<Guid> matchSubjectIdList, int countToSelect)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
// 使用 Fisher-Yates 随机置换算法来选择指定数量的 GUID
|
|
|
|
|
Random random = new Random();
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < countToSelect; i++)
|
|
|
|
|
{
|
|
|
|
|
// 生成一个随机索引
|
|
|
|
|
int randomIndex = random.Next(i, matchSubjectIdList.Count);
|
|
|
|
|
|
|
|
|
|
// 将选中的元素与当前元素交换位置
|
|
|
|
|
Guid temp = matchSubjectIdList[randomIndex];
|
|
|
|
|
matchSubjectIdList[randomIndex] = matchSubjectIdList[i];
|
|
|
|
|
matchSubjectIdList[i] = temp;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return matchSubjectIdList.Take(countToSelect).ToList();
|
|
|
|
|
|
|
|
|
|
// 使用洗牌算法来随机选择指定数量的GUID
|
|
|
|
|
//Random random = new Random();
|
|
|
|
|
//return matchSubjectIdList.OrderBy(g => random.Next()).Take(countToSelect).ToList();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|