using IRaCIS.Core.Application.Contracts; using Microsoft.AspNetCore.Mvc; using IRaCIS.Core.Domain.Share; using IRaCIS.Core.Application.Contracts.DTO; using IRaCIS.Core.Application.Service; using Microsoft.AspNetCore.Authorization; using IRaCIS.Application.Interfaces; using IRaCIS.Application.Contracts; using IRaCIS.Core.Application.ViewModel; using IRaCIS.Core.Application.Service.Reading.Dto; namespace IRaCIS.Core.Application.Image.QA { [ApiExplorerSettings(GroupName = "Image")] public class QCListService : BaseService, IQCListService { private readonly IRepository _subjectVisitRepository; private readonly IRepository _trialRepository; private readonly IRepository _trialQCQuestionAnswerRepository; private readonly IRepository _trialQCQuestionRepository; private readonly IRepository _consistencyCheckFileRepository; public QCListService( IRepository subjectVisitRepository, IRepository trialRepository, IRepository trialQCQuestionAnswerRepository, IRepository trialQCQuestionRepository, IRepository consistencyCheckFileRepository ) { _subjectVisitRepository = subjectVisitRepository; this._trialQCQuestionAnswerRepository = trialQCQuestionAnswerRepository; this._trialQCQuestionRepository = trialQCQuestionRepository; this._consistencyCheckFileRepository = consistencyCheckFileRepository; _trialRepository = trialRepository; } #region 导表查询 /// /// 影像上传列表 只导出已上传状态的访视记录 /// /// /// /// /// [HttpPost] [AllowAnonymous] public async Task CRCVisitListExport(CRCVisitSearchDTO visitSearchDTO, [FromServices] IRepository _commonDocumentRepository, [FromServices] IDictionaryService _dictionaryService) { var svExpression = QCCommon.GetSubjectVisitFilter(visitSearchDTO.VisitPlanArray); var list = await _subjectVisitRepository.Where(x => x.TrialId == visitSearchDTO.TrialId) .Where(t => t.Subject.FinalSubjectVisitId != null ? t.VisitNum <= t.Subject.FinalSubjectVisit.VisitNum : true) .WhereIf(visitSearchDTO.SiteId != null, t => t.SiteId == visitSearchDTO.SiteId) .WhereIf(visitSearchDTO.SubjectId != null, t => t.Subject.Id == visitSearchDTO.SubjectId) .WhereIf(!string.IsNullOrEmpty(visitSearchDTO.SubjectInfo), t => t.Subject.Code.Contains(visitSearchDTO.SubjectInfo)) .WhereIf(visitSearchDTO.VisitPlanArray != null && visitSearchDTO.VisitPlanArray?.Length > 0, svExpression) //.WhereIf(!string.IsNullOrEmpty(visitSearchDTO.VisitPlanInfo), visitSearchDTO.VisitPlanInfo.Contains('.') ? t => t.InPlan == false : t => t.VisitNum == decimal.Parse(visitSearchDTO.VisitPlanInfo)) .WhereIf(visitSearchDTO.AuditStateArray != null && visitSearchDTO.AuditStateArray?.Length > 0, t => visitSearchDTO.AuditStateArray!.Contains(t.AuditState)) .WhereIf(visitSearchDTO.SubmitState != null, t => t.SubmitState == visitSearchDTO.SubmitState) .WhereIf(visitSearchDTO.ChallengeState != null, t => t.ChallengeState == visitSearchDTO.ChallengeState) .WhereIf(visitSearchDTO.IsUrgent != null, t => t.IsUrgent == visitSearchDTO.IsUrgent) .WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.CRA, t => t.TrialSite.CRCUserList.Any(t => t.UserId == _userInfo.Id)) .ProjectTo(_mapper.ConfigurationProvider).ToListAsync(); list = list.OrderBy(t => t.TrialSiteCode).ThenBy(t => t.SubjectCode).ThenBy(t => t.BlindName).ToList(); var exportInfo = (await _trialRepository.Where(t => t.Id == visitSearchDTO.TrialId).IgnoreQueryFilters().ProjectTo(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException(); exportInfo.List = list; return await ExcelExportHelper.DataExportAsync(StaticData.Export.TrialCRCUploadImageList_Export, exportInfo, "", _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(CRCVisitExportDTO)); } /// /// 质疑列表 /// /// /// [HttpPost] [AllowAnonymous] public async Task GetQCChallengeList_Export(ChallengeQuery challengeQuery, [FromServices] IRepository _commonDocumentRepository, [FromServices] IDictionaryService _dictionaryService) { var svExpression = QCCommon.GetQCChallengeFilter(challengeQuery.VisitPlanArray); var list = await _repository.Where(x => x.TrialId == challengeQuery.TrialId) //.WhereIf(challengeQuery.ChallengeState != null, t => t.SubjectVisit.ChallengeState == challengeQuery.ChallengeState) .WhereIf(challengeQuery.ReuploadEnum != null, t => t.ReuploadEnum == challengeQuery.ReuploadEnum) .WhereIf(challengeQuery.IsClosed != null, t => t.IsClosed == challengeQuery.IsClosed) .WhereIf(challengeQuery.SiteId != null, t => t.SubjectVisit.SiteId == challengeQuery.SiteId) .WhereIf(challengeQuery.SubjectId != null, t => t.SubjectVisit.SubjectId == challengeQuery.SubjectId) .WhereIf(challengeQuery.CreateUserId != null, t => t.CreateUserId == challengeQuery.CreateUserId) .WhereIf(!string.IsNullOrEmpty(challengeQuery.SubjectCode), t => t.SubjectVisit.Subject.Code.Contains(challengeQuery.SubjectCode)) .WhereIf(challengeQuery.VisitPlanArray != null && challengeQuery.VisitPlanArray?.Length > 0, svExpression) //.WhereIf(!string.IsNullOrEmpty(challengeQuery.VisitPlanInfo), challengeQuery.VisitPlanInfo.Contains('.') ? t => t.SubjectVisit.InPlan == false : t => t.SubjectVisit.VisitNum == decimal.Parse(challengeQuery.VisitPlanInfo)) .WhereIf(challengeQuery.IsUrgent != null, t => t.SubjectVisit.IsUrgent == challengeQuery.IsUrgent) .WhereIf(challengeQuery.IsOverTime != null && challengeQuery.IsOverTime==true, t => t.IsClosed ? t.ClosedTime > t.DeadlineTime : DateTime.Now > t.DeadlineTime) .WhereIf(challengeQuery.IsOverTime != null && challengeQuery.IsOverTime == false, t => t.IsClosed ? t.ClosedTime < t.DeadlineTime : DateTime.Now < t.DeadlineTime) .ProjectTo(_mapper.ConfigurationProvider).ToListAsync(); list = list.OrderBy(t => t.TrialSiteCode).ThenBy(t => t.SubjectCode).ThenBy(t => t.ChallengeCode).ToList(); var exportInfo = (await _trialRepository.Where(t => t.Id == challengeQuery.TrialId).IgnoreQueryFilters().ProjectTo(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException(); exportInfo.List = list; return await ExcelExportHelper.DataExportAsync(StaticData.Export.TrialQCImageChanllengeList_Export, exportInfo, "", _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(QCChanllengeExportDto)); } /// /// 受试者信息导出表 /// /// /// [HttpPost] public async Task GetSubjectList_Export(SubjectQueryParam param, [FromServices] IRepository _commonDocumentRepository, [FromServices] IDictionaryService _dictionaryService) { var list = await _repository.Where(u => u.TrialId == param.TrialId) .WhereIf(!string.IsNullOrWhiteSpace(param.Code), t => t.Code.Contains(param.Code)) .WhereIf(!string.IsNullOrWhiteSpace(param.Name), t => t.ShortName.Contains(param.Name)) .WhereIf(!string.IsNullOrWhiteSpace(param.Sex), t => t.Sex.Contains(param.Sex)) .WhereIf(param.Status != null, t => t.Status == param.Status) .WhereIf(param.SiteId != null, t => t.SiteId == param.SiteId) // CRC 只负责他管理site的受试者 .WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.CRA, t => t.TrialSite.CRCUserList.Any(t => t.UserId == _userInfo.Id)) .ProjectTo(_mapper.ConfigurationProvider).ToListAsync(); list = list.OrderBy(t => t.TrialSiteCode).ThenBy(t => t.Code).ToList(); var exportInfo = (await _trialRepository.Where(t => t.Id == param.TrialId).IgnoreQueryFilters().ProjectTo(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException(); exportInfo.List = list; return await ExcelExportHelper.DataExportAsync(StaticData.Export.TrialSubjectList_Export, exportInfo, "", _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(SubjectExportDTO)); } /// /// 受试者 阅片期 进度表 导出 /// /// /// /// /// public async Task GetSubjectReadingPeriod_Export(GetReadModuleDto dto, [FromServices] IRepository _commonDocumentRepository, [FromServices] IDictionaryService _dictionaryService) { var list = await _repository.Where(u => u.TrialId == dto.TrialId) .WhereIf(dto.SubjectId != null, x => x.Id == dto.SubjectId) .WhereIf(dto.TrialSiteCode != null && dto.TrialSiteCode != string.Empty, x => x.TrialSite.TrialSiteCode == dto.TrialSiteCode) .WhereIf(dto.SubjectCode != null && dto.SubjectCode != string.Empty, x => x.Code == dto.SubjectCode) //.WhereIf(dto.ReadingStatus != null, x => x.ReadingStatus == dto.ReadingStatus) .ProjectTo(_mapper.ConfigurationProvider).ToListAsync(); list = list.OrderBy(t => t.TrialSiteCode).ThenBy(t => t.Code).ToList(); var exportInfo = (await _trialRepository.Where(t => t.Id == dto.TrialId).IgnoreQueryFilters().ProjectTo(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException(); exportInfo.List = list; return await ExcelExportHelper.DataExportAsync(StaticData.Export.TrialSubjectList_Export, exportInfo, "", _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(SubjectExportDTO)); } /// /// 阅片期信息表 /// /// /// public async Task GetReadingPeriodList_Export(ReadPeriodQuery param, [FromServices] IRepository _commonDocumentRepository, [FromServices] IDictionaryService _dictionaryService) { var list = await _repository.Where(u => u.TrialId == param.TrialId) .ProjectTo(_mapper.ConfigurationProvider).ToListAsync(); list = list.OrderBy(t => t.TrialSiteCode).ThenBy(t => t.SubjectCode).ToList(); var exportInfo = (await _trialRepository.Where(t => t.Id == param.TrialId).IgnoreQueryFilters().ProjectTo(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException(); exportInfo.List = list; return await ExcelExportHelper.DataExportAsync(StaticData.Export.TrialSubjectReadingPeriodList_Export, exportInfo, "", _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(ReadPeriodExportDto)); } /// /// 一致性核查 检查信息表 /// /// /// [HttpPost] public async Task GetDicomAndNoneDicomStudyList_Export(StudyQuery studyQuery, [FromServices] IRepository _commonDocumentRepository, [FromServices] IDictionaryService _dictionaryService) { var svExpression = QCCommon.GetDicomStudySubjectVisitFilter(studyQuery.VisitPlanArray); var dicomStudyQuery = _repository.Where(t => t.TrialId == studyQuery.TrialId) .WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.CRA, t => t.TrialSite.CRCUserList.Any(t => t.UserId == _userInfo.Id)) .WhereIf(studyQuery.VisitPlanArray != null && studyQuery.VisitPlanArray?.Length > 0, svExpression) .WhereIf(!string.IsNullOrWhiteSpace(studyQuery.SubjectInfo), t => t.Subject.Code.Contains(studyQuery.SubjectInfo)) .Select(t => new UnionStudyExportDTO() { VisitName = t.SubjectVisit.VisitName, VisitNum = t.SubjectVisit.VisitNum, IsDicom = true, SubjectCode = t.Subject.Code, Modality = t.Modalities, StudyCode = t.StudyCode, StudyTime = t.StudyTime, TrialSiteAliasName = t.TrialSite.TrialSiteAliasName, TrialSiteCode = t.TrialSite.TrialSiteCode, CheckState = t.SubjectVisit.CheckState, //Uploader = t.Uploader.UserName, //UploadTime = t.CreateTime }); var svExpression2 = QCCommon.GetNoneDicomStudySubjectVisitFilter(studyQuery.VisitPlanArray); var nodeDicomStudyQuery = _repository.Where(t => t.TrialId == studyQuery.TrialId) .WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.CRA, t => t.TrialSite.CRCUserList.Any(t => t.UserId == _userInfo.Id)) .WhereIf(studyQuery.VisitPlanArray != null && studyQuery.VisitPlanArray?.Length > 0, svExpression2) .WhereIf(!string.IsNullOrWhiteSpace(studyQuery.SubjectInfo), t => t.Subject.Code.Contains(studyQuery.SubjectInfo)) .Select(t => new UnionStudyExportDTO() { VisitName = t.SubjectVisit.VisitName, VisitNum = t.SubjectVisit.VisitNum, IsDicom = false, SubjectCode = t.Subject.Code, Modality = t.Modality, StudyCode = t.StudyCode, StudyTime = t.ImageDate, TrialSiteAliasName = t.TrialSite.TrialSiteAliasName, TrialSiteCode = t.TrialSite.TrialSiteCode, CheckState = t.SubjectVisit.CheckState, //Uploader = t.CreateUser.UserName, //UploadTime = t.CreateTime }); var list = await dicomStudyQuery.Union(nodeDicomStudyQuery) .ToListAsync(); list = list.OrderBy(t => t.TrialSiteCode).ThenBy(t => t.SubjectCode).ThenBy(t => t.VisitNum).ToList(); var exportInfo = (await _trialRepository.Where(t => t.Id == studyQuery.TrialId).IgnoreQueryFilters().ProjectTo(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException(); exportInfo.List = list; return await ExcelExportHelper.DataExportAsync(StaticData.Export.TrialStudyList_Export, exportInfo, "", _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(UnionStudyExportDTO)); } /// /// 一致性核查记录表 /// /// /// [HttpPost] public async Task GetConsistencyVerificationList_Export(CheckQuery checkQuery, [FromServices] IRepository _commonDocumentRepository, [FromServices] IDictionaryService _dictionaryService) { var svExpression = QCCommon.GetSubjectVisitFilter(checkQuery.VisitPlanArray); var list = await _subjectVisitRepository.Where(x => x.TrialId == checkQuery.TrialId) .Where(x => x.AuditState == AuditStateEnum.QCPassed) //一致性核查中的,或者还没一致性核查的 .WhereIf(checkQuery.CheckState != null, t => t.CheckState == checkQuery.CheckState) .WhereIf(checkQuery.SiteId != null, t => t.SiteId == checkQuery.SiteId) .WhereIf(!string.IsNullOrEmpty(checkQuery.SubjectInfo), t => t.Subject.Code.Contains(checkQuery.SubjectInfo)) .WhereIf(checkQuery.VisitPlanArray != null && checkQuery.VisitPlanArray?.Length > 0, svExpression) .WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.CRA, t => t.TrialSite.CRCUserList.Any(t => t.UserId == _userInfo.Id))//CRC 过滤负责的site .ProjectTo(_mapper.ConfigurationProvider).ToListAsync(); list = list.OrderBy(t => t.TrialSiteCode).ThenBy(t => t.SubjectCode).ThenBy(t => t.VisitNum).ToList(); var exportInfo = (await _trialRepository.Where(t => t.Id == checkQuery.TrialId).IgnoreQueryFilters().ProjectTo(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException(); exportInfo.List = list; return await ExcelExportHelper.DataExportAsync(StaticData.Export.TrialSubjectVisitCheckList_Export, exportInfo, "", _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(PMKCheckEXportDTO)); } /// /// PM阅片跟踪 /// /// /// [HttpPost] public async Task GetReadingTaskList_Export(VisitTaskQuery queryVisitTask, [FromServices] IRepository _commonDocumentRepository, [FromServices] IDictionaryService _dictionaryService) { var list = await _repository.Where(t => t.TrialId == queryVisitTask.TrialId && t.IsAnalysisCreate == false) //.Where(t => t.IsAnalysisCreate == false && t.DoctorUserId != null) .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(!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.BlindSubjectCode.Contains(queryVisitTask.SubjectCode)) .WhereIf(queryVisitTask.BeginAllocateDate != null, t => t.AllocateTime > queryVisitTask.BeginAllocateDate) .WhereIf(queryVisitTask.EndAllocateDate != null, t => t.AllocateTime < queryVisitTask.EndAllocateDate!.Value.AddDays(1)) .ProjectTo(_mapper.ConfigurationProvider).ToListAsync(); //var defalutSortArray = new string[] { nameof(VisitTask.IsUrgent) + " desc", nameof(VisitTask.SubjectId), nameof(VisitTask.VisitTaskNum) }; list = list.OrderBy(t => t.TrialSiteCode).ThenBy(t => t.SubjectCode).ThenBy(t => t.VisitTaskNum).ToList(); var exportInfo = (await _trialRepository.Where(t => t.Id == queryVisitTask.TrialId).IgnoreQueryFilters().ProjectTo(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException(); exportInfo.List = list; return await ExcelExportHelper.DataExportAsync(StaticData.Export.TrialReadingTaskList_Export, exportInfo, "", _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(ReadingTaskExportDto)); } /// /// PM 重阅追踪 /// /// /// [HttpPost] public async Task GetReReadingTaskList_Export(VisitTaskQuery queryVisitTask, [FromServices] IRepository _commonDocumentRepository, [FromServices] IDictionaryService _dictionaryService) { var list = await _repository.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.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.OriginalReReadingTask.TaskBlindName.Contains(queryVisitTask.TaskName)) .WhereIf(!string.IsNullOrEmpty(queryVisitTask.SubjectCode), t => t.OriginalReReadingTask.Subject.Code.Contains(queryVisitTask.SubjectCode) || t.OriginalReReadingTask.BlindSubjectCode.Contains(queryVisitTask.SubjectCode)) .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).ToListAsync(); //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) }; list = list.OrderBy(t => t.TrialSiteCode).ThenBy(t => t.SubjectCode).ThenBy(t => t.VisitTaskNum).ToList(); var exportInfo = (await _trialRepository.Where(t => t.Id == queryVisitTask.TrialId).IgnoreQueryFilters().ProjectTo(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException(); exportInfo.List = list; return await ExcelExportHelper.DataExportAsync(StaticData.Export.TrialReReadingTaskList_Export, exportInfo, "", _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(ReReadingTaskExportDto)); } /// /// PM 医学审核(挑选任务生成后的列表) /// /// /// [HttpPost] public async Task GetMedicalReviewTaskList_Export(TaskMedicalReviewQuery inQuery, [FromServices] IRepository _commonDocumentRepository, [FromServices] IDictionaryService _dictionaryService) { var list = await _repository.Where(t => t.VisitTask.TrialId == inQuery.TrialId) .WhereIf(inQuery.SiteId != null, t => t.VisitTask.Subject.SiteId == inQuery.SiteId) .WhereIf(inQuery.SubjectId != null, t => t.VisitTask.SubjectId == inQuery.SubjectId) .WhereIf(!string.IsNullOrEmpty(inQuery.SubjectCode), t => t.VisitTask.Subject.Code.Contains(inQuery.SubjectCode)) .WhereIf(!string.IsNullOrEmpty(inQuery.TaskName), t => t.VisitTask.TaskName.Contains(inQuery.TaskName) || t.VisitTask.TaskBlindName.Contains(inQuery.TaskName)) .WhereIf(inQuery.IsUrgent != null, t => t.VisitTask.IsUrgent == inQuery.IsUrgent) .WhereIf(inQuery.DoctorUserId != null, t => t.VisitTask.DoctorUserId == inQuery.DoctorUserId) .WhereIf(!string.IsNullOrEmpty(inQuery.TrialSiteCode), t => (t.VisitTask.BlindTrialSiteCode.Contains(inQuery.TrialSiteCode) && t.VisitTask.IsAnalysisCreate) || (t.VisitTask.Subject.TrialSite.TrialSiteCode.Contains(inQuery.TrialSiteCode) && t.VisitTask.IsAnalysisCreate == false)) .WhereIf(inQuery.ReadingCategory != null, t => t.VisitTask.ReadingCategory == inQuery.ReadingCategory) .WhereIf(inQuery.ReadingTaskState != null, t => t.VisitTask.ReadingTaskState == inQuery.ReadingTaskState) .WhereIf(inQuery.TrialReadingCriterionId != null, t => t.VisitTask.TrialReadingCriterionId == inQuery.TrialReadingCriterionId) .ProjectTo(_mapper.ConfigurationProvider).ToListAsync(); list = list.OrderBy(t => t.TrialSiteCode).ThenBy(t => t.SubjectCode).ThenBy(t => t.VisitTaskNum).ToList(); var exportInfo = (await _trialRepository.Where(t => t.Id == inQuery.TrialId).IgnoreQueryFilters().ProjectTo(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException(); exportInfo.List = list; return await ExcelExportHelper.DataExportAsync(StaticData.Export.TrialMedicalReviewList_Export, exportInfo, "", _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(TaskMedicalReviewExportDto)); } /// /// 自身一致性分析 /// /// /// [HttpPost] public async Task GetSelfAnalysisTaskList_Export(VisitTaskQuery queryVisitTask, [FromServices] IRepository _commonDocumentRepository, [FromServices] IDictionaryService _dictionaryService) { //产生一致性分析的Subject var subjectQuerybal= _repository.Where(t => t.TrialId == queryVisitTask.TrialId && t.TaskState == TaskState.Effect && t.IsSelfAnalysis == true).Select(t => t.SubjectId).Distinct(); var allList = await _repository.Where(t => t.TrialId == queryVisitTask.TrialId && t.TaskState == TaskState.Effect && subjectQuerybal.Contains(t.SubjectId)) .Where(t => t.IsSelfAnalysis == true || t.IsSelfAnalysis == null) //一致性分析的结果 + 正常任务的结果 //.WhereIf(queryVisitTask.SubjectId != null, t => t.SubjectId == queryVisitTask.SubjectId) //.WhereIf(queryVisitTask.TaskState != null, t => t.TaskState == queryVisitTask.TaskState) //.WhereIf(queryVisitTask.IsSelfAnalysis != null, t => t.IsSelfAnalysis == queryVisitTask.IsSelfAnalysis) .WhereIf(queryVisitTask.TrialReadingCriterionId != null, t => t.TrialReadingCriterionId == queryVisitTask.TrialReadingCriterionId) .WhereIf(queryVisitTask.SiteId != null, t => t.Subject.SiteId == queryVisitTask.SiteId) .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.ArmEnum != null, t => t.ArmEnum == queryVisitTask.ArmEnum) .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)) .WhereIf(queryVisitTask.BeginAllocateDate != null, t => t.AllocateTime > queryVisitTask.BeginAllocateDate) .WhereIf(queryVisitTask.EndAllocateDate != null, t => t.AllocateTime < queryVisitTask.EndAllocateDate!.Value.AddDays(1)) .ProjectTo(_mapper.ConfigurationProvider).ToListAsync(); var list = allList.Where(t => t.IsSelfAnalysis == null).OrderBy(t => t.TrialSiteCode).ThenBy(t => t.SubjectCode).ThenBy(t => t.VisitTaskNum).ToList(); //To do 根据任务Id 找对评估结果,这里需要考虑标准 以及对应的翻译 foreach (var item in list) { //找到一致性分析的结果 var origenalTask = allList.Where(t => t.IsSelfAnalysis == true && t.SubjectCode == item.SubjectCode && t.VisitTaskNum == item.VisitTaskNum && t.TaskName == t.TaskName).FirstOrDefault(); item.AgainEvaluateResult = origenalTask?.EvaluateResult ?? String.Empty ; } var exportInfo = (await _trialRepository.Where(t => t.Id == queryVisitTask.TrialId).IgnoreQueryFilters().ProjectTo(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException(); exportInfo.List = list; return await ExcelExportHelper.DataExportAsync(StaticData.Export.TrialMedicalReviewList_Export, exportInfo, "", _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(TaskMedicalReviewExportDto)); } /// /// 组件一致性分析 /// /// /// [HttpPost] public async Task GetGroupAnalysisTaskList_Export(VisitTaskQuery queryVisitTask, [FromServices] IRepository _commonDocumentRepository, [FromServices] IDictionaryService _dictionaryService) { //产生组间一致性分析的Subject var subjectQuerybal = _repository.Where(t => t.TrialId == queryVisitTask.TrialId && t.TaskState == TaskState.Effect && t.IsSelfAnalysis == false).Select(t => t.SubjectId).Distinct(); var allList = await _repository.Where(t => t.TrialId == queryVisitTask.TrialId && t.TaskState == TaskState.Effect && subjectQuerybal.Contains(t.SubjectId)) .Where(t => t.IsSelfAnalysis == false || t.IsSelfAnalysis == null) //一致性分析的结果 + 正常任务的结果 //.WhereIf(queryVisitTask.SubjectId != null, t => t.SubjectId == queryVisitTask.SubjectId) //.WhereIf(queryVisitTask.TaskState != null, t => t.TaskState == queryVisitTask.TaskState) //.WhereIf(queryVisitTask.IsSelfAnalysis != null, t => t.IsSelfAnalysis == queryVisitTask.IsSelfAnalysis) .WhereIf(queryVisitTask.TrialReadingCriterionId != null, t => t.TrialReadingCriterionId == queryVisitTask.TrialReadingCriterionId) .WhereIf(queryVisitTask.SiteId != null, t => t.Subject.SiteId == queryVisitTask.SiteId) .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.ArmEnum != null, t => t.ArmEnum == queryVisitTask.ArmEnum) .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)) .WhereIf(queryVisitTask.BeginAllocateDate != null, t => t.AllocateTime > queryVisitTask.BeginAllocateDate) .WhereIf(queryVisitTask.EndAllocateDate != null, t => t.AllocateTime < queryVisitTask.EndAllocateDate!.Value.AddDays(1)) .ProjectTo(_mapper.ConfigurationProvider).ToListAsync(); var list = allList.Where(t => t.IsSelfAnalysis == null).OrderBy(t => t.TrialSiteCode).ThenBy(t => t.SubjectCode).ThenBy(t => t.VisitTaskNum).ToList(); //To do 根据任务Id 找对评估结果,这里需要考虑标准 以及对应的翻译 foreach (var item in list) { //找到一致性分析的结果 var origenalTask = allList.Where(t => t.IsSelfAnalysis == false && t.SubjectCode == item.SubjectCode && t.VisitTaskNum == item.VisitTaskNum && t.TaskName == t.TaskName).FirstOrDefault(); item.AgainEvaluateResult = origenalTask?.EvaluateResult ?? String.Empty; } var exportInfo = (await _trialRepository.Where(t => t.Id == queryVisitTask.TrialId).IgnoreQueryFilters().ProjectTo(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException(); exportInfo.List = list; return await ExcelExportHelper.DataExportAsync(StaticData.Export.TrialMedicalReviewList_Export, exportInfo, "", _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(TaskMedicalReviewExportDto)); } /// /// 整体肿瘤评估 多个标准一个接口 Excel 列是一样的 /// /// /// [HttpPost] public async Task GetOverallTumorEvaluationList_Export(VisitTaskQuery queryVisitTask, [FromServices] IRepository _commonDocumentRepository, [FromServices] IDictionaryService _dictionaryService) { //每次查询必须是单标准的 var criterionType = await _repository.Where(t => t.Id == queryVisitTask.TrialReadingCriterionId).Select(t => t.CriterionType).FirstOrDefaultAsync(); var list = await _repository.Where(t => t.TrialId == queryVisitTask.TrialId && t.TaskState == TaskState.Effect && t.IsAnalysisCreate==false && t.ReadingTaskState==ReadingTaskState.HaveSigned) //.WhereIf(queryVisitTask.SubjectId != null, t => t.SubjectId == queryVisitTask.SubjectId) //.WhereIf(queryVisitTask.TaskState != null, t => t.TaskState == queryVisitTask.TaskState) //.WhereIf(queryVisitTask.IsSelfAnalysis != null, t => t.IsSelfAnalysis == queryVisitTask.IsSelfAnalysis) .WhereIf(queryVisitTask.TrialReadingCriterionId != null, t => t.TrialReadingCriterionId == queryVisitTask.TrialReadingCriterionId) .WhereIf(queryVisitTask.SiteId != null, t => t.Subject.SiteId == queryVisitTask.SiteId) .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.ArmEnum != null, t => t.ArmEnum == queryVisitTask.ArmEnum) .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)) .WhereIf(queryVisitTask.BeginAllocateDate != null, t => t.AllocateTime > queryVisitTask.BeginAllocateDate) .WhereIf(queryVisitTask.EndAllocateDate != null, t => t.AllocateTime < queryVisitTask.EndAllocateDate!.Value.AddDays(1)) .ProjectTo(_mapper.ConfigurationProvider,new { criterionType = criterionType }).ToListAsync(); var exportInfo = (await _trialRepository.Where(t => t.Id == queryVisitTask.TrialId).IgnoreQueryFilters().ProjectTo(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException(); exportInfo.List = list; return await ExcelExportHelper.DataExportAsync(StaticData.Export.TrialMedicalReviewList_Export, exportInfo, "", _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(OverallTumorEvaluationExport), criterionType); } /// /// 肿瘤疗效评估表 ( 目前 RECIST1.1) /// /// /// [HttpPost] public async Task GetEvaluationOfTumorEfficacy_Export(VisitTaskQuery queryVisitTask, [FromServices] IRepository _commonDocumentRepository, [FromServices] IDictionaryService _dictionaryService) { //每次查询必须是单标准的 var criterionType = await _repository.Where(t => t.Id == queryVisitTask.TrialReadingCriterionId).Select(t => t.CriterionType).FirstOrDefaultAsync(); var query = _repository.Where(t => t.TrialId == queryVisitTask.TrialId && t.TaskState == TaskState.Effect && t.IsAnalysisCreate == false && t.ReadingTaskState == ReadingTaskState.HaveSigned) //.WhereIf(queryVisitTask.SubjectId != null, t => t.SubjectId == queryVisitTask.SubjectId) //.WhereIf(queryVisitTask.TaskState != null, t => t.TaskState == queryVisitTask.TaskState) //.WhereIf(queryVisitTask.IsSelfAnalysis != null, t => t.IsSelfAnalysis == queryVisitTask.IsSelfAnalysis) .WhereIf(queryVisitTask.TrialReadingCriterionId != null, t => t.TrialReadingCriterionId == queryVisitTask.TrialReadingCriterionId) .WhereIf(queryVisitTask.SiteId != null, t => t.Subject.SiteId == queryVisitTask.SiteId) .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.ArmEnum != null, t => t.ArmEnum == queryVisitTask.ArmEnum) .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)) .WhereIf(queryVisitTask.BeginAllocateDate != null, t => t.AllocateTime > queryVisitTask.BeginAllocateDate) .WhereIf(queryVisitTask.EndAllocateDate != null, t => t.AllocateTime < queryVisitTask.EndAllocateDate!.Value.AddDays(1)); var exportInfo = (await _trialRepository.Where(t => t.Id == queryVisitTask.TrialId).IgnoreQueryFilters().ProjectTo(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException(); if (criterionType == CriterionType.RECIST1Pointt1) { var list = await query.ProjectTo(_mapper.ConfigurationProvider, new { criterionType = criterionType }).ToListAsync(); exportInfo.List = list; return await ExcelExportHelper.DataExportAsync(StaticData.Export.TrialMedicalReviewList_Export, exportInfo, "", _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(RECIST1Point1EvaluationOfTumorEfficacyExport), criterionType); } else { throw new Exception("当前标准导出还未支持"); } } /// /// 评估病灶明细表 ( 目前 RECIST1.1 PGW3 表都是不同的) /// /// /// [HttpPost] public async Task GetDetailedOfEvaluatedLesion_Export(VisitTaskQuery queryVisitTask, [FromServices] IRepository _commonDocumentRepository, [FromServices] IDictionaryService _dictionaryService) { //每次查询必须是单标准的 var criterionType = await _repository.Where(t => t.Id == queryVisitTask.TrialReadingCriterionId).Select(t => t.CriterionType).FirstOrDefaultAsync(); var query = _repository.Where(t => t.TrialId == queryVisitTask.TrialId && t.TaskState == TaskState.Effect && t.IsAnalysisCreate == false && t.ReadingTaskState == ReadingTaskState.HaveSigned) //.WhereIf(queryVisitTask.SubjectId != null, t => t.SubjectId == queryVisitTask.SubjectId) //.WhereIf(queryVisitTask.TaskState != null, t => t.TaskState == queryVisitTask.TaskState) //.WhereIf(queryVisitTask.IsSelfAnalysis != null, t => t.IsSelfAnalysis == queryVisitTask.IsSelfAnalysis) .WhereIf(queryVisitTask.TrialReadingCriterionId != null, t => t.TrialReadingCriterionId == queryVisitTask.TrialReadingCriterionId) .WhereIf(queryVisitTask.SiteId != null, t => t.Subject.SiteId == queryVisitTask.SiteId) .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.ArmEnum != null, t => t.ArmEnum == queryVisitTask.ArmEnum) .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)) .WhereIf(queryVisitTask.BeginAllocateDate != null, t => t.AllocateTime > queryVisitTask.BeginAllocateDate) .WhereIf(queryVisitTask.EndAllocateDate != null, t => t.AllocateTime < queryVisitTask.EndAllocateDate!.Value.AddDays(1)); var exportInfo = (await _trialRepository.Where(t => t.Id == queryVisitTask.TrialId).IgnoreQueryFilters().ProjectTo(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException(); if (criterionType == CriterionType.RECIST1Pointt1) { var list = await query.ProjectTo(_mapper.ConfigurationProvider, new { criterionType = criterionType }).ToListAsync(); var exportList = list.SelectMany(c => { return c.LesionList.Select(u => { var clone = c.Clone(); clone.LessionCode = u.LessionCode; clone.LessionType = u.LessionType; clone.LessionLocation = u.LessionLocation; clone.LessionOrgan = u.LessionOrgan; clone.IsLymph = u.IsLymph; clone.BodyPartDescription = u.BodyPartDescription; clone.MeasurementResult = u.MeasurementResult; clone.LongDiameter = u.LongDiameter; clone.ShortDiameter = u.ShortDiameter; clone.LessionState = u.LessionState; return clone; }); }); exportInfo.List = list; return await ExcelExportHelper.DataExportAsync(StaticData.Export.TrialMedicalReviewList_Export, exportInfo, "", _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(RECIST1Point1DetailedOfEvaluatedLesionExport), criterionType); } else { throw new Exception("当前标准导出还未支持"); } } #endregion #region CRC上传、质疑页面 /// /// CRC 访视上传列表 /// /// /// [HttpPost] public async Task<(PageOutput, TrialSubjectAndSVConfig)> GetCRCVisitList(CRCVisitSearchDTO visitSearchDTO) { var svExpression = QCCommon.GetSubjectVisitFilter(visitSearchDTO.VisitPlanArray); var query = _subjectVisitRepository.Where(x => x.TrialId == visitSearchDTO.TrialId) .Where(t => t.Subject.FinalSubjectVisitId != null ? t.VisitNum <= t.Subject.FinalSubjectVisit.VisitNum : true) .WhereIf(visitSearchDTO.SiteId != null, t => t.SiteId == visitSearchDTO.SiteId) .WhereIf(visitSearchDTO.SubjectId != null, t => t.Subject.Id == visitSearchDTO.SubjectId) .WhereIf(!string.IsNullOrEmpty(visitSearchDTO.SubjectInfo), t => t.Subject.Code.Contains(visitSearchDTO.SubjectInfo)) .WhereIf(visitSearchDTO.VisitPlanArray != null && visitSearchDTO.VisitPlanArray?.Length > 0, svExpression) //.WhereIf(!string.IsNullOrEmpty(visitSearchDTO.VisitPlanInfo), visitSearchDTO.VisitPlanInfo.Contains('.') ? t => t.InPlan == false : t => t.VisitNum == decimal.Parse(visitSearchDTO.VisitPlanInfo)) .WhereIf(visitSearchDTO.AuditStateArray != null && visitSearchDTO.AuditStateArray?.Length > 0, t => visitSearchDTO.AuditStateArray!.Contains(t.AuditState)) .WhereIf(visitSearchDTO.SubmitState != null, t => t.SubmitState == visitSearchDTO.SubmitState) .WhereIf(visitSearchDTO.ChallengeState != null, t => t.ChallengeState == visitSearchDTO.ChallengeState) .WhereIf(visitSearchDTO.IsUrgent != null, t => t.IsUrgent == visitSearchDTO.IsUrgent) .WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.CRA, t => t.TrialSite.CRCUserList.Any(t => t.UserId == _userInfo.Id)) .ProjectTo(_mapper.ConfigurationProvider); var defalutSortArray = new string[] { nameof(SubjectVisit.IsUrgent) + " desc", nameof(SubjectVisit.SubjectId), nameof(SubjectVisit.VisitNum) }; var pageList = await query.ToPagedListAsync(visitSearchDTO.PageIndex, visitSearchDTO.PageSize, visitSearchDTO.SortField, visitSearchDTO.Asc, string.IsNullOrWhiteSpace(visitSearchDTO.SortField), defalutSortArray); var config = await _repository.Where(t => t.Id == visitSearchDTO.TrialId).ProjectTo(_mapper.ConfigurationProvider).FirstOrDefaultAsync().IfNullThrowException(); return (pageList, config!); } /// /// CRC 质疑列表 /// /// /// [HttpPost] public async Task<(PageOutput, TrialSubjectAndSVConfig)> GetCRCChallengeList(ChallengeQuery challengeQuery) { #region CRC 质疑列表 join连表方式 //var query = from qcChanllenge in _qcChallengeRepository.Find(qcChallengeLambda) // join subjectVisit in _subjectVisitRepository.Find() on qcChanllenge.SubjectVisitId equals subjectVisit.Id // join trialSite in _trialSiteRepository.Find(t => t.TrialId == challengeQuery.TrialId) on subjectVisit.SiteId equals trialSite.SiteId // join subject in _subjectRepository.Find() on subjectVisit.SubjectId equals subject.Id // select new QCCRCChallengeViewModel() // { // Id = qcChanllenge.Id, // SubjectVisitId = qcChanllenge.SubjectVisitId, // ChallengeCode = qcChanllenge.ChallengeCode, // ChallengeType = qcChanllenge.ChallengeType, // Note = qcChanllenge.Note, // Content = qcChanllenge.Content, // UserTypeEnum = qcChanllenge.UserTypeEnum, // CreateTime = qcChanllenge.CreateTime, // CreateUser = qcChanllenge.CreateUser, // CreateUserId = qcChanllenge.CreateUserId, // DeadlineTime = qcChanllenge.DeadlineTime, // IsClosed = qcChanllenge.IsClosed, // ClosedTime = qcChanllenge.ClosedTime, // ClosedUser = qcChanllenge.ClosedUser, // NeedReUpload = qcChanllenge.NeedReUpload, // VisitName = subjectVisit.VisitName, // VisitNum = subjectVisit.VisitNum, // SubjectCode = subject.Code, // TrialSiteCode = trialSite.TrialSiteCode, // LatestMsgTime = qcChanllenge.LatestMsgTime, // LatestReplyUser = qcChanllenge.LatestReplyUser, // }; #endregion var svExpression = QCCommon.GetQCChallengeFilter(challengeQuery.VisitPlanArray); var query2 = _repository.Where(x => x.TrialId == challengeQuery.TrialId) //.WhereIf(challengeQuery.ChallengeState != null, t => t.SubjectVisit.ChallengeState == challengeQuery.ChallengeState) .WhereIf(challengeQuery.ReuploadEnum != null, t => t.ReuploadEnum == challengeQuery.ReuploadEnum) .WhereIf(challengeQuery.IsClosed != null, t => t.IsClosed == challengeQuery.IsClosed) .WhereIf(challengeQuery.SiteId != null, t => t.SubjectVisit.SiteId == challengeQuery.SiteId) .WhereIf(challengeQuery.SubjectId != null, t => t.SubjectVisit.SubjectId == challengeQuery.SubjectId) .WhereIf(challengeQuery.CreateUserId != null, t => t.CreateUserId == challengeQuery.CreateUserId) .WhereIf(challengeQuery.SubjectCode != null, t => t.SubjectVisit.Subject.Code.Contains(challengeQuery.SubjectCode!)) .WhereIf(challengeQuery.VisitPlanArray != null && challengeQuery.VisitPlanArray?.Length > 0, svExpression) //.WhereIf(!string.IsNullOrEmpty(challengeQuery.VisitPlanInfo), challengeQuery.VisitPlanInfo.Contains('.') ? t => t.SubjectVisit.VisitNum.ToString().Contains(".") : t => t.SubjectVisit.VisitNum == decimal.Parse(challengeQuery.VisitPlanInfo)) .WhereIf(challengeQuery.IsOverTime != null, t => DateTime.Now > t.DeadlineTime) .WhereIf(challengeQuery.IsUrgent != null, t => t.SubjectVisit.IsUrgent == challengeQuery.IsUrgent) .WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.CRA, t => t.SubjectVisit.TrialSite.CRCUserList.Any(t => t.UserId == _userInfo.Id)) .ProjectTo(_mapper.ConfigurationProvider); var pageList = await query2.ToPagedListAsync(challengeQuery.PageIndex, challengeQuery.PageSize, challengeQuery.SortField, challengeQuery.Asc, string.IsNullOrWhiteSpace(challengeQuery.SortField), new string[] { "IsUrgent desc", "IsClosed asc" }); var config = await _repository.Where(t => t.Id == challengeQuery.TrialId).ProjectTo(_mapper.ConfigurationProvider).FirstOrDefaultAsync().IfNullThrowException(); return (pageList, config); } #endregion #region QC 质疑 质控页面 /// /// QC 质疑列表 分页 /// /// /// [HttpPost] public async Task<(PageOutput, TrialSubjectAndSVConfig)> GetQCChallengeList(ChallengeQuery challengeQuery) { #region linq方式 + Expression 拼接 //Expression> qcChallengeLambda = x => x.TrialId == challengeQuery.TrialId; //if (challengeQuery.ReuploadEnum != null) //{ // qcChallengeLambda = qcChallengeLambda.And(t => t.ReuploadEnum == challengeQuery.ReuploadEnum); //} //if (challengeQuery.IsClosed != null) //{ // qcChallengeLambda = qcChallengeLambda.And(t => t.IsClosed == challengeQuery.IsClosed); //} //if (challengeQuery.SiteId != null) //{ // qcChallengeLambda = qcChallengeLambda.And(t => t.SubjectVisit.SiteId == challengeQuery.SiteId.Value); //} //if (challengeQuery.SubjectId != null) //{ // qcChallengeLambda = qcChallengeLambda.And(t => t.SubjectVisit.Subject.Id == challengeQuery.SubjectId.Value); //} //var query = from qcChanllenge in _qcChallengeRepository.Find(qcChallengeLambda) // join subjectVisit in _subjectVisitRepository.Find(subjectVisitLambda) on qcChanllenge.SubjectVisitId equals subjectVisit.Id // join trialSite in _trialSiteRepository.Find(t => t.TrialId == challengeQuery.TrialId) on subjectVisit.SiteId equals trialSite.SiteId // join subject in _subjectRepository.Find() on subjectVisit.SubjectId equals subject.Id // select new QCChallengeViewModel() // { // Id = qcChanllenge.Id, // SubjectVisitId = qcChanllenge.SubjectVisitId, // ChallengeCode = qcChanllenge.ChallengeCode.ToString(), // ChallengeType = qcChanllenge.ChallengeType, // Note = qcChanllenge.Note, // UserTypeEnum = qcChanllenge.UserTypeEnum, // Content = qcChanllenge.Content, // CreateTime = qcChanllenge.CreateTime, // CreateUserId = qcChanllenge.CreateUserId, // CreateUser = qcChanllenge.CreateUser, // SubjectCode = subject.Code, // TrialSiteCode = trialSite.TrialSiteCode, // DeadlineTime = qcChanllenge.DeadlineTime, // IsClosed = qcChanllenge.IsClosed, // ClosedTime = qcChanllenge.ClosedTime, // ClosedUser = qcChanllenge.ClosedUser, // NeedReUpload = qcChanllenge.NeedReUpload, // VisitName = subjectVisit.VisitName, // VisitNum = subjectVisit.VisitNum, // LatestMsgTime = qcChanllenge.LatestMsgTime, // LatestReplyUser = qcChanllenge.LatestReplyUser, // }; #endregion var svExpression = QCCommon.GetQCChallengeFilter(challengeQuery.VisitPlanArray); var query = _repository.Where(x => x.TrialId == challengeQuery.TrialId) //.WhereIf(challengeQuery.ChallengeState != null, t => t.SubjectVisit.ChallengeState == challengeQuery.ChallengeState) .WhereIf(challengeQuery.ReuploadEnum != null, t => t.ReuploadEnum == challengeQuery.ReuploadEnum) .WhereIf(challengeQuery.IsClosed != null, t => t.IsClosed == challengeQuery.IsClosed) .WhereIf(challengeQuery.SiteId != null, t => t.SubjectVisit.SiteId == challengeQuery.SiteId) .WhereIf(challengeQuery.SubjectId != null, t => t.SubjectVisit.SubjectId == challengeQuery.SubjectId) .WhereIf(challengeQuery.CreateUserId != null, t => t.CreateUserId == challengeQuery.CreateUserId) .WhereIf(!string.IsNullOrEmpty(challengeQuery.SubjectCode), t => t.SubjectVisit.Subject.Code.Contains(challengeQuery.SubjectCode)) .WhereIf(challengeQuery.VisitPlanArray != null && challengeQuery.VisitPlanArray?.Length > 0, svExpression) //.WhereIf(!string.IsNullOrEmpty(challengeQuery.VisitPlanInfo), challengeQuery.VisitPlanInfo.Contains('.') ? t => t.SubjectVisit.InPlan == false : t => t.SubjectVisit.VisitNum == decimal.Parse(challengeQuery.VisitPlanInfo)) .WhereIf(challengeQuery.IsUrgent != null, t => t.SubjectVisit.IsUrgent == challengeQuery.IsUrgent) .WhereIf(challengeQuery.IsOverTime != null && challengeQuery.IsOverTime == true, t => t.IsClosed ? t.ClosedTime > t.DeadlineTime : DateTime.Now > t.DeadlineTime) .WhereIf(challengeQuery.IsOverTime != null && challengeQuery.IsOverTime == false, t => t.IsClosed ? t.ClosedTime < t.DeadlineTime : DateTime.Now < t.DeadlineTime) .ProjectTo(_mapper.ConfigurationProvider); var pageList = await query.ToPagedListAsync(challengeQuery.PageIndex, challengeQuery.PageSize, challengeQuery.SortField, challengeQuery.Asc, string.IsNullOrWhiteSpace(challengeQuery.SortField), new string[] { "IsUrgent desc", "IsClosed asc" }); var config = await _repository.Where(t => t.Id == challengeQuery.TrialId).ProjectTo(_mapper.ConfigurationProvider).FirstOrDefaultAsync().IfNullThrowException(); return (pageList, config); } /// /// QC 访视列表 /// /// /// [HttpPost] public async Task<(PageOutput, TrialSubjectAndSVConfig)> GetQCVisitList(QCVisitSearchDTO visitSearchDTO) { #region 经典 linq //Expression> subjectLambda = x => true; //Expression> subjectVisitLambda = x => x.TrialId == visitSearchDTO.TrialId; //Expression> studyLambda = x => x.TrialId == visitSearchDTO.TrialId; ////Expression> visitPlanLambda = x => x.TrialId == subjectVisitSearch.TrialId; //if (visitSearchDTO.SiteId != null && visitSearchDTO.SiteId != Guid.Empty) //{ // subjectVisitLambda = subjectVisitLambda.And(t => t.SiteId == visitSearchDTO.SiteId.Value); // studyLambda = studyLambda.And(t => t.SiteId == visitSearchDTO.SiteId.Value); //} //if (visitSearchDTO.SubjectId != null && visitSearchDTO.SubjectId != Guid.Empty) //{ // subjectLambda = subjectLambda.And(t => t.Id == visitSearchDTO.SubjectId.Value); // studyLambda = studyLambda.And(t => t.SubjectId == visitSearchDTO.SubjectId.Value); //} //if (!string.IsNullOrEmpty(visitSearchDTO.SubjectInfo)) //{ // var search = visitSearchDTO.SubjectInfo.Trim(); // subjectLambda = subjectLambda.And(t => t.FirstName.Contains(search) || t.LastName.Contains(search) || t.Code.Contains(search)); //} //if (!string.IsNullOrWhiteSpace(visitSearchDTO.VisitPlanInfo)) //{ // var visitInfo = visitSearchDTO.VisitPlanInfo.Trim(); // if (visitInfo.Contains('.')) // 包含小数点的是计划外访视 // { // subjectVisitLambda = subjectVisitLambda.And(t => t.VisitNum.ToString().Contains(".")); // } // else // { // if (int.TryParse(visitInfo, out var visitNum)) // { // subjectVisitLambda = subjectVisitLambda.And(t => t.VisitNum == visitNum); // } // } //} //var query = from subjectVisit in _subjectVisitRepository.Where(subjectVisitLambda) // join subject in _subjectRepository.Where(subjectLambda) on subjectVisit.SubjectId equals subject.Id // join trialSite in _trialSiteRepository.Where(t => t.TrialId == visitSearchDTO.TrialId) on subjectVisit.SiteId equals trialSite.SiteId // join study in _studyRepository.Where(studyLambda).GroupBy(t => t.SubjectVisitId).Select(g => new { SubjectVisitId = g.Key, StudyCount = g.Count() }) on subjectVisit.Id equals study.SubjectVisitId into d // from study in d.DefaultIfEmpty() // join trial in _trialRepository.AsQueryable() on subjectVisit.TrialId equals trial.Id // select new QCVisitViewModel() // { // Id = subjectVisit.Id, // //VisitPlanId = visitStage.Id, // SubjectId = subjectVisit.SubjectId, // TrialId = subjectVisit.TrialId, // SiteId = subjectVisit.SiteId, // VisitDay = subjectVisit.VisitDay, // VisitNum = subjectVisit.VisitNum, // VisitName = subjectVisit.VisitName, // SVENDTC = subjectVisit.SVENDTC, // SVSTDTC = subjectVisit.SVSTDTC, // SVUPDES = subjectVisit.SVUPDES, // InPlan = subjectVisit.InPlan, // VisitExecuted = subjectVisit.VisitExecuted, // StudyCount = study.StudyCount, // SubjectStatus = subject.Status, // SubjectCode = subject.Code, // IsUrgent = subjectVisit.IsUrgent, // TrialSiteCode = trialSite.TrialSiteCode, // EarliestScanDate = subjectVisit.EarliestScanDate, // LatestScanDate = subjectVisit.LatestScanDate, // QCProcessEnum = trial.QCProcessEnum, // CurrentActionUserId = subjectVisit.CurrentActionUserId, // CurrentActionUser = subjectVisit.CurrentActionUser, // CurrentActionUserExpireTime = subjectVisit.CurrentActionUserExpireTime, // PreliminaryAuditTime = subjectVisit.PreliminaryAuditTime, // PreliminaryAuitUser = subjectVisit.PreliminaryAuitUser, // ReviewAuitTime = subjectVisit.ReviewAuitTime, // ReviewAuitUser = subjectVisit.ReviewAuitUser, // AuditState = subjectVisit.AuditState, // SubmitTime = subjectVisit.SubmitTime, // IsTake = subjectVisit.IsTake, // }; #endregion #region WhereIf + ling 统计 //var query = from subjectVisit in _subjectVisitRepository.Where(x => x.TrialId == visitSearchDTO.TrialId) // .WhereIf(visitSearchDTO.SiteId != null, t => t.SiteId == visitSearchDTO.SiteId) // .WhereIf(visitSearchDTO.SubjectId != null, t => t.Subject.Id == visitSearchDTO.SubjectId) // .WhereIf(!string.IsNullOrEmpty(subjectInfo), t => /*t.Subject.FirstName.Contains(subjectInfo) || t.Subject.LastName.Contains(subjectInfo) ||*/ t.Subject.Code.Contains(subjectInfo)) // .WhereIf(!string.IsNullOrEmpty(visitInfo), visitInfo.Contains('.') ? t => t.VisitNum.ToString().Contains(".") : t => t.VisitNum.ToString() == visitInfo) // .WhereIf(visitSearchDTO.AuditState != null, t => t.AuditState == visitSearchDTO.AuditState) // .WhereIf(visitSearchDTO.HandleUser != null, t => t.PreliminaryAuitUser.Contains(visitSearchDTO.HandleUser) || t.ReviewAuitUser.Contains(visitSearchDTO.HandleUser)) // .WhereIf(visitSearchDTO.IsUrgent != null, t => t.IsUrgent == visitSearchDTO.IsUrgent) // //.WhereIf(visitSearchDTO.SubmitState != null, t => t.SubmitState == visitSearchDTO.SubmitState) // //.WhereIf(visitSearchDTO.ChallengeState != null, t => t.ChallengeState == visitSearchDTO.ChallengeState) // join subject in _subjectRepository.AsQueryable() on subjectVisit.SubjectId equals subject.Id // join trialSite in _trialSiteRepository.Where(t => t.TrialId == visitSearchDTO.TrialId) on subjectVisit.SiteId equals trialSite.SiteId // join study in _studyRepository.AsQueryable().GroupBy(t => t.SubjectVisitId).Select(g => new { SubjectVisitId = g.Key, StudyCount = g.Count() }) on subjectVisit.Id equals study.SubjectVisitId into d // from study in d.DefaultIfEmpty() // join trial in _trialRepository.AsQueryable() on subjectVisit.TrialId equals trial.Id // select new QCVisitViewModel() // { // Id = subjectVisit.Id, // //VisitPlanId = visitStage.Id, // SubjectId = subjectVisit.SubjectId, // TrialId = subjectVisit.TrialId, // SiteId = subjectVisit.SiteId, // VisitDay = subjectVisit.VisitDay, // VisitNum = subjectVisit.VisitNum, // VisitName = subjectVisit.VisitName, // SVENDTC = subjectVisit.SVENDTC, // SVSTDTC = subjectVisit.SVSTDTC, // SVUPDES = subjectVisit.SVUPDES, // InPlan = subjectVisit.InPlan, // VisitExecuted = subjectVisit.VisitExecuted, // IsUrgent = subjectVisit.IsUrgent, // EarliestScanDate = subjectVisit.EarliestScanDate, // LatestScanDate = subjectVisit.LatestScanDate, // CurrentActionUserId = subjectVisit.CurrentActionUserId, // CurrentActionUser = subjectVisit.CurrentActionUser, // CurrentActionUserExpireTime = subjectVisit.CurrentActionUserExpireTime, // PreliminaryAuditTime = subjectVisit.PreliminaryAuditTime, // PreliminaryAuitUser = subjectVisit.PreliminaryAuitUser, // ReviewAuitTime = subjectVisit.ReviewAuitTime, // ReviewAuitUser = subjectVisit.ReviewAuitUser, // AuditState = subjectVisit.AuditState, // SubmitTime = subjectVisit.SubmitTime, // IsTake = subjectVisit.IsTake, // QCProcessEnum = trial.QCProcessEnum, // TrialSiteCode = trialSite.TrialSiteCode, // SubjectStatus = subject.Status, // SubjectCode = subject.Code, // StudyCount = study.StudyCount, // }; #endregion var svExpression = QCCommon.GetSubjectVisitFilter(visitSearchDTO.VisitPlanArray); var query = _subjectVisitRepository.Where(x => x.TrialId == visitSearchDTO.TrialId) .WhereIf(visitSearchDTO.ChallengeState != null, t => t.ChallengeState == visitSearchDTO.ChallengeState) .WhereIf(visitSearchDTO.SiteId != null, t => t.SiteId == visitSearchDTO.SiteId) .WhereIf(visitSearchDTO.SubjectId != null, t => t.Subject.Id == visitSearchDTO.SubjectId) .WhereIf(!string.IsNullOrEmpty(visitSearchDTO.SubjectInfo), t => /*t.Subject.FirstName.Contains(subjectInfo) || t.Subject.LastName.Contains(subjectInfo) ||*/ t.Subject.Code.Contains(visitSearchDTO.SubjectInfo)) .WhereIf(visitSearchDTO.VisitPlanArray != null && visitSearchDTO.VisitPlanArray?.Length > 0, svExpression) //.WhereIf(!string.IsNullOrEmpty(visitSearchDTO.VisitPlanInfo), visitSearchDTO.VisitPlanInfo.Contains('.') ? t => t.VisitNum.ToString().Contains(".") : t => t.VisitNum == decimal.Parse(visitSearchDTO.VisitPlanInfo)) //.WhereIf(visitSearchDTO.AuditState != null, t => t.AuditState == visitSearchDTO.AuditState) .WhereIf(visitSearchDTO.AuditStateArray != null && visitSearchDTO.AuditStateArray?.Length > 0, t => visitSearchDTO.AuditStateArray!.Contains(t.AuditState)) .WhereIf(visitSearchDTO.HandleUserId != null, t => t.PreliminaryAuditUserId == visitSearchDTO.HandleUserId || t.CurrentActionUserId == visitSearchDTO.HandleUserId || t.ReviewAuditUserId == visitSearchDTO.HandleUserId || t.QCChallengeList.Any(t => t.CreateUserId == visitSearchDTO.HandleUserId) || t.QCChallengeDialogList.Any(t => t.CreateUserId == visitSearchDTO.HandleUserId)) .WhereIf(visitSearchDTO.IsUrgent != null, t => t.IsUrgent == visitSearchDTO.IsUrgent) .Where(t => t.SubmitState != SubmitStateEnum.None) //.WhereIf(visitSearchDTO.SubmitState != null, t => t.SubmitState == visitSearchDTO.SubmitState) //.WhereIf(visitSearchDTO.ChallengeState != null, t => t.ChallengeState == visitSearchDTO.ChallengeState) .ProjectTo(_mapper.ConfigurationProvider); var defalutSortArray = new string[] { nameof(SubjectVisit.IsUrgent) + " desc", nameof(SubjectVisit.SubjectId), nameof(SubjectVisit.VisitNum) }; var pageList = await query.ToPagedListAsync(visitSearchDTO.PageIndex, visitSearchDTO.PageSize, visitSearchDTO.SortField, visitSearchDTO.Asc, string.IsNullOrWhiteSpace(visitSearchDTO.SortField), defalutSortArray); var config = await _repository.Where(t => t.Id == visitSearchDTO.TrialId).ProjectTo(_mapper.ConfigurationProvider).FirstOrDefaultAsync().IfNullThrowException(); return (pageList, config); } #endregion #region 一致性核查 转发页面 /// /// 获取一致性核查列表 CRC/PM 公用 /// /// /// [HttpPost] public async Task<(PageOutput, TrialSubjectAndSVConfig)> GetConsistencyVerificationList(CheckQuery checkQuery) { #region linq 废弃 byzhouhang 2021 11 30 //Expression> subjectLambda = x => true; //Expression> subjectVisitLambda = x => x.TrialId == checkQuery.TrialId && x.AuditState == AuditStateEnum.QCPassed; //Expression> studyLambda = x => x.TrialId == checkQuery.TrialId; //if (checkQuery.SiteId != null && checkQuery.SiteId != Guid.Empty) //{ // subjectVisitLambda = subjectVisitLambda.And(t => t.SiteId == checkQuery.SiteId.Value); //} //if (checkQuery.SubjectId != null && checkQuery.SubjectId != Guid.Empty) //{ // subjectLambda = subjectLambda.And(t => t.Id == checkQuery.SubjectId.Value); //} //if (_userInfo.UserTypeEnumInt == (int)UserType.ClinicalResearchCoordinator) //{ // var siteQuery = _userTrialSiteRepository.Where(t => t.UserId == _userInfo.Id && t.TrialId == checkQuery.TrialId).Select(t => t.SiteId); // subjectVisitLambda = subjectVisitLambda.And(t => siteQuery.Contains(t.SiteId)); //} //var query = // from subjectVisit in _subjectVisitRepository.Where(subjectVisitLambda) // join trialSite in _trialSiteRepository.Where(t => t.TrialId == checkQuery.TrialId) on subjectVisit.SiteId equals trialSite.SiteId // join subject in _subjectRepository.Where() on subjectVisit.SubjectId equals subject.Id // select new QCCheckViewModel() // { // Id = subjectVisit.Id, // AuditState = subjectVisit.AuditState, // CheckTime = subjectVisit.CheckTime, // CheckState = subjectVisit.CheckState, // CheckChallengeState = subjectVisit.CheckChallengeState, // CheckResult = subjectVisit.CheckResult, // VisitName = subjectVisit.VisitName, // VisitNum = subjectVisit.VisitNum, // SubjectCode = subject.Code, // //Modality=study.Modalities, // //StudyTime = subjectVisit.sv, // TrialSiteCode = trialSite.TrialSiteCode, // }; #endregion var svExpression = QCCommon.GetSubjectVisitFilter(checkQuery.VisitPlanArray); var query = _subjectVisitRepository.Where(x => x.TrialId == checkQuery.TrialId) .Where(x => x.AuditState == AuditStateEnum.QCPassed) //一致性核查中的,或者还没一致性核查的 .WhereIf(checkQuery.CheckState != null, t => t.CheckState == checkQuery.CheckState) .WhereIf(checkQuery.SiteId != null, t => t.SiteId == checkQuery.SiteId) .WhereIf(!string.IsNullOrEmpty(checkQuery.SubjectInfo), t => t.Subject.Code.Contains(checkQuery.SubjectInfo)) .WhereIf(checkQuery.VisitPlanArray != null && checkQuery.VisitPlanArray?.Length > 0, svExpression) //.WhereIf(!string.IsNullOrEmpty(checkQuery.VisitPlanInfo), checkQuery.VisitPlanInfo.Contains('.') ? t => t.InPlan == false : t => t.VisitNum == decimal.Parse(checkQuery.VisitPlanInfo)) .WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.CRA, t => t.TrialSite.CRCUserList.Any(t => t.UserId == _userInfo.Id))//CRC 过滤负责的site .ProjectTo(_mapper.ConfigurationProvider); var pageList = await query.ToPagedListAsync(checkQuery.PageIndex, checkQuery.PageSize, checkQuery.SortField, checkQuery.Asc); var config = await _repository.Where(t => t.Id == checkQuery.TrialId).ProjectTo(_mapper.ConfigurationProvider).FirstOrDefaultAsync().IfNullThrowException(); return (pageList, config); } /// /// 一致性核查 聊天记录列表 /// /// /// /// [HttpGet("{subjectVisitId:guid}")] public async Task GetCheckChallengeDialogList(Guid subjectVisitId) { var sv = (await _subjectVisitRepository.Where(t => t.Id == subjectVisitId) .ProjectTo(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException(); sv.DialogList.ForEach(t => t.IsCurrentUser = _userInfo.Id == t.CreateUserId); return sv; } /// /// 转发列表 查询一致性核查通过的,针对不一致性核查的 要维护CV状态 /// /// /// [HttpPost] public async Task> GetForwardList(ForwardQuery forwardQuery) { //var trialConfig = _trialReposioty.Select(t => new { TrialId = t.Id, t.QCProcessEnum, t.IsImageConsistencyVerification }).FirstOrDefault(t => t.TrialId == forwardQuery.TrialId); var svExpression = QCCommon.GetSubjectVisitFilter(forwardQuery.VisitPlanArray); var query = _subjectVisitRepository.Where(x => x.TrialId == forwardQuery.TrialId) .Where(t => t.CheckState == CheckStateEnum.CVPassed) .WhereIf(forwardQuery.ForwardState != null, t => t.ForwardState == forwardQuery.ForwardState) .WhereIf(forwardQuery.SiteId != null, t => t.SiteId == forwardQuery.SiteId) .WhereIf(!string.IsNullOrEmpty(forwardQuery.SubjectInfo), t => t.Subject.Code.Contains(forwardQuery.SubjectInfo)) .WhereIf(forwardQuery.VisitPlanArray != null && forwardQuery.VisitPlanArray?.Length > 0, svExpression) //.WhereIf(!string.IsNullOrEmpty(forwardQuery.VisitPlanInfo), forwardQuery.VisitPlanInfo.Contains('.') ? t => t.InPlan == false : t => t.VisitNum == decimal.Parse(forwardQuery.VisitPlanInfo)) //.WhereIf(_userInfo.UserTypeEnumInt == (int)UserType.ClinicalResearchCoordinator, t => t.TrialSite.CRCUserList.Any(t => t.UserId == _userInfo.Id))//CRC 过滤负责的site .ProjectTo(_mapper.ConfigurationProvider); return await query.ToPagedListAsync(forwardQuery.PageIndex, forwardQuery.PageSize, forwardQuery.SortField, forwardQuery.Asc); } #endregion #region QC 具体质控页面 各种列表 /// /// 获取某次访视 QA界面所有信息 单独每一项都有接口(往下看),这里是一个大接口,方便第一次获取完整的所有的数据 /// /// /// 项目配置的针对访视检查是那种审核,0 不审,1 单审,2双审 /// 当前 QC进入的是那种审核 1 单审,2复审 [HttpGet("{subjectVisitId:guid}/{trialQCProcess:int}/{currentQCType:int}")] public async Task GetVisitQCInfo(Guid subjectVisitId, [FromRoute] TrialQCProcess trialQCProcess, [FromRoute] CurrentQC currentQCType) { var sv = (await _subjectVisitRepository.FirstOrDefaultAsync(t => t.Id == subjectVisitId)).IfNullThrowException(); var temp = await GetVisitQCStudyAndSeriesList(subjectVisitId); var qacheckList = await GetQCQuestionAnswerList(subjectVisitId, sv.TrialId, trialQCProcess, currentQCType); return new TrialVisitQADTO { QCQuestionAnswerList = qacheckList, StudyList = temp.StudyList, SeriesList = temp.SeriesList, RelationInfo = await GetVisitQCSubjectInfo(subjectVisitId), NoneDicomStudyList = await _repository.Where(t => t.SubjectVisitId == subjectVisitId).ProjectTo(_mapper.ConfigurationProvider, new { token = _userInfo.UserToken }).ToListAsync(), SubjectClinicalData = await _subjectVisitRepository.Where(t => t.Id == subjectVisitId) .ProjectTo(_mapper.ConfigurationProvider, new { subjectVisitId = subjectVisitId, token = _userInfo.UserToken }).FirstOrDefaultAsync() }; } /// /// 获取质控问题答案 /// /// /// [HttpPost] public async Task> GetQCQuestionAnswer(GetQCQuestionAnswerInDto inDto) { var questionAnswerlist = await (from data in _trialQCQuestionRepository.Where(x => x.TrialId == inDto.TrialId && x.IsEnable) join answer in _trialQCQuestionAnswerRepository.Where(x => x.SubjectVisitId == inDto.SubjectVisitId && x.QCProcessEnum == inDto.QCProcessEnum && x.CurrentQCEnum == inDto.CurrentQCEnum).AsQueryable() on data.Id equals answer.TrialQCQuestionConfigureId into answertemp from leftanswer in answertemp.DefaultIfEmpty() select new QCQuestionAnswer() { Answer = leftanswer.Answer, ShowOrder = data.ShowOrder, QuestionName = data.QuestionName, Id = data.Id, IsRequired = data.IsRequired, ParentId = data.ParentId, ParentTriggerValue = data.ParentTriggerValue, Type = data.Type, TypeValue = data.TypeValue }).ToListAsync(); var result = questionAnswerlist.Where(x => x.ParentId == null).ToList(); result.ForEach(x => { GetQuestionChild(x, questionAnswerlist); }); return result; } private void GetQuestionChild(QCQuestionAnswer parent, List dataList) { parent.Childrens = dataList.Where(x => x.ParentId == parent.Id).ToList(); if (parent.Childrens.Count != 0) { parent.Childrens.ForEach(x => { GetQuestionChild(x, dataList); }); } } /// /// 获取某次访视 QC 问题核对答案 列表 初始化进去的时候是模板项,QC填写了就是对应的内容 /// /// /// /// 项目配置的针对访视检查是那种审核,0 不审,1 单审,2双审 /// 当前 QC进入的是那种审核 1 单审,2复审 [HttpGet("{trialId:guid}/{subjectVisitId:guid}/{trialQCProcess:int}/{currentQCType:int}")] public async Task> GetQCQuestionAnswerList(Guid subjectVisitId, Guid trialId, [FromRoute] TrialQCProcess trialQCProcess, [FromRoute] CurrentQC currentQCType) { //https://github.com/dotnet/efcore/issues/26833 ef core 导航属性不支持右连接 // 直接用ProjectTo的方式 多做一次查询 代码简洁很多 特别是连表多,字段多的情况 if (await _repository.AnyAsync(t => t.SubjectVisitId == subjectVisitId && t.QCProcessEnum == trialQCProcess && t.CurrentQCEnum == currentQCType)) { var list = await _repository.Where(t => t.SubjectVisitId == subjectVisitId && t.QCProcessEnum == trialQCProcess && t.CurrentQCEnum == currentQCType).OrderBy(t => t.TrialQCQuestionConfigure.ShowOrder) .ProjectTo(_mapper.ConfigurationProvider).ToListAsync(); return list; } else { return await _repository.Where(t => t.IsEnable == true && t.TrialId == trialId).OrderBy(t => t.ShowOrder).ProjectTo(_mapper.ConfigurationProvider).ToListAsync(); } } /// /// 获次QC 历史质疑列表 不分页 /// /// /// 项目配置的针对访视检查是那种审核,0 不审,1 单审,2双审 /// 当前 QC进入的是那种审核 1 单审,2复审 [HttpGet("{subjectVisitId:guid}/{trialQCProcess:int}/{currentQCType:int}")] public async Task> GetHistoryChallengeList(Guid subjectVisitId, [FromRoute] TrialQCProcess trialQCProcess, [FromRoute] CurrentQC currentQCType) { var qaChallengeQuery = _repository.Where(t => t.SubjectVisitId == subjectVisitId && t.QCProcessEnum == trialQCProcess) .WhereIf(currentQCType == CurrentQC.First, t => t.CurrentQCEnum == currentQCType)//复审的时候可以看到初审的质疑 .ProjectTo(_mapper.ConfigurationProvider); var qaChallenges = await qaChallengeQuery.ToListAsync(); return qaChallenges; } /// /// 获取访视下的受试者访视、受试者、site信息 /// /// /// public async Task GetVisitQCSubjectInfo(Guid subjectVisitId) { // automapper Explicit expansion ProjectTo return await _subjectVisitRepository.Where(t => t.Id == subjectVisitId).ProjectTo(_mapper.ConfigurationProvider).FirstOrDefaultAsync().IfNullThrowException(); } /// /// 访视下的Study 和Series列表 /// /// /// [HttpGet("{subjectVisitId:guid}")] public async Task GetVisitQCStudyAndSeriesList(Guid subjectVisitId) { var studyList = await _repository.Where(s => s.SubjectVisitId == subjectVisitId).IgnoreQueryFilters().ProjectTo(_mapper.ConfigurationProvider).ToListAsync(); var studyIds = studyList.Select(t => t.StudyId).ToList(); var seriesList = await _repository.Where(t => studyIds.Contains(t.StudyId)).IgnoreQueryFilters().ProjectTo(_mapper.ConfigurationProvider) .OrderBy(t => t.StudyCode).ThenBy(t => t.SeriesNumber).ToListAsync(); return new QAStudySeriesInfo { StudyList = studyList, SeriesList = seriesList }; } /// /// 访视下的检查列表 /// /// /// [HttpGet("{subjectVisitId:guid}")] public async Task<(List,object)> GetSubjectVisitUploadedStudyList(Guid subjectVisitId) { var list= await _repository.Where(s => s.SubjectVisitId == subjectVisitId).IgnoreQueryFilters().ProjectTo(_mapper.ConfigurationProvider).ToListAsync(); var config = await _repository.Where(t => t.Id == subjectVisitId).Select(t=>t.Trial).ProjectTo(_mapper.ConfigurationProvider).FirstOrDefaultAsync().IfNullThrowException(); return (list, config); } /// /// 展开 某一QC质疑 下得 聊天记录 /// /// /// [HttpGet("{qaChallengeId:guid}")] public async Task> GetQCChallengeDialogList(Guid qaChallengeId) { var list = await _repository.Where(t => t.Id == qaChallengeId) .ProjectTo(_mapper.ConfigurationProvider, new { currentUserId = _userInfo.Id }).ToListAsync(); //利用automapper 运行时映射 //list.ForEach(t => t.IsCurrentUser = _userInfo.Id == t.CreateUserId); return list; } #endregion /// /// CRC/PM 看到某次访视下的所有质疑和聊天内容 包括初审和复审的 。 /// /// /// /// [HttpGet("{subjectVisitId:guid}/{trialQCProcess:int}")] public async Task> GetCRCVisitChallengeAndDialog(Guid subjectVisitId, [FromRoute] TrialQCProcess trialQCProcess) { var qaChallengeQuery = _repository.Where(t => t.SubjectVisitId == subjectVisitId && t.QCProcessEnum == trialQCProcess) .ProjectTo(_mapper.ConfigurationProvider, new { currentUserId = _userInfo.Id }); var list = await qaChallengeQuery.ToListAsync(); //list.ForEach(t => t.DialogList.ToList().ForEach(u => u.IsCurrentUser = _userInfo.Id == u.CreateUserId)); return list; } /// /// 质询发起人 /// /// /// [HttpGet("{trialId:guid}")] public async Task> GetQCChallengeCreatorList(Guid trialId) { return await _repository.Where(t => t.TrialId == trialId && t.User.UserTypeEnum == UserTypeEnum.IQC).Select(t => new QCChanllengeCreatorDto() { CreatorRealName = t.User.FullName, Creator = t.User.UserName, CreateUserId = t.UserId }).ToListAsync(); } /// /// QC 质疑页面 处理用户 下拉框 /// /// /// [HttpGet("{trialId:guid}")] public async Task> GetQCParticipantList(Guid trialId) { return await _repository.Where(t => t.TrialId == trialId && (t.User.UserTypeEnum == UserTypeEnum.IQC || t.User.UserTypeEnum == UserTypeEnum.ClinicalResearchCoordinator)).Select(t => new ParticipantDTO() { HandleUserRealName = t.User.FullName, HandleUser = t.User.UserName, HandleUserId = t.UserId }).ToListAsync(); } /// /// 获取一致性核查文件上传记录 /// /// [HttpPost] public async Task> GetConsistencyCheckFile(GetConsistencyCheckFileInDto indto) { var query = _repository.Where(t => t.TrialId == indto.TrialId) .ProjectTo(_mapper.ConfigurationProvider); return await query.ToPagedListAsync(indto.PageIndex, indto.PageSize, "CreateTime", false); } /// /// 添加计划外访视 下拉框 选择上一次访视 /// /// /// [HttpGet("{subjectId:guid}")] public async Task> GetSubjectVisitSelectList(Guid subjectId) { return await _subjectVisitRepository.Where(t => t.SubjectId == subjectId).OrderBy(T => T.VisitNum).ProjectTo(_mapper.ConfigurationProvider).ToListAsync(); } /// /// 上传界面 受试者 访视、site 基本信息 /// /// /// [HttpGet("{subjectVisitId:guid}/{trialQCProcess:int}")] [Obsolete] public async Task GetUploadInitInfo(Guid subjectVisitId) { return await _subjectVisitRepository.Where(t => t.Id == subjectVisitId).ProjectTo(_mapper.ConfigurationProvider).FirstOrDefaultAsync().IfNullThrowException(); } } }