886 lines
51 KiB
C#
886 lines
51 KiB
C#
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<SubjectVisit> _subjectVisitRepository;
|
||
private readonly IRepository<Trial> _trialRepository;
|
||
private readonly IRepository<ClinicalDataTrialSet> _clinicalDataTrialSet;
|
||
private readonly IRepository<TrialQCQuestionAnswer> _trialQCQuestionAnswerRepository;
|
||
private readonly IRepository<TrialQCQuestion> _trialQCQuestionRepository;
|
||
private readonly IRepository<ConsistencyCheckFile> _consistencyCheckFileRepository;
|
||
|
||
public QCListService(
|
||
IRepository<SubjectVisit> subjectVisitRepository,
|
||
IRepository<Trial> trialRepository,
|
||
IRepository<ClinicalDataTrialSet> clinicalDataTrialSet,
|
||
IRepository<TrialQCQuestionAnswer> trialQCQuestionAnswerRepository,
|
||
IRepository<TrialQCQuestion> trialQCQuestionRepository,
|
||
IRepository<ConsistencyCheckFile> consistencyCheckFileRepository
|
||
)
|
||
{
|
||
_subjectVisitRepository = subjectVisitRepository;
|
||
this._trialQCQuestionAnswerRepository = trialQCQuestionAnswerRepository;
|
||
this._trialQCQuestionRepository = trialQCQuestionRepository;
|
||
this._consistencyCheckFileRepository = consistencyCheckFileRepository;
|
||
_trialRepository = trialRepository;
|
||
this._clinicalDataTrialSet = clinicalDataTrialSet;
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
#region IC上传、质疑页面
|
||
/// <summary>
|
||
/// IC 检查批次上传列表
|
||
/// </summary>
|
||
/// <param name="visitSearchDTO"></param>
|
||
/// <returns></returns>
|
||
[HttpPost]
|
||
public async Task<(PageOutput<QCCRCVisitViewModel>, 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.BeginSubmitTime != null, t => t.SubmitTime >= visitSearchDTO.BeginSubmitTime)
|
||
.WhereIf(visitSearchDTO.EndSubmitTime != null, t => t.SubmitTime <= visitSearchDTO.EndSubmitTime)
|
||
.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<QCCRCVisitViewModel>(_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<Trial>(t => t.Id == visitSearchDTO.TrialId).ProjectTo<TrialSubjectAndSVConfig>(_mapper.ConfigurationProvider).FirstOrDefaultAsync().IfNullThrowException();
|
||
config.IsHaveSubjectClinicalData = await _clinicalDataTrialSet.AnyAsync(x => x.TrialId == visitSearchDTO.TrialId && x.IsConfirm && x.ClinicalDataLevel == ClinicalLevel.Subject && x.UploadRole == UploadRole.CRC);
|
||
config.IsHaveVisitClinicalData = await _clinicalDataTrialSet.AnyAsync(x => x.TrialId == visitSearchDTO.TrialId && x.IsConfirm && x.ClinicalDataLevel == ClinicalLevel.SubjectVisit && x.UploadRole == UploadRole.CRC);
|
||
return (pageList, config);
|
||
|
||
}
|
||
|
||
|
||
|
||
/// <summary>
|
||
/// IC 质疑列表
|
||
/// </summary>
|
||
/// <param name="challengeQuery"></param>
|
||
/// <returns></returns>
|
||
[HttpPost]
|
||
public async Task<(PageOutput<QCCRCChallengeViewModel>, TrialSubjectAndSVConfig)> GetCRCChallengeList(ChallengeQuery challengeQuery)
|
||
{
|
||
|
||
#region IC 质疑列表 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<QCChallenge>(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 && 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)
|
||
.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<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 (pageList, config);
|
||
|
||
}
|
||
|
||
#endregion
|
||
|
||
|
||
#region QC 质疑 质控页面
|
||
|
||
/// <summary>
|
||
/// QC 质疑列表 分页
|
||
/// </summary>
|
||
/// <param name="challengeQuery"></param>
|
||
/// <returns></returns>
|
||
[HttpPost]
|
||
public async Task<(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 svExpression = QCCommon.GetQCChallengeFilter(challengeQuery.VisitPlanArray);
|
||
|
||
var query = _repository.Where<QCChallenge>(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<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 (pageList, config);
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
/// 获取下一个Qc信息
|
||
/// </summary>
|
||
/// <param name="inDto"></param>
|
||
/// <returns></returns>
|
||
[HttpPost]
|
||
public async Task<QCVisitViewModel?> GetNextQCInfo(GetNextQCInfoInDto inDto)
|
||
{
|
||
var result= await GetQCVisitList(new QCVisitSearchDTO()
|
||
{
|
||
|
||
TrialId = inDto.TrialId,
|
||
CurrentActionUserId=_userInfo.Id,
|
||
PageIndex=1,
|
||
PageSize=1,
|
||
});
|
||
|
||
return result.Item1.CurrentPageData.Count > 0 ? result.Item1.CurrentPageData[0] : null;
|
||
}
|
||
|
||
/// <summary>
|
||
/// QC 检查批次列表
|
||
/// </summary>
|
||
/// <param name="visitSearchDTO"></param>
|
||
/// <returns></returns>
|
||
[HttpPost]
|
||
public async Task<(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 svExpression = QCCommon.GetSubjectVisitFilter(visitSearchDTO.VisitPlanArray);
|
||
var query = _subjectVisitRepository.Where(x => x.TrialId == visitSearchDTO.TrialId)
|
||
.WhereIf(visitSearchDTO.CurrentActionUserId != null, t => t.CurrentActionUserId == visitSearchDTO.CurrentActionUserId)
|
||
.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<QCVisitViewModel>(_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<Trial>(t => t.Id == visitSearchDTO.TrialId).ProjectTo<TrialSubjectAndSVConfig>(_mapper.ConfigurationProvider).FirstOrDefaultAsync().IfNullThrowException();
|
||
|
||
return (pageList, config);
|
||
|
||
}
|
||
|
||
#endregion
|
||
|
||
|
||
#region 一致性核查 转发页面
|
||
/// <summary>
|
||
/// 获取一致性核查列表 IC/PM 公用
|
||
/// </summary>
|
||
/// <param name="checkQuery"></param>
|
||
/// <returns></returns>
|
||
[HttpPost]
|
||
public async Task<(PageOutput<QCCheckWithModalityView>, 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 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))//IC 过滤负责的site
|
||
.ProjectTo<QCCheckWithModalityView>(_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 (pageList, config);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 一致性核查 聊天记录列表
|
||
/// </summary>
|
||
/// <param name="subjectVisitId"></param>
|
||
/// <returns></returns>
|
||
///
|
||
|
||
[HttpGet("{subjectVisitId:guid}")]
|
||
public async Task<CheckDialogDTO> GetCheckChallengeDialogList(Guid subjectVisitId)
|
||
{
|
||
|
||
var sv = (await _subjectVisitRepository.Where(t => t.Id == subjectVisitId)
|
||
.ProjectTo<CheckDialogDTO>(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException();
|
||
|
||
sv.DialogList.ForEach(t => t.IsCurrentUser = _userInfo.Id == t.CreateUserId);
|
||
|
||
return sv;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 转发列表 查询一致性核查通过的,针对不一致性核查的 要维护CV状态
|
||
/// </summary>
|
||
/// <param name="forwardQuery"></param>
|
||
/// <returns></returns>
|
||
[HttpPost]
|
||
public async Task<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 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))//IC 过滤负责的site
|
||
.ProjectTo<ForWardViewModel>(_mapper.ConfigurationProvider);
|
||
|
||
return await query.ToPagedListAsync(forwardQuery.PageIndex, forwardQuery.PageSize, forwardQuery.SortField, forwardQuery.Asc);
|
||
|
||
}
|
||
|
||
#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();
|
||
|
||
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>
|
||
/// 获取质控问题答案
|
||
/// </summary>
|
||
/// <param name="inDto"></param>
|
||
/// <returns></returns>
|
||
[HttpPost]
|
||
public async Task<List<QCQuestionAnswer>> 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<QCQuestionAnswer> dataList)
|
||
{
|
||
parent.Childrens = dataList.Where(x => x.ParentId == parent.Id).ToList();
|
||
|
||
if (parent.Childrens.Count != 0)
|
||
{
|
||
parent.Childrens.ForEach(x =>
|
||
{
|
||
GetQuestionChild(x, dataList);
|
||
});
|
||
}
|
||
|
||
|
||
}
|
||
|
||
/// <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)
|
||
.OrderBy(t => t.StudyCode).ThenBy(t => t.SeriesNumber).ToListAsync();
|
||
|
||
return new QAStudySeriesInfo { StudyList = studyList, SeriesList = seriesList };
|
||
|
||
}
|
||
|
||
/// <summary>
|
||
/// 检查批次下的检查列表
|
||
/// </summary>
|
||
/// <param name="subjectVisitId"></param>
|
||
/// <returns></returns>
|
||
[HttpGet("{subjectVisitId:guid}")]
|
||
public async Task<(List<QAStudyInfoDTO>,object)> GetSubjectVisitUploadedStudyList(Guid subjectVisitId)
|
||
{
|
||
var list= await _repository.Where<DicomStudy>(s => s.SubjectVisitId == subjectVisitId).IgnoreQueryFilters().ProjectTo<QAStudyInfoDTO>(_mapper.ConfigurationProvider).ToListAsync();
|
||
|
||
|
||
var config = await _repository.Where<SubjectVisit>(t => t.Id == subjectVisitId).Select(t=>t.Trial).ProjectTo<TrialSubjectAndSVConfig>(_mapper.ConfigurationProvider).FirstOrDefaultAsync().IfNullThrowException();
|
||
|
||
return (list, config);
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
/// 展开 某一QC质疑 下得 聊天记录
|
||
/// </summary>
|
||
/// <param name="qaChallengeId"></param>
|
||
/// <returns></returns>
|
||
[HttpGet("{qaChallengeId:guid}")]
|
||
public async Task<List<ChallengeAndDialog>> GetQCChallengeDialogList(Guid qaChallengeId)
|
||
{
|
||
|
||
var list = await _repository.Where<QCChallenge>(t => t.Id == qaChallengeId)
|
||
.ProjectTo<ChallengeAndDialog>(_mapper.ConfigurationProvider, new { currentUserId = _userInfo.Id }).ToListAsync();
|
||
|
||
//利用automapper 运行时映射
|
||
//list.ForEach(t => t.IsCurrentUser = _userInfo.Id == t.CreateUserId);
|
||
|
||
return list;
|
||
}
|
||
|
||
#endregion
|
||
|
||
|
||
/// <summary>
|
||
/// IC/PM 看到某次检查批次下的所有质疑和聊天内容 包括初审和复审的 。
|
||
/// </summary>
|
||
/// <param name="subjectVisitId"></param>
|
||
/// <param name="trialQCProcess"></param>
|
||
/// <returns></returns>
|
||
[HttpGet("{subjectVisitId:guid}/{trialQCProcess:int}")]
|
||
public async Task<List<ChallengeAndDialog>> GetCRCVisitChallengeAndDialog(Guid subjectVisitId, [FromRoute] TrialQCProcess trialQCProcess)
|
||
{
|
||
|
||
var qaChallengeQuery = _repository.Where<QCChallenge>(t => t.SubjectVisitId == subjectVisitId && t.QCProcessEnum == trialQCProcess)
|
||
.ProjectTo<ChallengeAndDialog>(_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.FullName,
|
||
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.FullName,
|
||
HandleUser = t.User.UserName,
|
||
HandleUserId = t.UserId
|
||
}).ToListAsync();
|
||
}
|
||
|
||
|
||
|
||
/// <summary>
|
||
/// 获取一致性核查文件上传记录
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
[HttpPost]
|
||
public async Task<PageOutput<GetConsistencyCheckFileDto>> GetConsistencyCheckFile(GetConsistencyCheckFileInDto indto)
|
||
{
|
||
var query = _repository.Where<ConsistencyCheckFile>(t => t.TrialId == indto.TrialId)
|
||
.ProjectTo<GetConsistencyCheckFileDto>(_mapper.ConfigurationProvider);
|
||
|
||
return await query.ToPagedListAsync(indto.PageIndex, indto.PageSize, "CreateTime", false);
|
||
}
|
||
|
||
|
||
/// <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();
|
||
}
|
||
|
||
|
||
}
|
||
}
|