757 lines
		
	
	
		
			43 KiB
		
	
	
	
		
			C#
		
	
	
			
		
		
	
	
			757 lines
		
	
	
		
			43 KiB
		
	
	
	
		
			C#
		
	
	
| using IRaCIS.Core.Application.Contracts;
 | ||
| using Microsoft.AspNetCore.Mvc;
 | ||
| using IRaCIS.Core.Infrastructure.ExpressionExtend;
 | ||
| using IRaCIS.Core.Domain.Share;
 | ||
| using IRaCIS.Core.Application.Contracts.DTO;
 | ||
| using IRaCIS.Core.Infra.EFCore;
 | ||
| 
 | ||
| namespace IRaCIS.Core.Application.Image.QA
 | ||
| {
 | ||
|     [ApiExplorerSettings(GroupName = "Image")]
 | ||
|     public class QCListService : BaseService, IQCListService
 | ||
|     {
 | ||
|         private readonly IRepository<SubjectVisit> _subjectVisitRepository;
 | ||
| 
 | ||
| 
 | ||
|         public QCListService(IRepository<SubjectVisit> subjectVisitRepository)
 | ||
|         {
 | ||
|             _subjectVisitRepository = subjectVisitRepository;
 | ||
|         }
 | ||
| 
 | ||
|         #region CRC上传、质疑页面
 | ||
|         /// <summary>
 | ||
|         /// CRC 访视上传列表
 | ||
|         /// </summary>
 | ||
|         /// <param name="visitSearchDTO"></param>
 | ||
|         /// <returns></returns>
 | ||
|         [HttpPost]
 | ||
|         public async Task<IResponseOutput<PageOutput<QCCRCVisitViewModel>, TrialSubjectAndSVConfig>> GetCRCVisitList(CRCVisitSearchDTO visitSearchDTO)
 | ||
|         {
 | ||
| 
 | ||
|             var query = _repository.Where<SubjectVisit>(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(visitSearchDTO.SubjectInfo), t => t.Subject.Code.Contains(visitSearchDTO.SubjectInfo))
 | ||
|                         .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, t => t.TrialSite.CRCUserList.Any(t => t.UserId == _userInfo.Id))
 | ||
|                         .ProjectTo<QCCRCVisitViewModel>(_mapper.ConfigurationProvider);
 | ||
| 
 | ||
| 
 | ||
|             var pageList = await query.ToPagedListAsync(visitSearchDTO.PageIndex, visitSearchDTO.PageSize, visitSearchDTO.SortField, visitSearchDTO.Asc);
 | ||
| 
 | ||
|             var config = await _repository.Where<Trial>(t => t.Id == visitSearchDTO.TrialId).ProjectTo<TrialSubjectAndSVConfig>(_mapper.ConfigurationProvider).FirstOrDefaultAsync().IfNullThrowException();
 | ||
| 
 | ||
|             return ResponseOutput.Ok(pageList, config!);
 | ||
| 
 | ||
|         }
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
|         /// <summary>
 | ||
|         /// CRC 质疑列表
 | ||
|         /// </summary>
 | ||
|         /// <param name="challengeQuery"></param>
 | ||
|         /// <returns></returns>
 | ||
|         [HttpPost]
 | ||
|         public async Task<IResponseOutput<PageOutput<QCCRCChallengeViewModel>, 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 query2 = _repository.Where<QCChallenge>(x => x.TrialId == challengeQuery.TrialId)
 | ||
|                 .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(!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, t => t.SubjectVisit.TrialSite.CRCUserList.Any(t => t.UserId == _userInfo.Id))
 | ||
|               .ProjectTo<QCCRCChallengeViewModel>(_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<Trial>(t => t.Id == challengeQuery.TrialId).ProjectTo<TrialSubjectAndSVConfig>(_mapper.ConfigurationProvider).FirstOrDefaultAsync().IfNullThrowException();
 | ||
|             return ResponseOutput.Ok(pageList, config);
 | ||
| 
 | ||
| 
 | ||
|         }
 | ||
| 
 | ||
|         #endregion
 | ||
| 
 | ||
| 
 | ||
|         #region QC 质疑 质控页面
 | ||
| 
 | ||
|         /// <summary>
 | ||
|         /// QC 质疑列表   分页
 | ||
|         /// </summary>
 | ||
|         /// <param name="challengeQuery"></param>
 | ||
|         /// <returns></returns>
 | ||
|         [HttpPost]
 | ||
|         public async Task<IResponseOutput<PageOutput<QCCRCChallengeViewModel>, TrialSubjectAndSVConfig>> GetQCChallengeList(ChallengeQuery challengeQuery)
 | ||
|         {
 | ||
|             #region linq方式 + Expression 拼接
 | ||
| 
 | ||
|             //Expression<Func<QCChallenge, bool>> 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 query = _repository.Where<QCChallenge>(x => x.TrialId == challengeQuery.TrialId)
 | ||
|                 .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(!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, t => DateTime.Now > t.DeadlineTime)
 | ||
|                 .ProjectTo<QCCRCChallengeViewModel>(_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<Trial>(t => t.Id == challengeQuery.TrialId).ProjectTo<TrialSubjectAndSVConfig>(_mapper.ConfigurationProvider).FirstOrDefaultAsync().IfNullThrowException();
 | ||
|             return ResponseOutput.Ok(pageList, config);
 | ||
|         }
 | ||
| 
 | ||
|         /// <summary>
 | ||
|         /// QC 访视列表
 | ||
|         /// </summary>
 | ||
|         /// <param name="visitSearchDTO"></param>
 | ||
|         /// <returns></returns>
 | ||
|         [HttpPost]
 | ||
|         public async Task<IResponseOutput<PageOutput<QCVisitViewModel>, TrialSubjectAndSVConfig>> GetQCVisitList(QCVisitSearchDTO visitSearchDTO)
 | ||
|         {
 | ||
| 
 | ||
|             #region 经典 linq
 | ||
|             //Expression<Func<Subject, bool>> subjectLambda = x => true;
 | ||
| 
 | ||
|             //Expression<Func<SubjectVisit, bool>> subjectVisitLambda = x => x.TrialId == visitSearchDTO.TrialId;
 | ||
|             //Expression<Func<DicomStudy, bool>> studyLambda = x => x.TrialId == visitSearchDTO.TrialId;
 | ||
|             ////Expression<Func<VisitStage, bool>> 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 query = _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(visitSearchDTO.SubjectInfo), t => /*t.Subject.FirstName.Contains(subjectInfo) || t.Subject.LastName.Contains(subjectInfo) ||*/ t.Subject.Code.Contains(visitSearchDTO.SubjectInfo))
 | ||
|                         .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.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)
 | ||
|                         //.WhereIf(visitSearchDTO.SubmitState != null, t => t.SubmitState == visitSearchDTO.SubmitState)
 | ||
|                         //.WhereIf(visitSearchDTO.ChallengeState != null, t => t.ChallengeState == visitSearchDTO.ChallengeState)
 | ||
|                         .ProjectTo<QCVisitViewModel>(_mapper.ConfigurationProvider);
 | ||
| 
 | ||
|             var pageList = query.ToPagedList(visitSearchDTO.PageIndex, visitSearchDTO.PageSize, visitSearchDTO.SortField, visitSearchDTO.Asc);
 | ||
| 
 | ||
|             var config = await _repository.Where<Trial>(t => t.Id == visitSearchDTO.TrialId).ProjectTo<TrialSubjectAndSVConfig>(_mapper.ConfigurationProvider).FirstOrDefaultAsync().IfNullThrowException();
 | ||
|             return ResponseOutput.Ok(pageList, config);
 | ||
| 
 | ||
|         }
 | ||
| 
 | ||
|         #endregion
 | ||
| 
 | ||
| 
 | ||
|         #region 一致性核查 转发页面
 | ||
|         /// <summary>
 | ||
|         /// 获取一致性核查列表  CRC/PM 公用
 | ||
|         /// </summary>
 | ||
|         /// <param name="checkQuery"></param>
 | ||
|         /// <returns></returns>
 | ||
|         [HttpPost]
 | ||
|         public async Task<IResponseOutput<PageOutput<QCCheckViewModel>, TrialSubjectAndSVConfig>> GetConsistencyVerificationList(CheckQuery checkQuery)
 | ||
|         {
 | ||
|             #region linq 废弃 byzhouhang  2021 11 30
 | ||
|             //Expression<Func<Subject, bool>> subjectLambda = x => true;
 | ||
|             //Expression<Func<SubjectVisit, bool>> subjectVisitLambda = x => x.TrialId == checkQuery.TrialId && x.AuditState == AuditStateEnum.QCPassed;
 | ||
|             //Expression<Func<DicomStudy, bool>> 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 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(!string.IsNullOrEmpty(checkQuery.VisitPlanInfo), checkQuery.VisitPlanInfo.Contains('.') ? t => t.InPlan == false : t => t.VisitNum == decimal.Parse(checkQuery.VisitPlanInfo))
 | ||
|                         .WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator, t => t.TrialSite.CRCUserList.Any(t => t.UserId == _userInfo.Id))//CRC 过滤负责的site
 | ||
|                         .ProjectTo<QCCheckViewModel>(_mapper.ConfigurationProvider);
 | ||
| 
 | ||
|             var pageList = await query.ToPagedListAsync(checkQuery.PageIndex, checkQuery.PageSize, checkQuery.SortField, checkQuery.Asc);
 | ||
|             var config = await _repository.Where<Trial>(t => t.Id == checkQuery.TrialId).ProjectTo<TrialSubjectAndSVConfig>(_mapper.ConfigurationProvider).FirstOrDefaultAsync().IfNullThrowException();
 | ||
|             return ResponseOutput.Ok(pageList, config);
 | ||
|         }
 | ||
|         
 | ||
|         /// <summary>
 | ||
|         /// 一致性核查 聊天记录列表
 | ||
|         /// </summary>
 | ||
|         /// <param name="subjectVisitId"></param>
 | ||
|         /// <returns></returns>
 | ||
|         /// 
 | ||
| 
 | ||
|         [HttpGet("{subjectVisitId:guid}")]
 | ||
|         public async Task<List<CheckChanllengeDialogDTO>> GetCheckChallengeDialogList(Guid subjectVisitId)
 | ||
|         {
 | ||
| 
 | ||
|             var list = await _repository.Where<CheckChallengeDialog>(t => t.SubjectVisitId == subjectVisitId).OrderBy(t => t.CreateTime)
 | ||
|                   .ProjectTo<CheckChanllengeDialogDTO>(_mapper.ConfigurationProvider).ToListAsync();
 | ||
| 
 | ||
|             list.ForEach(t => t.IsCurrentUser = _userInfo.Id == t.CreateUserId);
 | ||
| 
 | ||
|             return list;
 | ||
|         }
 | ||
| 
 | ||
|         /// <summary>
 | ||
|         /// 转发列表  查询一致性核查通过的,针对不一致性核查的 要维护CV状态
 | ||
|         /// </summary>
 | ||
|         /// <param name="forwardQuery"></param>
 | ||
|         /// <returns></returns>
 | ||
|         [HttpPost]
 | ||
|         public async Task<IResponseOutput<PageOutput<ForWardViewModel>>> GetForwardList(ForwardQuery forwardQuery)
 | ||
|         {
 | ||
|             //var trialConfig = _trialReposioty.Select(t => new { TrialId = t.Id, t.QCProcessEnum, t.IsImageConsistencyVerification }).FirstOrDefault(t => t.TrialId == forwardQuery.TrialId);
 | ||
| 
 | ||
|             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(!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<ForWardViewModel>(_mapper.ConfigurationProvider);
 | ||
| 
 | ||
|             var pageList = await query.ToPagedListAsync(forwardQuery.PageIndex, forwardQuery.PageSize, forwardQuery.SortField, forwardQuery.Asc);
 | ||
| 
 | ||
|             return ResponseOutput.Ok(pageList);
 | ||
|         }
 | ||
| 
 | ||
|         #endregion
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
|         #region QC 具体质控页面 各种列表
 | ||
|         /// <summary>
 | ||
|         /// 获取某次访视 QA界面所有信息  单独每一项都有接口(往下看),这里是一个大接口,方便第一次获取完整的所有的数据
 | ||
|         /// </summary>
 | ||
|         /// <param name="subjectVisitId"></param>
 | ||
|         /// <param name="trialQCProcess">项目配置的针对访视检查是那种审核,0 不审,1 单审,2双审</param>
 | ||
|         /// <param name="currentQCType">当前 QC进入的是那种审核 1 单审,2复审</param>
 | ||
| 
 | ||
|         [HttpGet("{subjectVisitId:guid}/{trialQCProcess:int}/{currentQCType:int}")]
 | ||
|         public async Task<TrialVisitQADTO> GetVisitQCInfo(Guid subjectVisitId, [FromRoute] TrialQCProcess trialQCProcess, [FromRoute] CurrentQC currentQCType)
 | ||
|         {
 | ||
|             var sv = (await _subjectVisitRepository.FirstOrDefaultAsync(t => t.Id == subjectVisitId)).IfNullThrowException();
 | ||
| 
 | ||
|             if (currentQCType == CurrentQC.First)
 | ||
|             {
 | ||
|                 if (_userInfo.Id != sv.CurrentActionUserId)
 | ||
|                 {
 | ||
|                     throw new Exception("当前用户不是初审用户,不允许操作!");
 | ||
|                 }
 | ||
|             }
 | ||
|             else
 | ||
|             {
 | ||
|                 if (_userInfo.Id != sv.CurrentActionUserId)
 | ||
|                 {
 | ||
|                     throw new Exception("当前用户不是复审用户,不允许操作!");
 | ||
|                 }
 | ||
|             }
 | ||
| 
 | ||
|             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<NoneDicomStudy>(t => t.SubjectVisitId == subjectVisitId).ProjectTo<NoneDicomStudyView>(_mapper.ConfigurationProvider, new { token = _userInfo.UserToken }).ToListAsync(),
 | ||
|                 SubjectClinicalData = await _subjectVisitRepository.Where(t => t.Id == subjectVisitId)
 | ||
|                 .ProjectTo<SubjectClinicalDataDto>(_mapper.ConfigurationProvider, new { subjectVisitId = subjectVisitId, token = _userInfo.UserToken }).FirstOrDefaultAsync()
 | ||
|             };
 | ||
|         }
 | ||
| 
 | ||
|         /// <summary>
 | ||
|         /// 获取某次访视 QC 问题核对答案 列表  初始化进去的时候是模板项,QC填写了就是对应的内容
 | ||
|         /// </summary>
 | ||
|         /// <param name="subjectVisitId"></param>
 | ||
|         /// <param name="trialId"></param>
 | ||
|         /// <param name="trialQCProcess">项目配置的针对访视检查是那种审核,0 不审,1 单审,2双审</param>
 | ||
|         /// <param name="currentQCType">当前 QC进入的是那种审核 1 单审,2复审</param>
 | ||
| 
 | ||
|         [HttpGet("{trialId:guid}/{subjectVisitId:guid}/{trialQCProcess:int}/{currentQCType:int}")]
 | ||
|         public async Task<List<QCQuestionAnswerItemDto>> 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<TrialQCQuestionAnswer>(t => t.SubjectVisitId == subjectVisitId && t.QCProcessEnum == trialQCProcess && t.CurrentQCEnum == currentQCType))
 | ||
|             {
 | ||
|                 var list = await _repository.Where<TrialQCQuestionAnswer>(t => t.SubjectVisitId == subjectVisitId && t.QCProcessEnum == trialQCProcess && t.CurrentQCEnum == currentQCType).OrderBy(t => t.TrialQCQuestionConfigure.ShowOrder)
 | ||
|                        .ProjectTo<QCQuestionAnswerItemDto>(_mapper.ConfigurationProvider).ToListAsync();
 | ||
| 
 | ||
|                 return list;
 | ||
|             }
 | ||
|             else
 | ||
|             {
 | ||
|                 return await _repository.Where<TrialQCQuestion>(t => t.IsEnable == true && t.TrialId == trialId).OrderBy(t => t.ShowOrder).ProjectTo<QCQuestionAnswerItemDto>(_mapper.ConfigurationProvider).ToListAsync();
 | ||
|             }
 | ||
| 
 | ||
|         }
 | ||
| 
 | ||
| 
 | ||
|         /// <summary>
 | ||
|         /// 获次QC 历史质疑列表  不分页
 | ||
|         /// </summary>
 | ||
|         /// <param name="subjectVisitId"></param>
 | ||
|         /// <param name="trialQCProcess">项目配置的针对访视检查是那种审核,0 不审,1 单审,2双审</param>
 | ||
|         /// <param name="currentQCType">当前 QC进入的是那种审核 1 单审,2复审</param>
 | ||
| 
 | ||
|         [HttpGet("{subjectVisitId:guid}/{trialQCProcess:int}/{currentQCType:int}")]
 | ||
|         public async Task<List<QCChallengeWithUser>> GetHistoryChallengeList(Guid subjectVisitId, [FromRoute] TrialQCProcess trialQCProcess, [FromRoute] CurrentQC currentQCType)
 | ||
|         {
 | ||
|             var qaChallengeQuery = _repository.Where<QCChallenge>(t => t.SubjectVisitId == subjectVisitId && t.QCProcessEnum == trialQCProcess)
 | ||
|                 .WhereIf(currentQCType == CurrentQC.First, t => t.CurrentQCEnum == currentQCType)//复审的时候可以看到初审的质疑
 | ||
|                 .ProjectTo<QCChallengeWithUser>(_mapper.ConfigurationProvider);
 | ||
|             var qaChallenges = await qaChallengeQuery.ToListAsync();
 | ||
| 
 | ||
|             return qaChallenges;
 | ||
|         }
 | ||
| 
 | ||
| 
 | ||
|         /// <summary>
 | ||
|         /// 获取访视下的受试者访视、受试者、site信息
 | ||
|         /// </summary>
 | ||
|         /// <param name="subjectVisitId"></param>
 | ||
|         /// <returns></returns>
 | ||
|         public async Task<QARelationInfo> GetVisitQCSubjectInfo(Guid subjectVisitId)
 | ||
|         {
 | ||
| 
 | ||
|             // automapper  Explicit expansion  ProjectTo 
 | ||
|             return await _subjectVisitRepository.Where(t => t.Id == subjectVisitId).ProjectTo<QARelationInfo>(_mapper.ConfigurationProvider).FirstOrDefaultAsync().IfNullThrowException();
 | ||
| 
 | ||
|         }
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
|         /// <summary>
 | ||
|         ///   访视下的Study 和Series列表
 | ||
|         /// </summary>
 | ||
|         /// <param name="subjectVisitId"></param>
 | ||
|         /// <returns></returns>
 | ||
|         [HttpGet("{subjectVisitId:guid}")]
 | ||
|         public async Task<QAStudySeriesInfo> GetVisitQCStudyAndSeriesList(Guid subjectVisitId)
 | ||
|         {
 | ||
|             var studyList = await _repository.Where<DicomStudy>(s => s.SubjectVisitId == subjectVisitId).IgnoreQueryFilters().ProjectTo<QAStudyInfoDTO>(_mapper.ConfigurationProvider).ToListAsync();
 | ||
|             var studyIds = studyList.Select(t => t.StudyId).ToList();
 | ||
| 
 | ||
|             var seriesList = await _repository.Where<DicomSeries>(t => studyIds.Contains(t.StudyId)).IgnoreQueryFilters().ProjectTo<QASeriesInfoDto>(_mapper.ConfigurationProvider).ToListAsync();
 | ||
| 
 | ||
|             return new QAStudySeriesInfo { StudyList = studyList, SeriesList = seriesList };
 | ||
| 
 | ||
|         }
 | ||
| 
 | ||
|         /// <summary>
 | ||
|         /// 访视下的检查列表  
 | ||
|         /// </summary>
 | ||
|         /// <param name="subjectVisitId"></param>
 | ||
|         /// <returns></returns>
 | ||
|         [HttpGet("{subjectVisitId:guid}")]
 | ||
|         public async Task<List<QAStudyInfoDTO>> GetSubjectVisitUploadedStudyList(Guid subjectVisitId)
 | ||
|         {
 | ||
|             return await _repository.Where<DicomStudy>(s => s.SubjectVisitId == subjectVisitId).IgnoreQueryFilters().ProjectTo<QAStudyInfoDTO>(_mapper.ConfigurationProvider).ToListAsync();
 | ||
|         }
 | ||
| 
 | ||
| 
 | ||
|         /// <summary>
 | ||
|         /// 展开 某一QC质疑 下得 聊天记录 
 | ||
|         /// </summary>
 | ||
|         /// <param name="qaChallengeId"></param>
 | ||
|         /// <returns></returns>
 | ||
|         [HttpGet("{qaChallengeId:guid}")]
 | ||
|         public async Task<List<QCChanllengeDialogDTO>> GetQCChallengeDialogList(Guid qaChallengeId)
 | ||
|         {
 | ||
| 
 | ||
|             var list = await _repository.Where<QCChallengeDialog>(t => t.QCChallengeId == qaChallengeId).OrderBy(t => t.CreateTime)
 | ||
|                   .ProjectTo<QCChanllengeDialogDTO>(_mapper.ConfigurationProvider, new { currentUserId = _userInfo.Id }).ToListAsync();
 | ||
| 
 | ||
|             //利用automapper 运行时映射
 | ||
|             //list.ForEach(t => t.IsCurrentUser = _userInfo.Id == t.CreateUserId);
 | ||
| 
 | ||
|             return list;
 | ||
|         }
 | ||
| 
 | ||
|         #endregion
 | ||
| 
 | ||
| 
 | ||
|         /// <summary>
 | ||
|         /// CRC/PM  看到某次访视下的所有质疑和聊天内容  包括初审和复审的 。
 | ||
|         /// </summary>
 | ||
|         /// <param name="subjectVisitId"></param>
 | ||
|         /// <param name="trialQCProcess"></param>
 | ||
|         /// <returns></returns>
 | ||
|         [HttpGet("{subjectVisitId:guid}/{trialQCProcess:int}")]
 | ||
|         public async Task<List<QCChallengeWithUser>> GetCRCVisitChallengeAndDialog(Guid subjectVisitId, [FromRoute] TrialQCProcess trialQCProcess)
 | ||
|         {
 | ||
| 
 | ||
|             var qaChallengeQuery = _repository.Where<QCChallenge>(t => t.SubjectVisitId == subjectVisitId && t.QCProcessEnum == trialQCProcess)
 | ||
|                 .ProjectTo<QCChallengeWithUser>(_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;
 | ||
|         }
 | ||
| 
 | ||
|         /// <summary>
 | ||
|         ///  质询发起人
 | ||
|         /// </summary>
 | ||
|         /// <param name="trialId"></param>
 | ||
|         /// <returns></returns>
 | ||
|         [HttpGet("{trialId:guid}")]
 | ||
|         public async Task<List<QCChanllengeCreatorDto>> GetQCChallengeCreatorList(Guid trialId)
 | ||
|         {
 | ||
| 
 | ||
|             return await _repository.Where<TrialUser>(t => t.TrialId == trialId && t.User.UserTypeEnum == UserTypeEnum.IQC).Select(t => new QCChanllengeCreatorDto()
 | ||
|             {
 | ||
|                 CreatorRealName = t.User.LastName + " / " + t.User.FirstName,
 | ||
|                 Creator = t.User.UserName,
 | ||
|                 CreateUserId = t.UserId
 | ||
|             }).ToListAsync();
 | ||
| 
 | ||
|         }
 | ||
| 
 | ||
|         /// <summary>
 | ||
|         ///  QC  质疑页面  处理用户 下拉框
 | ||
|         /// </summary>
 | ||
|         /// <param name="trialId"></param>
 | ||
|         /// <returns></returns>
 | ||
|         [HttpGet("{trialId:guid}")]
 | ||
|         public async Task<List<ParticipantDTO>> GetQCParticipantList(Guid trialId)
 | ||
|         {
 | ||
|             return await _repository.Where<TrialUser>(t => t.TrialId == trialId && (t.User.UserTypeEnum == UserTypeEnum.IQC || t.User.UserTypeEnum == UserTypeEnum.ClinicalResearchCoordinator)).Select(t => new ParticipantDTO()
 | ||
|             {
 | ||
|                 HandleUserRealName = t.User.LastName + " / " + t.User.FirstName,
 | ||
|                 HandleUser = t.User.UserName,
 | ||
|                 HandleUserId = t.UserId
 | ||
|             }).ToListAsync();
 | ||
|         }
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
|         /// <summary>
 | ||
|         ///  添加计划外访视 下拉框 选择上一次访视
 | ||
|         /// </summary>
 | ||
|         /// <param name="subjectId"></param>
 | ||
|         /// <returns></returns>
 | ||
|         [HttpGet("{subjectId:guid}")]
 | ||
|         public async Task<List<SubjectVisitSelectItem>> GetSubjectVisitSelectList(Guid subjectId)
 | ||
|         {
 | ||
|             return await _subjectVisitRepository.Where(t => t.SubjectId == subjectId).OrderBy(T => T.VisitNum).ProjectTo<SubjectVisitSelectItem>(_mapper.ConfigurationProvider).ToListAsync();
 | ||
|         }
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
|         /// <summary>
 | ||
|         /// 上传界面 受试者 访视、site 基本信息
 | ||
|         /// </summary>
 | ||
|         /// <param name="subjectVisitId"></param>
 | ||
|         /// <returns></returns>
 | ||
|         [HttpGet("{subjectVisitId:guid}/{trialQCProcess:int}")]
 | ||
|         [Obsolete]
 | ||
|         public async Task<UploadViewInitDto> GetUploadInitInfo(Guid subjectVisitId)
 | ||
|         {
 | ||
|             return await _subjectVisitRepository.Where(t => t.Id == subjectVisitId).ProjectTo<UploadViewInitDto>(_mapper.ConfigurationProvider).FirstOrDefaultAsync().IfNullThrowException();
 | ||
|         }
 | ||
| 
 | ||
| 
 | ||
|     }
 | ||
| }
 |