修改访视名称验证和 搜索条件
parent
8e7dab028e
commit
316c9f779b
|
@ -10,7 +10,7 @@ using IRaCIS.Core.Application.Contracts.Dicom.DTO;
|
|||
using IRaCIS.Core.Application.Filter;
|
||||
using IRaCIS.Core.Application.Helper;
|
||||
using IRaCIS.Core.Application.MediatR.CommandAndQueries;
|
||||
using IRaCIS.Core.Application.Service.Verify;
|
||||
using IRaCIS.Core.Application.Service;
|
||||
using IRaCIS.Core.Domain.Models;
|
||||
using IRaCIS.Core.Domain.Share;
|
||||
using IRaCIS.Core.Infra.EFCore;
|
||||
|
@ -370,7 +370,7 @@ namespace IRaCIS.Core.API.Controllers
|
|||
[Authorize(Policy = IRaCISPolicy.CRC)]
|
||||
public async Task<IResponseOutput> UploadVisitClinicalData(Guid subjectVisitId, [FromServices] IRepository _repository)
|
||||
{
|
||||
await QCCommonVerify.VerifyIsCRCSubmmitAsync(_repository, _userInfo, subjectVisitId);
|
||||
await QCCommon.VerifyIsCRCSubmmitAsync(_repository, _userInfo, subjectVisitId);
|
||||
|
||||
var sv = _repository.Where<SubjectVisit>(t => t.Id == subjectVisitId).Select(t => new { t.TrialId, t.SiteId, t.SubjectId }).FirstOrDefault().IfNullThrowException();
|
||||
|
||||
|
@ -409,7 +409,7 @@ namespace IRaCIS.Core.API.Controllers
|
|||
{
|
||||
var startTime = DateTime.Now;
|
||||
|
||||
await QCCommonVerify.VerifyIsCRCSubmmitAsync(_repository, _userInfo, subjectVisitId);
|
||||
await QCCommon.VerifyIsCRCSubmmitAsync(_repository, _userInfo, subjectVisitId);
|
||||
|
||||
var sv = (await _repository.Where<SubjectVisit>(t => t.Id == subjectVisitId).Select(t => new { t.TrialId, t.SiteId, t.SubjectId }).FirstOrDefaultAsync()).IfNullThrowConvertException();
|
||||
|
||||
|
|
|
@ -417,7 +417,7 @@
|
|||
<member name="M:IRaCIS.Core.Application.Service.SystemNoticeService.GetUserSystemNoticeList(IRaCIS.Core.Application.ViewModel.SystemNoticeQuery)">
|
||||
<summary>获取登陆用户的系统通知列表 只是过滤了用户类型 和已经发布的</summary>
|
||||
</member>
|
||||
<member name="M:IRaCIS.Core.Application.Service.Verify.QCCommonVerify.VerifyIsCRCSubmmitAsync(IRaCIS.Core.Infra.EFCore.IRepository,IRaCIS.Core.Domain.Share.IUserInfo,System.Nullable{System.Guid})">
|
||||
<member name="M:IRaCIS.Core.Application.Service.QCCommon.VerifyIsCRCSubmmitAsync(IRaCIS.Core.Infra.EFCore.IRepository,IRaCIS.Core.Domain.Share.IUserInfo,System.Nullable{System.Guid})">
|
||||
<summary>
|
||||
验证CRC 是否已提交 已提交 就不允许进行任何操作,如果是IQC 那么还验证是否是当前任务领取人
|
||||
</summary>
|
||||
|
|
|
@ -42,7 +42,6 @@ namespace IRaCIS.Application.Services
|
|||
|
||||
var systemBasicDataQueryable = _dicRepository.Where(t => t.ParentId == null)
|
||||
.WhereIf(!string.IsNullOrEmpty(basicDicQuery.Code), t => t.Code.Contains(basicDicQuery.Code!))
|
||||
.WhereIf(!string.IsNullOrEmpty(basicDicQuery.KeyName), t => t.KeyName.Contains(basicDicQuery.KeyName!))
|
||||
.WhereIf(basicDicQuery.ConfigTypeId != null, t => t.ConfigTypeId == basicDicQuery.ConfigTypeId!)
|
||||
.WhereIf(basicDicQuery.IsConfig != null, t => t.IsConfig == basicDicQuery.IsConfig)
|
||||
|
||||
|
|
|
@ -34,96 +34,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
|||
}
|
||||
|
||||
|
||||
private Expression<Func<DicomStudy, bool>> GetDicomStudySubjectVisitFilter(string[]? VisitPlanArray)
|
||||
{
|
||||
Expression<Func<DicomStudy, bool>> svExpression = x => true;
|
||||
|
||||
bool isNeedVisitSearch = VisitPlanArray != null && VisitPlanArray?.Length > 0;
|
||||
|
||||
if (isNeedVisitSearch)
|
||||
{
|
||||
var inPlanArray = VisitPlanArray!.Where(t => !t.Contains('.')).Select(t => decimal.Parse(t)).ToArray();
|
||||
var isSelectOutPlan = VisitPlanArray!.Any(t => t.Contains('.'));
|
||||
|
||||
|
||||
if (inPlanArray.Length > 0)
|
||||
{
|
||||
svExpression = svExpression.And(t => inPlanArray.Contains(t.SubjectVisit.VisitNum));
|
||||
}
|
||||
|
||||
|
||||
if (isSelectOutPlan)
|
||||
{
|
||||
svExpression = svExpression.Or(t => t.SubjectVisit.InPlan == false);
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
return svExpression;
|
||||
}
|
||||
|
||||
|
||||
private Expression<Func<NoneDicomStudy, bool>> GetNoneDicomStudySubjectVisitFilter(string[]? VisitPlanArray)
|
||||
{
|
||||
Expression<Func<NoneDicomStudy, bool>> svExpression = x => true;
|
||||
|
||||
bool isNeedVisitSearch = VisitPlanArray != null && VisitPlanArray?.Length > 0;
|
||||
|
||||
if (isNeedVisitSearch)
|
||||
{
|
||||
var inPlanArray = VisitPlanArray!.Where(t => !t.Contains('.')).Select(t => decimal.Parse(t)).ToArray();
|
||||
var isSelectOutPlan = VisitPlanArray!.Any(t => t.Contains('.'));
|
||||
|
||||
|
||||
if (inPlanArray.Length > 0)
|
||||
{
|
||||
svExpression = svExpression.And(t => inPlanArray.Contains(t.SubjectVisit.VisitNum));
|
||||
}
|
||||
|
||||
|
||||
if (isSelectOutPlan)
|
||||
{
|
||||
svExpression = svExpression.Or(t => t.SubjectVisit.InPlan == false);
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
return svExpression;
|
||||
}
|
||||
|
||||
private Expression<Func<StudyMonitor, bool>> GetStudyMonitorSubjectVisitFilter(string[]? VisitPlanArray)
|
||||
{
|
||||
Expression<Func<StudyMonitor, bool>> svExpression = x => true;
|
||||
|
||||
bool isNeedVisitSearch = VisitPlanArray != null && VisitPlanArray?.Length > 0;
|
||||
|
||||
if (isNeedVisitSearch)
|
||||
{
|
||||
var inPlanArray = VisitPlanArray!.Where(t => !t.Contains('.')).Select(t => decimal.Parse(t)).ToArray();
|
||||
var isSelectOutPlan = VisitPlanArray!.Any(t => t.Contains('.'));
|
||||
|
||||
|
||||
if (inPlanArray.Length > 0)
|
||||
{
|
||||
svExpression = svExpression.And(t => inPlanArray.Contains(t.SubjectVisit.VisitNum));
|
||||
}
|
||||
|
||||
|
||||
if (isSelectOutPlan)
|
||||
{
|
||||
svExpression = svExpression.Or(t => t.SubjectVisit.InPlan == false);
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
return svExpression;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -131,7 +42,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
|||
public async Task<PageOutput<UnionStudyViewModel>> GetDicomAndNoneDicomStudyList(StudyQuery studyQuery)
|
||||
{
|
||||
|
||||
var svExpression = GetDicomStudySubjectVisitFilter(studyQuery.VisitPlanArray);
|
||||
var svExpression = QCCommon.GetDicomStudySubjectVisitFilter(studyQuery.VisitPlanArray);
|
||||
|
||||
var dicomStudyQuery = _repository.Where<DicomStudy>(t => t.TrialId == studyQuery.TrialId)
|
||||
.WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.CRA, t => t.TrialSite.CRCUserList.Any(t => t.UserId == _userInfo.Id))
|
||||
|
@ -178,7 +89,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
|||
|
||||
|
||||
//.ProjectTo<UnionStudyViewDodel>(_mapper.ConfigurationProvider);
|
||||
var svExpression2 = GetNoneDicomStudySubjectVisitFilter(studyQuery.VisitPlanArray);
|
||||
var svExpression2 = QCCommon.GetNoneDicomStudySubjectVisitFilter(studyQuery.VisitPlanArray);
|
||||
|
||||
|
||||
var nodeDicomStudyQuery = _repository.Where<NoneDicomStudy>(t => t.TrialId == studyQuery.TrialId)
|
||||
|
@ -240,7 +151,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
|||
[HttpPost]
|
||||
public async Task<PageOutput<UnionStudyMonitorModel>> GetDicomAndNoneDicomStudyMonitorList(StudyQuery studyQuery)
|
||||
{
|
||||
var svExpression = GetStudyMonitorSubjectVisitFilter(studyQuery.VisitPlanArray);
|
||||
var svExpression = QCCommon.GetStudyMonitorSubjectVisitFilter(studyQuery.VisitPlanArray);
|
||||
var StudyMonitorQuery = _repository.Where<StudyMonitor>(t => t.TrialId == studyQuery.TrialId)
|
||||
.WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.CRA, t => t.TrialSite.CRCUserList.Any(t => t.UserId == _userInfo.Id))
|
||||
//.WhereIf(!string.IsNullOrEmpty(studyQuery.VisitPlanInfo), studyQuery.VisitPlanInfo.Contains('.') ? t => t.SubjectVisit.VisitNum.ToString().Contains(".") : t => t.SubjectVisit.VisitNum == decimal.Parse(studyQuery.VisitPlanInfo))
|
||||
|
|
|
@ -4,8 +4,7 @@
|
|||
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
|
||||
//--------------------------------------------------------------------
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using IRaCIS.Core.Application.Service.Verify;
|
||||
|
||||
using IRaCIS.Core.Application.Service;
|
||||
|
||||
namespace IRaCIS.Core.Application.Contracts
|
||||
{
|
||||
|
@ -97,7 +96,7 @@ namespace IRaCIS.Core.Application.Contracts
|
|||
[HttpPost("{trialId:guid}")]
|
||||
public async Task<IResponseOutput<Guid>> AddOrUpdatePreviousHistory(PreviousHistoryAddOrEdit addOrEditPreviousHistory)
|
||||
{
|
||||
await QCCommonVerify.VerifyIsCRCSubmmitAsync(_repository, _userInfo, addOrEditPreviousHistory.SubjectVisitId);
|
||||
await QCCommon.VerifyIsCRCSubmmitAsync(_repository, _userInfo, addOrEditPreviousHistory.SubjectVisitId);
|
||||
|
||||
var entity = await _previousHistoryRepository.InsertOrUpdateAsync(addOrEditPreviousHistory, true);
|
||||
return ResponseOutput.Ok(entity.Id);
|
||||
|
@ -107,7 +106,7 @@ namespace IRaCIS.Core.Application.Contracts
|
|||
[HttpDelete("{trialId:guid}/{subjectVisitId:guid}/{previousHistoryId:guid}")]
|
||||
public async Task<IResponseOutput> DeletePreviousHistory(Guid previousHistoryId,Guid subjectVisitId)
|
||||
{
|
||||
await QCCommonVerify.VerifyIsCRCSubmmitAsync(_repository, _userInfo, subjectVisitId);
|
||||
await QCCommon.VerifyIsCRCSubmmitAsync(_repository, _userInfo, subjectVisitId);
|
||||
await _previousHistoryRepository.DeleteFromQueryAsync(t => t.Id == previousHistoryId,true);
|
||||
return ResponseOutput.Ok();
|
||||
}
|
||||
|
@ -124,7 +123,7 @@ namespace IRaCIS.Core.Application.Contracts
|
|||
[HttpPost("{trialId:guid}")]
|
||||
public async Task<IResponseOutput<Guid>> AddOrUpdatePreviousOther(PreviousOtherAddOrEdit addOrEditPreviousOther)
|
||||
{
|
||||
await QCCommonVerify.VerifyIsCRCSubmmitAsync(_repository, _userInfo, addOrEditPreviousOther.SubjectVisitId);
|
||||
await QCCommon.VerifyIsCRCSubmmitAsync(_repository, _userInfo, addOrEditPreviousOther.SubjectVisitId);
|
||||
var entity = await _previousOtherRepository.InsertOrUpdateAsync(addOrEditPreviousOther, true);
|
||||
return ResponseOutput.Ok(entity.Id);
|
||||
|
||||
|
@ -134,7 +133,7 @@ namespace IRaCIS.Core.Application.Contracts
|
|||
[HttpDelete("{trialId:guid}/{subjectVisitId:guid}/{previousOtherId:guid}")]
|
||||
public async Task<IResponseOutput> DeletePreviousOther(Guid previousOtherId, Guid subjectVisitId)
|
||||
{
|
||||
await QCCommonVerify.VerifyIsCRCSubmmitAsync(_repository, _userInfo, subjectVisitId);
|
||||
await QCCommon.VerifyIsCRCSubmmitAsync(_repository, _userInfo, subjectVisitId);
|
||||
|
||||
await _previousOtherRepository.DeleteFromQueryAsync(t => t.Id == previousOtherId,true);
|
||||
return ResponseOutput.Ok();
|
||||
|
@ -152,7 +151,7 @@ namespace IRaCIS.Core.Application.Contracts
|
|||
[HttpPost("{trialId:guid}")]
|
||||
public async Task<IResponseOutput<Guid>> AddOrUpdatePreviousSurgery(PreviousSurgeryAddOrEdit addOrEditPreviousSurgery)
|
||||
{
|
||||
await QCCommonVerify.VerifyIsCRCSubmmitAsync(_repository, _userInfo, addOrEditPreviousSurgery.SubjectVisitId);
|
||||
await QCCommon.VerifyIsCRCSubmmitAsync(_repository, _userInfo, addOrEditPreviousSurgery.SubjectVisitId);
|
||||
var entity = await _previousSurgeryRepository.InsertOrUpdateAsync(addOrEditPreviousSurgery, true);
|
||||
return ResponseOutput.Ok(entity.Id);
|
||||
}
|
||||
|
@ -161,7 +160,7 @@ namespace IRaCIS.Core.Application.Contracts
|
|||
[HttpDelete("{trialId:guid}/{subjectVisitId:guid}/{previousSurgeryId:guid}")]
|
||||
public async Task<IResponseOutput> DeletePreviousSurgery(Guid previousSurgeryId, Guid subjectVisitId)
|
||||
{
|
||||
await QCCommonVerify.VerifyIsCRCSubmmitAsync(_repository, _userInfo, subjectVisitId);
|
||||
await QCCommon.VerifyIsCRCSubmmitAsync(_repository, _userInfo, subjectVisitId);
|
||||
var success = await _previousSurgeryRepository.DeleteFromQueryAsync(t => t.Id == previousSurgeryId,true);
|
||||
return ResponseOutput.Ok();
|
||||
}
|
||||
|
@ -178,7 +177,7 @@ namespace IRaCIS.Core.Application.Contracts
|
|||
|
||||
public async Task<IResponseOutput> AddOrUpdatePreviousPDF(PreviousPDFAddOrEdit addOrEditPreviousPDF)
|
||||
{
|
||||
await QCCommonVerify.VerifyIsCRCSubmmitAsync(_repository, _userInfo, addOrEditPreviousPDF.SubjectVisitId);
|
||||
await QCCommon.VerifyIsCRCSubmmitAsync(_repository, _userInfo, addOrEditPreviousPDF.SubjectVisitId);
|
||||
var entity = await _previousPdfRepository.InsertOrUpdateAsync(addOrEditPreviousPDF, true);
|
||||
return ResponseOutput.Ok(entity.Id);
|
||||
|
||||
|
@ -187,7 +186,7 @@ namespace IRaCIS.Core.Application.Contracts
|
|||
[HttpDelete("{trialId:guid}/{subjectVisitId:guid}/{previousPDFId:guid}")]
|
||||
public async Task<IResponseOutput> DeletePreviousPDF(Guid previousPDFId, Guid subjectVisitId)
|
||||
{
|
||||
await QCCommonVerify.VerifyIsCRCSubmmitAsync(_repository, _userInfo, subjectVisitId);
|
||||
await QCCommon.VerifyIsCRCSubmmitAsync(_repository, _userInfo, subjectVisitId);
|
||||
|
||||
await _previousPdfRepository.DeleteFromQueryAsync(t => t.Id == previousPDFId,true);
|
||||
return ResponseOutput.Ok();
|
||||
|
|
|
@ -7,7 +7,7 @@ using Microsoft.AspNetCore.Mvc;
|
|||
using IRaCIS.Core.Application.Filter;
|
||||
using Nito.AsyncEx;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using IRaCIS.Core.Application.Service.Verify;
|
||||
using IRaCIS.Core.Application.Service;
|
||||
|
||||
namespace IRaCIS.Core.Application.Contracts
|
||||
{
|
||||
|
@ -50,9 +50,9 @@ namespace IRaCIS.Core.Application.Contracts
|
|||
public async Task<IResponseOutput<NoneDicomStudyAddReturnDto>> AddOrUpdateNoneDicomStudy(NoneDicomStudyAddOrEdit addOrEditNoneDicomStudy)
|
||||
{
|
||||
|
||||
await QCCommonVerify.VerifyIsCRCSubmmitAsync(_repository, _userInfo, addOrEditNoneDicomStudy.SubjectVisitId);
|
||||
await QCCommon.VerifyIsCRCSubmmitAsync(_repository, _userInfo, addOrEditNoneDicomStudy.SubjectVisitId);
|
||||
|
||||
await QCCommonVerify.VerifyStudyImageDataAsync(_repository, addOrEditNoneDicomStudy.SubjectId, addOrEditNoneDicomStudy.SubjectVisitId, addOrEditNoneDicomStudy.ImageDate);
|
||||
await QCCommon.VerifyStudyImageDataAsync(_repository, addOrEditNoneDicomStudy.SubjectId, addOrEditNoneDicomStudy.SubjectVisitId, addOrEditNoneDicomStudy.ImageDate);
|
||||
|
||||
|
||||
NoneDicomStudy? optEntity = null;
|
||||
|
@ -95,7 +95,7 @@ namespace IRaCIS.Core.Application.Contracts
|
|||
//提交了 但是IQC同意的时候 是可以删除的 | 普通提交后也不能删除
|
||||
|
||||
|
||||
await QCCommonVerify.VerifyIsCRCSubmmitAsync(_repository,_userInfo, subjectVisitId);
|
||||
await QCCommon.VerifyIsCRCSubmmitAsync(_repository,_userInfo, subjectVisitId);
|
||||
|
||||
await _noneDicomStudyRepository.DeleteFromQueryAsync(noneDicomStudyId);
|
||||
|
||||
|
@ -115,7 +115,7 @@ namespace IRaCIS.Core.Application.Contracts
|
|||
public async Task<IResponseOutput> DeleteNoneDicomStudyFile(Guid noneDicomStudyFileId, Guid subjectVisitId)
|
||||
{
|
||||
//提交了 但是IQC同意的时候 是可以删除的 | 普通提交后也不能删除
|
||||
await QCCommonVerify.VerifyIsCRCSubmmitAsync(_repository, _userInfo, subjectVisitId);
|
||||
await QCCommon.VerifyIsCRCSubmmitAsync(_repository, _userInfo, subjectVisitId);
|
||||
|
||||
var success = await _noneDicomStudyFileRepository.DeleteFromQueryAsync(t => t.Id == noneDicomStudyFileId, true);
|
||||
|
||||
|
|
|
@ -0,0 +1,264 @@
|
|||
using IRaCIS.Core.Domain.Share;
|
||||
using IRaCIS.Core.Infrastructure;
|
||||
using System.Linq.Expressions;
|
||||
|
||||
namespace IRaCIS.Core.Application.Service
|
||||
{
|
||||
public static class QCCommon
|
||||
{
|
||||
/// <summary>
|
||||
/// 验证CRC 是否已提交 已提交 就不允许进行任何操作,如果是IQC 那么还验证是否是当前任务领取人
|
||||
/// </summary>
|
||||
/// <param name="_repository"></param>
|
||||
/// <param name="_userInfo"></param>
|
||||
/// <param name="subjectVisitId"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="BusinessValidationFailedException"></exception>
|
||||
public static async Task VerifyIsCRCSubmmitAsync(IRepository _repository, IUserInfo _userInfo, Guid? subjectVisitId=null)
|
||||
{
|
||||
//添加的时候不验证
|
||||
if (subjectVisitId != null)
|
||||
{
|
||||
if (await _repository.AnyAsync<SubjectVisit>(t => t.Id == subjectVisitId && t.SubmitState == SubmitStateEnum.Submitted &&
|
||||
(!t.QCChallengeList.Any(u => u.ReuploadEnum == QCChanllengeReuploadEnum.QCAgreeUpload))))
|
||||
{
|
||||
throw new BusinessValidationFailedException("CRC 已提交影像,不能进行操作。");
|
||||
}
|
||||
}
|
||||
|
||||
//IQC 的时候 验证是不是当前领取人
|
||||
if (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.IQC)
|
||||
{
|
||||
|
||||
await VerifyIsCanQCAsync(_repository, _userInfo, null, subjectVisitId);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static async Task VerifyIsCanQCAsync(IRepository _repository,IUserInfo _userInfo, SubjectVisit? subjectVisit=null, Guid? subjectVisitId=null)
|
||||
{
|
||||
if (subjectVisitId != null)
|
||||
{
|
||||
subjectVisit = (await _repository.FirstOrDefaultAsync<SubjectVisit>(t => t.Id == subjectVisitId)).IfNullThrowException();
|
||||
}
|
||||
|
||||
if (subjectVisit!.CurrentActionUserId != _userInfo.Id)
|
||||
{
|
||||
throw new BusinessValidationFailedException("您不是该质控任务当前领取人,没有操作权限!");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static async Task VerifyStudyImageDataAsync(IRepository _repository, Guid subjectId, Guid subjectVisitId,DateTime imageDate)
|
||||
{
|
||||
var visitList = await _repository.Where<SubjectVisit>(t => t.SubjectId == subjectId).Select(t => new { t.VisitNum, t.EarliestScanDate, t.LatestScanDate, t.Id }).ToListAsync();
|
||||
|
||||
var currentVisitNum = await _repository.Where<SubjectVisit>(t => t.Id == subjectVisitId).Select(t => t.VisitNum).FirstOrDefaultAsync();
|
||||
|
||||
|
||||
|
||||
//小于当前访视 最近的最晚拍片
|
||||
var before = visitList.Where(u => u.VisitNum < currentVisitNum).Max(k => k.LatestScanDate);
|
||||
|
||||
if (before != null && before > imageDate)
|
||||
{
|
||||
throw new BusinessValidationFailedException($"当前访视检查时间{imageDate.ToString("yyyy-MM-dd")}不能早于前序访视检查时间{before?.ToString("yyyy-MM-dd")},请核对检查数据是否有误");
|
||||
}
|
||||
|
||||
|
||||
//大于当前访视 最近的最早拍片日期
|
||||
var after = visitList.Where(u => u.VisitNum > currentVisitNum).Min(k => k.EarliestScanDate);
|
||||
|
||||
if (after != null && after < imageDate)
|
||||
{
|
||||
throw new BusinessValidationFailedException($"当前访视检查时间{imageDate.ToString("yyyy-MM-dd")}不能晚于该访视之后的检查时间{after?.ToString("yyyy-MM-dd")},请核对检查数据是否有误");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
#region 处理方式多选过滤条件
|
||||
|
||||
public static Expression<Func<SubjectVisit, bool>> GetSubjectVisitFilter(string[]? VisitPlanArray)
|
||||
{
|
||||
Expression<Func<SubjectVisit, bool>> svExpression = x => true;
|
||||
|
||||
bool isNeedVisitSearch = VisitPlanArray != null && VisitPlanArray?.Length > 0;
|
||||
|
||||
if (isNeedVisitSearch)
|
||||
{
|
||||
var inPlanArray = VisitPlanArray!.Where(t => !t.Contains('.')).Select(t => decimal.Parse(t)).ToArray();
|
||||
var isSelectOutPlan = VisitPlanArray!.Any(t => t.Contains('.'));
|
||||
|
||||
|
||||
if (inPlanArray.Length > 0)
|
||||
{
|
||||
svExpression = svExpression.And(t => inPlanArray.Contains(t.VisitNum));
|
||||
|
||||
if (isSelectOutPlan)
|
||||
{
|
||||
svExpression = svExpression.Or(t => t.InPlan == false);
|
||||
|
||||
}
|
||||
}
|
||||
else if (isSelectOutPlan)
|
||||
{
|
||||
svExpression = t => t.InPlan == false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
return svExpression;
|
||||
}
|
||||
|
||||
|
||||
public static Expression<Func<QCChallenge, bool>> GetQCChallengeFilter(string[]? VisitPlanArray)
|
||||
{
|
||||
Expression<Func<QCChallenge, bool>> svExpression = x => true;
|
||||
|
||||
bool isNeedVisitSearch = VisitPlanArray != null && VisitPlanArray?.Length > 0;
|
||||
|
||||
if (isNeedVisitSearch)
|
||||
{
|
||||
var inPlanArray = VisitPlanArray!.Where(t => !t.Contains('.')).Select(t => decimal.Parse(t)).ToArray();
|
||||
var isSelectOutPlan = VisitPlanArray!.Any(t => t.Contains('.'));
|
||||
|
||||
|
||||
if (inPlanArray.Length > 0)
|
||||
{
|
||||
svExpression = svExpression.And(t => inPlanArray.Contains(t.SubjectVisit.VisitNum));
|
||||
|
||||
if (isSelectOutPlan)
|
||||
{
|
||||
svExpression = svExpression.Or(t => t.SubjectVisit.InPlan == false);
|
||||
|
||||
}
|
||||
}
|
||||
else if (isSelectOutPlan)
|
||||
{
|
||||
svExpression = t => t.SubjectVisit.InPlan == false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
return svExpression;
|
||||
}
|
||||
|
||||
|
||||
public static Expression<Func<DicomStudy, bool>> GetDicomStudySubjectVisitFilter(string[]? VisitPlanArray)
|
||||
{
|
||||
Expression<Func<DicomStudy, bool>> svExpression = x => true;
|
||||
|
||||
bool isNeedVisitSearch = VisitPlanArray != null && VisitPlanArray?.Length > 0;
|
||||
|
||||
if (isNeedVisitSearch)
|
||||
{
|
||||
var inPlanArray = VisitPlanArray!.Where(t => !t.Contains('.')).Select(t => decimal.Parse(t)).ToArray();
|
||||
var isSelectOutPlan = VisitPlanArray!.Any(t => t.Contains('.'));
|
||||
|
||||
|
||||
if (inPlanArray.Length > 0)
|
||||
{
|
||||
svExpression = svExpression.And(t => inPlanArray.Contains(t.SubjectVisit.VisitNum));
|
||||
|
||||
if (isSelectOutPlan)
|
||||
{
|
||||
svExpression = svExpression.Or(t => t.SubjectVisit.InPlan == false);
|
||||
|
||||
}
|
||||
}
|
||||
else if (isSelectOutPlan)
|
||||
{
|
||||
svExpression = t => t.SubjectVisit.InPlan == false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
return svExpression;
|
||||
}
|
||||
|
||||
|
||||
public static Expression<Func<NoneDicomStudy, bool>> GetNoneDicomStudySubjectVisitFilter(string[]? VisitPlanArray)
|
||||
{
|
||||
Expression<Func<NoneDicomStudy, bool>> svExpression = x => true;
|
||||
|
||||
bool isNeedVisitSearch = VisitPlanArray != null && VisitPlanArray?.Length > 0;
|
||||
|
||||
if (isNeedVisitSearch)
|
||||
{
|
||||
var inPlanArray = VisitPlanArray!.Where(t => !t.Contains('.')).Select(t => decimal.Parse(t)).ToArray();
|
||||
var isSelectOutPlan = VisitPlanArray!.Any(t => t.Contains('.'));
|
||||
|
||||
|
||||
if (inPlanArray.Length > 0)
|
||||
{
|
||||
svExpression = svExpression.And(t => inPlanArray.Contains(t.SubjectVisit.VisitNum));
|
||||
|
||||
if (isSelectOutPlan)
|
||||
{
|
||||
svExpression = svExpression.Or(t => t.SubjectVisit.InPlan == false);
|
||||
|
||||
}
|
||||
}
|
||||
else if (isSelectOutPlan)
|
||||
{
|
||||
svExpression = t => t.SubjectVisit.InPlan == false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
return svExpression;
|
||||
}
|
||||
|
||||
public static Expression<Func<StudyMonitor, bool>> GetStudyMonitorSubjectVisitFilter(string[]? VisitPlanArray)
|
||||
{
|
||||
Expression<Func<StudyMonitor, bool>> svExpression = x => true;
|
||||
|
||||
bool isNeedVisitSearch = VisitPlanArray != null && VisitPlanArray?.Length > 0;
|
||||
|
||||
if (isNeedVisitSearch)
|
||||
{
|
||||
var inPlanArray = VisitPlanArray!.Where(t => !t.Contains('.')).Select(t => decimal.Parse(t)).ToArray();
|
||||
var isSelectOutPlan = VisitPlanArray!.Any(t => t.Contains('.'));
|
||||
|
||||
|
||||
if (inPlanArray.Length > 0)
|
||||
{
|
||||
svExpression = svExpression.And(t => inPlanArray.Contains(t.SubjectVisit.VisitNum));
|
||||
|
||||
if (isSelectOutPlan)
|
||||
{
|
||||
svExpression = svExpression.Or(t => t.SubjectVisit.InPlan == false);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
else if (isSelectOutPlan)
|
||||
{
|
||||
svExpression = t => t.SubjectVisit.InPlan == false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
return svExpression;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
|
@ -1,83 +0,0 @@
|
|||
using IRaCIS.Core.Domain.Share;
|
||||
using IRaCIS.Core.Infrastructure;
|
||||
|
||||
|
||||
namespace IRaCIS.Core.Application.Service.Verify
|
||||
{
|
||||
public static class QCCommonVerify
|
||||
{
|
||||
/// <summary>
|
||||
/// 验证CRC 是否已提交 已提交 就不允许进行任何操作,如果是IQC 那么还验证是否是当前任务领取人
|
||||
/// </summary>
|
||||
/// <param name="_repository"></param>
|
||||
/// <param name="_userInfo"></param>
|
||||
/// <param name="subjectVisitId"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="BusinessValidationFailedException"></exception>
|
||||
public static async Task VerifyIsCRCSubmmitAsync(IRepository _repository, IUserInfo _userInfo, Guid? subjectVisitId=null)
|
||||
{
|
||||
//添加的时候不验证
|
||||
if (subjectVisitId != null)
|
||||
{
|
||||
if (await _repository.AnyAsync<SubjectVisit>(t => t.Id == subjectVisitId && t.SubmitState == SubmitStateEnum.Submitted &&
|
||||
(!t.QCChallengeList.Any(u => u.ReuploadEnum == QCChanllengeReuploadEnum.QCAgreeUpload))))
|
||||
{
|
||||
throw new BusinessValidationFailedException("CRC 已提交影像,不能进行操作。");
|
||||
}
|
||||
}
|
||||
|
||||
//IQC 的时候 验证是不是当前领取人
|
||||
if (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.IQC)
|
||||
{
|
||||
|
||||
await VerifyIsCanQCAsync(_repository, _userInfo, null, subjectVisitId);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static async Task VerifyIsCanQCAsync(IRepository _repository,IUserInfo _userInfo, SubjectVisit? subjectVisit=null, Guid? subjectVisitId=null)
|
||||
{
|
||||
if (subjectVisitId != null)
|
||||
{
|
||||
subjectVisit = (await _repository.FirstOrDefaultAsync<SubjectVisit>(t => t.Id == subjectVisitId)).IfNullThrowException();
|
||||
}
|
||||
|
||||
if (subjectVisit!.CurrentActionUserId != _userInfo.Id)
|
||||
{
|
||||
throw new BusinessValidationFailedException("您不是该质控任务当前领取人,没有操作权限!");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static async Task VerifyStudyImageDataAsync(IRepository _repository, Guid subjectId, Guid subjectVisitId,DateTime imageDate)
|
||||
{
|
||||
var visitList = await _repository.Where<SubjectVisit>(t => t.SubjectId == subjectId).Select(t => new { t.VisitNum, t.EarliestScanDate, t.LatestScanDate, t.Id }).ToListAsync();
|
||||
|
||||
var currentVisitNum = await _repository.Where<SubjectVisit>(t => t.Id == subjectVisitId).Select(t => t.VisitNum).FirstOrDefaultAsync();
|
||||
|
||||
|
||||
|
||||
//小于当前访视 最近的最晚拍片
|
||||
var before = visitList.Where(u => u.VisitNum < currentVisitNum).Max(k => k.LatestScanDate);
|
||||
|
||||
if (before != null && before > imageDate)
|
||||
{
|
||||
throw new BusinessValidationFailedException($"当前访视检查时间{imageDate.ToString("yyyy-MM-dd")}不能早于前序访视检查时间{before?.ToString("yyyy-MM-dd")},请核对检查数据是否有误");
|
||||
}
|
||||
|
||||
|
||||
//大于当前访视 最近的最早拍片日期
|
||||
var after = visitList.Where(u => u.VisitNum > currentVisitNum).Min(k => k.EarliestScanDate);
|
||||
|
||||
if (after != null && after < imageDate)
|
||||
{
|
||||
throw new BusinessValidationFailedException($"当前访视检查时间{imageDate.ToString("yyyy-MM-dd")}不能晚于该访视之后的检查时间{after?.ToString("yyyy-MM-dd")},请核对检查数据是否有误");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -2,8 +2,7 @@
|
|||
using Microsoft.AspNetCore.Mvc;
|
||||
using IRaCIS.Core.Domain.Share;
|
||||
using IRaCIS.Core.Application.Contracts.DTO;
|
||||
using System.Linq.Expressions;
|
||||
using IRaCIS.Core.Infrastructure;
|
||||
using IRaCIS.Core.Application.Service;
|
||||
|
||||
namespace IRaCIS.Core.Application.Image.QA
|
||||
{
|
||||
|
@ -23,70 +22,7 @@ namespace IRaCIS.Core.Application.Image.QA
|
|||
}
|
||||
|
||||
|
||||
#region 处理方式多选过滤条件
|
||||
|
||||
private Expression<Func<SubjectVisit, bool>> GetSubjectVisitFilter(string[]? VisitPlanArray)
|
||||
{
|
||||
Expression<Func<SubjectVisit, bool>> svExpression = x => true;
|
||||
|
||||
bool isNeedVisitSearch = VisitPlanArray != null && VisitPlanArray?.Length > 0;
|
||||
|
||||
if (isNeedVisitSearch)
|
||||
{
|
||||
var inPlanArray = VisitPlanArray!.Where(t => !t.Contains('.')).Select(t => decimal.Parse(t)).ToArray();
|
||||
var isSelectOutPlan = VisitPlanArray!.Any(t => t.Contains('.'));
|
||||
|
||||
|
||||
if (inPlanArray.Length > 0)
|
||||
{
|
||||
svExpression = svExpression.And(t => inPlanArray.Contains(t.VisitNum));
|
||||
}
|
||||
|
||||
|
||||
if (isSelectOutPlan)
|
||||
{
|
||||
svExpression = svExpression.Or(t => t.InPlan == false);
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
return svExpression;
|
||||
}
|
||||
|
||||
|
||||
private Expression<Func<QCChallenge, bool>> GetQCChallengeFilter(string[]? VisitPlanArray)
|
||||
{
|
||||
Expression<Func<QCChallenge, bool>> svExpression = x => true;
|
||||
|
||||
bool isNeedVisitSearch = VisitPlanArray != null && VisitPlanArray?.Length > 0;
|
||||
|
||||
if (isNeedVisitSearch)
|
||||
{
|
||||
var inPlanArray = VisitPlanArray!.Where(t => !t.Contains('.')).Select(t => decimal.Parse(t)).ToArray();
|
||||
var isSelectOutPlan = VisitPlanArray!.Any(t => t.Contains('.'));
|
||||
|
||||
|
||||
if (inPlanArray.Length > 0)
|
||||
{
|
||||
svExpression = svExpression.And(t => inPlanArray.Contains(t.SubjectVisit.VisitNum));
|
||||
}
|
||||
|
||||
if (isSelectOutPlan)
|
||||
{
|
||||
svExpression = svExpression.Or(t => t.SubjectVisit.InPlan == false);
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
return svExpression;
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
#region CRC上传、质疑页面
|
||||
/// <summary>
|
||||
|
@ -97,7 +33,7 @@ namespace IRaCIS.Core.Application.Image.QA
|
|||
[HttpPost]
|
||||
public async Task<(PageOutput<QCCRCVisitViewModel>, TrialSubjectAndSVConfig)> GetCRCVisitList(CRCVisitSearchDTO visitSearchDTO)
|
||||
{
|
||||
var svExpression = GetSubjectVisitFilter(visitSearchDTO.VisitPlanArray);
|
||||
var svExpression = QCCommon.GetSubjectVisitFilter(visitSearchDTO.VisitPlanArray);
|
||||
|
||||
var query = _repository.Where<SubjectVisit>(x => x.TrialId == visitSearchDTO.TrialId)
|
||||
.WhereIf(visitSearchDTO.SiteId != null, t => t.SiteId == visitSearchDTO.SiteId)
|
||||
|
@ -168,7 +104,7 @@ namespace IRaCIS.Core.Application.Image.QA
|
|||
// };
|
||||
#endregion
|
||||
|
||||
var svExpression = GetQCChallengeFilter(challengeQuery.VisitPlanArray);
|
||||
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)
|
||||
|
@ -257,7 +193,7 @@ namespace IRaCIS.Core.Application.Image.QA
|
|||
// };
|
||||
#endregion
|
||||
|
||||
var svExpression = GetQCChallengeFilter(challengeQuery.VisitPlanArray);
|
||||
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)
|
||||
|
@ -446,7 +382,7 @@ namespace IRaCIS.Core.Application.Image.QA
|
|||
|
||||
#endregion
|
||||
|
||||
var svExpression = GetSubjectVisitFilter(visitSearchDTO.VisitPlanArray);
|
||||
var svExpression = QCCommon.GetSubjectVisitFilter(visitSearchDTO.VisitPlanArray);
|
||||
var query = _subjectVisitRepository.Where(x => x.TrialId == visitSearchDTO.TrialId)
|
||||
.WhereIf(visitSearchDTO.ChallengeState != null, t => t.ChallengeState == visitSearchDTO.ChallengeState)
|
||||
.WhereIf(visitSearchDTO.SiteId != null, t => t.SiteId == visitSearchDTO.SiteId)
|
||||
|
@ -535,7 +471,7 @@ namespace IRaCIS.Core.Application.Image.QA
|
|||
// };
|
||||
#endregion
|
||||
|
||||
var svExpression = GetSubjectVisitFilter(checkQuery.VisitPlanArray);
|
||||
var svExpression = QCCommon.GetSubjectVisitFilter(checkQuery.VisitPlanArray);
|
||||
|
||||
var query = _subjectVisitRepository.Where(x => x.TrialId == checkQuery.TrialId)
|
||||
.Where(x => x.AuditState == AuditStateEnum.QCPassed) //一致性核查中的,或者还没一致性核查的
|
||||
|
@ -581,7 +517,7 @@ namespace IRaCIS.Core.Application.Image.QA
|
|||
{
|
||||
//var trialConfig = _trialReposioty.Select(t => new { TrialId = t.Id, t.QCProcessEnum, t.IsImageConsistencyVerification }).FirstOrDefault(t => t.TrialId == forwardQuery.TrialId);
|
||||
|
||||
var svExpression = GetSubjectVisitFilter(forwardQuery.VisitPlanArray);
|
||||
var svExpression = QCCommon.GetSubjectVisitFilter(forwardQuery.VisitPlanArray);
|
||||
|
||||
var query = _subjectVisitRepository.Where(x => x.TrialId == forwardQuery.TrialId)
|
||||
.Where(t => t.CheckState == CheckStateEnum.CVPassed)
|
||||
|
|
|
@ -44,6 +44,12 @@ namespace IRaCIS.Core.Application.Services
|
|||
IsVerify = svCommand.IsFinalVisit
|
||||
};
|
||||
|
||||
var verifyExp3 = new EntityVerifyExp<SubjectVisit>()
|
||||
{
|
||||
VerifyExp = t => t.SubjectId == svCommand.SubjectId && t.VisitName==svCommand.VisitName,
|
||||
VerifyMsg = "该受试者的访视计划中已经包含一个具有相同访视名称的访视。"
|
||||
|
||||
};
|
||||
|
||||
svCommand.BlindName = "B" + ((int)(svCommand.VisitNum * 10)).ToString("D3");
|
||||
svCommand.VisitExecuted = svCommand.IsLostVisit ? VisitExecutedEnum.Executed : svCommand.VisitExecuted;
|
||||
|
@ -63,12 +69,12 @@ namespace IRaCIS.Core.Application.Services
|
|||
}
|
||||
}
|
||||
|
||||
dbBeforeEntity = await _subjectVisitRepository.InsertFromDTOAsync(svCommand, false, verifyExp1, verifyExp2);
|
||||
dbBeforeEntity = await _subjectVisitRepository.InsertFromDTOAsync(svCommand, false, verifyExp1, verifyExp2,verifyExp3);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
dbBeforeEntity = await _subjectVisitRepository.UpdateFromDTOAsync(svCommand, false, false, verifyExp1, verifyExp2);
|
||||
dbBeforeEntity = await _subjectVisitRepository.UpdateFromDTOAsync(svCommand, false, false, verifyExp1, verifyExp2, verifyExp3);
|
||||
|
||||
if (svCommand.PDState != dbBeforeEntity.PDState && dbBeforeEntity.SubmitState == SubmitStateEnum.Submitted)
|
||||
{
|
||||
|
|
|
@ -9,5 +9,22 @@ namespace IRaCIS.Core.Domain.Share
|
|||
Phone = 1
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
public enum DicDataTypeEnum
|
||||
{
|
||||
//字典下拉配置
|
||||
Config = 0,
|
||||
|
||||
//下拉框
|
||||
Select = 1,
|
||||
|
||||
//枚举
|
||||
Enum=2,
|
||||
|
||||
//Bool
|
||||
|
||||
Bool=3
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,6 +12,13 @@ namespace IRaCIS.Core.Domain.Models
|
|||
|
||||
public List<DoctorDictionary> DoctorDicRelationList { get; set; } = new List<DoctorDictionary>();
|
||||
|
||||
public string ChildGroup { get; set; }
|
||||
|
||||
public int ChildCodeEnum { get; set; }
|
||||
|
||||
|
||||
public DicDataTypeEnum DataTypeEnum { get; set; }
|
||||
|
||||
|
||||
[Column("Value")]
|
||||
public string Value { get; set; } = string.Empty;
|
||||
|
@ -25,7 +32,6 @@ namespace IRaCIS.Core.Domain.Models
|
|||
|
||||
public int ShowOrder { get; set; }
|
||||
|
||||
public string ChildGroup { get; set; }
|
||||
|
||||
public Guid UpdateUserId { get; set; }
|
||||
public DateTime UpdateTime { get; set; }
|
||||
|
@ -52,11 +58,6 @@ namespace IRaCIS.Core.Domain.Models
|
|||
[ForeignKey("ParentId")]
|
||||
public Dictionary Parent { get; set; }
|
||||
|
||||
public int ChildCodeEnum { get; set; }
|
||||
|
||||
|
||||
[StringLength(50)]
|
||||
public string KeyName { get; set; } = string.Empty;
|
||||
|
||||
|
||||
[NotMapped]
|
||||
|
|
Loading…
Reference in New Issue