修改一致性分析
parent
c3b62137d8
commit
74399df5eb
|
@ -24,7 +24,9 @@ namespace IRaCIS.Core.Application.ViewModel
|
|||
|
||||
public int? GeneratedSubjectCount { get; set; }
|
||||
|
||||
public int? MatchSubejctCount { get; set; }
|
||||
|
||||
public int? CanGeneratedSubejctCount => MatchSubejctCount - GeneratedSubjectCount;
|
||||
|
||||
}
|
||||
|
||||
|
@ -34,6 +36,13 @@ namespace IRaCIS.Core.Application.ViewModel
|
|||
|
||||
}
|
||||
|
||||
public class SubjectGeneratedTask
|
||||
{
|
||||
public Guid SubjectId { get; set; }
|
||||
|
||||
public bool IsHaveGeneratedTask { get; set; }
|
||||
}
|
||||
|
||||
public class ConsistentQuery : PageInput
|
||||
{
|
||||
[NotDefault]
|
||||
|
@ -46,6 +55,15 @@ namespace IRaCIS.Core.Application.ViewModel
|
|||
|
||||
}
|
||||
|
||||
public class GroupConsistentSimpleQuery
|
||||
{
|
||||
[NotDefault]
|
||||
public Guid TrialId { get; set; }
|
||||
|
||||
[NotDefault]
|
||||
|
||||
public Guid TrialReadingCriterionId { get; set; }
|
||||
}
|
||||
public class GroupConsistentQuery : PageInput
|
||||
{
|
||||
[NotDefault]
|
||||
|
@ -56,13 +74,21 @@ namespace IRaCIS.Core.Application.ViewModel
|
|||
public Guid TrialReadingCriterionId { get; set; }
|
||||
}
|
||||
|
||||
public class ConsistentConfirmGenerateCommand
|
||||
public class SelfConsistentSimpleQuery
|
||||
{
|
||||
[NotDefault]
|
||||
public Guid TaskConsistentRuleId { get; set; }
|
||||
[NotDefault]
|
||||
public Guid DoctorUserId { get; set; }
|
||||
}
|
||||
|
||||
public class ConsistentConfirmGenerateCommand: SelfConsistentSimpleQuery
|
||||
{
|
||||
|
||||
|
||||
public List<Guid> SubejctIdList { get; set; }
|
||||
|
||||
public bool IsAutoAllocateGenerateTask { get; set; }
|
||||
}
|
||||
|
||||
|
||||
|
@ -70,7 +96,13 @@ namespace IRaCIS.Core.Application.ViewModel
|
|||
{
|
||||
[NotDefault]
|
||||
public Guid TrialId { get; set; }
|
||||
|
||||
[NotDefault]
|
||||
|
||||
public Guid TrialReadingCriterionId { get; set; }
|
||||
public List<Guid> SubejctIdList { get; set; }
|
||||
|
||||
public bool IsAutoAllocateGenerateTask { get; set; }
|
||||
}
|
||||
|
||||
public class DoctorSelfConsistentSubjectView: ConsistentCommonView
|
||||
|
@ -105,6 +137,8 @@ namespace IRaCIS.Core.Application.ViewModel
|
|||
public List<VisitTaskGroupSimpleDTO> SubjectTaskVisitList => VisitTaskList.GroupBy(t => new { t.SubjectId, t.VisitTaskNum }).Where(g => g.Count() == 2).Select(g => g.First()).OrderBy(t=>t.VisitTaskNum).ToList();
|
||||
|
||||
public List<VisitTaskGroupSimpleDTO> VisitTaskList { get; set; } = new List<VisitTaskGroupSimpleDTO>();
|
||||
|
||||
public List<UserSimpleInfo> DoctorUserList { get; set; }=new List<UserSimpleInfo>();
|
||||
}
|
||||
|
||||
public class VisitTaskGroupSimpleDTO
|
||||
|
|
|
@ -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(),
|
||||
|
||||
|
@ -688,9 +733,19 @@ namespace IRaCIS.Core.Application.Service
|
|||
[HttpPost]
|
||||
public async Task<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()
|
||||
{
|
||||
|
@ -831,8 +905,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();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue