//-------------------------------------------------------------------- // 此代码由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; using IRaCIS.Core.Infra.EFCore.Common; using System.Linq.Expressions; using IRaCIS.Application.Contracts; using IRaCIS.Core.Application.Filter; using DocumentFormat.OpenXml.Office2010.Word; using System.Linq.Dynamic.Core; using System.Linq; using DocumentFormat.OpenXml.Bibliography; using Org.BouncyCastle.Crypto; using IRaCIS.Core.Domain.Share.Reading; using Quartz; using IRaCIS.Application.Services.BackGroundJob; using Magicodes.ExporterAndImporter.Core.Extension; using Hangfire; using MassTransit; using static IRaCIS.Core.Domain.Models.ReadingQuestionTrial; namespace IRaCIS.Core.Application.Service.Allocation { /// /// 访视读片任务 /// [ApiExplorerSettings(GroupName = "Trial")] public class VisitTaskService : BaseService, IVisitTaskService { private readonly IRepository _visitTaskRepository; private readonly IRepository _trialRepository; private readonly IRepository _subjectVisitRepository; private readonly IRepository _subjectRepository; private readonly IRepository _readModuleRepository; private readonly IRepository _visitTaskReReadingRepository; private readonly IRepository _taskMedicalReviewRepository; private readonly IRepository _readingTaskQuestionAnswerRepository; private readonly IRepository _readingQuestionTrialRepository; private readonly IRepository _readingClinicalDataReposiotry; private readonly IRepository _trialReadingCriterionRepository; private readonly IRepository _PIAuditRepository; public VisitTaskService(IRepository subjectVisitRepository, IRepository visitTaskRepository, IRepository trialRepository, IRepository subjectRepository, IRepository readModuleRepository, IRepository visitTaskReReadingRepository, IRepository taskMedicalReviewRepository, IRepository readingTaskQuestionAnswerRepository , IRepository trialReadingCriterionRepository, IRepository readingClinicalDataReposiotry, IRepository PIAuditRepository, IRepository readingQuestionTrialRepository ) { _PIAuditRepository = PIAuditRepository; _readingClinicalDataReposiotry = readingClinicalDataReposiotry; _visitTaskRepository = visitTaskRepository; _trialRepository = trialRepository; _subjectVisitRepository = subjectVisitRepository; _subjectRepository = subjectRepository; _readModuleRepository = readModuleRepository; _visitTaskReReadingRepository = visitTaskReReadingRepository; _taskMedicalReviewRepository = taskMedicalReviewRepository; _readingTaskQuestionAnswerRepository = readingTaskQuestionAnswerRepository; _trialReadingCriterionRepository = trialReadingCriterionRepository; _readingQuestionTrialRepository = readingQuestionTrialRepository; } /// /// 设置任务加急 /// /// /// [HttpPost] public async Task SetTaskUrgent(SetTaskUrgentInDto inDto) { await _visitTaskRepository.UpdatePartialFromQueryAsync(inDto.VisitTaskId, x => new VisitTask() { IsUrgent = inDto.IsUrgent, TaskUrgentType = inDto.TaskUrgentType, TaskUrgentRemake = inDto.TaskUrgentRemake, }); return await _visitTaskRepository.SaveChangesAsync(); } public async Task> GetTrialCriterionList(Guid trialId, bool isHaveSigned = true, bool? isAutoCreate = null) { var list = await _repository.Where(t => t.TrialId == trialId && t.IsConfirm) .OrderBy(t => t.ShowOrder) .Select(t => new TrialReadingCriterionDto() { TrialReadingCriterionId = t.Id, IsAutoCreate = t.IsAutoCreate, IsAdditionalAssessment = t.IsAdditionalAssessment, TrialReadingCriterionName = t.CriterionName, CriterionType = t.CriterionType, ReadingType = t.ReadingType, ReadingInfoSignTime = t.ReadingInfoSignTime , IsReadingPeriod= t.IsReadingPeriod }) .ToListAsync(); return list.AsQueryable().WhereIf(isHaveSigned == true, t => t.ReadingInfoSignTime != null) .WhereIf(isAutoCreate == false, t => t.IsAutoCreate == isAutoCreate).ToList(); } /// /// 获取项目下 阅片人下拉 /// /// /// [HttpGet("{trialId:guid}")] public async Task> GetTrialDoctorUserSelectList(Guid trialId) { var query = from trialUser in _trialRepository.Where(t => t.Id == trialId).SelectMany(t => t.TrialUserList).Where(t => t.User.UserTypeEnum == UserTypeEnum.SR || t.User.UserTypeEnum == UserTypeEnum.PI) select new TrialDoctorUserSelectView() { TrialId = trialUser.TrialId, //ReadingType = enroll.Trial.ReadingType, DoctorUserId = trialUser.UserId, FullName = trialUser.User.FullName, UserCode = trialUser.User.UserCode, UserName = trialUser.User.UserName, UserTypeEnum = trialUser.User.UserTypeRole.UserTypeEnum }; return await query.ToListAsync(); } /// /// 访视任务 /// /// /// /// [HttpPost] public async Task> 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 && t.IsAnalysisCreate == false) .WhereIf(queryVisitTask.ReadingCategory != null, t => t.ReadingCategory == queryVisitTask.ReadingCategory) .WhereIf(queryVisitTask.ReadingCategory == null, t => t.ReadingCategory != ReadingCategory.Judge) .WhereIf(queryVisitTask.TaskState != null, t => t.TaskState == queryVisitTask.TaskState) .WhereIf(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.TaskAllocationState != null, t => t.TaskAllocationState == queryVisitTask.TaskAllocationState) .WhereIf(queryVisitTask.TrialReadingCriterionId != null, t => t.TrialReadingCriterionId == queryVisitTask.TrialReadingCriterionId) .WhereIf(!string.IsNullOrEmpty(queryVisitTask.TrialSiteCode), t => (t.BlindTrialSiteCode.Contains(queryVisitTask.TrialSiteCode!) && t.IsAnalysisCreate) || (t.Subject.TrialSite.TrialSiteCode.Contains(queryVisitTask.TrialSiteCode!) && t.IsAnalysisCreate == false)) .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) && t.IsAnalysisCreate == false) || (t.BlindSubjectCode.Contains(queryVisitTask.SubjectCode) && t.IsAnalysisCreate)) .WhereIf(queryVisitTask.BeginAllocateDate != null, t => t.AllocateTime > queryVisitTask.BeginAllocateDate) .WhereIf(queryVisitTask.EndAllocateDate != null, t => t.AllocateTime < queryVisitTask.EndAllocateDate!.Value.AddDays(1)) .ProjectTo(_mapper.ConfigurationProvider); var defalutSortArray = new string[] { nameof(VisitTask.IsUrgent) + " desc", nameof(VisitTask.SubjectId), nameof(VisitTask.VisitTaskNum) }; 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(_mapper.ConfigurationProvider).FirstOrDefault(); return pageList; } private IQueryable GetReadingTaskQueryable(VisitTaskQuery queryVisitTask) { var trialConfig = _trialRepository.Where(t => t.Id == queryVisitTask.TrialId).Select(t => new { t.EnrollConfirmDefaultUserType, t.PDProgressDefaultUserType }).FirstOrDefault(); var visitTaskQueryable = _visitTaskRepository.Where(t => t.TrialId == queryVisitTask.TrialId && t.IsAnalysisCreate == false) .WhereIf(queryVisitTask.TaskState != null, t => t.TaskState == queryVisitTask.TaskState) .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.TaskAllocationState != null, t => t.TaskAllocationState == queryVisitTask.TaskAllocationState) .WhereIf(queryVisitTask.TrialReadingCriterionId != null, t => t.TrialReadingCriterionId == queryVisitTask.TrialReadingCriterionId) .WhereIf(queryVisitTask.ReReadingApplyState != null, t => t.ReReadingApplyState == queryVisitTask.ReReadingApplyState) .WhereIf(queryVisitTask.CompleteClinicalDataEnum == CompleteClinicalDataEnum.Complete, t => t.IsClinicalDataSign && t.IsNeedClinicalDataSign == true) .WhereIf(queryVisitTask.CompleteClinicalDataEnum == CompleteClinicalDataEnum.NotComplete, t => t.IsClinicalDataSign == false && t.IsNeedClinicalDataSign == true) .WhereIf(queryVisitTask.CompleteClinicalDataEnum == CompleteClinicalDataEnum.NA, t => t.IsNeedClinicalDataSign == false) .WhereIf(!string.IsNullOrEmpty(queryVisitTask.TrialSiteCode), t => (t.BlindTrialSiteCode.Contains(queryVisitTask.TrialSiteCode!) && t.IsAnalysisCreate) || (t.Subject.TrialSite.TrialSiteCode.Contains(queryVisitTask.TrialSiteCode!) && t.IsAnalysisCreate == false)) .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) && t.IsAnalysisCreate == false) || (t.BlindSubjectCode.Contains(queryVisitTask.SubjectCode) && t.IsAnalysisCreate)) .WhereIf(queryVisitTask.BeginAllocateDate != null, t => t.AllocateTime > queryVisitTask.BeginAllocateDate) .WhereIf(queryVisitTask.EndAllocateDate != null, t => t.AllocateTime < queryVisitTask.EndAllocateDate!.Value.AddDays(1)) .WhereIf(trialConfig?.EnrollConfirmDefaultUserType == UserTypeEnum.MIM && trialConfig?.PDProgressDefaultUserType != UserTypeEnum.MIM && _userInfo.UserTypeEnumInt == (int)UserTypeEnum.MIM , t => t.SourceSubjectVisit.IsBaseLine == true) .WhereIf(trialConfig?.EnrollConfirmDefaultUserType != UserTypeEnum.MIM && trialConfig?.PDProgressDefaultUserType == UserTypeEnum.MIM && _userInfo.UserTypeEnumInt == (int)UserTypeEnum.MIM, t => t.SourceSubjectVisit.IsBaseLine == false) .WhereIf(queryVisitTask.IsWaitPIAudit == true, t => t.FirstAuditUserId == null) .WhereIf(queryVisitTask.IsWaitPIAudit == false, t => t.FirstAuditUserId != null) .WhereIf(queryVisitTask.PIAuditState != null, t => t.PIAuditState == queryVisitTask.PIAuditState) .WhereIf(queryVisitTask.FirstAuditTimeBegin != null, t => t.AllocateTime > queryVisitTask.FirstAuditTimeBegin) .WhereIf(queryVisitTask.FirstAuditTimeEnd != null, t => t.AllocateTime < queryVisitTask.FirstAuditTimeEnd) .WhereIf(queryVisitTask.LatestReplyTimeBegin != null, t => t.AllocateTime > queryVisitTask.LatestReplyTimeBegin) .WhereIf(queryVisitTask.LatestReplyTimeEnd != null, t => t.AllocateTime < queryVisitTask.LatestReplyTimeEnd); return visitTaskQueryable; } [HttpPost] public async Task>> GetPIReadingAuditList(VisitTaskQuery queryVisitTask) { //CriterionType? criterionType = _trialReadingCriterionRepository.Where(t => t.Id == queryVisitTask.TrialReadingCriterionId).Select(t=>t.CriterionType).FirstOrDefault(); var visitTaskQueryable = GetReadingTaskQueryable(queryVisitTask) .ProjectTo(_mapper.ConfigurationProvider); var defalutSortArray = new string[] { nameof(VisitTask.IsUrgent) + " desc", nameof(VisitTask.SubjectId), nameof(VisitTask.VisitTaskNum) }; 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(_mapper.ConfigurationProvider).FirstOrDefault(); var questionList = _readingQuestionTrialRepository.Where(t => t.TrialId == queryVisitTask.TrialId && t.ReadingQuestionCriterionTrialId == queryVisitTask.TrialReadingCriterionId) .Where(t => t.IsJudgeQuestion == true) //.WhereIf(criterionType!=null&& criterionType!=CriterionType.SelfDefine,t=>t.IsJudgeQuestion==true) // .WhereIf(criterionType != null && criterionType == CriterionType.SelfDefine, t => t.AssessmentResultEnum == AssessmentResultType.AssessmentResult) .Select(t => new { QuestionId = t.Id, QuestionName = _userInfo.IsEn_Us ? t.QuestionEnName : t.QuestionName ,t.DictionaryCode}).ToList(); trialTaskConfig!.OtherObj = questionList; return ResponseOutput.Ok(pageList, trialTaskConfig); } /// ///new- 首次审核 后续编辑审核 /// /// /// [HttpPost] public async Task PIAuditTask(PIAuditTaskCommand incommand) { //需要设置首次审核时间 审核人 var visitTask = await _visitTaskRepository.FirstOrDefaultAsync(t => t.Id == incommand.VisitTaskId); var isFirstAudit = visitTask.FirstAuditUserId == null; visitTask.NotAgreeReason = incommand.NotAgreeReason; visitTask.PIAuditNote = incommand.PIAuditNote; visitTask.PIAuditImagePath = string.Join('|', incommand.PIAuditImagePathList); visitTask.PIAuditState = incommand.PIAuditState; visitTask.LatestReplyUserId = _userInfo.Id; visitTask.LatestReplyTime = DateTime.Now; visitTask.IsEnrollment = incommand.PIAuditState == PIAuditState.PINotAgree ? null : visitTask.IsEnrollment; visitTask.IsPDConfirm = incommand.PIAuditState == PIAuditState.PINotAgree ? null : visitTask.IsPDConfirm; if (isFirstAudit) { visitTask.FirstAuditUserId = _userInfo.Id; visitTask.FirstAuditTime = DateTime.Now; } //发送对话 var addDialig = _mapper.Map(incommand); addDialig.PIAuditState = incommand.PIAuditState; addDialig.PIAuditImagePath = visitTask.PIAuditImagePath; await _PIAuditRepository.AddAsync(addDialig); await _visitTaskRepository.SaveChangesAsync(); return ResponseOutput.Ok(); } [HttpPost] [UnitOfWork] public async Task PIAuditTaskEnrollOrPD(PIAuditTaskEnrollOrPdCommand incommand, [FromServices] IEmailSendService emailSendService) { var visitTask = await _visitTaskRepository.FirstOrDefaultAsync(t => t.Id == incommand.VisitTaskId); visitTask.IsEnrollment = incommand.IsEnrollment != null ? incommand.IsEnrollment : visitTask.IsEnrollment; visitTask.IsPDConfirm = incommand.IsPDConfirm != null ? incommand.IsPDConfirm : visitTask.IsPDConfirm; visitTask.LatestReplyUserId = _userInfo.Id; visitTask.LatestReplyTime = DateTime.Now; await _visitTaskRepository.SaveChangesAsync(); await emailSendService.SendEnrollOrPdEmail(visitTask.Id, incommand.IsEnrollment, incommand.IsPDConfirm); return ResponseOutput.Ok(); } /// ///new- 回复审核内容 /// /// /// public async Task PIAuditTaskReply(PIAuditTaskReplyCommand incommand) { await _PIAuditRepository.AddAsync(new PIAudit() { ReplyContent = incommand.ReplyContent, VisitTaskId = incommand.VisitTaskId }); await _PIAuditRepository.SaveChangesAsync(); return ResponseOutput.Ok(); } /// /// new- 获取审核对话列表 /// /// /// [HttpPost] public async Task> GetPIAuditDialogList(PIAuditDialogQuery inQuery) { var list = await _PIAuditRepository.Where(t => t.VisitTaskId == inQuery.VisitTaskId).OrderBy(t => t.CreateTime).ProjectTo(_mapper.ConfigurationProvider).ToListAsync(); foreach (var item in list) { item.IsCurrentUser = item.CreateUserId == _userInfo.Id; } return list; } public async Task AddClinicalDataDialog(Guid visiTaskId, string content, [FromServices] IRepository subjectVisitClinicalDialogRepository, [FromServices] IEmailSendService emailSendService) { var taskInfo = await _visitTaskRepository.Where(t => t.Id == visiTaskId).Select(t => new { t.SourceSubjectVisitId, t.Subject.Code, t.SourceSubjectVisit.VisitName, t.Trial.ResearchProgramNo, t.Trial.TrialCode }).FirstOrDefaultAsync(); await subjectVisitClinicalDialogRepository.AddAsync(new SubjectVisitClinicalDialog() { SubjectVisitId = (Guid)taskInfo.SourceSubjectVisitId, Content = content }, true); await emailSendService.SendClinicalDataQuestionAsync(visiTaskId, content); return ResponseOutput.Ok(); } public async Task> GetClinicalDataDialog(Guid visiTaskId, [FromServices] IRepository _subjectVisitClinicalDialogRepository) { var subjectVisitId = await _visitTaskRepository.Where(t => t.Id == visiTaskId).Select(t => t.SourceSubjectVisitId).FirstOrDefaultAsync(); var list = _subjectVisitClinicalDialogRepository.Where(t => t.SubjectVisitId == subjectVisitId).ProjectTo(_mapper.ConfigurationProvider).OrderByDescending(t => t.CreateTime).ToList(); return list; } /// /// PM阅片跟踪 /// /// /// [HttpPost] public async Task>> GetReadingTaskList(VisitTaskQuery queryVisitTask) { var visitTaskQueryable = GetReadingTaskQueryable(queryVisitTask) .ProjectTo(_mapper.ConfigurationProvider,new { isEn_Us =_userInfo.IsEn_Us }); var defalutSortArray = new string[] { nameof(VisitTask.IsUrgent) + " desc", nameof(VisitTask.SubjectId), nameof(VisitTask.VisitTaskNum) }; 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(_mapper.ConfigurationProvider).FirstOrDefault(); var questionList = _readingQuestionTrialRepository.Where(t => t.TrialId == queryVisitTask.TrialId && t.Id == queryVisitTask.TrialReadingCriterionId) .Where(t => t.IsJudgeQuestion == true) .Select(t => new { QuestionId = t.Id, QuestionName = _userInfo.IsEn_Us ? t.QuestionEnName : t.QuestionName, t.DictionaryCode }).ToList(); trialTaskConfig!.OtherObj = questionList; return ResponseOutput.Ok(pageList, trialTaskConfig); } /// /// PM 重阅追踪 /// /// /// [HttpPost] public async Task> GetReReadingTaskList(VisitTaskQuery queryVisitTask) { var visitTaskQueryable = _visitTaskReReadingRepository .Where(t => t.OriginalReReadingTask.TrialId == queryVisitTask.TrialId /*&& t.OriginalReReadingTask.IsAnalysisCreate == false*/) .WhereIf(queryVisitTask.RootReReadingTaskId != null, t => t.RootReReadingTaskId == queryVisitTask.RootReReadingTaskId || t.OriginalReReadingTaskId == queryVisitTask.RootReReadingTaskId) .WhereIf(!string.IsNullOrEmpty(queryVisitTask.TaskCode), t => t.OriginalReReadingTask.TaskCode.Contains(queryVisitTask.TaskCode!) || t.RootReReadingTask.TaskCode.Contains(queryVisitTask.TaskCode!)) .WhereIf(queryVisitTask.SiteId != null, t => t.OriginalReReadingTask.Subject.SiteId == queryVisitTask.SiteId) .WhereIf(queryVisitTask.TaskState != null, t => t.OriginalReReadingTask.TaskState == queryVisitTask.TaskState) .WhereIf(queryVisitTask.ReReadingApplyState != null, t => t.OriginalReReadingTask.ReReadingApplyState == queryVisitTask.ReReadingApplyState) .WhereIf(queryVisitTask.RequestReReadingType != null, t => t.RequestReReadingType == queryVisitTask.RequestReReadingType) .WhereIf(queryVisitTask.SubjectId != null, t => t.OriginalReReadingTask.SubjectId == queryVisitTask.SubjectId) .WhereIf(queryVisitTask.IsUrgent != null, t => t.OriginalReReadingTask.IsUrgent == queryVisitTask.IsUrgent) .WhereIf(queryVisitTask.DoctorUserId != null, t => t.OriginalReReadingTask.DoctorUserId == queryVisitTask.DoctorUserId) .WhereIf(queryVisitTask.ReadingTaskState != null, t => t.OriginalReReadingTask.ReadingTaskState == queryVisitTask.ReadingTaskState) .WhereIf(queryVisitTask.TaskAllocationState != null, t => t.OriginalReReadingTask.TaskAllocationState == queryVisitTask.TaskAllocationState) .WhereIf(queryVisitTask.TrialReadingCriterionId != null, t => t.OriginalReReadingTask.TrialReadingCriterionId == queryVisitTask.TrialReadingCriterionId) .WhereIf(queryVisitTask.ReadingCategory != null, t => t.OriginalReReadingTask.ReadingCategory == queryVisitTask.ReadingCategory) .WhereIf(!string.IsNullOrEmpty(queryVisitTask.RequestReReadingReason), t => t.RequestReReadingReason.Contains(queryVisitTask.RequestReReadingReason)) .WhereIf(queryVisitTask.RequestReReadingResultEnum != null, t => t.RequestReReadingResultEnum == queryVisitTask.RequestReReadingResultEnum) .WhereIf(queryVisitTask.PIAuditState != null, t => t.OriginalReReadingTask.PIAuditState == queryVisitTask.PIAuditState) .WhereIf(!string.IsNullOrEmpty(queryVisitTask.TrialSiteCode), t => (t.OriginalReReadingTask.BlindTrialSiteCode.Contains(queryVisitTask.TrialSiteCode!) && t.OriginalReReadingTask.IsAnalysisCreate) || (t.OriginalReReadingTask.Subject.TrialSite.TrialSiteCode.Contains(queryVisitTask.TrialSiteCode!) && t.OriginalReReadingTask.IsAnalysisCreate == false)) .WhereIf(!string.IsNullOrEmpty(queryVisitTask.TaskName), t => t.OriginalReReadingTask.TaskName.Contains(queryVisitTask.TaskName) || t.OriginalReReadingTask.TaskBlindName.Contains(queryVisitTask.TaskName)) .WhereIf(!string.IsNullOrEmpty(queryVisitTask.SubjectCode), t => (t.OriginalReReadingTask.Subject.Code.Contains(queryVisitTask.SubjectCode) && t.OriginalReReadingTask.IsAnalysisCreate == false) || (t.OriginalReReadingTask.BlindSubjectCode.Contains(queryVisitTask.SubjectCode) && t.OriginalReReadingTask.IsAnalysisCreate)) .WhereIf(queryVisitTask.BeginAllocateDate != null, t => t.OriginalReReadingTask.AllocateTime > queryVisitTask.BeginAllocateDate) .WhereIf(queryVisitTask.EndAllocateDate != null, t => t.OriginalReReadingTask.AllocateTime < queryVisitTask.EndAllocateDate!.Value.AddDays(1)) .ProjectTo(_mapper.ConfigurationProvider); //var defalutSortArray = new string[] { nameof(ReReadingTaskView.OriginalReReadingTask) + "." + nameof(ReReadingTaskView.OriginalReReadingTask.IsUrgent) + " desc", nameof(ReReadingTaskView.OriginalReReadingTask) + "." + nameof(ReReadingTaskView.OriginalReReadingTask.SubjectId), nameof(ReReadingTaskView.OriginalReReadingTask) + "." + nameof(ReReadingTaskView.OriginalReReadingTask.VisitTaskNum) }; var defalutSortArray = new string[] { nameof(ReReadingTaskView.RequestReReadingResultEnum) , nameof(ReReadingTaskView.OriginalReReadingTask) + "." + nameof(ReReadingTaskView.OriginalReReadingTask.IsUrgent) + " desc", nameof(ReReadingTaskView.OriginalReReadingTask) + "." + nameof(ReReadingTaskView.OriginalReReadingTask.TaskState), nameof(ReReadingTaskView.OriginalReReadingTask) + "." + nameof(ReReadingTaskView.OriginalReReadingTask.SubjectId),nameof(ReReadingTaskView.OriginalReReadingTask) + "." + nameof(ReReadingTaskView.OriginalReReadingTask.VisitTaskNum) }; var pageList = await visitTaskQueryable.ToPagedListAsync(queryVisitTask.PageIndex, queryVisitTask.PageSize, queryVisitTask.SortField, queryVisitTask.Asc, string.IsNullOrWhiteSpace(queryVisitTask.SortField), defalutSortArray); return pageList; } /// /// 获取IR 重阅影像阅片列表 /// /// /// [HttpPost] public async Task> GetIRReReadingTaskList(VisitTaskQuery queryVisitTask) { var visitTaskQueryable = _visitTaskReReadingRepository .Where(t => t.RequestReReadingType == RequestReReadingType.DocotorApply) .Where(t => t.OriginalReReadingTask.DoctorUserId == _userInfo.Id) .Where(t => t.OriginalReReadingTask.TrialId == queryVisitTask.TrialId) .WhereIf(queryVisitTask.RootReReadingTaskId != null, t => t.RootReReadingTaskId == queryVisitTask.RootReReadingTaskId || t.OriginalReReadingTaskId == queryVisitTask.RootReReadingTaskId) .WhereIf(!string.IsNullOrEmpty(queryVisitTask.TaskCode), t => t.OriginalReReadingTask.TaskCode.Contains(queryVisitTask.TaskCode!) || t.RootReReadingTask.TaskCode.Contains(queryVisitTask.TaskCode!)) .WhereIf(queryVisitTask.TaskState != null, t => t.OriginalReReadingTask.TaskState == queryVisitTask.TaskState) .WhereIf(queryVisitTask.ReReadingApplyState != null, t => t.OriginalReReadingTask.ReReadingApplyState == queryVisitTask.ReReadingApplyState) .WhereIf(queryVisitTask.SiteId != null, t => t.OriginalReReadingTask.Subject.SiteId == queryVisitTask.SiteId) .WhereIf(queryVisitTask.SubjectId != null, t => t.OriginalReReadingTask.SubjectId == queryVisitTask.SubjectId) .WhereIf(queryVisitTask.IsUrgent != null, t => t.OriginalReReadingTask.IsUrgent == queryVisitTask.IsUrgent) .WhereIf(queryVisitTask.DoctorUserId != null, t => t.OriginalReReadingTask.DoctorUserId == queryVisitTask.DoctorUserId) .WhereIf(queryVisitTask.ReadingTaskState != null, t => t.OriginalReReadingTask.ReadingTaskState == queryVisitTask.ReadingTaskState) .WhereIf(queryVisitTask.TaskAllocationState != null, t => t.OriginalReReadingTask.TaskAllocationState == queryVisitTask.TaskAllocationState) .WhereIf(queryVisitTask.TrialReadingCriterionId != null, t => t.OriginalReReadingTask.TrialReadingCriterionId == queryVisitTask.TrialReadingCriterionId) .WhereIf(!string.IsNullOrEmpty(queryVisitTask.TrialSiteCode), t => (t.OriginalReReadingTask.BlindTrialSiteCode.Contains(queryVisitTask.TrialSiteCode!) && t.OriginalReReadingTask.IsAnalysisCreate) || (t.OriginalReReadingTask.Subject.TrialSite.TrialSiteCode.Contains(queryVisitTask.TrialSiteCode!) && t.OriginalReReadingTask.IsAnalysisCreate == false)) .WhereIf(!string.IsNullOrEmpty(queryVisitTask.TaskName), t => t.OriginalReReadingTask.TaskName.Contains(queryVisitTask.TaskName) || t.NewReReadingTask.TaskBlindName.Contains(queryVisitTask.TaskName)) .WhereIf(!string.IsNullOrEmpty(queryVisitTask.SubjectCode), t => (t.OriginalReReadingTask.Subject.Code.Contains(queryVisitTask.SubjectCode) && t.OriginalReReadingTask.IsAnalysisCreate == false) || (t.OriginalReReadingTask.BlindSubjectCode.Contains(queryVisitTask.SubjectCode) && t.OriginalReReadingTask.IsAnalysisCreate)) .WhereIf(queryVisitTask.BeginAllocateDate != null, t => t.OriginalReReadingTask.AllocateTime > queryVisitTask.BeginAllocateDate) .WhereIf(queryVisitTask.EndAllocateDate != null, t => t.OriginalReReadingTask.AllocateTime < queryVisitTask.EndAllocateDate!.Value.AddDays(1)) .ProjectTo(_mapper.ConfigurationProvider); var defalutSortArray = new string[] { nameof(ReReadingTaskView.OriginalReReadingTask) + "." + nameof(ReReadingTaskView.OriginalReReadingTask.IsUrgent) + " desc", nameof(ReReadingTaskView.OriginalReReadingTask) + "." + nameof(ReReadingTaskView.OriginalReReadingTask.SubjectId), nameof(ReReadingTaskView.OriginalReReadingTask) + "." + nameof(ReReadingTaskView.OriginalReReadingTask.VisitTaskNum) }; var pageList = await visitTaskQueryable.ToPagedListAsync(queryVisitTask.PageIndex, queryVisitTask.PageSize, queryVisitTask.SortField, queryVisitTask.Asc, string.IsNullOrWhiteSpace(queryVisitTask.SortField), defalutSortArray); return pageList; } /// /// IR 待阅片任务列表 /// /// [HttpPost] public async Task<(PageOutput, object)> GetIRUnReadSubjectTaskList(IRUnReadSubjectQuery iRUnReadSubjectQuery) { var trialId = iRUnReadSubjectQuery.TrialId; var trialReadingCriterionId = iRUnReadSubjectQuery.TrialReadingCriterionId; var critrion = await _trialReadingCriterionRepository.Where(x => x.Id == iRUnReadSubjectQuery.TrialReadingCriterionId).FirstNotNullAsync(); var readingTool = critrion.ReadingTool; var isReadingTaskViewInOrder = critrion.IsReadingTaskViewInOrder; #region 按照Subject 维度 if (isReadingTaskViewInOrder) { var visitTaskListInfo = await GetOrderReadingIQueryable(new GetOrderReadingIQueryableInDto() { TrialId = trialId, TrialReadingCriterionId = trialReadingCriterionId, SubjectCode = iRUnReadSubjectQuery.SubjectCode, Page = new PageInput() { PageIndex = iRUnReadSubjectQuery.PageIndex, PageSize = iRUnReadSubjectQuery.PageSize, Asc = iRUnReadSubjectQuery.Asc, SortField = iRUnReadSubjectQuery.SortField, } }); var totalCount = visitTaskListInfo.Item1; var currentPageData = visitTaskListInfo.Item2; var result = new PageOutput() { PageSize = iRUnReadSubjectQuery.PageSize, PageIndex = iRUnReadSubjectQuery.PageIndex, TotalCount = totalCount, CurrentPageData = currentPageData, }; // 封装的方法有问题 //var result = await visitQuery.ToPagedListAsync(iRUnReadSubjectQuery.PageIndex, iRUnReadSubjectQuery.PageSize, String.IsNullOrEmpty(iRUnReadSubjectQuery.SortField) ? nameof(IRUnReadSubjectView.SubjectId) : iRUnReadSubjectQuery.SortField, iRUnReadSubjectQuery.Asc); return (result, new { RandomReadInfo = new IRUnReadOutDto(), IsReadingTaskViewInOrder = isReadingTaskViewInOrder, ReadingTool = readingTool, IseCRFShowInDicomReading = critrion.IseCRFShowInDicomReading, IsReadingShowSubjectInfo = critrion.IsReadingShowSubjectInfo, IsReadingShowPreviousResults = critrion.IsReadingShowPreviousResults, DigitPlaces = critrion.DigitPlaces, CriterionType = critrion.CriterionType, }); } else { var taskQuery = await GetNotOrderReadingQueryableAsync(iRUnReadSubjectQuery.TrialId, trialReadingCriterionId); IRUnReadOutDto iRUnReadOut = new IRUnReadOutDto() { FinishTaskCount = await taskQuery.Where(x => x.ReadingCategory != ReadingCategory.Judge && x.ReadingTaskState == ReadingTaskState.HaveSigned).CountAsync(), SuggesteFinishedTime = await taskQuery.Where(x => x.ReadingTaskState != ReadingTaskState.HaveSigned).MaxAsync(x => x.SuggesteFinishedTime), UnReadTaskCount = await taskQuery.Where(x => x.ReadingCategory != ReadingCategory.Judge && x.ReadingTaskState != ReadingTaskState.HaveSigned).CountAsync(), }; var result = new PageOutput() { PageSize = iRUnReadSubjectQuery.PageSize, PageIndex = iRUnReadSubjectQuery.PageIndex, }; return (result, new { IsReadingTaskViewInOrder = isReadingTaskViewInOrder, RandomReadInfo = iRUnReadOut, ReadingTool = readingTool, IseCRFShowInDicomReading = critrion.IseCRFShowInDicomReading, IsReadingShowSubjectInfo = critrion.IsReadingShowSubjectInfo, IsReadingShowPreviousResults = critrion.IsReadingShowPreviousResults, DigitPlaces = critrion.DigitPlaces, CriterionType = critrion.CriterionType, }); } #endregion } public async Task> GetNotOrderReadingQueryableAsync(Guid trialId, Guid trialReadingCriterionId) { var critrion = await _trialReadingCriterionRepository.FindAsync(trialReadingCriterionId); var readingDivisionEnum = critrion.ReadingDivisionEnum; var piReadingScopenEnum = critrion.PIReadingScopenEnum; var taskQuery = _visitTaskRepository.Where(x => x.TrialId == trialId /*&& x.DoctorUserId == _userInfo.Id*/ && x.TaskState == TaskState.Effect && x.TrialReadingCriterionId == trialReadingCriterionId) .Where(x => (x.IsNeedClinicalDataSign && x.IsClinicalDataSign) || !x.IsNeedClinicalDataSign) .WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.SR, t => t.Subject.TrialSite.CRCUserList.Any(u => u.UserId == _userInfo.Id)) // 仅仅SR阅片 PI 没有任务列表 .WhereIf(readingDivisionEnum == ReadingDivisionEnum.OnlySR && _userInfo.UserTypeEnumInt == (int)UserTypeEnum.PI, t => t.TrialId == Guid.Empty) .WhereIf(readingDivisionEnum == ReadingDivisionEnum.PIandSR && _userInfo.UserTypeEnumInt == (int)UserTypeEnum.PI && piReadingScopenEnum == PIReadingScopenEnum.AllBaseline, t => t.SourceSubjectVisit.IsBaseLine == true) //PI 阅片所有 .WhereIf(readingDivisionEnum == ReadingDivisionEnum.PIandSR && _userInfo.UserTypeEnumInt == (int)UserTypeEnum.PI && piReadingScopenEnum == PIReadingScopenEnum.AllBaselineandVisit, t => true) .WhereIf(readingDivisionEnum == ReadingDivisionEnum.PIandSR && _userInfo.UserTypeEnumInt == (int)UserTypeEnum.PI && piReadingScopenEnum == PIReadingScopenEnum.AllVisit, t => t.SourceSubjectVisit.IsBaseLine == false) .WhereIf(readingDivisionEnum == ReadingDivisionEnum.PIandSR && _userInfo.UserTypeEnumInt == (int)UserTypeEnum.SR && piReadingScopenEnum == PIReadingScopenEnum.AllBaseline, t => t.SourceSubjectVisit.IsBaseLine == false) //SR 不阅片 .WhereIf(readingDivisionEnum == ReadingDivisionEnum.PIandSR && _userInfo.UserTypeEnumInt == (int)UserTypeEnum.SR && piReadingScopenEnum == PIReadingScopenEnum.AllBaselineandVisit, t => t.TrialId == Guid.Empty) .WhereIf(readingDivisionEnum == ReadingDivisionEnum.PIandSR && _userInfo.UserTypeEnumInt == (int)UserTypeEnum.SR && piReadingScopenEnum == PIReadingScopenEnum.AllVisit, t => t.SourceSubjectVisit.IsBaseLine == true); return taskQuery; } /// /// 获取有序阅片IQuery对象 /// /// /// public async Task<(int, List)> GetOrderReadingIQueryable(GetOrderReadingIQueryableInDto inDto) { var trialReadingCriterionId = inDto.TrialReadingCriterionId; var critrion = await _trialReadingCriterionRepository.FindAsync(trialReadingCriterionId); var readingDivisionEnum = critrion.ReadingDivisionEnum; var piReadingScopenEnum = critrion.PIReadingScopenEnum; var visitQuery = _visitTaskRepository .Where(x => x.TrialId == inDto.TrialId && x.TaskState == TaskState.Effect) .WhereIf(inDto.SubjectId!=null,t=>t.SubjectId==inDto.SubjectId) //PI 读基线的时候,subject 如果PI基线没阅片完,SR就不能看 .WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.SR && piReadingScopenEnum == PIReadingScopenEnum.AllBaseline && readingDivisionEnum == ReadingDivisionEnum.PIandSR, t => t.Subject.SubjectVisitTaskList.Any(c => c.SourceSubjectVisit.IsBaseLine == true && c.ReadingTaskState == ReadingTaskState.HaveSigned && c.TaskState == TaskState.Effect && c.TrialReadingCriterionId == trialReadingCriterionId)) //PI 读随访的时候, subject 如果SR基线没阅片完,PI就不能看 .WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.PI && piReadingScopenEnum == PIReadingScopenEnum.AllVisit && readingDivisionEnum == ReadingDivisionEnum.PIandSR, t => t.Subject.SubjectVisitTaskList.Any(c => c.SourceSubjectVisit.IsBaseLine == true && c.ReadingTaskState == ReadingTaskState.HaveSigned && c.TaskState == TaskState.Effect && c.TrialReadingCriterionId == trialReadingCriterionId)) .WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.SR, t => t.Subject.TrialSite.CRCUserList.Any(u => u.UserId == _userInfo.Id)) // 仅仅SR阅片 PI 没有任务列表 .WhereIf(readingDivisionEnum == ReadingDivisionEnum.OnlySR && _userInfo.UserTypeEnumInt == (int)UserTypeEnum.PI, t => t.TrialId == Guid.Empty) //PI查看 PI阅片所有基线 .WhereIf(readingDivisionEnum == ReadingDivisionEnum.PIandSR && _userInfo.UserTypeEnumInt == (int)UserTypeEnum.PI && piReadingScopenEnum == PIReadingScopenEnum.AllBaseline, t => t.SourceSubjectVisit.IsBaseLine == true) // PI查看 PI 阅片所有 .WhereIf(readingDivisionEnum == ReadingDivisionEnum.PIandSR && _userInfo.UserTypeEnumInt == (int)UserTypeEnum.PI && piReadingScopenEnum == PIReadingScopenEnum.AllBaselineandVisit, t => true) // PI查看 PI 阅片访视 .WhereIf(readingDivisionEnum == ReadingDivisionEnum.PIandSR && _userInfo.UserTypeEnumInt == (int)UserTypeEnum.PI && piReadingScopenEnum == PIReadingScopenEnum.AllVisit, t => t.SourceSubjectVisit.IsBaseLine == false) //SR查看 PI阅片所有基线 .WhereIf(readingDivisionEnum == ReadingDivisionEnum.PIandSR && _userInfo.UserTypeEnumInt == (int)UserTypeEnum.SR && piReadingScopenEnum == PIReadingScopenEnum.AllBaseline, t => t.SourceSubjectVisit.IsBaseLine == false) //SR查看 PI 阅片所有 .WhereIf(readingDivisionEnum == ReadingDivisionEnum.PIandSR && _userInfo.UserTypeEnumInt == (int)UserTypeEnum.SR && piReadingScopenEnum == PIReadingScopenEnum.AllBaselineandVisit, t => t.TrialId == Guid.Empty) //SR查看 PI 阅片访视 .WhereIf(readingDivisionEnum == ReadingDivisionEnum.PIandSR && _userInfo.UserTypeEnumInt == (int)UserTypeEnum.SR && piReadingScopenEnum == PIReadingScopenEnum.AllVisit, t => t.SourceSubjectVisit.IsBaseLine == true) // 前序 不存在 未一致性核查未通过的 并且前序不存在未完成阅片的有效任务 .Where(t => !t.Subject.SubjectVisitList.Any(sv => sv.CheckState != CheckStateEnum.CVPassed && t.VisitTaskNum > sv.VisitNum)) //.WhereIf(piReadingScopenEnum == PIReadingScopenEnum.AllVisit,t => // !t.Subject.SubjectVisitTaskList.Any(tk => tk.ReadingTaskState != ReadingTaskState.HaveSigned && tk.TaskState == TaskState.Effect && tk.VisitTaskNum < t.VisitTaskNum)) .WhereIf(!string.IsNullOrEmpty(inDto.SubjectCode), t => (t.Subject.Code.Contains(inDto.SubjectCode) && t.IsAnalysisCreate == false) || (t.BlindSubjectCode.Contains(inDto.SubjectCode) && t.IsAnalysisCreate)); var visitGroupQuery = visitQuery.GroupBy(x => new { x.SubjectId, x.Subject.Code, x.BlindSubjectCode, x.SubjectCriterionClaimUserId, x.SubjectCriterionClaimUser.UserName }); var visitTaskQuery = visitGroupQuery.Select(x => new IRUnReadSubjectView() { SubjectId = x.Key.SubjectId, SubjectCode = x.Key.BlindSubjectCode == string.Empty ? x.Key.Code : x.Key.BlindSubjectCode, ClaimUserId = x.Key.SubjectCriterionClaimUserId, ClaimUserName = x.Key.UserName, SuggesteFinishedTime = x.Where(y => y.TrialReadingCriterionId == trialReadingCriterionId && y.ReadingTaskState != ReadingTaskState.HaveSigned).Min(x => x.SuggesteFinishedTime), //未读任务量 UnReadTaskCount = x.Where(y => y.TrialReadingCriterionId == trialReadingCriterionId && y.ReadingTaskState != ReadingTaskState.HaveSigned).Count(), //未读 里可读任务量 UnReadCanReadTaskCount = x.Where(y => y.TrialReadingCriterionId == trialReadingCriterionId && y.ReadingTaskState != ReadingTaskState.HaveSigned && y.IsFrontTaskNeedSignButNotSign == false && (y.IsNeedClinicalDataSign == false || y.IsClinicalDataSign == true) ).Count(), //已读任务量 HaveReadTaskCount = x.Where(y => y.TrialReadingCriterionId == trialReadingCriterionId && y.ReadingTaskState == ReadingTaskState.HaveSigned).Count(), ExistReadingApply = x.Any(y => (y.ReReadingApplyState == ReReadingApplyState.DocotorHaveApplyed && y.TrialReadingCriterionId == trialReadingCriterionId) || y.ReReadingApplyState == ReReadingApplyState.TrialGroupHaveApplyed), //查出所有未读的 未读的可读的 在这个列表基础上 过滤下 y.IsFrontTaskNeedSignButNotSign==false && (y.IsNeedClinicalDataSign == false || y.IsClinicalDataSign == true) 这样容易排错 确认这三个字段是否维护有误 UnReadTaskList = x.Where(y => y.TrialReadingCriterionId == trialReadingCriterionId && y.ReadingTaskState != ReadingTaskState.HaveSigned).OrderBy(x => x.VisitTaskNum) .Select(u => new IRUnreadTaskView() { Id = u.Id, IsUrgent = u.IsUrgent, VisitNum = u.VisitTaskNum, TaskBlindName = u.TaskBlindName, VisistId = u.SourceSubjectVisitId, SuggesteFinishedTime = u.SuggesteFinishedTime, ReadingCategory = u.ReadingCategory, IsAnalysisCreate = u.IsAnalysisCreate, ArmEnum = u.ArmEnum, TrialReadingCriterionId = u.TrialReadingCriterionId, IsNeedClinicalDataSign = u.IsNeedClinicalDataSign, IsClinicalDataSign = u.IsClinicalDataSign, IsFrontTaskNeedSignButNotSign = u.IsFrontTaskNeedSignButNotSign }) .ToList(), }).Where(x => x.UnReadCanReadTaskCount > 0)/*.OrderBy(x => x.UnReadCanReadTaskCount)*/; // 有序阅片需要找到最小需要 // 不这样写会有问题 var count = visitQuery.Where(y => y.TrialReadingCriterionId == trialReadingCriterionId && y.ReadingTaskState != ReadingTaskState.HaveSigned && y.IsFrontTaskNeedSignButNotSign == false && (y.IsNeedClinicalDataSign == false || y.IsClinicalDataSign == true)) .GroupBy(x => new { x.SubjectId, x.Subject.Code, x.BlindSubjectCode }).Count(); var result = new List(); var propName = string.IsNullOrWhiteSpace(inDto.Page.SortField) ? "UnReadCanReadTaskCount" : inDto.Page.SortField; var visitTaskOrderQuery = inDto.Page.Asc ? visitTaskQuery.OrderBy(propName) : visitTaskQuery.OrderBy(propName + " desc"); if (inDto.Page != null) { result = await visitTaskOrderQuery .Skip((inDto.Page.PageIndex - 1) * inDto.Page.PageSize) .Take(inDto.Page.PageSize).ToListAsync(); } else { result = await visitTaskOrderQuery.ToListAsync(); } return (count, result); } /// /// IR 已阅片任务 /// /// /// [HttpPost] public async Task> GetIRHaveReadTaskList(VisitTaskQuery queryVisitTask) { var curentUserSiteIdList=_trialRepository.Where(t=>t.Id==queryVisitTask.TrialId).SelectMany(t=>t.TrialSiteUserList).Where(t=>t.UserId==_userInfo.Id).Select(t=>t.SiteId).ToList(); var visitTaskQueryable = _visitTaskRepository.Where(t => t.TrialId == queryVisitTask.TrialId) .Where(t =>/* t.DoctorUserId == _userInfo.Id &&*/ t.ReadingTaskState == ReadingTaskState.HaveSigned)//该医生 已经签名的数据 .WhereIf(_userInfo.UserTypeEnumInt==(int)UserTypeEnum.PI,t=>t.DoctorUser.UserTypeEnum==UserTypeEnum.PI) .WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.SR, t => t.DoctorUser.UserTypeEnum == UserTypeEnum.SR && curentUserSiteIdList.Contains(t.Subject.SiteId)) .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.TaskAllocationState != null, t => t.TaskAllocationState == queryVisitTask.TaskAllocationState) .WhereIf(queryVisitTask.TrialReadingCriterionId != null, t => t.TrialReadingCriterionId == queryVisitTask.TrialReadingCriterionId) .WhereIf(queryVisitTask.PIAuditState != null, t => t.PIAuditState == queryVisitTask.PIAuditState) .WhereIf(queryVisitTask.TaskState != null, t => t.TaskState == queryVisitTask.TaskState) .WhereIf(!string.IsNullOrEmpty(queryVisitTask.TrialSiteCode), t => (t.BlindTrialSiteCode.Contains(queryVisitTask.TrialSiteCode!) && t.IsAnalysisCreate) || (t.Subject.TrialSite.TrialSiteCode.Contains(queryVisitTask.TrialSiteCode!) && t.IsAnalysisCreate == false)) .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) && t.IsAnalysisCreate == false) || (t.BlindSubjectCode.Contains(queryVisitTask.SubjectCode) && t.IsAnalysisCreate)) .WhereIf(queryVisitTask.BeginAllocateDate != null, t => t.AllocateTime > queryVisitTask.BeginAllocateDate) .WhereIf(queryVisitTask.EndAllocateDate != null, t => t.AllocateTime < queryVisitTask.EndAllocateDate!.Value.AddDays(1)) .ProjectTo(_mapper.ConfigurationProvider); var defalutSortArray = new string[] { nameof(VisitTask.IsUrgent) + " desc", nameof(VisitTask.SubjectId), nameof(VisitTask.VisitTaskNum) }; var pageList = await visitTaskQueryable.ToPagedListAsync(queryVisitTask.PageIndex, queryVisitTask.PageSize, queryVisitTask.SortField, queryVisitTask.Asc, string.IsNullOrWhiteSpace(queryVisitTask.SortField), defalutSortArray); return pageList; } [HttpPost] [UnitOfWork] public async Task AIRReReading(AIRReReadingCommand command, [FromServices] IVisitTaskHelpeService _visitTaskCommonService) { var baseLineTaskList = await _visitTaskRepository.Where(t => t.TrialId == command.TrialId && t.TrialReadingCriterionId == command.TrialReadingCriterionId && t.DoctorUserId == _userInfo.Id && t.TaskState == TaskState.Effect && t.ReadingCategory == ReadingCategory.Visit && t.ReadingTaskState == ReadingTaskState.HaveSigned && t.SourceSubjectVisit.IsBaseLine == true).ToListAsync(); var baseLineTaskIdList = baseLineTaskList.Select(t => t.Id).ToList(); if (baseLineTaskIdList.Count == 0) { return ResponseOutput.Ok(); } //if (baseLineTaskList == null) //{ // return ResponseOutput.NotOk("基线任务未阅完,不允许重阅基线任务"); //} await ApplyReReading(new ApplyReReadingCommand() { IsCopyFollowForms = false, IsCopyOrigenalForms = false, TaskIdList = baseLineTaskIdList, TrialId = command.TrialId, RequestReReadingReason = "AIR自动重阅基线", RequestReReadingType = RequestReReadingType.DocotorApply }); var requestRecordList = await _visitTaskReReadingRepository.Where(t => baseLineTaskIdList.Contains(t.OriginalReReadingTaskId) && t.RequestReReadingUserId == _userInfo.Id && t.RequestReReadingReason == "AIR自动重阅基线").ToListAsync(); if (requestRecordList.Count != baseLineTaskIdList.Count) { //---后台数据有错误 return ResponseOutput.NotOk(_localizer["VisitTask_DoctorConfiguration"]); } await ConfirmReReading(new ConfirmReReadingCommand() { TrialId = command.TrialId, RequestReReadingResultEnum = RequestReReadingResult.Agree, //ConfirmReReadingList = new List() { new ConfirmReReadingDTO() { Id = requestRecord.Id, OriginalReReadingTaskId = task.Id } } ConfirmReReadingList = requestRecordList.Select(t => new ConfirmReReadingDTO() { Id = t.Id, OriginalReReadingTaskId = t.OriginalReReadingTaskId }).ToList() }, _visitTaskCommonService); return ResponseOutput.Ok(); } /// /// 申请重阅 1:IR 2:PM /// /// /// [HttpPost] [UnitOfWork] [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })] public async Task ApplyReReading(ApplyReReadingCommand applyReReadingCommand) { var taskList = await _visitTaskRepository.Where(t => applyReReadingCommand.TaskIdList.Contains(t.Id), true).ToListAsync(); var trialReadingCriterionId = taskList.First()!.TrialReadingCriterionId; var criterionConfig = (await _trialReadingCriterionRepository.Where(x => x.Id == trialReadingCriterionId).Select(x => new { x.ReadingTool, x.IsAutoCreate, x.IsReadingTaskViewInOrder }).FirstOrDefaultAsync()).IfNullThrowException(); foreach (var task in taskList) { if (task.ReadingTaskState != ReadingTaskState.HaveSigned || (task.TaskState != TaskState.Effect && task.TaskState != TaskState.Freeze)) { //---未阅片完成,或者未生效的任务不允许申请重阅 throw new BusinessValidationFailedException(_localizer["VisitTask_BackendData"]); } if (task.ReReadingApplyState == ReReadingApplyState.DocotorHaveApplyed || task.ReReadingApplyState == ReReadingApplyState.TrialGroupHaveApplyed || task.ReReadingApplyState == ReReadingApplyState.Agree) { //---重阅已申请,或者重阅已同意状态下不允许申请重阅 throw new BusinessValidationFailedException(_localizer["VisitTask_UnreadTask"]); } if (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.SR || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.PI) { task.ReReadingApplyState = ReReadingApplyState.DocotorHaveApplyed; // 有序 if (criterionConfig.IsReadingTaskViewInOrder) { // 针对同一个subject 不同阅片人 针对同一个访视申请重阅,是允许的,所以同一阅片人,针对同一suject 有访视申请重阅还未处理,不允许申请重阅 if (await _visitTaskReReadingRepository.AnyAsync(t => t.OriginalReReadingTask.TrialId == task.TrialId && t.OriginalReReadingTask.SubjectId == task.SubjectId && t.OriginalReReadingTask.TaskState == TaskState.Effect && t.OriginalReReadingTask.TrialReadingCriterionId == task.TrialReadingCriterionId && t.OriginalReReadingTask.ReadingTaskState == ReadingTaskState.HaveSigned && t.RequestReReadingType == RequestReReadingType.DocotorApply && t.RequestReReadingResultEnum == RequestReReadingResult.Default)) { //---当前为有序阅片,该受试者已有访视已申请重阅还未处理,暂不能继续申请重阅 throw new BusinessValidationFailedException(_localizer["VisitTask_SequentialReading"]); } } else { if (task.ReadingCategory != ReadingCategory.Visit && task.ReadingCategory != ReadingCategory.Global) { //---无序阅片,仅仅允许IR 申请 全局和访视类型类别的任务进行重阅 throw new BusinessValidationFailedException(_localizer["VisitTask_IRGlobalRecheck"]); } } } //AIR 不加验证 if (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.AIR) { task.ReReadingApplyState = ReReadingApplyState.DocotorHaveApplyed; } var rootReReadingTaskId = _visitTaskReReadingRepository.Where(t => t.NewReReadingTaskId == task.Id).Select(u => u.RootReReadingTaskId).FirstOrDefault(); //添加申请记录 var visitTaskReReading = await _visitTaskReReadingRepository.AddAsync(new VisitTaskReReading() { TrialId = applyReReadingCommand.TrialId, RootReReadingTaskId = rootReReadingTaskId == Guid.Empty ? task.Id : rootReReadingTaskId, OriginalReReadingTaskId = task.Id, RequestReReadingTime = DateTime.Now, RequestReReadingUserId = _userInfo.Id, IsCopyOrigenalForms = applyReReadingCommand.IsCopyOrigenalForms, IsCopyFollowForms = applyReReadingCommand.IsCopyFollowForms, RequestReReadingReason = applyReReadingCommand.RequestReReadingReason, RequestReReadingType = applyReReadingCommand.RequestReReadingType, }); } await _visitTaskRepository.SaveChangesAsync(); return ResponseOutput.Ok(); } /// /// 重阅原任务跟踪处理 只会在同意的时候调用这个 /// /// /// /// private void ReReadingTaskTrackingDeal(VisitTask origenalTask, ConfirmReReadingCommand agreeReReadingCommand) { if (origenalTask.ReReadingApplyState == ReReadingApplyState.DocotorHaveApplyed || origenalTask.ReReadingApplyState == ReReadingApplyState.TrialGroupHaveApplyed) { origenalTask.ReReadingApplyState = agreeReReadingCommand.RequestReReadingResultEnum == RequestReReadingResult.Agree ? ReReadingApplyState.Agree : ReReadingApplyState.Reject; origenalTask.TaskState = agreeReReadingCommand.RequestReReadingResultEnum == RequestReReadingResult.Agree ? TaskState.HaveReturned : origenalTask.TaskState; } else { //---当前重阅任务状态不为已申请状态,不允许进行处理,请刷新页面 throw new BusinessValidationFailedException(_localizer["VisitTask_InvalidReapplyStatus"]); } } private async Task SetMedicalReviewInvalidAsync(List influenceTaskList, bool isPMApply = true) { //将医学审核设置为失效 var taskIdList = influenceTaskList.Select(t => t.Id).ToList(); //PM 申请 医学审核任务状态为待审核、审核中的,设置为失效。 //IR 申请 当前任务进入医学审核,医学审核任务未签名且结论中是否有问题项,答案为否的,设置为失效 if (isPMApply) { await _taskMedicalReviewRepository.UpdatePartialFromQueryAsync(t => taskIdList.Contains(t.VisitTaskId) && t.AuditState != MedicalReviewAuditState.HaveSigned, u => new TaskMedicalReview() { IsInvalid = true }); } else { await _taskMedicalReviewRepository.UpdatePartialFromQueryAsync(t => taskIdList.Contains(t.VisitTaskId) && t.IsHaveQuestion == false && t.AuditState != MedicalReviewAuditState.HaveSigned, u => new TaskMedicalReview() { IsInvalid = true }); } } /// /// PM 申请重阅 被同意 或者 PM 直接退回的时候影响 /// /// /// private async Task SetReReadingOrBackInfluenceAnalysisAsync(Guid subjectId) { if (await _repository.AnyAsync(t => t.IsAnalysisCreate && t.SubjectId == subjectId)) { await _repository.UpdatePartialFromQueryAsync(t => t.Id == subjectId, u => new Subject() { IsReReadingOrBackInfluenceAnalysis = true }); } } public DateTime GetSuggessFinishTime(bool isInOrder, UrgentType urgentType) { var datetime = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, 22, 0, 0).AddDays(7); return datetime; } /// /// 确认重阅与否 1同意 2 拒绝 /// /// /// /// [HttpPost] [UnitOfWork] [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })] public async Task ConfirmReReading(ConfirmReReadingCommand agreeReReadingCommand, [FromServices] IVisitTaskHelpeService _visitTaskCommonService) { var trialId = agreeReReadingCommand.TrialId; foreach (var item in agreeReReadingCommand.ConfirmReReadingList) { var origenalTask = (await _visitTaskRepository.Where(t => item.OriginalReReadingTaskId == t.Id).FirstOrDefaultAsync()).IfNullThrowException(); if ((origenalTask.TaskState != TaskState.Effect && origenalTask.TaskState != TaskState.Freeze)) { //---当前申请重阅任务的状态,已被其他任务重阅已影响,不允许对该状态下的任务进行重阅同意与否操作 return ResponseOutput.NotOk(_localizer["VisitTask_ReapplyStatusConflict"]); } var criterionConfig = await _trialReadingCriterionRepository.Where(x => x.Id == origenalTask.TrialReadingCriterionId).Select(x => new { x.ReadingTool, x.CriterionType, x.IsAdditionalAssessment, x.IsReadingTaskViewInOrder }).FirstOrDefaultAsync(); //更新申请信息 var visitTaskReReadingAppply = await _visitTaskReReadingRepository.FirstOrDefaultAsync(t => t.Id == item.Id); visitTaskReReadingAppply.RequestReReadingConfirmUserId = _userInfo.Id; visitTaskReReadingAppply.RequestReReadingResultEnum = agreeReReadingCommand.RequestReReadingResultEnum; visitTaskReReadingAppply.RequestReReadingRejectReason = agreeReReadingCommand.RequestReReadingRejectReason; Expression> filterExpression = t => t.TrialId == trialId && t.SubjectId == origenalTask.SubjectId && (t.TaskState == TaskState.Effect || t.TaskState == TaskState.Freeze); //是否是一致性分析任务 正常申请 会影响一致性分析任务 filterExpression = filterExpression.And(t => t.IsAnalysisCreate == origenalTask.IsAnalysisCreate); //IR 申请1.1 基线重阅,影响附加评估两个IR所有的任务 var isIR1Point1AdditionalAssessmentBaseline = false; //附加评估 IR 和PM 看到的影响列表不一样 //1.1 有附加评估,会影响其他标准的任务 if (criterionConfig.CriterionType == CriterionType.RECIST1Point1 && criterionConfig.IsAdditionalAssessment) { // PM申请 SPM / CPM审批 if (visitTaskReReadingAppply.RequestReReadingType == RequestReReadingType.TrialGroupApply && (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.SPM || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.CPM)) { filterExpression = filterExpression.And(t => t.TrialReadingCriterionId == origenalTask.TrialReadingCriterionId || t.TrialReadingCriterion.CriterionType == CriterionType.RECIST1Pointt1_MB); } //IR 申请 PM审批 else { // 1.1 基线任务影响BM任务 if (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ProjectManager && _subjectVisitRepository.Any(t => t.Id == origenalTask.SourceSubjectVisitId && t.IsBaseLine == true)) { isIR1Point1AdditionalAssessmentBaseline = true; //filterExpression = filterExpression.And(t => t.TrialReadingCriterionId == origenalTask.TrialReadingCriterionId || t.TrialReadingCriterion.CriterionType == CriterionType.RECIST1Pointt1_MB); } // 1.1 非基线任务不影响BM任务 else { filterExpression = filterExpression.And(t => t.TrialReadingCriterionId == origenalTask.TrialReadingCriterionId); } } } else { //默认影响的都是该标准的任务 filterExpression = filterExpression.And(t => t.TrialReadingCriterionId == origenalTask.TrialReadingCriterionId); } if (agreeReReadingCommand.RequestReReadingResultEnum == RequestReReadingResult.Agree) { //IR申请 PM 审批 注意这里有一致性分析的申请同意 不会回退访视,在此要生成影响的访视任务 if (visitTaskReReadingAppply.RequestReReadingType == RequestReReadingType.DocotorApply && _userInfo.UserTypeEnumInt == (int)UserTypeEnum.ProjectManager) { //有序阅片 if (criterionConfig.IsReadingTaskViewInOrder) { filterExpression = filterExpression.And(t => t.VisitTaskNum >= origenalTask.VisitTaskNum); #region 这里时影响其他的任务 /*不包括申请的任务 申请的任务,在上面会统一处理*/ var influenceTaskList = await _visitTaskRepository.Where(filterExpression, true).OrderBy(t => t.VisitTaskNum).ToListAsync(); var trakingOrigenalTask = influenceTaskList.Where(t => t.Id == origenalTask.Id).FirstOrDefault(); foreach (var influenceTask in influenceTaskList) { var beforeTaskState = influenceTask.TaskState; //已签名的任务 设置转变后的标志 if (criterionConfig.CriterionType == CriterionType.IRECIST1Point1 && influenceTask.ReadingTaskState == ReadingTaskState.HaveSigned) { var isConvertedTask = _visitTaskRepository.Where(t => t.Id == influenceTask.Id).Select(t => t.IsConvertedTask).FirstOrDefault(); if (isConvertedTask) { influenceTask.IsHistoryConvertedTask = true; } } //处理申请的任务 if (influenceTask.Id == origenalTask.Id) { ReReadingTaskTrackingDeal(influenceTask, agreeReReadingCommand); await SetMedicalReviewInvalidAsync(influenceTaskList, false); } if (influenceTask.ReadingTaskState == ReadingTaskState.HaveSigned) { influenceTask.TaskState = TaskState.HaveReturned; trakingOrigenalTask?.TaskInfluenceList.Add(new TaskInfluence() { InfluenceTaskId = influenceTask.Id, OptType = ReReadingOrBackOptType.Return }); } else { influenceTask.TaskState = TaskState.Adbandon; trakingOrigenalTask?.TaskInfluenceList.Add(new TaskInfluence() { InfluenceTaskId = influenceTask.Id, OptType = ReReadingOrBackOptType.Abandon }); } // 影响的任务 仅仅访视类别的才生成 或者就是IR 申请的任务 if (influenceTask.ReadingCategory == ReadingCategory.Visit || influenceTask.Id == origenalTask.Id) { // 影响的其他标准的附加评估的任务不立即生成 比如1.1基线 重阅 PM 同意仅仅生成1.1任务,不生成BM任务 if (criterionConfig.CriterionType == CriterionType.RECIST1Point1 && criterionConfig.IsAdditionalAssessment && influenceTask.TrialReadingCriterionId != origenalTask.TrialReadingCriterionId) { //BM标准的不生成任务 continue; } // i1.1标准 当前任务是转变任务,并且影响列表里有转变之前的任务 那么该访视任务就不生成 if (criterionConfig.CriterionType == CriterionType.IRECIST1Point1) { //申请的任务是冻结的任务(该任务发生转变) 影响自己 以及转变后的 以及后续任务 但是生成的时候,仅仅生成转变之前的 //申请的是转变之后的任务 (转变生成的任务) 影响自己以及后续任务 生成转变后的任务 if (influenceTask.BeforeConvertedTaskId != null && influenceTaskList.Any(t => t.Id == influenceTask.BeforeConvertedTaskId)) { //有转化的任务 和转化之前的任务时,转化后的任务时不生成的 continue; } //var canGenerateTaskIdList = influenceTaskList.GroupBy(t => new { t.VisitTaskNum, t.DoctorUserId, t.TrialReadingCriterionId, t.SubjectId }) // .Select(g => g.First().Id); } #region 影响的任务生成 await _visitTaskCommonService.AddTaskAsync(new GenerateTaskCommand() { TrialId = trialId, ReadingCategory = GenerateTaskCategory.ReReading, ReReadingTask = influenceTask, //同步才可以 Action = (newTask) => { //申请表 设置新任务Id visitTaskReReadingAppply.NewReReadingTaskId = newTask.Id; //生成的任务分配给原始医生 newTask.TaskAllocationState = TaskAllocationState.Allocated; newTask.AllocateTime = DateTime.Now; newTask.SuggesteFinishedTime = GetSuggessFinishTime(true, UrgentType.NotUrget); if (visitTaskReReadingAppply.IsCopyOrigenalForms && influenceTask.Id == origenalTask.Id) { if (origenalTask.ReadingCategory == ReadingCategory.Visit) { CopyForms(newTask, origenalTask); } } //拷贝后续表单 if (visitTaskReReadingAppply.IsCopyFollowForms && origenalTask.VisitTaskNum != influenceTask.VisitTaskNum) { if (origenalTask.ReadingCategory == ReadingCategory.Visit) { CopyForms(newTask, origenalTask); } } } }); #endregion } } #endregion } //无序阅片 只会申请访视类型和裁判类型的任务 注意这里有一致性分析的申请同意 else { //1.当前任务及裁判任务 //2.影响当前阅片人的任务 filterExpression = filterExpression.And(t => t.Id == origenalTask.Id || t.Id == origenalTask.JudgeVisitTaskId); var influenceTaskList = await _visitTaskRepository.Where(filterExpression, true).ToListAsync(); var trakingOrigenalTask = influenceTaskList.Where(t => t.Id == origenalTask.Id).FirstOrDefault(); foreach (var influenceTask in influenceTaskList) { //申请原任务处理 if (influenceTask.Id == origenalTask.Id) { ReReadingTaskTrackingDeal(influenceTask, agreeReReadingCommand); await SetMedicalReviewInvalidAsync(influenceTaskList, false); trakingOrigenalTask?.TaskInfluenceList.Add(new TaskInfluence() { InfluenceTaskId = influenceTask.Id, OptType = ReReadingOrBackOptType.Return }); } else { if (influenceTask.ReadingTaskState == ReadingTaskState.HaveSigned) { influenceTask.TaskState = TaskState.HaveReturned; trakingOrigenalTask?.TaskInfluenceList.Add(new TaskInfluence() { InfluenceTaskId = influenceTask.Id, OptType = ReReadingOrBackOptType.Return }); } else { influenceTask.TaskState = TaskState.Adbandon; trakingOrigenalTask?.TaskInfluenceList.Add(new TaskInfluence() { InfluenceTaskId = influenceTask.Id, OptType = ReReadingOrBackOptType.Abandon }); } } if (influenceTask.ReadingCategory == ReadingCategory.Visit || influenceTask.Id == origenalTask.Id) { await _visitTaskCommonService.AddTaskAsync(new GenerateTaskCommand() { TrialId = trialId, ReadingCategory = GenerateTaskCategory.ReReading, ReReadingTask = origenalTask, //同步才可以 Action = (newTask) => { //申请表 设置新任务Id visitTaskReReadingAppply.NewReReadingTaskId = newTask.Id; newTask.AllocateTime = DateTime.Now; newTask.SuggesteFinishedTime = GetSuggessFinishTime(true, UrgentType.NotUrget); //裁判任务 需要进行特殊处理 在重阅逻辑里面处理 if (visitTaskReReadingAppply.IsCopyOrigenalForms && influenceTask.Id == origenalTask.Id) { if (origenalTask.ReadingCategory == ReadingCategory.Visit) { CopyForms(newTask, origenalTask); } } //拷贝后续表单 if (visitTaskReReadingAppply.IsCopyFollowForms && origenalTask.VisitTaskNum != influenceTask.VisitTaskNum) { if (origenalTask.ReadingCategory == ReadingCategory.Visit) { CopyForms(newTask, origenalTask); } } } }); } } } } else { //---不符合 PM申请 SPM / CPM审批 | IR申请 PM 审批 throw new BusinessValidationFailedException(_localizer["VisitTask_ReReadTaskAlreadyAffected"]); } } else if (agreeReReadingCommand.RequestReReadingResultEnum == RequestReReadingResult.Reject) { if (origenalTask.ReReadingApplyState == ReReadingApplyState.DocotorHaveApplyed || origenalTask.ReReadingApplyState == ReReadingApplyState.TrialGroupHaveApplyed) { await _visitTaskRepository.UpdatePartialFromQueryAsync(t => t.Id == origenalTask.Id, u => new VisitTask() { ReReadingApplyState = ReReadingApplyState.Reject }); } else { //---当前重阅任务状态不为已申请状态,不允许进行处理,请刷新页面 throw new BusinessValidationFailedException(_localizer["VisitTask_InvalidReapplyStatus"]); } } } await _visitTaskRepository.SaveChangesAsync(); return ResponseOutput.Ok(); } private void CopyForms(VisitTask newTask, VisitTask origenalTask) { //自定义 var readingCustomTagList = _repository.Where(t => t.VisitTaskId == origenalTask.Id).ToList(); foreach (var item in readingCustomTagList) { item.Id = Guid.Empty; item.VisitTaskId = newTask.Id; } _ = _repository.AddRangeAsync(readingCustomTagList).Result; //var readingTaskQuestionMarkList = _repository.Where(t => t.VisitTaskId == origenalTask.Id).ToList(); //foreach (var item in readingTaskQuestionMarkList) //{ // item.Id = Guid.Empty; // item.VisitTaskId = newTask.Id; //} //_ = _repository.AddRangeAsync(readingTaskQuestionMarkList).Result; var readingTaskQuestionAnswerList = _repository.Where(t => t.VisitTaskId == origenalTask.Id).ToList(); foreach (var item in readingTaskQuestionAnswerList) { item.Id = Guid.Empty; item.VisitTaskId = newTask.Id; } _ = _repository.AddRangeAsync(readingTaskQuestionAnswerList).Result; //ReadingTableAnswerRowInfo ReadingTableQuestionAnswer 一起加 var readingTableAnswerRowInfoList = _repository.Where(t => t.VisitTaskId == origenalTask.Id).Include(t => t.LesionAnswerList).ToList(); foreach (var item in readingTableAnswerRowInfoList) { var originalVisitTaskId = item.VisitTaskId; var originalFristAddTaskId = item.FristAddTaskId; item.Id = NewId.NextSequentialGuid(); item.VisitTaskId = newTask.Id; item.FristAddTaskId = originalVisitTaskId == originalFristAddTaskId ? newTask.Id : item.FristAddTaskId; foreach (var item2 in item.LesionAnswerList) { item2.Id = Guid.Empty; item2.RowId = item.Id; item2.VisitTaskId = newTask.Id; } } _ = _repository.AddRangeAsync(readingTableAnswerRowInfoList).Result; } /// /// PM 设置任务 退回 /// /// [HttpPut("{trialId:guid}/{taskId:guid}")] [UnitOfWork] [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })] public async Task PMSetTaskBack(Guid trialId, Guid taskId) { var task = (await _visitTaskRepository.Where(t => t.Id == taskId).FirstOrDefaultAsync()).IfNullThrowException(); var criterionConfig = (await _trialReadingCriterionRepository.Where(x => x.Id == task.TrialReadingCriterionId).Select(x => new { x.ReadingTool, x.CriterionType, x.IsAutoCreate, x.IsAdditionalAssessment, x.IsReadingTaskViewInOrder }).FirstOrDefaultAsync()).IfNullThrowException(); if (criterionConfig.IsAutoCreate == false) { //---手动生成任务的不允许在此入口影像退回 return ResponseOutput.NotOk(_localizer["VisitTask_NoImageReturn"]); } if (task.TaskState != TaskState.Effect || task.ReadingCategory != ReadingCategory.Visit /*|| task.ReadingTaskState == ReadingTaskState.HaveSigned*/) { //---仅仅允许针对生效、未完成的访视任务进行退回操作,请刷新页面数据 return ResponseOutput.NotOk(_localizer["VisitTask_NonEffectiveTaskCannotBeReturned"]); } if (await _subjectVisitRepository.AnyAsync(t => t.Id == task.SourceSubjectVisitId && t.CheckState != CheckStateEnum.CVPassed)) { //---当前访视已回退到影像上传,不允许继续回退! return ResponseOutput.NotOk(_localizer["VisitTask_NoFurtherReturn"]); } if (task.IsAnalysisCreate) { //---一致性分析的任务,不允许设置退回 return ResponseOutput.NotOk(_localizer["VisitTask_ConsistencyTaskCannotBeReturned"]); } Expression> filterExpression = t => t.TrialId == trialId && t.SubjectId == task.SubjectId && (t.TaskState == TaskState.Effect || t.TaskState == TaskState.Freeze); //PM 才允许操作 if (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ProjectManager) { #region 有序 无序公用流程 //执行类似一致性核查回退流程 回退访视到影像上传流程 await VisitBackAsync(task.SourceSubjectVisitId); #endregion //有序 if (criterionConfig.IsReadingTaskViewInOrder) { filterExpression = filterExpression.And(t => t.IsAnalysisCreate == false); //另一个阅片人的任务根据任务进度自动进入PM退回或PM申请重阅 filterExpression = filterExpression.And(t => t.VisitTaskNum >= task.VisitTaskNum); var influenceTaskList = await _visitTaskRepository.Where(filterExpression, true).ToListAsync(); #region 方式二 //var origenalTask = influenceTaskList.Where(t => t.Id == task.Id).FirstOrDefault(); var origenalTask = await _visitTaskRepository.FindAsync(task.Id); foreach (var influenceTask in influenceTaskList) { //已签名的任务 设置转变后的标志 if (criterionConfig.CriterionType == CriterionType.IRECIST1Point1 && influenceTask.ReadingTaskState == ReadingTaskState.HaveSigned) { var isConvertedTask = _visitTaskRepository.Where(t => t.Id == influenceTask.Id).Select(t => t.IsConvertedTask).FirstOrDefault(); if (isConvertedTask) { influenceTask.IsHistoryConvertedTask = true; } } //同意的访视 因为要记录具体的操作,所以废弃 if (influenceTask.Id == task.Id) { await SetReReadingOrBackInfluenceAnalysisAsync(influenceTask.SubjectId); await SetMedicalReviewInvalidAsync(influenceTaskList); influenceTask.IsPMSetBack = true; } if (influenceTask.ReadingTaskState == ReadingTaskState.HaveSigned) { influenceTask.TaskState = TaskState.HaveReturned; origenalTask.TaskInfluenceList.Add(new TaskInfluence() { InfluenceTaskId = influenceTask.Id, OptType = ReReadingOrBackOptType.Return }); } else { influenceTask.TaskState = TaskState.Adbandon; origenalTask.TaskInfluenceList.Add(new TaskInfluence() { InfluenceTaskId = influenceTask.Id, OptType = ReReadingOrBackOptType.Abandon }); } } #endregion } else { //无序 无序阅片没有 全局 肿瘤学 // 申请该访视的任务 申请人失效 另外一个人重阅重置或者失效 var currentVisitList = await _visitTaskRepository.Where(t => t.SourceSubjectVisitId == task.SourceSubjectVisitId && t.ReadingCategory == ReadingCategory.Visit && (t.TaskState == TaskState.Effect || t.TaskState == TaskState.Freeze) && t.VisitTaskNum == task.VisitTaskNum, true).ToListAsync(); await SetMedicalReviewInvalidAsync(currentVisitList); //var origenalTask = currentVisitList.Where(t => t.Id == task.Id).First(); var origenalTask = await _visitTaskRepository.FindAsync(task.Id); foreach (var influenceTask in currentVisitList) { if (influenceTask.ReadingTaskState == ReadingTaskState.HaveSigned) { //另外阅片人完成阅片了 就设置为重阅重置 influenceTask.TaskState = TaskState.HaveReturned; origenalTask.TaskInfluenceList.Add(new TaskInfluence() { InfluenceTaskId = influenceTask.Id, OptType = ReReadingOrBackOptType.Return }); } else { influenceTask.TaskState = TaskState.Adbandon; origenalTask.TaskInfluenceList.Add(new TaskInfluence() { InfluenceTaskId = influenceTask.Id, OptType = ReReadingOrBackOptType.Abandon }); } } } } else { //---仅PM 可以进行回退操作 return ResponseOutput.NotOk(_localizer["VisitTask_PMOnlyAllowedForReturn"]); } await _visitTaskRepository.SaveChangesAsync(); return ResponseOutput.Ok(); } //包括临床数据签名状态 private async Task VisitBackAsync(Guid? subjectVisitId) { var sv = (await _subjectVisitRepository.FirstOrDefaultAsync(t => t.Id == subjectVisitId)).IfNullThrowException(); //需要重新产生任务 sv.IsVisitTaskGenerated = false; sv.IsPMBackOrReReading = true; sv.AuditState = AuditStateEnum.None; sv.SubmitState = SubmitStateEnum.ToSubmit; sv.ReadingStatus = ReadingStatusEnum.ImageNotSubmit; //回退后,回退状态恢复 sv.RequestBackState = RequestBackStateEnum.NotRequest; sv.IsCheckBack = false; sv.CheckBackTime = null; sv.CheckState = CheckStateEnum.None; sv.CheckChallengeState = CheckChanllengeTypeEnum.None; sv.SVENDTC = null; sv.SVSTDTC = null; sv.PreliminaryAuditTime = null; sv.SubmitTime = null; sv.ReviewAuditTime = null; sv.CurrentActionUserExpireTime = null; sv.IsTake = false; sv.CurrentActionUserId = null; sv.PreliminaryAuditUserId = null; sv.ReviewAuditUserId = null; if (sv.IsBaseLine) { await _readingClinicalDataReposiotry.UpdatePartialFromQueryAsync(t => t.ReadingId == sv.Id && (t.ClinicalDataTrialSet.ClinicalDataLevel == ClinicalLevel.Subject || t.ClinicalDataTrialSet.ClinicalDataLevel == ClinicalLevel.SubjectVisit), c => new ReadingClinicalData() { IsSign = false, ReadingClinicalDataState = ReadingClinicalDataStatus.HaveUploaded }); } else { await _readingClinicalDataReposiotry.UpdatePartialFromQueryAsync(t => t.ReadingId == sv.Id && t.ClinicalDataTrialSet.ClinicalDataLevel == ClinicalLevel.SubjectVisit, c => new ReadingClinicalData() { IsSign = false, ReadingClinicalDataState = ReadingClinicalDataStatus.HaveUploaded, IsBlind = null, IsComplete = null }); } //await _repository.AddAsync(new CheckChallengeDialog() { SubjectVisitId = subjectVisitId, TalkContent = "PM/APM同意一致性核查回退。", UserTypeEnum = (UserTypeEnum)_userInfo.UserTypeEnumInt }); await _repository.BatchDeleteAsync(t => t.SubjectVisitId == subjectVisitId); await _repository.BatchDeleteAsync(t => t.DicomSerie.IsDeleted); await _repository.BatchDeleteAsync(t => t.IsDeleted); var success = await _subjectVisitRepository.SaveChangesAsync(); } /// /// 影响提示列表 重阅仅仅针对已完成的任务申请 退回针对的是未完成的(退回仅仅针对是访视类型的) /// /// /// 重阅还是直接回退 /// 申请记录的Id /// [HttpGet("{taskId:guid}/{isReReading:bool}")] public async Task<(List, object)> GetReReadingOrBackInfluenceTaskList(Guid taskId, bool isReReading, Guid? applyId) { var isIRAppyTaskInfluenced = false; var filterObj = (await _visitTaskRepository.FirstOrDefaultNoTrackingAsync(t => t.Id == taskId)).IfNullThrowException(); var trialId = filterObj.TrialId; var criterionConfig = (await _trialReadingCriterionRepository.Where(x => x.Id == filterObj.TrialReadingCriterionId).Select(x => new { x.ReadingTool, x.CriterionType, x.IsAdditionalAssessment, x.IsReadingTaskViewInOrder }).FirstOrDefaultAsync()).IfNullThrowException(); Expression> filterExpression = t => t.TrialId == trialId && t.SubjectId == filterObj.SubjectId && (t.TaskState == TaskState.Effect || t.TaskState == TaskState.Freeze) /*&& t.TaskAllocationState == TaskAllocationState.Allocated*/; //是否是一致性分析任务 (一致性分析的任务 不会产生裁判 肿瘤学 仅仅有生成的访视和全局) filterExpression = filterExpression.And(t => t.IsAnalysisCreate == filterObj.IsAnalysisCreate); //IR 申请1.1 基线重阅,影响附加评估所有的任务 var isIR1Point1AdditionalAssessmentBaseline = false; //重阅影响 if (isReReading) { //默认影响的都是该标准的任务 filterExpression = filterExpression.And(t => t.TrialReadingCriterionId == filterObj.TrialReadingCriterionId); //IR 申请 PM 同意 仅仅影响自己 if ((_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ProjectManager && applyId != null && await _visitTaskReReadingRepository.AnyAsync(t => t.Id == applyId && (t.CreateUser.UserTypeEnum == UserTypeEnum.SR || t.CreateUser.UserTypeEnum == UserTypeEnum.PI))) || ((_userInfo.UserTypeEnumInt == (int)UserTypeEnum.SR || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.PI) && applyId == null)) { //当前任务及其之后的所有访视任务、全局任务、裁判任务、肿瘤学阅片任务 //有序 if (criterionConfig.IsReadingTaskViewInOrder) { filterExpression = filterExpression.And(t => t.VisitTaskNum >= filterObj.VisitTaskNum); } //无序 else { //1.当前任务及裁判任务 //2.影响当前阅片人的任务 filterExpression = filterExpression.And(t => t.Id == filterObj.Id || t.Id == filterObj.JudgeVisitTaskId); } //throw new BusinessValidationFailedException("仅允许PM 同意 IR 申请的任务"); } else { //---当前用户查看列表未定义 throw new BusinessValidationFailedException(_localizer["VisitTask_UndefinedList"]); } } //退回影响 仅仅针对是访视类型的 影响多个标准的任务 else { if (filterObj.IsAnalysisCreate) { //---不允许退回一致性分析任务 throw new BusinessValidationFailedException(_localizer["VisitTask_NoConsistencyReturn"]); } if (filterObj.ReadingCategory == ReadingCategory.Visit && _userInfo.UserTypeEnumInt == (int)UserTypeEnum.ProjectManager) { //有序 if (criterionConfig.IsReadingTaskViewInOrder) { // 当前任务及其之后的所有访视任务 两个阅片人的 //2.当前任务未完成,不会产生全局任务。后续任务均为访视任务,且均为待阅片,取消分配; filterExpression = filterExpression.And(t => t.VisitTaskNum >= filterObj.VisitTaskNum); if (await _visitTaskReReadingRepository.AnyAsync(t => t.RequestReReadingType == RequestReReadingType.DocotorApply && t.RequestReReadingResultEnum == RequestReReadingResult.Default && t.OriginalReReadingTask.VisitTaskNum >= filterObj.VisitTaskNum && t.OriginalReReadingTask.SubjectId == filterObj.SubjectId && t.OriginalReReadingTask.TrialReadingCriterionId == filterObj.TrialReadingCriterionId && t.OriginalReReadingTask.IsAnalysisCreate == filterObj.IsAnalysisCreate)) { isIRAppyTaskInfluenced = true; } } //无序 else { //自己和另一个人的当前任务 退回针对的是未完成的肯定不会有裁判 filterExpression = filterExpression.And(t => t.VisitTaskNum == filterObj.VisitTaskNum); } } else { //---仅仅访视类型的任务支持PM退回 throw new BusinessValidationFailedException(_localizer["VisitTask_VisitTypeTaskAllowedForPMOnly"]); } } var list = await _visitTaskRepository.Where(filterExpression) //IR 申请的时候,仅仅看到影响自己的 .WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.IndependentReviewer, t => t.DoctorUserId == _userInfo.Id) .OrderBy(t => t.VisitTaskNum).ProjectTo(_mapper.ConfigurationProvider).ToListAsync(); #region 影响后的操作 foreach (var influenceTask in list) { influenceTask.OptType = influenceTask.ReadingTaskState == ReadingTaskState.HaveSigned ? ReReadingOrBackOptType.Return : ReReadingOrBackOptType.Abandon; } #endregion return (list, new { IsIRAppyTaskInfluenced = isIRAppyTaskInfluenced }); } /// /// 获取已影响的列表 /// /// public async Task> GetInfluencedTaskList(Guid taskId) { var list = await _repository.Where(t => t.OriginalTaskId == taskId)/*.Select(t => t.InfluenceTask)*/.ProjectTo(_mapper.ConfigurationProvider).ToListAsync(); return list; } } }