//--------------------------------------------------------------------
// 此代码由T4模板自动生成 byzhouhang 20210918
// 生成时间 2022-07-01 15:33:04
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
//--------------------------------------------------------------------
using IRaCIS.Core.Application.Contracts;
using IRaCIS.Core.Application.Filter;
using IRaCIS.Core.Application.Interfaces;
using IRaCIS.Core.Application.Service.Reading.Dto;
using IRaCIS.Core.Application.ViewModel;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Infra.EFCore.Common;
using IRaCIS.Core.Infrastructure;
using Medallion.Threading;
using Microsoft.AspNetCore.Mvc;
namespace IRaCIS.Core.Application.Service
{
///
/// 一致性分析配置表
///
[ApiExplorerSettings(GroupName = "Trial")]
public class TaskConsistentRuleService(IRepository _taskConsistentRuleRepository,
IRepository _visitTaskRepository,
IRepository _trialReadingCriterionRepository,
IReadingClinicalDataService _readingClinicalDataService,
IRepository _subjectRepository,
IDistributedLockProvider _distributedLockProvider,
IRepository _trialRepository,
IRepository _trialSiteRepository,
IRepository _enrollRepository,
IRepository _userRoleRepository,
IRepository _trialVirtualSiteCodeUpdateRepository,
IVisitTaskHelpeService _visitTaskCommonService, IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer) : BaseService, ITaskConsistentRuleService
{
///
/// 设置一致性分析任务失效
///
///
///
[HttpPost]
public async Task SetAnalysisTaskInvalid(List taskIdList)
{
await _visitTaskRepository.UpdatePartialFromQueryAsync(t => taskIdList.Contains(t.Id), u => new VisitTask() { TaskState = TaskState.Adbandon }, true);
await _visitTaskRepository.SaveChangesAsync();
return ResponseOutput.Ok();
}
///
/// 一致性分析列表 (自身 组内 最后勾选 产生的任务)
///
///
///
[HttpPost]
public async Task>> GetAnalysisTaskList(VisitTaskQuery inQuery)
{
var visitTaskQueryable = _visitTaskRepository.Where(t => t.TrialId == inQuery.TrialId)
.Where(t => t.IsAnalysisCreate)
.WhereIf(inQuery.TrialReadingCriterionId != null, t => t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId)
.WhereIf(inQuery.TrialSiteId != null, t => t.Subject.TrialSiteId == inQuery.TrialSiteId)
.WhereIf(inQuery.SubjectId != null, t => t.SubjectId == inQuery.SubjectId)
.WhereIf(inQuery.TaskState != null, t => t.TaskState == inQuery.TaskState)
.WhereIf(inQuery.IsUrgent != null, t => t.IsUrgent == inQuery.IsUrgent)
.WhereIf(inQuery.DoctorUserId != null, t => t.DoctorUserId == inQuery.DoctorUserId)
.WhereIf(inQuery.ReadingCategory != null, t => t.ReadingCategory == inQuery.ReadingCategory)
.WhereIf(inQuery.ReadingTaskState != null, t => t.ReadingTaskState == inQuery.ReadingTaskState)
.WhereIf(inQuery.TaskAllocationState != null, t => t.TaskAllocationState == inQuery.TaskAllocationState)
.WhereIf(inQuery.IsSelfAnalysis != null, t => t.IsSelfAnalysis == inQuery.IsSelfAnalysis)
.WhereIf(inQuery.ArmEnum != null, t => t.ArmEnum == inQuery.ArmEnum)
.WhereIf(!string.IsNullOrEmpty(inQuery.TrialSiteCode), t => /*(t.BlindTrialSiteCode.Contains(queryVisitTask.TrialSiteCode!) && t.IsAnalysisCreate) ||*/ (t.Subject.TrialSite.TrialSiteCode.Contains(inQuery.TrialSiteCode!) /*&& t.IsAnalysisCreate == false*/))
.WhereIf(!string.IsNullOrEmpty(inQuery.TaskName), t => t.TaskName.Contains(inQuery.TaskName) || t.TaskBlindName.Contains(inQuery.TaskName))
.WhereIf(!string.IsNullOrEmpty(inQuery.SubjectCode), t => ((t.Subject.Code.Contains(inQuery.SubjectCode) || t.Subject.MedicalNo.Contains(inQuery.SubjectCode)) && t.IsAnalysisCreate == false) || (t.BlindSubjectCode.Contains(inQuery.SubjectCode) && t.IsAnalysisCreate))
.WhereIf(inQuery.BeginAllocateDate != null, t => t.AllocateTime >= inQuery.BeginAllocateDate)
.WhereIf(inQuery.EndAllocateDate != null, t => t.AllocateTime <= inQuery.EndAllocateDate)
.WhereIf(inQuery.BeginSignTime != null, t => t.SignTime >= inQuery.BeginSignTime)
.WhereIf(inQuery.EndSignTime != null, t => t.SignTime <= inQuery.EndSignTime)
.ProjectTo(_mapper.ConfigurationProvider);
var defalutSortArray = new string[] { nameof(AnalysisTaskView.IsUrgent) + " desc", nameof(AnalysisTaskView.SubjectCode), nameof(AnalysisTaskView.VisitTaskNum) };
var pageList = await visitTaskQueryable.ToPagedListAsync(inQuery, defalutSortArray);
#region 统计一致性分析临床数据数量
foreach (var item in pageList.CurrentPageData)
{
item.ConsistentClinicalDataCount = (await _readingClinicalDataService.GetClinicalDataList(new GetReadingOrTaskClinicalDataListInDto()
{
SubjectId = item.SubjectId,
TrialId = item.TrialId,
SelectIsSign = false,
IsGetAllConsistencyAnalysis = false,
VisitTaskId = item.Id,
})).Count();
}
#endregion
var trialTaskConfig = _trialRepository.Where(t => t.Id == inQuery.TrialId).Select(t => new { IsHaveDoubleReadCriterion = t.TrialReadingCriterionList.Any(t => t.IsSigned && t.IsConfirm && t.ReadingType == ReadingMethod.Double), t.VitrualSiteCode }).FirstOrDefault();
return ResponseOutput.Ok(pageList, trialTaskConfig);
}
///
/// 为自身一致性分析医生,选择Subejct 列表
///
///
///
[HttpPost]
public async Task> GetDoctorSelfConsistentRuleSubjectList(ConsistentQuery inQuery)
{
var filterObj = await _taskConsistentRuleRepository.FirstOrDefaultAsync(t => t.Id == inQuery.TaskConsistentRuleId);
var pagedList = await GetIQueryableDoctorSelfConsistentSubjectView(filterObj, inQuery.DoctorUserId).ToPagedListAsync(inQuery, nameof(DoctorSelfConsistentSubjectView.SubjectCode));
return pagedList;
}
///
/// 确认生成自身一致性分析任务
///
///
///
[HttpPost]
[UnitOfWork]
//[TrialGlobalLimit( "AfterStopCannNotOpt" )]
public async Task ConfirmGenerateSelfConsistentTask(ConsistentConfirmGenerateCommand inCommand)
{
var filterObj = await _taskConsistentRuleRepository.Where(t => t.Id == inCommand.TaskConsistentRuleId).Include(t => t.TrialReadingCriterion).FirstOrDefaultAsync();
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"]);
}
if (subjectList.Count < 2 * filterObj.PlanSubjectCount)
{
throw new BusinessValidationFailedException(_localizer["TaskConsistent_NotAllowedGenerate1"]);
}
inCommand.SubejctIdList = subjectList.Select(t => t.SubjectId).ToList().GetRandomCountList(filterObj.PlanSubjectCount);
}
var list = await GetIQueryableDoctorSelfConsistentSubjectView(filterObj, doctorUserId, inCommand.SubejctIdList).ToListAsync();
var @lock = _distributedLockProvider.CreateLock($"VisitTaskCode");
using (await @lock.AcquireAsync())
{
int maxCodeInt = 0;
foreach (var subject in list)
{
//处理 Subject 编号
var blindSubjectCode = string.Empty;
var subjectTask = _visitTaskRepository.Where(t => t.SubjectId == subject.SubjectId && t.TrialReadingCriterionId == trialReadingCriterionId && t.IsSelfAnalysis == true).OrderByDescending(t => t.BlindSubjectCode).FirstOrDefault();
if (subjectTask != null && subjectTask.BlindSubjectCode != String.Empty)
{
blindSubjectCode = subjectTask.BlindSubjectCode;
}
else
{
var maxCodeStr = _visitTaskRepository.Where(t => t.TrialId == subject.TrialId && t.TrialReadingCriterionId == trialReadingCriterionId && t.IsSelfAnalysis == true).OrderByDescending(t => t.BlindSubjectCode).Select(t => t.BlindSubjectCode).FirstOrDefault();
if (!string.IsNullOrEmpty(maxCodeStr))
{
int.TryParse(maxCodeStr.Substring(maxCodeStr.Length - filterObj.BlindSubjectNumberOfPlaces), out maxCodeInt);
}
blindSubjectCode = filterObj.BlindTrialSiteCode + (maxCodeInt + 1).ToString($"D{filterObj.BlindSubjectNumberOfPlaces}");
}
//有序阅片
if (filterObj.TrialReadingCriterion.IsReadingTaskViewInOrder == ReadingOrder.InOrder)
{
subject.VisitTaskList = subject.VisitTaskList.Take(filterObj.PlanVisitCount).ToList();
}
else
{
//完全随机 和受试者随机,都是随机挑选访视
subject.VisitTaskList = subject.VisitTaskList.GetRandomCountList(filterObj.PlanVisitCount);
}
subject.VisitTaskList.ForEach(t =>
{
t.DoctorUserId = doctorUserId;
//t.TaskConsistentRuleId = filterObj.Id;
t.BlindTrialSiteCode = filterObj.BlindTrialSiteCode;
t.BlindSubjectCode = blindSubjectCode;
});
//最后一个访视添加全局
if (filterObj.IsGenerateGlobalTask)
{
var lastTask = (subject.VisitTaskList.Take(filterObj.PlanVisitCount).Last()).Clone();
var existGlobal = _visitTaskRepository.Where(t => t.SubjectId == lastTask.SubjectId && t.ArmEnum==lastTask.ArmEnum && t.TrialReadingCriterionId == trialReadingCriterionId && t.TaskState == TaskState.Effect && t.ReadingCategory == ReadingCategory.Global && t.VisitTaskNum == lastTask.VisitTaskNum + ReadingCommon.TaskNumDic[ReadingCategory.Global]).ProjectTo(_mapper.ConfigurationProvider).FirstOrDefault();
if (existGlobal == null)
{
existGlobal = new VisitTaskSimpleDTO()
{
SubjectId = lastTask.SubjectId,
TrialId = lastTask.TrialId,
ArmEnum = lastTask.ArmEnum,
ReadingCategory = ReadingCategory.Global,
TaskName = lastTask.TaskName + "_Global",
TaskBlindName = lastTask.TaskBlindName + "_Global",
TrialReadingCriterionId = trialReadingCriterionId,
VisitTaskNum = lastTask.VisitTaskNum + ReadingCommon.TaskNumDic[ReadingCategory.Global]
};
var afterGlobal = _visitTaskRepository.Where(t => t.SubjectId == lastTask.SubjectId && t.TrialReadingCriterionId == trialReadingCriterionId && t.TaskState == TaskState.Effect && t.ReadingCategory == ReadingCategory.Global && t.VisitTaskNum > lastTask.VisitTaskNum).ProjectTo(_mapper.ConfigurationProvider).FirstOrDefault();
if (afterGlobal == null)
{
throw new BusinessValidationFailedException("联系后台排查数据,没找到后续全局");
}
else
{
existGlobal.SouceReadModuleId = afterGlobal.SouceReadModuleId;
}
}
existGlobal.DoctorUserId = doctorUserId;
existGlobal.BlindSubjectCode = lastTask.BlindSubjectCode;
existGlobal.BlindTrialSiteCode = lastTask.BlindTrialSiteCode;
subject.VisitTaskList.Add(existGlobal);
}
await _visitTaskCommonService.AddTaskAsync(new GenerateTaskCommand()
{
TrialId = filterObj.TrialId,
ReadingCategory = GenerateTaskCategory.SelfConsistent,
//产生的过滤掉已经生成的
GenerataConsistentTaskList = subject.VisitTaskList.Where(t => t.IsHaveGeneratedTask == false).ToList()
});
await _visitTaskRepository.SaveChangesAsync();
}
}
return ResponseOutput.Ok();
}
///
/// 组间一致性分析 选择Subejct 列表
///
///
///
[HttpPost]
public async Task>> GetGroupConsistentRuleSubjectList(GroupConsistentQuery inQuery)
{
var trialId = inQuery.TrialId;
var filterObj = await _taskConsistentRuleRepository.FirstOrDefaultAsync(t => t.TrialId == trialId && t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId && t.IsSelfAnalysis == false);
if (filterObj == null)
{
object tt = null;
return ResponseOutput.Ok(new PageOutput(), new { Rule = tt, IsAllowAutoAllocate = false });
}
var query = await GetGroupConsistentQueryAsync(filterObj);
var pagedList = await query.ToPagedListAsync(inQuery, nameof(DoctorSelfConsistentSubjectView.SubjectCode));
var rule = await _taskConsistentRuleRepository.Where(t => t.TrialId == inQuery.TrialId && t.IsSelfAnalysis == false && t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId).ProjectTo(_mapper.ConfigurationProvider).FirstOrDefaultAsync();
var list = await GetGroupConsistentRuleMatchSubjectIdListAsync(new GroupConsistentSimpleQuery() { TrialId = inQuery.TrialId, TrialReadingCriterionId = inQuery.TrialReadingCriterionId });
var isAllowAutoAllocate = !list.Any(t => t.IsHaveGeneratedTask) && list.Count() > 2 * (rule?.PlanSubjectCount ?? 0);
return ResponseOutput.Ok(pagedList, new { Rule = rule, IsAllowAutoAllocate = isAllowAutoAllocate });
}
///
/// 确认生成组间一致性分析任务
///
///
///
[HttpPost]
[UnitOfWork]
[TrialGlobalLimit( "AfterStopCannNotOpt" )]
public async Task ConfirmGenerateGroupConsistentTask(GroupConsistentConfirmGenrateCommand inCommand)
{
var trialId = inCommand.TrialId;
var filterObj = await _taskConsistentRuleRepository.Where(t => t.TrialId == trialId && t.TrialReadingCriterionId == inCommand.TrialReadingCriterionId && t.IsSelfAnalysis == false).Include(t => t.TrialReadingCriterion).FirstNotNullAsync();
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"]);
}
if (subjectSelectList.Count < 2 * filterObj.PlanSubjectCount)
{
throw new BusinessValidationFailedException(_localizer["TaskConsistent_NotAllowedGenerate1"]);
}
inCommand.SubejctIdList = subjectSelectList.Select(t => t.SubjectId).ToList().GetRandomCountList(filterObj.PlanSubjectCount);
}
var query = await GetGroupConsistentQueryAsync(filterObj, inCommand.SubejctIdList);
var subjectList = query.ToList();
var doctorUserIdQuery = from enroll in _enrollRepository.Where(t => t.TrialId == trialId).Where(t => t.EnrollReadingCategoryList.Where(t => t.TrialReadingCriterionId == trialReadingCriterionId).Any(c => c.ReadingCategory == ReadingCategory.Global || c.ReadingCategory == ReadingCategory.Visit))
.Where(t => t.EnrollReadingCriteriaList.Any(t => t.TrialReadingCriterionId == trialReadingCriterionId && t.IsJoinAnalysis == true))
join user in _userRoleRepository.Where() on enroll.DoctorId equals user.DoctorId
select user.Id;
var configDoctorUserIdList = await doctorUserIdQuery.ToListAsync();
var @lock = _distributedLockProvider.CreateLock($"VisitTaskCode");
using (await @lock.AcquireAsync())
{
int maxCodeInt = 0;
foreach (var subject in subjectList.Where(t => t.IsHaveGeneratedTask == false))
{
//组间一致性分析 也用盲态SubjectCode
//处理 Subject 编号
var blindSubjectCode = string.Empty;
var subjectTask = _visitTaskRepository.Where(t => t.SubjectId == subject.SubjectId && t.TrialReadingCriterionId == trialReadingCriterionId && t.IsSelfAnalysis == false).OrderByDescending(t => t.BlindSubjectCode).FirstOrDefault();
if (subjectTask != null && subjectTask.BlindSubjectCode != String.Empty)
{
blindSubjectCode = subjectTask.BlindSubjectCode;
}
else
{
var maxCodeStr = _visitTaskRepository.Where(t => t.TrialId == subject.TrialId && t.TrialReadingCriterionId == trialReadingCriterionId && t.IsSelfAnalysis == false).OrderByDescending(t => t.BlindSubjectCode).Select(t => t.BlindSubjectCode).FirstOrDefault();
if (!string.IsNullOrEmpty(maxCodeStr))
{
int.TryParse(maxCodeStr.Substring(maxCodeStr.Length - filterObj.BlindSubjectNumberOfPlaces), out maxCodeInt);
}
blindSubjectCode = filterObj.BlindTrialSiteCode + (maxCodeInt + 1).ToString($"D{filterObj.BlindSubjectNumberOfPlaces}");
}
var subjectAddTaskList = new List();
//需要处理的医生
var needAddDoctorUserIdList = configDoctorUserIdList.Except(subject.VisitTaskList.Select(t => t.DoctorUserId!.Value)).ToList();
if (needAddDoctorUserIdList.Count == 0)
{
//"请配置一致性分析的医生"
throw new BusinessValidationFailedException(_localizer["TaskConsistent_ConsistencyConfigExists"]);
}
foreach (var needAddDoctorUserId in needAddDoctorUserIdList)
{
//if(filterObj.TrialReadingCriterion.IsReadingTaskViewInOrder== ReadingOrder.InOrder)
//{
//}
//每个医生 都生成处理的任务
foreach (var task in subject.SubjectTaskVisitList.Take(filterObj.PlanVisitCount))
{
subjectAddTaskList.Add(new VisitTaskGroupSimpleDTO()
{
ReadingCategory = task.ReadingCategory,
ReadingTaskState = task.ReadingTaskState,
TaskBlindName = task.TaskBlindName,
TaskName = task.TaskName,
TaskState = task.TaskState,
SubjectId = task.SubjectId,
VisitTaskNum = task.VisitTaskNum,
TrialId = task.TrialId,
DoctorUserId = needAddDoctorUserId,
ArmEnum = Arm.GroupConsistentArm,
SouceReadModuleId = task.SouceReadModuleId,
SourceSubjectVisitId = task.SourceSubjectVisitId,
TrialReadingCriterionId = task.TrialReadingCriterionId,
BlindSubjectCode = blindSubjectCode,
BlindTrialSiteCode = filterObj.BlindTrialSiteCode
});
}
//最后一个访视添加全局
if (filterObj.IsGenerateGlobalTask)
{
var lastTask = (subjectAddTaskList.Take(filterObj.PlanVisitCount).Last()).Clone();
var existGlobal = _visitTaskRepository.Where(t => t.SubjectId == lastTask.SubjectId && t.ArmEnum == lastTask.ArmEnum && t.TrialReadingCriterionId == trialReadingCriterionId && t.TaskState == TaskState.Effect && t.ReadingCategory == ReadingCategory.Global && t.VisitTaskNum == lastTask.VisitTaskNum + ReadingCommon.TaskNumDic[ReadingCategory.Global]).ProjectTo(_mapper.ConfigurationProvider).FirstOrDefault();
if (existGlobal == null)
{
existGlobal = new VisitTaskSimpleDTO()
{
SubjectId = lastTask.SubjectId,
TrialId = lastTask.TrialId,
ReadingCategory = ReadingCategory.Global,
TaskName = lastTask.TaskName + "_Global",
TaskBlindName = lastTask.TaskBlindName + "_Global",
TrialReadingCriterionId = trialReadingCriterionId,
BlindSubjectCode = blindSubjectCode,
BlindTrialSiteCode = filterObj.BlindTrialSiteCode,
VisitTaskNum = lastTask.VisitTaskNum + ReadingCommon.TaskNumDic[ReadingCategory.Global]
};
}
existGlobal.BlindSubjectCode = blindSubjectCode;
existGlobal.BlindTrialSiteCode = filterObj.BlindTrialSiteCode;
existGlobal.ArmEnum = Arm.GroupConsistentArm;
existGlobal.DoctorUserId = needAddDoctorUserId;
subjectAddTaskList.Add(existGlobal);
}
}
await _visitTaskCommonService.AddTaskAsync(new GenerateTaskCommand()
{
TrialId = filterObj.TrialId,
ReadingCategory = GenerateTaskCategory.GroupConsistent,
GenerataGroupConsistentTaskList = subjectAddTaskList
});
await _taskConsistentRuleRepository.SaveChangesAsync();
}
}
return ResponseOutput.Ok();
}
///
/// 仅仅自身一致性时使用(
///
///
///
///
///
private IQueryable GetIQueryableDoctorSelfConsistentSubjectView(TaskConsistentRule filterObj, Guid doctorUserId, List? subejctIdList = null)
{
var trialId = filterObj.TrialId;
var trialReadingCriterionId = filterObj.TrialReadingCriterionId;
//防止生成sql生成GETDATE() 时区导致的问题
var appDateTimeNow = DateTime.Now;
#region Subejct 维度
Expression> comonTaskFilter = u => u.TrialId == trialId && u.IsAnalysisCreate == false && u.TaskState == TaskState.Effect && u.ReadingTaskState == ReadingTaskState.HaveSigned && u.TrialReadingCriterionId == trialReadingCriterionId &&
u.SignTime!.Value.AddDays(filterObj.IntervalWeeks * 7) < appDateTimeNow && (u.ReReadingApplyState == ReReadingApplyState.Default || u.ReReadingApplyState == ReReadingApplyState.Reject) && u.DoctorUserId == doctorUserId;
if (subejctIdList != null && subejctIdList?.Count > 0)
{
comonTaskFilter = comonTaskFilter.And(t => subejctIdList.Contains(t.SubjectId));
}
Expression> visitTaskFilter = comonTaskFilter.And(t => t.ReadingCategory == ReadingCategory.Visit);
////所选访视数量 的访视 其中必有一个访视后有全局任务
//if (filterObj.IsHaveReadingPeriod == true)
//{
// //这里的过滤条件 不能用 where(comonTaskFilter) 会报错,奇怪的问题 只能重新写一遍
// visitTaskFilter = visitTaskFilter.And(c => c.Subject.SubjectVisitTaskList.Any(t => t.VisitTaskNum == c.VisitTaskNum + ReadingCommon.TaskNumDic[ReadingCategory.Global] && t.ReadingCategory == ReadingCategory.Global && t.IsAnalysisCreate == false && t.TaskState == TaskState.Effect && t.ReadingTaskState == ReadingTaskState.HaveSigned &&
// t.SignTime!.Value.AddDays(filterObj.IntervalWeeks * 7) < appDateTimeNow && (t.ReReadingApplyState == ReReadingApplyState.Default || t.ReReadingApplyState == ReReadingApplyState.Reject)));
//}
var subjectQuery = _subjectRepository.Where(t => t.TrialId == trialId &&
t.SubjectVisitTaskList.AsQueryable().Where(visitTaskFilter).Count() >= filterObj.PlanVisitCount)
.WhereIf(filterObj.IsHaveReadingPeriod == true, u => u.SubjectVisitTaskList.AsQueryable().Where(comonTaskFilter)
.Where(t => t.ReadingCategory == ReadingCategory.Visit || t.ReadingCategory == ReadingCategory.Global).Any(t => t.ReadingCategory == ReadingCategory.Global && t.VisitTaskNum > filterObj.PlanVisitCount - 1))
;
var query = subjectQuery.Select(t => new DoctorSelfConsistentSubjectView()
{
TrialId = t.TrialId,
TrialSiteId = t.TrialSiteId,
SubjectCode = t.Code,
TrialSiteCode = t.TrialSite.TrialSiteCode,
SubjectId = t.Id,
IsReReadingOrBackInfluenceAnalysis = t.IsReReadingOrBackInfluenceAnalysis,
FirstGlobalVisitName = t.ReadModuleList.Where(c => c.TrialReadingCriterionId == trialReadingCriterionId && c.ModuleType == ModuleTypeEnum.Global).OrderBy(k => k.SubjectVisit.VisitNum).Select(u => u.SubjectVisit.VisitName).FirstOrDefault(),
BlindSubjectCode = t.SubjectVisitTaskList.Where(t => t.IsAnalysisCreate && t.TrialReadingCriterionId == trialReadingCriterionId).OrderByDescending(t => t.BlindSubjectCode).Select(t => t.BlindSubjectCode).FirstOrDefault(),
IsHaveGeneratedTask = t.SubjectVisitTaskList.Any(c => c.DoctorUserId == doctorUserId && c.IsSelfAnalysis == true && c.TrialReadingCriterionId == trialReadingCriterionId),
ValidVisitCount = t.SubjectVisitTaskList.AsQueryable().Where(visitTaskFilter).Count(),
VisitTaskList = t.SubjectVisitTaskList.AsQueryable().Where(visitTaskFilter).OrderBy(t => t.VisitTaskNum).Select(c => new VisitTaskSimpleDTO()
{
Id = c.Id,
ReadingCategory = c.ReadingCategory,
ReadingTaskState = c.ReadingTaskState,
TaskBlindName = c.TaskBlindName,
TaskCode = c.TaskCode,
TaskName = c.TaskName,
TaskState = c.TaskState,
ArmEnum = c.ArmEnum,
SubjectId = c.SubjectId,
VisitTaskNum = c.VisitTaskNum,
TrialId = c.TrialId,
SourceSubjectVisitId = c.SourceSubjectVisitId,
SouceReadModuleId = c.SouceReadModuleId,
TrialReadingCriterionId = c.TrialReadingCriterionId,
IsClinicalDataSign = c.IsClinicalDataSign,
IsNeedClinicalDataSign = c.IsNeedClinicalDataSign,
//GlobalVisitTaskList = c.Subject.SubjectVisitTaskList.AsQueryable().Where(comonTaskFilter).Where(t => t.VisitTaskNum == c.VisitTaskNum + ReadingCommon.TaskNumDic[ReadingCategory.Global]).Select(c => new VisitTaskSimpleDTO()
//{
// Id = c.Id,
// ReadingCategory = c.ReadingCategory,
// ReadingTaskState = c.ReadingTaskState,
// TaskBlindName = c.TaskBlindName,
// TaskCode = c.TaskCode,
// TaskName = c.TaskName,
// TaskState = c.TaskState,
// ArmEnum = c.ArmEnum,
// SubjectId = c.SubjectId,
// VisitTaskNum = c.VisitTaskNum,
// TrialId = c.TrialId,
// SourceSubjectVisitId = c.SourceSubjectVisitId,
// SouceReadModuleId = c.SouceReadModuleId,
// TrialReadingCriterionId = c.TrialReadingCriterionId,
// IsClinicalDataSign = c.IsClinicalDataSign,
// IsNeedClinicalDataSign = c.IsNeedClinicalDataSign,
//}).ToList(),
}).ToList()
});
return query.OrderByDescending(t => t.IsHaveGeneratedTask);
#endregion
}
///
/// 组间一致性分析 满足条件的subject 筛选
///
///
///
///
private async Task> GetGroupConsistentQueryAsync(TaskConsistentRule filterObj, List? subejctIdList = null)
{
//单重阅片没有组件一致性
var trialId = filterObj.TrialId;
var trialReadingCriterionId = filterObj.TrialReadingCriterionId;
Expression> comonTaskFilter = u => u.TrialId == trialId && u.IsAnalysisCreate == false && u.TaskState == TaskState.Effect && u.ReadingTaskState == ReadingTaskState.HaveSigned && u.TrialReadingCriterionId == trialReadingCriterionId
&& (u.ReReadingApplyState == ReReadingApplyState.Default || u.ReReadingApplyState == ReReadingApplyState.Reject);
if (subejctIdList != null && subejctIdList?.Count > 0)
{
comonTaskFilter = comonTaskFilter.And(t => subejctIdList.Contains(t.SubjectId));
}
Expression> visitTaskFilter = comonTaskFilter.And(t => t.ReadingCategory == ReadingCategory.Visit);
IQueryable subjectQuery = default;
//双重阅片,并且都阅片完成
subjectQuery = _subjectRepository.Where(t => t.TrialId == trialId &&
t.SubjectVisitTaskList.AsQueryable().Where(comonTaskFilter).Where(t => t.ReadingCategory == ReadingCategory.Visit || t.ReadingCategory == ReadingCategory.Global).Select(t => t.DoctorUserId).Distinct().Count() == 2 &&
t.SubjectVisitTaskList.AsQueryable().Where(visitTaskFilter).GroupBy(t => new { t.SubjectId, t.VisitTaskNum }).Where(g => g.Count() == 2).Count() >= filterObj.PlanVisitCount
)
//.WhereIf(filterObj.IsHaveReadingPeriod == true, u => u.SubjectVisitTaskList.AsQueryable().Where(comonTaskFilter).Where(t => t.ReadingCategory == ReadingCategory.Visit || t.ReadingCategory == ReadingCategory.Global).OrderBy(t => t.VisitTaskNum).Take(filterObj.PlanVisitCount * 2 + 2).Any(t => t.ReadingCategory == ReadingCategory.Global))
.WhereIf(filterObj.IsHaveReadingPeriod == true, u => u.SubjectVisitTaskList.AsQueryable().Where(comonTaskFilter).Where(t => t.ReadingCategory == ReadingCategory.Global && t.VisitTaskNum > filterObj.PlanVisitCount - 1).Select(t => t.DoctorUserId).Distinct().Count() == 2)
;
var query = subjectQuery.Select(t => new DoctorGroupConsistentSubjectView()
{
TrialId = t.TrialId,
TrialSiteId = t.TrialSiteId,
SubjectCode = t.Code,
TrialSiteCode = t.TrialSite.TrialSiteCode,
SubjectId = t.Id,
IsReReadingOrBackInfluenceAnalysis = t.IsReReadingOrBackInfluenceAnalysis,
IsHaveGeneratedTask = t.SubjectVisitTaskList.Any(c => c.IsSelfAnalysis == false && c.TrialReadingCriterionId == trialReadingCriterionId),
DoctorUserList = t.SubjectDoctorList.Where(t => t.TrialReadingCriterionId == trialReadingCriterionId && t.IsConfirmed && t.ArmEnum <= Arm.DoubleReadingArm2).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(),
VisitTaskList = t.SubjectVisitTaskList.AsQueryable().Where(visitTaskFilter)
.Select(c => new VisitTaskGroupSimpleDTO()
{
ReadingCategory = c.ReadingCategory,
ReadingTaskState = c.ReadingTaskState,
TaskBlindName = c.TaskBlindName,
TaskName = c.TaskName,
TaskState = c.TaskState,
SubjectId = c.SubjectId,
VisitTaskNum = c.VisitTaskNum,
TrialId = c.TrialId,
DoctorUserId = c.DoctorUserId,
SourceSubjectVisitId = c.SourceSubjectVisitId,
SouceReadModuleId = c.SouceReadModuleId,
TrialReadingCriterionId = c.TrialReadingCriterionId,
IsClinicalDataSign = c.IsClinicalDataSign,
IsNeedClinicalDataSign = c.IsNeedClinicalDataSign,
}).ToList()
//
});
query = query.OrderByDescending(t => t.IsHaveGeneratedTask);
return query;
}
[HttpPost]
public async Task GetConsistentRule(TaskConsistentRuleQuery inQuery)
{
var IsReadingTaskViewInOrder = await _trialReadingCriterionRepository.Where(x => x.Id == inQuery.TrialReadingCriterionId).Select(x => x.IsReadingTaskViewInOrder).FirstNotNullAsync();
var result = await _taskConsistentRuleRepository.Where(t => t.TrialId == inQuery.TrialId && t.IsSelfAnalysis == inQuery.IsSelfAnalysis && t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId).ProjectTo(_mapper.ConfigurationProvider).FirstOrDefaultAsync();
return new GetConsistentRuleOut()
{
ConsistentRuleBasic = result,
IsReadingTaskViewInOrder = IsReadingTaskViewInOrder
};
}
///
/// 自身一致性分配 配置+ 统计已经生成数量统计表
///
///
///
[HttpPost]
public async Task>> GetSelfConsistentDoctorStatList(TaskConsistentRuleQuery inQuery)
{
var trialId = inQuery.TrialId;
//防止生成sql生成GETDATE() 时区导致的问题
var appDateTimeNow = DateTime.Now;
Expression> 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) < appDateTimeNow && u.DoctorUserId == doctorUserId;
Expression> visitTaskFilter = comonTaskFilter.And(t => t.ReadingCategory == ReadingCategory.Visit);
var taskConsistentRuleQueryable = from enroll in _enrollRepository.Where(t => t.TrialId == trialId && t.EnrollStatus == EnrollStatus.ConfirmIntoGroup
&& t.EnrollReadingCriteriaList.Any(c => c.TrialReadingCriterionId == inQuery.TrialReadingCriterionId && c.IsJoinAnalysis))
join user in _userRoleRepository.Where() on enroll.DoctorUserId equals user.Id
join taskConsistentRule in _taskConsistentRuleRepository.Where(t => t.TrialId == trialId && t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId && t.IsSelfAnalysis) on enroll.TrialId equals taskConsistentRule.TrialId
select new TaskConsistentRuleView()
{
Id = taskConsistentRule.Id,
CreateTime = taskConsistentRule.CreateTime,
BlindTrialSiteCode = taskConsistentRule.BlindTrialSiteCode,
BlindSubjectNumberOfPlaces = taskConsistentRule.BlindSubjectNumberOfPlaces,
CreateUserId = taskConsistentRule.CreateUserId,
IntervalWeeks = taskConsistentRule.IntervalWeeks,
IsEnable = taskConsistentRule.IsEnable,
PlanSubjectCount = taskConsistentRule.PlanSubjectCount,
Note = taskConsistentRule.Note,
TrialId = taskConsistentRule.TrialId,
UpdateTime = taskConsistentRule.UpdateTime,
UpdateUserId = taskConsistentRule.UpdateUserId,
IsGenerateGlobalTask = taskConsistentRule.IsGenerateGlobalTask,
IsHaveReadingPeriod = taskConsistentRule.IsHaveReadingPeriod,
PlanVisitCount = taskConsistentRule.PlanVisitCount,
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.AsQueryable()
.Where(t => taskConsistentRule.IsHaveReadingPeriod == false ? t.SubjectVisitTaskList.AsQueryable()
.Where(visitTaskFilter).Where(t => t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId && t.SignTime!.Value.AddDays(taskConsistentRule.IntervalWeeks * 7) < appDateTimeNow && t.DoctorUserId == user.Id)
.Count() >= taskConsistentRule.PlanVisitCount :
//全局要>计划访视数量后面
t.SubjectVisitTaskList.AsQueryable().Where(comonTaskFilter)
.Where(t => t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId && t.SignTime!.Value.AddDays(taskConsistentRule.IntervalWeeks * 7) < appDateTimeNow && t.DoctorUserId == user.Id)
.Where(t => t.ReadingCategory == ReadingCategory.Visit || t.ReadingCategory == ReadingCategory.Global).Any(t => t.ReadingCategory == ReadingCategory.Global && t.VisitTaskNum > taskConsistentRule.PlanVisitCount - 1)
&&
t.SubjectVisitTaskList.AsQueryable().Where(visitTaskFilter)
.Where(t => t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId && t.SignTime!.Value.AddDays(taskConsistentRule.IntervalWeeks * 7) < appDateTimeNow && t.DoctorUserId == user.Id)
.Count() >= taskConsistentRule.PlanVisitCount
)
.Count(),
AnalysisDoctorUser = new UserSimpleInfo()
{
UserId = user.Id,
UserCode = user.UserCode,
FullName = user.FullName,
UserName = user.UserName
}
};
//if (await _taskConsistentRuleRepository.AnyAsync(t => t.TrialId == inQuery.TrialId))
//{
// var rule = await _taskConsistentRuleRepository.Where(t => t.TrialId == inQuery.TrialId).ProjectTo(_mapper.ConfigurationProvider).FirstAsync();
// rule.IsBatchAdd = true;
// await BatchAddOrUpdateTaskConsistentRule(rule);
//}
//#endregion
//var taskConsistentRuleQueryable = _taskConsistentRuleRepository.Where(t => t.TrialId == inQuery.TrialId)
// .ProjectTo(_mapper.ConfigurationProvider);
var list = await taskConsistentRuleQueryable.ToListAsync();
var rule = await _taskConsistentRuleRepository.Where(t => t.TrialId == inQuery.TrialId && t.IsSelfAnalysis == true && t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId).ProjectTo(_mapper.ConfigurationProvider).FirstOrDefaultAsync();
return ResponseOutput.Ok(list, rule);
}
[HttpPost]
[UnitOfWork]
[TrialGlobalLimit( "AfterStopCannNotOpt" )]
public async Task UpdateTrialVirtualSiteCode(UpdateTrialSiteCodeCommand inCommand)
{
if (_trialSiteRepository.Where(t => t.TrialId == inCommand.TrialId, false, true).Any(t => t.TrialSiteCode == inCommand.VirtualSiteCode))
{
return ResponseOutput.NotOk(_localizer["TaskConsistent_SiteCodeExists"]);
}
var trial = await _trialRepository.FirstOrDefaultAsync(t => t.Id == inCommand.TrialId);
var oldCode = trial.VitrualSiteCode;
trial.VitrualSiteCode = inCommand.VirtualSiteCode;
await _visitTaskRepository.BatchUpdateNoTrackingAsync(t => t.TrialId == trial.Id, u => new VisitTask() { BlindTrialSiteCode = inCommand.VirtualSiteCode });
await _taskConsistentRuleRepository.BatchUpdateNoTrackingAsync(t => t.TrialId == trial.Id, u => new TaskConsistentRule() { BlindTrialSiteCode = inCommand.VirtualSiteCode });
await _visitTaskRepository.ExecuteUpdateAsync(t => t.TrialId == trial.Id, s => s.SetProperty(e => e.BlindSubjectCode, u => u.BlindSubjectCode.Replace(oldCode, inCommand.VirtualSiteCode)));
await _trialVirtualSiteCodeUpdateRepository.AddAsync(new TrialVirtualSiteCodeUpdate() { VirturalSiteCode = inCommand.VirtualSiteCode, TrialId = inCommand.TrialId });
await _trialRepository.SaveChangesAsync();
return ResponseOutput.Ok();
}
public async Task> GetUpdateVirtualSiteCodeList(Guid trialId)
{
var list = await _trialVirtualSiteCodeUpdateRepository.Where(t => t.TrialId == trialId).Select(t => new UpdateTrialSiteCodeCommandView() { TrialId = trialId, VirtualSiteCode = t.VirturalSiteCode, Creatime = t.CreateTime }).OrderByDescending(t => t.Creatime).ToListAsync();
return list;
}
[TrialGlobalLimit( "AfterStopCannNotOpt" )]
public async Task AddOrUpdateTaskConsistentRule(TaskConsistentRuleAddOrEdit addOrEditTaskConsistentRule)
{
var verifyExp1 = new EntityVerifyExp()
{
VerifyExp = t => t.TrialId == addOrEditTaskConsistentRule.TrialId && t.IsSelfAnalysis == addOrEditTaskConsistentRule.IsSelfAnalysis && t.TrialReadingCriterionId == addOrEditTaskConsistentRule.TrialReadingCriterionId,
//"已有该项目配置,不允许继续增加"
VerifyMsg = _localizer["TaskConsistent_TaskGenerated"]
};
if (await _visitTaskRepository.AnyAsync(t => t.IsSelfAnalysis == addOrEditTaskConsistentRule.IsSelfAnalysis && t.TrialId == addOrEditTaskConsistentRule.TrialId && t.TrialReadingCriterionId == addOrEditTaskConsistentRule.TrialReadingCriterionId))
{
//"该标准已有Subject 生成了任务,不允许修改配置"
return ResponseOutput.NotOk(_localizer["TaskConsistent_MedicalAuditTaskExists"]);
}
if (_trialSiteRepository.Where(t => t.TrialId == addOrEditTaskConsistentRule.TrialId, false, true).Any(t => t.TrialSiteCode == addOrEditTaskConsistentRule.BlindTrialSiteCode))
{
return ResponseOutput.NotOk(_localizer["TaskConsistent_SiteCodeExists"]);
}
var trial = await _trialRepository.FirstOrDefaultAsync(t => t.Id == addOrEditTaskConsistentRule.TrialId);
if (string.IsNullOrEmpty(trial.VitrualSiteCode))
{
await _trialVirtualSiteCodeUpdateRepository.AddAsync(new TrialVirtualSiteCodeUpdate() { VirturalSiteCode = addOrEditTaskConsistentRule.BlindTrialSiteCode, TrialId = addOrEditTaskConsistentRule.TrialId });
}
trial.VitrualSiteCode = addOrEditTaskConsistentRule.BlindTrialSiteCode;
var entity = await _taskConsistentRuleRepository.InsertOrUpdateAsync(addOrEditTaskConsistentRule, true, verifyExp1);
return ResponseOutput.Ok(entity.Id.ToString());
}
[TrialGlobalLimit( "AfterStopCannNotOpt" )]
[HttpDelete("{taskConsistentRuleId:guid}")]
public async Task DeleteTaskConsistentRule(Guid taskConsistentRuleId)
{
var config = await _taskConsistentRuleRepository.FirstOrDefaultAsync(t => t.Id == taskConsistentRuleId);
if (await _visitTaskRepository.AnyAsync(t => t.IsAnalysisCreate && t.TrialId == config.TrialId && t.IsSelfAnalysis == config.IsSelfAnalysis && t.TrialReadingCriterionId == config.TrialReadingCriterionId))
{
//"该标准已产生一致性分析任务,不允许删除"
throw new BusinessValidationFailedException(_localizer["TaskConsistent_SignedTaskCannotBeInvalidated"]);
}
var success = await _taskConsistentRuleRepository.DeleteFromQueryAsync(t => t.Id == taskConsistentRuleId, true);
return ResponseOutput.Ok();
}
///
/// 获取自身一致性分析 符合条件的subject 数组
///
///
///
public async Task> 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;
}
///
/// 获取组件一致性分析符合条件的subject 数组
///
///
///
public async Task> 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;
}
}
}