//-------------------------------------------------------------------- // 此代码由T4模板自动生成 byzhouhang 20210918 // 生成时间 2023-06-15 15:06:06 // 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。 //-------------------------------------------------------------------- using Microsoft.AspNetCore.Mvc; using IRaCIS.Core.Application.Interfaces; using IRaCIS.Core.Application.ViewModel; using IRaCIS.Core.Application.Service.Reading.Dto; using IRaCIS.Core.Infra.EFCore.Common; using IRaCIS.Core.Domain.Share; using MassTransit; using IRaCIS.Core.Infrastructure; using IRaCIS.Core.Domain.Models; using IRaCIS.Core.Infrastructure.Extention; using IRaCIS.Core.Application.Service.Reading.Interface; using IRaCIS.Core.Application.Contracts; namespace IRaCIS.Core.Application.Service { /// <summary> /// 临床答案 /// </summary> [ApiExplorerSettings(GroupName = "Reading")] public class ClinicalAnswerService : BaseService, IClinicalAnswerService { private readonly IRepository<TrialClinicalQuestion> _trialClinicalQuestionRepository; private readonly IRepository<SystemClinicalQuestion> _systemClinicalQuestionRepository; private readonly IRepository<SystemClinicalTableQuestion> _systemClinicalTableQuestionRepository; private readonly IRepository<TrialClinicalTableQuestion> _trialClinicalTableQuestionRepository; private readonly IRepository<ClinicalDataTrialSet> _clinicalDataTrialSetRepository; private readonly IRepository<ClinicalForm> _clinicalFormRepository; private readonly IRepository<Subject> _subjectRepository; private readonly IRepository<ReadModuleCriterionFrom> _readModuleCriterionFromRepository; private readonly IRepository<ReadModule> _readModuleRepository; private readonly IRepository<ClinicalQuestionAnswer> _clinicalQuestionAnswerRepository; private readonly IRepository<ClinicalTableAnswer> _clinicalTableAnswerRepository; private readonly IRepository<ClinicalAnswerRowInfo> _clinicalAnswerRowInfoRepository; private readonly IRepository<ReadingClinicalData> _readingClinicalDataRepository; private readonly IRepository<SubjectVisit> _subjectVisitRepository; private readonly IClinicalQuestionService _iClinicalQuestionService; private readonly IReadingClinicalDataService _iReadingClinicalDataService; public ClinicalAnswerService(IRepository<TrialClinicalQuestion> trialClinicalQuestionRepository, IRepository<SystemClinicalTableQuestion> systemClinicalTableQuestionRepository, IRepository<TrialClinicalTableQuestion> trialClinicalTableQuestionRepository, IRepository<ReadingClinicalData> readingClinicalDataRepository, IRepository<ClinicalForm> clinicalFormRepository, IRepository<Subject> subjectRepository, IReadingClinicalDataService iReadingClinicalDataService, IRepository<ReadModuleCriterionFrom> readModuleCriterionFromRepository, IRepository<ReadModule> readModuleRepository, IRepository<SubjectVisit> subjectVisitRepository, IRepository<ClinicalTableAnswer> clinicalTableAnswerRepository, IRepository<ClinicalQuestionAnswer> clinicalQuestionAnswerRepository, IClinicalQuestionService iClinicalQuestionService, IRepository<ClinicalAnswerRowInfo> clinicalAnswerRowInfoRepository, IRepository<ClinicalDataTrialSet> clinicalDataTrialSetRepository, IRepository<SystemClinicalQuestion> systemClinicalQuestionRepository ) { _subjectVisitRepository = subjectVisitRepository; _readingClinicalDataRepository = readingClinicalDataRepository; _clinicalAnswerRowInfoRepository = clinicalAnswerRowInfoRepository; _clinicalQuestionAnswerRepository = clinicalQuestionAnswerRepository; _systemClinicalTableQuestionRepository = systemClinicalTableQuestionRepository; _trialClinicalQuestionRepository = trialClinicalQuestionRepository; _trialClinicalTableQuestionRepository = trialClinicalTableQuestionRepository; _systemClinicalQuestionRepository = systemClinicalQuestionRepository; _clinicalDataTrialSetRepository = clinicalDataTrialSetRepository; _iReadingClinicalDataService = iReadingClinicalDataService; _clinicalFormRepository = clinicalFormRepository; this._subjectRepository = subjectRepository; this._readModuleCriterionFromRepository = readModuleCriterionFromRepository; this._readModuleRepository = readModuleRepository; _clinicalTableAnswerRepository = clinicalTableAnswerRepository; _iClinicalQuestionService = iClinicalQuestionService; } /// <summary> /// CRC签名临床数据 /// </summary> /// <param name="inDto"></param> /// <returns></returns> [HttpPost] public async Task<IResponseOutput> CRCSignClinicalData(CRCSignClinicalDataInDto inDto) { await _readingClinicalDataRepository.UpdatePartialFromQueryAsync(x =>x.Id==inDto.ReadingClinicalDataId, x => new ReadingClinicalData() { IsSign = true, ReadingClinicalDataState = ReadingClinicalDataStatus.HaveSigned }); await _readingClinicalDataRepository.SaveChangesAsync(); return ResponseOutput.Ok(true); } /// <summary> /// 自动添加CRC临床数据 /// </summary> /// <param name="inDto"></param> /// <returns></returns> public async Task AutoAddCRCClinical(AutoAddClinicalInDto inDto) { var dataTrialSetList = await _clinicalDataTrialSetRepository.Where(x =>x.TrialId == inDto.TrialId && x.UploadRole == UploadRole.CRC && x.IsConfirm) .IgnoreAutoIncludes().ToListAsync(); var baseLine = await _subjectVisitRepository.Where(x => x.TrialId == inDto.TrialId) .WhereIf(inDto.SubjectId!=null,x=>x.SubjectId==inDto.SubjectId) .Select(x => new { x.SubjectId, VisitId = x.Id, x.IsBaseLine, }).ToListAsync(); var clinicalDataList =await _readingClinicalDataRepository .WhereIf(inDto.SubjectId != null, x => x.SubjectId == inDto.SubjectId) .Where(x =>x.TrialId==inDto.TrialId&&x.ClinicalDataTrialSet.UploadRole== UploadRole.CRC) .Select(x=>new { ClinicalDataTrialSetId=x.ClinicalDataTrialSetId, SubjectId=x.SubjectId, x.ReadingId, }).ToListAsync(); List<ReadingClinicalData> readingClinicalDatas = new List<ReadingClinicalData>(); baseLine.Select(x => x.SubjectId).Distinct().ForEach(n => { var baseLineVisitId = baseLine.Where(x => x.IsBaseLine && x.SubjectId == n).Select(x => x.VisitId).First(); readingClinicalDatas.AddRange( dataTrialSetList.Where(x => x.ClinicalDataLevel == ClinicalLevel.Subject).Where(x => clinicalDataList.Where(y => y.ClinicalDataTrialSetId == x.Id && y.SubjectId == n).Count() == 0) .Select(x => new ReadingClinicalData() { ClinicalDataTrialSetId = x.Id, IsVisit = true, SubjectId = n, ReadingId = baseLineVisitId, TrialId = inDto.TrialId }).ToList()); readingClinicalDatas.AddRange( dataTrialSetList.Where(x => x.ClinicalDataLevel == ClinicalLevel.ImageRead).Where(x => clinicalDataList.Where(y => y.ClinicalDataTrialSetId == x.Id && y.SubjectId == n).Count() == 0) .Select(x => new ReadingClinicalData() { ClinicalDataTrialSetId = x.Id, IsVisit = false, SubjectId = n, ReadingId = default(Guid), TrialId = inDto.TrialId }).ToList()); readingClinicalDatas.AddRange( dataTrialSetList.Where(x => x.ClinicalDataLevel == ClinicalLevel.OncologyRead).Where(x => clinicalDataList.Where(y => y.ClinicalDataTrialSetId == x.Id && y.SubjectId == n).Count() == 0) .Select(x => new ReadingClinicalData() { ClinicalDataTrialSetId = x.Id, IsVisit = false, SubjectId = n, ReadingId = default(Guid), TrialId = inDto.TrialId }).ToList()); }); baseLine.ForEach(n => { readingClinicalDatas.AddRange( dataTrialSetList.Where(x => x.ClinicalDataLevel == ClinicalLevel.SubjectVisit).Where(x => clinicalDataList.Where(y => y.ClinicalDataTrialSetId == x.Id && y.ReadingId == n.VisitId).Count() == 0) .Select(x => new ReadingClinicalData() { ClinicalDataTrialSetId = x.Id, IsVisit = true, SubjectId = n.SubjectId, ReadingId = n.VisitId, TrialId = inDto.TrialId }).ToList()); }); await _readingClinicalDataRepository.AddRangeAsync(readingClinicalDatas); await _readingClinicalDataRepository.SaveChangesAsync(); } /// <summary> /// 获取CRC受试者临床数据 /// </summary> /// <param name="inDto"></param> /// <returns></returns> [HttpPost] public async Task<PageOutput<GetCRCSubjectClinicalOutDto>> GetCRCSubjectClinicalList(GetCRCSubjectClinicalInDto inDto) { //await AutoAddCRCClinical(new AutoAddClinicalInDto() //{ // TrialId = inDto.TrialId //}) ; var subjects = await _subjectRepository.Where(x => x.TrialId == inDto.TrialId).Select(x => new GetCRCSubjectClinicalResultDto() { SubjectId = x.Id, SubjectCode = x.Code }).ToListAsync(); var clinicalData= _readingClinicalDataRepository.Where(x=>x.TrialId == inDto.TrialId&&x.ClinicalDataTrialSet.UploadRole==UploadRole.CRC&&x.ClinicalDataTrialSet.ClinicalDataLevel!= ClinicalLevel.SubjectVisit) .Where(x=>!x.IsSign) .WhereIf(inDto.SubjectId!=null,x=>x.SubjectId==inDto.SubjectId) .WhereIf(inDto.SubjectCode != null, x => x.Subject.Code.Contains(inDto.SubjectCode??string.Empty)) .Where(x=> x.ClinicalDataTrialSet.ClinicalDataLevel != ClinicalLevel.Subject) .Include(x=>x.ClinicalDataTrialSet).Select(x=>new GetCRCSubjectClinicalOutDto() { SubjectId=x.SubjectId, SubjectCode=x.Subject.Code, TrialId=inDto.TrialId, ReadingId= x.ReadingId, ReadingClinicalDataId=x.Id, UploadRole = x.ClinicalDataTrialSet.UploadRole, ClinicalDataLevel = x.ClinicalDataTrialSet.ClinicalDataLevel, ClinicalUploadType= x.ClinicalDataTrialSet.ClinicalUploadType, BaseLineVisitId= x.Subject.SubjectVisitList.Where(x=>x.IsBaseLine).Select(x=>x.Id).FirstOrDefault(), ClinicalDataTrialSetId = x.ClinicalDataTrialSet.Id, ClinicalDataSetEnName= x.ClinicalDataTrialSet.ClinicalDataSetEnName, ClinicalDataSetName = x.ClinicalDataTrialSet.ClinicalDataSetName, }); var pageList = await clinicalData.ToPagedListAsync(inDto.PageIndex, inDto.PageSize, string.IsNullOrWhiteSpace(inDto.SortField) ? nameof(GetCRCSubjectClinicalOutDto.SubjectCode) : inDto.SortField, inDto.Asc); // 一次查询报错 分两次写 pageList.CurrentPageData.ForEach(x => { x.ClinicalDataSetEnName = x.ClinicalDataSetName.LanguageName(x.ClinicalDataSetEnName, _userInfo.IsEn_Us); }); var clinicalFormData = await _clinicalFormRepository.Where(x => x.TrialId == inDto.TrialId).ToListAsync(); pageList.CurrentPageData.ForEach(n => { n.ClinicalCount = clinicalFormData.Where(y => y.ClinicalDataTrialSetId == n.ClinicalDataTrialSetId && y.SubjectId == n.SubjectId).Count(); }); return pageList; } /// <summary> /// 获取表单列表 /// </summary> /// <param name="inDto"></param> /// <returns></returns> [HttpPost] public async Task<GetClinicalQuestionAnswerListOutDto> GetClinicalQuestionFormList(GetClinicalQuestionAnswerListInDto inDto) { var result = new GetClinicalQuestionAnswerListOutDto(); result.AnswerList = new List<Dictionary<string, string>>(); result.QuestionList=await _trialClinicalQuestionRepository.Where(x=>x.TrialClinicalId==inDto.ClinicalDataTrialSetId &&x.ClinicalQuestionType!= ReadingQestionType.Group && x.ClinicalQuestionType != ReadingQestionType.Table).OrderByDescending(x=>x.IsCheckDate).ThenBy(x=>x.ShowOrder) .ProjectTo<TrialClinicalQuestionDto>(_mapper.ConfigurationProvider).ToListAsync(); var answers = await _clinicalQuestionAnswerRepository.Where(x => x.SubjectId == inDto.SubjectId && x.ClinicalDataTrialSetId == inDto.ClinicalDataTrialSetId) .Select(x => new { x.ClinicalFormId, x.ClinicalForm.CheckDate, x.QuestionId, x.Answer }) .ToListAsync(); var ClinicalFormIds = answers.OrderBy(x=>x.CheckDate).Select(x => x.ClinicalFormId).Distinct().ToList(); ClinicalFormIds.ForEach(x => { var dic = answers.Where(y => y.ClinicalFormId == x).ToDictionary(x => x.QuestionId.ToString(), x => x.Answer); dic.Add("ClinicalFormId", x.ToString()); dic.Add("TrialId", inDto.TrialId.ToString()); dic.Add("SubjectId", inDto.SubjectId.ToString()); dic.Add("ClinicalDataTrialSetId", inDto.ClinicalDataTrialSetId.ToString()); result.AnswerList.Add(dic); }); return result; } /// <summary> /// 获取临床数据表单问题 /// </summary> /// <param name="inDto"></param> /// <returns></returns> [HttpPost] public async Task<List<ClinicalQuestionPreviewDto>> GetClinicalFormInfo(GetClinicalFormInfoInDto inDto) { var formInfo = await _clinicalFormRepository.Where(x => x.Id == inDto.ClinicalFormId).FirstNotNullAsync(); var questionAnswer = await _clinicalQuestionAnswerRepository.Where(x => x.ClinicalFormId == inDto.ClinicalFormId).Select(x => new ClinicalFormQuestionAnswer { QuestionId = x.QuestionId, Answer = x.Answer }).ToListAsync(); var tableAnswer = await _clinicalTableAnswerRepository.Where(x => x.ClinicalFormId == inDto.ClinicalFormId).Select(x => new ClinicalFormTableQuestionAnswer { TableQuestionId = x.TableQuestionId, Answer = x.Answer, QuestionId = x.QuestionId, RowIndex = x.ClinicalAnswerRowInfo.RowIndex }).ToListAsync(); var questions = await _trialClinicalQuestionRepository.Where(x => x.TrialClinicalId == formInfo.ClinicalDataTrialSetId) .ProjectTo<ClinicalQuestionPreviewDto>(_mapper.ConfigurationProvider).ToListAsync(); var tableQuestions = await _trialClinicalTableQuestionRepository.Where(x => x.TrialClinicalId == formInfo.ClinicalDataTrialSetId) .ProjectTo<ClinicalTablePreviewDto>(_mapper.ConfigurationProvider).ToListAsync(); var result = questions.Where(x => x.ClinicalQuestionType == ReadingQestionType.Group).ToList(); result.ForEach(x => { _iClinicalQuestionService.FindChildQuestion(x, questions, tableQuestions, questionAnswer, tableAnswer); }); return result; } /// <summary> /// 提交临床数据表单 /// </summary> /// <param name="inDto"></param> /// <returns></returns> [HttpPost] public async Task<IResponseOutput> SubmitClinicalForm(SubmitClinicalFormInDto inDto) { ClinicalForm clinicalForm = new ClinicalForm() { }; clinicalForm = new ClinicalForm() { ClinicalDataTrialSetId = inDto.ClinicalDataTrialSetId, SubjectId = inDto.SubjectId, TrialId= inDto.TrialId, Id = inDto.ClinicalFormId ?? NewId.NextGuid(), ReadingId = inDto.ReadingId, }; if (inDto.ClinicalFormId!=null&&(await _readModuleCriterionFromRepository.AnyAsync(x => x.ClinicalFormId == inDto.ClinicalFormId.Value))) { throw new BusinessValidationFailedException("当前表单已确认,无法修改!"); } var existsClinical = await _clinicalFormRepository.Where(x => x.SubjectId == inDto.SubjectId && x.ClinicalDataTrialSetId == inDto.ClinicalDataTrialSetId ).WhereIf(inDto.ReadingId != null, x => x.ReadingId == inDto.ReadingId) .Where(x => x.ClinicalDataTrialSet.UploadRole != UploadRole.CRC && !(x.ClinicalDataTrialSet.ClinicalDataLevel == ClinicalLevel.ImageRead || x.ClinicalDataTrialSet.ClinicalDataLevel == ClinicalLevel.OncologyRead)).AnyAsync(); if (existsClinical) { throw new BusinessValidationFailedException("已经添加过临床数据,不允许多次添加!"); } try { var checkDateQuestionId = await _trialClinicalQuestionRepository.Where(x => x.TrialClinicalId == inDto.ClinicalDataTrialSetId && x.IsCheckDate).Select(x => x.Id).FirstNotNullAsync(); clinicalForm.CheckDate = DateTime.Parse(inDto.QuestionAnswers.Where(x => x.QuestionId == checkDateQuestionId).Select(x => x.Answer).First()); } catch (Exception) { } if (clinicalForm.CheckDate != null) { if (await _readModuleRepository.AnyAsync(x =>x.SubjectId== inDto.SubjectId&& x.SubjectVisit.LatestScanDate <= clinicalForm.CheckDate && x.IsCRCConfirm)) { throw new BusinessValidationFailedException("无法添加和修改当前日期的临床数据,因为CRC已经确认!"); } } List<ClinicalQuestionAnswer> clinicalQuestionAnswers = inDto.QuestionAnswers.Select(x => new ClinicalQuestionAnswer() { Answer=x.Answer, ClinicalDataTrialSetId=inDto.ClinicalDataTrialSetId, SubjectId=inDto.SubjectId, ClinicalFormId= clinicalForm.Id, QuestionId=x.QuestionId, }).ToList(); List<ClinicalAnswerRowInfo> clinicalAnswerRowInfos = new List<ClinicalAnswerRowInfo>(); List<ClinicalTableAnswer> clinicalTableAnswers = new List<ClinicalTableAnswer>(); inDto.TableQuestionAnswerList.ForEach(x => { var questionid = x.QuestionId; for (int i = 0; i < x.TableQuestionAnswers.Count(); i++) { var rowInfo = new ClinicalAnswerRowInfo() { Id = NewId.NextGuid(), SubjectId = inDto.SubjectId, ClinicalFormId = clinicalForm.Id, QuestionId = questionid, RowIndex = i+1, }; clinicalAnswerRowInfos.Add(rowInfo); x.TableQuestionAnswers[i].ForEach(y => { clinicalTableAnswers.Add(new ClinicalTableAnswer() { Answer=y.Answer, ClinicalFormId= clinicalForm.Id, QuestionId= questionid, RowId= rowInfo.Id, TableQuestionId=y.TableQuestionId, SubjectId= inDto.SubjectId, }); }); } }); if (inDto.ClinicalFormId != null) { await _clinicalFormRepository.BatchDeleteNoTrackingAsync(x => x.Id == inDto.ClinicalFormId); await _clinicalQuestionAnswerRepository.BatchDeleteNoTrackingAsync(x => x.ClinicalFormId == inDto.ClinicalFormId); await _clinicalAnswerRowInfoRepository.BatchDeleteNoTrackingAsync(x => x.ClinicalFormId == inDto.ClinicalFormId); await _clinicalTableAnswerRepository.BatchDeleteNoTrackingAsync(x => x.ClinicalFormId == inDto.ClinicalFormId); } //if(inDto.ReadingId!=null) //{ // await _readingClinicalDataRepository.UpdatePartialFromQueryAsync(x => x.ReadingId == inDto.ReadingId && x.ClinicalDataTrialSetId == inDto.ClinicalDataTrialSetId, x => new ReadingClinicalData() // { // IsSign = true // }); //} await _clinicalFormRepository.AddAsync(clinicalForm); await _clinicalQuestionAnswerRepository.AddRangeAsync(clinicalQuestionAnswers); await _clinicalAnswerRowInfoRepository.AddRangeAsync(clinicalAnswerRowInfos); await _clinicalTableAnswerRepository.AddRangeAsync(clinicalTableAnswers); await _clinicalTableAnswerRepository.SaveChangesAsync(); return ResponseOutput.Ok(true); } /// <summary> /// 删除表单数据 /// </summary> /// <param name="inDto"></param> /// <returns></returns> /// <exception cref="BusinessValidationFailedException"></exception> [HttpPost] public async Task<IResponseOutput> DeleteClinicalForm(DeleteClinicalFormInDto inDto) { if (await _readModuleCriterionFromRepository.AnyAsync(x => x.ClinicalFormId == inDto.ClinicalFormId)) { throw new BusinessValidationFailedException("当前表单已确认,无法删除!"); } await _clinicalFormRepository.BatchDeleteNoTrackingAsync(x => x.Id == inDto.ClinicalFormId); await _clinicalQuestionAnswerRepository.BatchDeleteNoTrackingAsync(x => x.ClinicalFormId == inDto.ClinicalFormId); await _clinicalAnswerRowInfoRepository.BatchDeleteNoTrackingAsync(x => x.ClinicalFormId == inDto.ClinicalFormId); await _clinicalTableAnswerRepository.BatchDeleteNoTrackingAsync(x => x.ClinicalFormId == inDto.ClinicalFormId); return ResponseOutput.Ok(true); } /// <summary> /// 获取PM待确认列表 /// </summary> /// <param name="inDto"></param> /// <returns></returns> [HttpPost] public async Task<PageOutput<GetCRCConfirmListOutDto>> GetPMConfirmList(GetPMConfirmListInDto inDto) { return await GetCRCConfirmList(new GetCRCConfirmListInDto() { TrialId = inDto.TrialId, IsCRCConfirm = true, IsPMConfirm = false, PageIndex = inDto.PageIndex, PageSize = inDto.PageSize, Asc = inDto.Asc, SortField = inDto.SortField, TrialReadingCriterionId = inDto.TrialReadingCriterionId }); } /// <summary> /// 获取CRC确认列表 /// </summary> /// <param name="inDto"></param> /// <returns></returns> [HttpPost] public async Task<PageOutput<GetCRCConfirmListOutDto>> GetCRCConfirmList(GetCRCConfirmListInDto inDto) { if (inDto.ReadModuleId != null) { var readModule = await _readModuleRepository.Where(x => x.Id == inDto.ReadModuleId).FirstNotNullAsync(); inDto.TrialReadingCriterionId = readModule.TrialReadingCriterionId; } var query = _readModuleRepository.Where(x => x.TrialId == inDto.TrialId) .WhereIf(inDto.ReadModuleId != null, x => x.Id == inDto.ReadModuleId) .WhereIf(inDto.IsCRCConfirm != null, x => x.IsCRCConfirm == inDto.IsCRCConfirm) .WhereIf(inDto.IsPMConfirm != null, x => x.IsPMConfirm == inDto.IsPMConfirm) .WhereIf(inDto.SubjectCode != null, x => x.Subject.Code.Contains(inDto.SubjectCode??string.Empty)) .WhereIf(inDto.TrialReadingCriterionId != null, x => x.TrialReadingCriterionId == inDto.TrialReadingCriterionId) .WhereIf(inDto.SubjectId != null, x => x.SubjectId == inDto.SubjectId) .WhereIf(inDto.StartTime != null, x => x.SubjectVisit.LatestScanDate >= inDto.StartTime) .WhereIf(inDto.EndTime != null, x => x.SubjectVisit.LatestScanDate <= inDto.EndTime) .Select(x => new GetCRCConfirmListOutDto() { SubjectId = x.SubjectId, IsNotNeedPMConfirm=x.IsNotNeedPMConfirm, IsCRCConfirm = x.IsCRCConfirm, IsCRCApplicationRevoke=x.IsCRCApplicationRevoke, VisitBlindName=x.SubjectVisit.BlindName, LatestScanDate = x.SubjectVisit.LatestScanDate, ReadingSetType = x.ReadingSetType, IsPMConfirm = x.IsPMConfirm, SubjectCode = x.Subject.Code, ReadModuleId = x.Id, ModuleName=x.ModuleName, }); var result = await query.ToPagedListAsync(inDto.PageIndex, inDto.PageSize, new string[2] { "SubjectCode asc", "LatestScanDate asc" }); var formList = await _clinicalFormRepository.Where(x => x.TrialId == inDto.TrialId) .Where(x => x.ClinicalDataTrialSet.UploadRole == UploadRole.CRC) .WhereIf(inDto.TrialReadingCriterionId!=null, x=>x.ClinicalDataTrialSet.TrialClinicalDataSetCriteriaList.Any(y=>y.TrialReadingCriterionId== inDto.TrialReadingCriterionId)) .Where(x => x.ClinicalDataTrialSet.ClinicalDataLevel == ClinicalLevel.ImageRead || x.ClinicalDataTrialSet.ClinicalDataLevel == ClinicalLevel.OncologyRead) .Include(x=>x.ClinicalDataTrialSet) .Select(x => new CRCClinicalForm { SubjectId=x.SubjectId, CheckDate = x.CheckDate, ClinicalDataLevel = x.ClinicalDataTrialSet.ClinicalDataLevel, ClinicalFormId = x.Id, ClinicalDataTrialSetId= x.ClinicalDataTrialSet.Id, ClinicalDataSetName =x.ClinicalDataTrialSet.ClinicalDataSetName, ClinicalDataSetEnName=x.ClinicalDataTrialSet.ClinicalDataSetEnName, IsHaveTableQuestion=x.ClinicalDataTrialSet.TrialClinicalQuestionList.Any(y=>y.ClinicalQuestionType== ReadingQestionType.Table), }).ToListAsync(); var confirmList = await _readModuleCriterionFromRepository.Where(x => x.TrialId == inDto.TrialId &&x.ClinicalForm.ClinicalDataTrialSet.UploadRole== UploadRole.CRC &&(x.ClinicalForm.ClinicalDataTrialSet.ClinicalDataLevel==ClinicalLevel.ImageRead|| x.ClinicalForm.ClinicalDataTrialSet.ClinicalDataLevel == ClinicalLevel.OncologyRead)) .Select(x => new GetCRCBeConfirm { CheckDate = x.ClinicalForm.CheckDate ?? default(DateTime), ClinicalDataSetName = x.ClinicalForm.ClinicalDataTrialSet.ClinicalDataSetName, ClinicalDataSetEnName = x.ClinicalForm.ClinicalDataTrialSet.ClinicalDataSetEnName, ClinicalFormId = x.ClinicalFormId, ClinicalDataTrialSetId = x.ClinicalForm.ClinicalDataTrialSet.Id, ReadModuleId=x.ReadModuleId, IsHaveTableQuestion=x.ClinicalForm.ClinicalDataTrialSet.TrialClinicalQuestionList.Any(y => y.ClinicalQuestionType == ReadingQestionType.Table) }).ToListAsync(); result.CurrentPageData.ForEach(x => { if (x.IsCRCConfirm) { x.ClinicalFormList = confirmList.Where(y => y.ReadModuleId == x.ReadModuleId).Select(y=>new GetCRCBeConfirmListOutDto() { CheckDate = y.CheckDate, ClinicalDataSetName= y.ClinicalDataSetName.LanguageName(y.ClinicalDataSetEnName, _userInfo.IsEn_Us), ClinicalDataSetEnName= y.ClinicalDataSetEnName, ClinicalFormId=y.ClinicalFormId, ClinicalDataTrialSetId=y.ClinicalDataTrialSetId, IsHaveTableQuestion=y.IsHaveTableQuestion, }).ToList(); } else { if (x.ReadingSetType == ReadingSetType.ImageReading) { x.ClinicalFormList = formList.Where(y => y.ClinicalDataLevel == ClinicalLevel.ImageRead&&y.CheckDate <= x.LatestScanDate&&y.SubjectId==x.SubjectId) .Select(y => new GetCRCBeConfirmListOutDto() { CheckDate = y.CheckDate ?? default(DateTime), ClinicalDataSetName = y.ClinicalDataSetName.LanguageName(y.ClinicalDataSetEnName, _userInfo.IsEn_Us), ClinicalDataSetEnName = y.ClinicalDataSetEnName, ClinicalFormId = y.ClinicalFormId, ClinicalDataTrialSetId = y.ClinicalDataTrialSetId, IsHaveTableQuestion = y.IsHaveTableQuestion, }).ToList(); } else { x.ClinicalFormList = formList.Where(y => y.ClinicalDataLevel == ClinicalLevel.OncologyRead&&y.CheckDate <= x.LatestScanDate && y.SubjectId == x.SubjectId) .Select(y => new GetCRCBeConfirmListOutDto() { CheckDate = y.CheckDate ?? default(DateTime), ClinicalDataSetName = y.ClinicalDataSetName.LanguageName(y.ClinicalDataSetEnName, _userInfo.IsEn_Us), ClinicalDataSetEnName = y.ClinicalDataSetEnName, ClinicalFormId = y.ClinicalFormId, ClinicalDataTrialSetId = y.ClinicalDataTrialSetId, IsHaveTableQuestion = y.IsHaveTableQuestion, }).ToList(); } } }); return result; } /// <summary> /// 获取CRC待确认列表 /// </summary> /// <param name="inDto"></param> /// <returns></returns> [HttpPost] public async Task<List<GetCRCBeConfirmListOutDto>> GetCRCBeConfirmList(GetCRCBeConfirmListInDto inDto) { var result = (await this.GetCRCConfirmList(new GetCRCConfirmListInDto() { ReadModuleId = inDto.ReadModuleId, TrialId = inDto.TrialId, PageIndex=1, PageSize=9999, })).CurrentPageData.SelectMany(x => x.ClinicalFormList).ToList(); return result.OrderBy(x => x.ClinicalDataSetName).ThenBy(x => x.CheckDate).ToList(); } /// <summary> /// 获取临床数据表格信息 查看没有表格问题的列表 /// </summary> /// <param name="inDto"></param> /// <returns></returns> [HttpPost] public async Task<(List<GetClinicalTableListOutDto>,object)> GetClinicalTableList(GetClinicalTableListInDto inDto) { var readModule=await _readModuleRepository.Where(x => x.Id == inDto.ReadModuleId).FirstNotNullAsync(); var confirmList = (await this.GetCRCConfirmList(new GetCRCConfirmListInDto() { ReadModuleId = inDto.ReadModuleId, TrialId = inDto.TrialId, PageIndex = 1, PageSize = 9999, })).CurrentPageData.SelectMany(x => x.ClinicalFormList).ToList(); var clinicalDataTrialSetIds = confirmList.Select(x => x.ClinicalDataTrialSetId).Distinct().ToList(); var clinicalFormIds = confirmList.Select(x => x.ClinicalFormId).ToList(); var questionList = await _trialClinicalQuestionRepository.Where(x => clinicalDataTrialSetIds.Contains( x.TrialClinicalId) && x.ClinicalQuestionType != ReadingQestionType.Group && x.ClinicalQuestionType != ReadingQestionType.Table).OrderBy(x=>x.TrialClinicalId).ThenBy(x => x.ShowOrder) .ProjectTo<TrialClinicalQuestionDto>(_mapper.ConfigurationProvider).ToListAsync(); var answers = await _clinicalQuestionAnswerRepository.Where(x => clinicalFormIds.Contains(x.ClinicalFormId)) .Select(x => new { x.ClinicalDataTrialSetId, x.ClinicalFormId, x.ClinicalForm.CheckDate, x.QuestionId, x.Answer }) .ToListAsync(); List<GetClinicalTableListOutDto> result = new List<GetClinicalTableListOutDto>(); clinicalDataTrialSetIds.ForEach(x => { GetClinicalTableListOutDto dto = new GetClinicalTableListOutDto(); dto.ModuleName = readModule.ModuleName; dto.ClinicalDataSetName = confirmList.Where(y => y.ClinicalDataTrialSetId == x).Select(y => y.ClinicalDataSetName).First(); dto.QuestionList = questionList.Where(y => y.TrialClinicalId == x).OrderBy(y => y.ShowOrder).ToList(); dto.AnswerList = new List<Dictionary<string, string>>(); var ClinicalFormIds= answers.Where(y => y.ClinicalDataTrialSetId == x).OrderBy(x => x.CheckDate).Select(x => x.ClinicalFormId).Distinct().ToList(); ClinicalFormIds.ForEach(z => { var dic = answers.Where(y => y.ClinicalFormId == z).OrderBy(y => y.CheckDate).ToDictionary(x => x.QuestionId.ToString(), x => x.Answer); dic.Add("ClinicalFormId", z.ToString()); dic.Add("TrialId", inDto.TrialId.ToString()); dic.Add("SubjectId", readModule.SubjectId.ToString()); dic.Add("ClinicalDataTrialSetId", x.ToString()); dto.AnswerList.Add(dic); }); result.Add(dto); }); return (result, new { readModule.ModuleName, }); } /// <summary> /// 获取临床数据表格信息 查看有表格问题的列表 /// </summary> /// <param name="inDto"></param> /// <returns></returns> [HttpPost] public async Task<(List<GetClinicalDateListOutDto>,object)> GetClinicalDateList(GetCRCBeConfirmListInDto inDto) { var readModule = await _readModuleRepository.Where(x => x.Id == inDto.ReadModuleId).FirstNotNullAsync(); var confirmList = (await this.GetCRCConfirmList(new GetCRCConfirmListInDto() { ReadModuleId = inDto.ReadModuleId, TrialId = inDto.TrialId, PageIndex = 1, PageSize = 9999, })).CurrentPageData.SelectMany(x => x.ClinicalFormList).ToList(); var clinicalDataTrialSetIds = confirmList.Select(x => x.ClinicalDataTrialSetId).Distinct().ToList(); List<GetClinicalDateListOutDto> result = new List<GetClinicalDateListOutDto>(); clinicalDataTrialSetIds.ForEach(x => { result.Add(new GetClinicalDateListOutDto() { ClinicalDataSetName = confirmList.Where(y => y.ClinicalDataTrialSetId == x).Select(y => y.ClinicalDataSetName).First(), DateList = confirmList.Where(y => y.ClinicalDataTrialSetId == x).ToList() }); }); return (result,new { readModule.ModuleName, }); } /// <summary> /// CRC 确认临床数据 /// </summary> /// <param name="inDto"></param> /// <returns></returns> [HttpPost] public async Task<IResponseOutput> CRCConfirmClinical(CRCConfirmClinicalInDto inDto) { var readModule = await _readModuleRepository.Where(x => x.Id == inDto.ReadModuleId).FirstNotNullAsync(); var confirmlist = (await this.GetCRCConfirmList(new GetCRCConfirmListInDto() { TrialId = inDto.TrialId, SubjectId= readModule.SubjectId, IsCRCConfirm=false, TrialReadingCriterionId = readModule.TrialReadingCriterionId, //ReadModuleId = inDto.ReadModuleId, PageIndex =1, PageSize=9999, })).CurrentPageData.ToList(); var presentData = confirmlist.Where(x => x.ReadModuleId == inDto.ReadModuleId).First(); confirmlist = confirmlist.Where(x => x.LatestScanDate <= presentData.LatestScanDate).ToList(); await _readModuleCriterionFromRepository.BatchDeleteNoTrackingAsync(x=>x.ReadModuleId== inDto.ReadModuleId); List<ReadModuleCriterionFrom> needAddList = new List<ReadModuleCriterionFrom>() { }; confirmlist.ForEach(x => { x.ClinicalFormList.ForEach(y => { needAddList.Add(new ReadModuleCriterionFrom() { ClinicalFormId = y.ClinicalFormId, ReadModuleId = x.ReadModuleId, SubjectId = x.SubjectId, TrialId = inDto.TrialId, }); }); }); foreach (var item in confirmlist) { await _readModuleRepository.UpdatePartialFromQueryAsync(x =>x.Id==item.ReadModuleId , x => new ReadModule() { IsCRCConfirm = true, IsPMConfirm=item.ClinicalFormList.Count()==0?true:false, IsNotNeedPMConfirm= item.ClinicalFormList.Count() == 0 ? true : false, }); } await _readModuleCriterionFromRepository.AddRangeAsync(needAddList); await _readModuleCriterionFromRepository.SaveChangesAsync(); await _iReadingClinicalDataService.DealVisiTaskClinicalDataSignedAsync(inDto.TrialId, inDto.SubjectId, inDto.ReadModuleId, false, readModule.TrialReadingCriterionId); return ResponseOutput.Ok(true); } /// <summary> /// CRC 取消确认 /// </summary> /// <param name="inDto"></param> /// <returns></returns> [HttpPost] public async Task<IResponseOutput> CRCCancelConfirmClinical(CRCCancelConfirmClinicalInDto inDto) { var readModule = await _readModuleRepository.Where(x => x.Id == inDto.ReadModuleId).FirstNotNullAsync(); var dataList = (await this.GetCRCConfirmList(new GetCRCConfirmListInDto() { TrialId = inDto.TrialId, SubjectId = readModule.SubjectId, TrialReadingCriterionId = readModule.TrialReadingCriterionId, PageIndex = 1, PageSize = 9999, })).CurrentPageData; var presentData = dataList.Where(x => x.ReadModuleId == inDto.ReadModuleId).First(); if (dataList.Any(x => x.IsCRCConfirm && x.LatestScanDate > presentData.LatestScanDate && x.ReadingSetType == presentData.ReadingSetType)) { throw new BusinessValidationFailedException("当前数据并非最后一条确认信息,无法取消!"); } if(presentData.IsPMConfirm) { throw new BusinessValidationFailedException("PM已确认,无法取消!"); } if (presentData.IsNotNeedPMConfirm) { await _readModuleRepository.UpdatePartialFromQueryAsync(x => presentData.ReadModuleId == x.Id, x => new ReadModule() { IsPMConfirm = false, IsCRCConfirm = false, IsNotNeedPMConfirm = false, }); } else { await _readModuleRepository.UpdatePartialFromQueryAsync(x => presentData.ReadModuleId == x.Id, x => new ReadModule() { IsCRCApplicationRevoke = true, }); } //await _readModuleCriterionFromRepository.BatchDeleteNoTrackingAsync(x=>x.ReadModuleId== presentData.ReadModuleId); await _readModuleCriterionFromRepository.SaveChangesAsync(); return ResponseOutput.Ok(true); } /// <summary> /// PM确认临床数据 /// </summary> /// <param name="inDto"></param> /// <returns></returns> /// <exception cref="BusinessValidationFailedException"></exception> [HttpPost] public async Task<IResponseOutput> PMConfirmClinical(CRCConfirmClinicalInDto inDto) { var readModuleData = await _readModuleRepository.Where(x => x.Id == inDto.ReadModuleId).FirstNotNullAsync(); if (!readModuleData.IsCRCConfirm) { throw new BusinessValidationFailedException("CRC还未确认数据,PM无法操作"); } if (readModuleData.IsCRCApplicationRevoke && inDto.IsConfirm) { throw new BusinessValidationFailedException("CRC正在申请退回,PM无法确认"); } if (!readModuleData.IsCRCApplicationRevoke && !inDto.IsConfirm) { throw new BusinessValidationFailedException("CRC未申请退回,PM无法撤销"); } if (inDto.IsConfirm) { await _readModuleRepository.UpdatePartialFromQueryAsync(x => inDto.ReadModuleId == x.Id, x => new ReadModule() { IsPMConfirm = true, IsClinicalDataBlind=inDto.IsClinicalDataBlind, IsClinicalDataComplete=inDto.IsClinicalDataComplete, }); await _readModuleRepository.SaveChangesAsync(); await _iReadingClinicalDataService.DealVisiTaskClinicalDataSignedAsync(inDto.TrialId, inDto.SubjectId, inDto.ReadModuleId, false, readModuleData.TrialReadingCriterionId); } else { await _readModuleRepository.UpdatePartialFromQueryAsync(x => inDto.ReadModuleId == x.Id, x => new ReadModule() { IsCRCConfirm = false, IsCRCApplicationRevoke=false, }); await _readModuleCriterionFromRepository.BatchDeleteNoTrackingAsync(x=>x.ReadModuleId== inDto.ReadModuleId); await _readModuleRepository.SaveChangesAsync(); } return ResponseOutput.Ok(true); } } }