diff --git a/IRaCIS.Core.API/Controllers/InspectionController.cs b/IRaCIS.Core.API/Controllers/InspectionController.cs index b7e4df48a..d6a227a8f 100644 --- a/IRaCIS.Core.API/Controllers/InspectionController.cs +++ b/IRaCIS.Core.API/Controllers/InspectionController.cs @@ -58,7 +58,7 @@ namespace IRaCIS.Core.API.Controllers ITrialConfigService _trialConfigService, INoneDicomStudyService noneDicomStudyService, ISubjectService _subjectService, - + ISubjectVisitService subjectVisitService, IQCOperationService qCOperationService, IClinicalDataService clinicalDataService, @@ -82,7 +82,7 @@ namespace IRaCIS.Core.API.Controllers this._dataInspectionRepository = dataInspectionRepository; } - + //[HttpPost, Route("Inspection/Test")] //public async Task Test(string Table, string ForeignKeyValue, string ForeignKeyText, string value) //{ @@ -100,8 +100,8 @@ namespace IRaCIS.Core.API.Controllers [UnitOfWork] public async Task AbandonTrial(DataInspectionDto opt) { - var fun = await _trialConfigService.AbandonTrial(opt.OptCommand.trialId,opt.OptCommand.isAbandon); - return await _inspectionService.Enforcement(opt.OptCommand, opt.AuditInfo, opt.SignInfo,null, fun); + var fun = await _trialConfigService.AbandonTrial(opt.OptCommand.trialId, opt.OptCommand.isAbandon); + return await _inspectionService.Enforcement(opt.OptCommand, opt.AuditInfo, opt.SignInfo, null, fun); } /// @@ -183,7 +183,7 @@ namespace IRaCIS.Core.API.Controllers public async Task AddOrUpdateQCQuestionAnswerList(DataInspectionDto opt) { - var fun = await _qCOperationService.AddOrUpdateQCQuestionAnswerList(opt.OptCommand.qcQuestionAnswerCommands, opt.OptCommand.trialId, opt.OptCommand.subjectVisitId,opt.OptCommand.trialQCProcess,opt.OptCommand.currentQCType); + var fun = await _qCOperationService.AddOrUpdateQCQuestionAnswerList(opt.OptCommand.qcQuestionAnswerCommands, opt.OptCommand.trialId, opt.OptCommand.subjectVisitId, opt.OptCommand.trialQCProcess, opt.OptCommand.currentQCType); if (!fun.IsSuccess) { return ResponseOutput.NotOk(fun.ErrorMessage); @@ -204,7 +204,7 @@ namespace IRaCIS.Core.API.Controllers var fun = await _qCOperationService.AddOrUpdateQCChallenge(opt.OptCommand.qaQuestionCommand, opt.OptCommand.trialId, opt.OptCommand.trialQCProcess, opt.OptCommand.currentQCType); opt.AuditInfo.GeneralId = fun.Id; Dictionary keyValuePairs = new Dictionary(); - keyValuePairs.Add("ChallengeCode", "Q" + fun.ChallengeCode.ToString("D5") ); + keyValuePairs.Add("ChallengeCode", "Q" + fun.ChallengeCode.ToString("D5")); opt.AuditInfo.JsonDetail = _inspectionService.AddJsonItem(opt.AuditInfo.JsonDetail, keyValuePairs); return await _inspectionService.Enforcement(opt.OptCommand, opt.AuditInfo, opt.SignInfo, null, ResponseOutput.Ok()); } @@ -266,7 +266,7 @@ namespace IRaCIS.Core.API.Controllers { var fun = _qCOperationService.AddCheckChallengeReply; - + return await _inspectionService.Enforcement(opt.OptCommand, opt.AuditInfo, opt.SignInfo, fun); } @@ -327,8 +327,8 @@ namespace IRaCIS.Core.API.Controllers [UnitOfWork] public async Task UpdateModality(DataInspectionDto opt) { - var fun =await _qCOperationService.UpdateModality(opt.OptCommand.id, opt.OptCommand.type, opt.OptCommand.modality, opt.OptCommand.bodyPart); - return await _inspectionService.Enforcement(opt.OptCommand, opt.AuditInfo, opt.SignInfo,null, fun); + var fun = await _qCOperationService.UpdateModality(opt.OptCommand.id, (Guid)opt.AuditInfo.SubjectVisitId, opt.OptCommand.type, opt.OptCommand.modality, opt.OptCommand.bodyPart); + return await _inspectionService.Enforcement(opt.OptCommand, opt.AuditInfo, opt.SignInfo, null, fun); } /// @@ -359,7 +359,7 @@ namespace IRaCIS.Core.API.Controllers /// [HttpPost, Route("Inspection/QCOperation/SetVisitUrgent")] [UnitOfWork] - public async Task SetVisitUrgent(DataInspectionDto opt ) + public async Task SetVisitUrgent(DataInspectionDto opt) { var fun = await _qCOperationService.SetVisitUrgent(opt.OptCommand.trialId, opt.OptCommand.subjectVisitId, opt.OptCommand.setOrCancel); return await _inspectionService.Enforcement(opt.OptCommand, opt.AuditInfo, opt.SignInfo, null, fun); @@ -386,7 +386,7 @@ namespace IRaCIS.Core.API.Controllers public async Task SetReuploadFinished(DataInspectionDto opt) { var fun = _qCOperationService.SetReuploadFinished; - return await _inspectionService.Enforcement(opt.OptCommand, opt.AuditInfo, opt.SignInfo, fun); + return await _inspectionService.Enforcement(opt.OptCommand, opt.AuditInfo, opt.SignInfo, fun); } /// @@ -423,9 +423,9 @@ namespace IRaCIS.Core.API.Controllers /// [HttpPost, Route("Inspection/QCOperation/UploadVisitCheckExcel")] [UnitOfWork] - public async Task UploadVisitCheckExcel(IFormFile file, [FromForm]UploadVisitCheckExcelDto opt) + public async Task UploadVisitCheckExcel(IFormFile file, [FromForm] UploadVisitCheckExcelDto opt) { - + var fun = await _qCOperationService.UploadVisitCheckExcel(file, opt.trialId); return fun; @@ -466,7 +466,7 @@ namespace IRaCIS.Core.API.Controllers return ResponseOutput.NotOk(fun.ErrorMessage); } opt.AuditInfo.NeedSava = false; - return await _inspectionService.Enforcement(opt.OptCommand, opt.AuditInfo, opt.SignInfo,null, fun); + return await _inspectionService.Enforcement(opt.OptCommand, opt.AuditInfo, opt.SignInfo, null, fun); } @@ -507,7 +507,7 @@ namespace IRaCIS.Core.API.Controllers } opt.AuditInfo.GeneralId = fun.Data.Id; - return await _inspectionService.Enforcement(opt.OptCommand, opt.AuditInfo, opt.SignInfo,null, fun); + return await _inspectionService.Enforcement(opt.OptCommand, opt.AuditInfo, opt.SignInfo, null, fun); } @@ -554,7 +554,7 @@ namespace IRaCIS.Core.API.Controllers { var fun = await _clinicalDataService.AddOrUpdatePreviousHistory(opt.OptCommand); opt.AuditInfo.GeneralId = fun.Data; - return await _inspectionService.Enforcement(opt.OptCommand, opt.AuditInfo, opt.SignInfo,null, fun); + return await _inspectionService.Enforcement(opt.OptCommand, opt.AuditInfo, opt.SignInfo, null, fun); } @@ -586,7 +586,7 @@ namespace IRaCIS.Core.API.Controllers { var fun = await _clinicalDataService.AddOrUpdatePreviousSurgery(opt.OptCommand); opt.AuditInfo.GeneralId = fun.Data; - return await _inspectionService.Enforcement(opt.OptCommand, opt.AuditInfo, opt.SignInfo,null, fun); + return await _inspectionService.Enforcement(opt.OptCommand, opt.AuditInfo, opt.SignInfo, null, fun); } @@ -616,7 +616,7 @@ namespace IRaCIS.Core.API.Controllers { var fun = await _clinicalDataService.AddOrUpdatePreviousOther(opt.OptCommand); opt.AuditInfo.GeneralId = fun.Data; - return await _inspectionService.Enforcement(opt.OptCommand, opt.AuditInfo, opt.SignInfo,null, fun); + return await _inspectionService.Enforcement(opt.OptCommand, opt.AuditInfo, opt.SignInfo, null, fun); } @@ -666,8 +666,8 @@ namespace IRaCIS.Core.API.Controllers [UnitOfWork] public async Task DeleteVisitStage(DataInspectionDto opt) { - var fun = _visitPlanService.DeleteVisitStage; - + var fun = _visitPlanService.DeleteVisitStage; + return await _inspectionService.Enforcement(opt.OptCommand.Id, opt.AuditInfo, opt.SignInfo, fun); } @@ -825,11 +825,12 @@ namespace IRaCIS.Core.API.Controllers return ResponseOutput.NotOk(data.ErrorMessage); } var fun = _trialConfigService.TrialConfigSignatureConfirm; - return await _inspectionService.Enforcement(new SignConfirmDTO() { - TrialId=opt.OptCommand.TrialId, - SignCode=opt.OptCommand.SignCode + return await _inspectionService.Enforcement(new SignConfirmDTO() + { + TrialId = opt.OptCommand.TrialId, + SignCode = opt.OptCommand.SignCode }, opt.AuditInfo, opt.SignInfo, fun); - + } /// @@ -934,7 +935,7 @@ namespace IRaCIS.Core.API.Controllers public async Task UpdateSubjectStatus(InsUpdateSubjectStatus opt) { var fun = _subjectService.UpdateSubjectStatus; - + return await _inspectionService.Enforcement(opt.OptCommand, opt.AuditInfo, opt.SignInfo, fun); } diff --git a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml index a26ad13da..012c5bef3 100644 --- a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml +++ b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml @@ -1551,7 +1551,7 @@ - + type 1 :study 2: series 3:非dicom QC修改检查部位和 拍片类型 diff --git a/IRaCIS.Core.Application/Service/QC/Interface/IQCOperationService.cs b/IRaCIS.Core.Application/Service/QC/Interface/IQCOperationService.cs index 44a5b794e..789270fee 100644 --- a/IRaCIS.Core.Application/Service/QC/Interface/IQCOperationService.cs +++ b/IRaCIS.Core.Application/Service/QC/Interface/IQCOperationService.cs @@ -34,7 +34,7 @@ namespace IRaCIS.Core.Application.Image.QA Task SetReuploadFinished(CRCReuploadFinishedCommand cRCReuploadFinishedCommand); Task SetSeriesState(Guid subjectVisitId, Guid studyId, Guid seriesId, int state); Task SetVisitUrgent(Guid trialId, Guid subjectVisitId, bool setOrCancel); - Task UpdateModality(Guid id, int type, [FromQuery] string modality, [FromQuery] string bodyPart); + Task UpdateModality(Guid id, Guid subjectVisitId, int type, [FromQuery] string modality, [FromQuery] string bodyPart); Task UpdateSubjectAndSVInfo(UploadSubjectAndVisitCommand command); Task UploadVisitCheckExcel(IFormFile file, Guid trialId); Task VerifyCanQCPassedOrFailed(Guid subjectVisitId); diff --git a/IRaCIS.Core.Application/Service/QC/QCOperationService.cs b/IRaCIS.Core.Application/Service/QC/QCOperationService.cs index c08a4493f..bf0071dc2 100644 --- a/IRaCIS.Core.Application/Service/QC/QCOperationService.cs +++ b/IRaCIS.Core.Application/Service/QC/QCOperationService.cs @@ -70,6 +70,7 @@ namespace IRaCIS.Core.Application.Image.QA [TypeFilter(typeof(TrialResourceFilter))] public async Task VerifyQCCanAddChallenge(Guid subjectVisitId, [FromRoute] CurrentQC currentQCType) { + VerifyIsCanQC(null, subjectVisitId); if (!await _repository.AnyAsync(t => t.SubjectVisitId == subjectVisitId && t.CurrentQCEnum == currentQCType)) { return ResponseOutput.NotOk("请先核查图像,保存审核问题后,再发质疑。"); @@ -91,6 +92,7 @@ namespace IRaCIS.Core.Application.Image.QA [Authorize(Policy = "ImageQCPolicy")] public async Task AddOrUpdateQCChallenge(QCChallengeCommand qaQuestionCommand, Guid trialId, [FromRoute] TrialQCProcess trialQCProcess, [FromRoute] CurrentQC currentQCType) { + VerifyIsCanQC(null, qaQuestionCommand.SubjectVisitId); if (qaQuestionCommand.Id == null) { @@ -288,17 +290,20 @@ namespace IRaCIS.Core.Application.Image.QA [Authorize(Policy = "ImageCheckPolicy")] public async Task> AddCheckChallengeReply(CheckChallengeDialogCommand checkDialogCommand) { - var qaReply = _mapper.Map(checkDialogCommand); - qaReply.UserTypeEnum = (UserTypeEnum)_userInfo.UserTypeEnumInt; - - await _repository.AddAsync(qaReply); //修改一致性核查 质疑状态 var sv = await _subjectVisitRepository.FirstOrDefaultAsync(t => t.Id == checkDialogCommand.SubjectVisitId); + + var qaReply = _mapper.Map(checkDialogCommand); + + qaReply.UserTypeEnum = (UserTypeEnum)_userInfo.UserTypeEnumInt; + + await _repository.AddAsync(qaReply); + if (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator) { sv.CheckChallengeState = CheckChanllengeTypeEnum.CRCWaitPMReply; @@ -327,9 +332,9 @@ namespace IRaCIS.Core.Application.Image.QA public async Task CloseCheckChallenge(CloseCheckChallengeDto input) { - var sv = await _subjectVisitRepository.FirstOrDefaultAsync(t => t.Id == input.subjectVisitId); + var sv = (await _subjectVisitRepository.FirstOrDefaultAsync(t => t.Id == input.subjectVisitId)).IfNullThrowException(); + - if (sv == null) return Null404NotFound(sv); if (sv.RequestBackState == RequestBackStateEnum.PM_AgressBack) { @@ -689,12 +694,7 @@ namespace IRaCIS.Core.Application.Image.QA public async Task AddOrUpdateQCQuestionAnswerList(QCQuestionAnswerCommand[] qcQuestionAnswerCommands, Guid trialId, Guid subjectVisitId, [FromRoute] TrialQCProcess trialQCProcess, [FromRoute] CurrentQC currentQCType) { //验证是否能操作 - var verifyResult = await VerifyQCCanOpt(subjectVisitId); - - if (!verifyResult.IsSuccess) - { - return verifyResult; - } + VerifyIsCanQC(null, subjectVisitId); //更新 if (qcQuestionAnswerCommands.Any(t => t.Id != null)) @@ -763,13 +763,9 @@ namespace IRaCIS.Core.Application.Image.QA [TypeFilter(typeof(TrialResourceFilter))] public async Task SetSeriesState(Guid subjectVisitId, Guid studyId, Guid seriesId, int state) { - //验证是否能操作 - var verifyResult = await VerifyQCCanOpt(subjectVisitId); - if (!verifyResult.IsSuccess) - { - return verifyResult; - } + VerifyIsCanQC(null, subjectVisitId); + var series = await _repository.Where(t => t.Id == seriesId, true).IgnoreQueryFilters().FirstOrDefaultAsync(); @@ -838,9 +834,9 @@ namespace IRaCIS.Core.Application.Image.QA /// /// /// - [HttpPut("{trialId:guid}/{id:guid}/{type:int}")] + [HttpPut("{trialId:guid}/{subjectVisitId:guid}/{id:guid}/{type:int}")] [TypeFilter(typeof(TrialResourceFilter))] - public async Task UpdateModality(Guid id, int type, [FromQuery] string modality, [FromQuery] string bodyPart) + public async Task UpdateModality(Guid id, Guid subjectVisitId, int type, [FromQuery] string modality, [FromQuery] string bodyPart) { var DicomSeriesdata = await _repository.GetQueryable().Where(x => x.StudyId == id).ToListAsync(); @@ -934,6 +930,7 @@ namespace IRaCIS.Core.Application.Image.QA [HttpGet("{subjectVisitId:guid}")] public async Task VerifyCanQCPassedOrFailed(Guid subjectVisitId) { + VerifyIsCanQC(null, subjectVisitId); if (await _repository.AnyAsync(t => t.SubjectVisitId == subjectVisitId && t.IsClosed == false)) { @@ -957,6 +954,8 @@ namespace IRaCIS.Core.Application.Image.QA [UnitOfWork] public async Task DeleteStudyList(Guid[] ids, Guid subjectVisitId, Guid trialId) { + + //提交了 但是IQC同意的时候 是可以删除的 if (await _subjectVisitRepository.AnyAsync(t => t.Id == subjectVisitId && t.SubmitState == SubmitStateEnum.Submitted && (!t.QCChallengeList.Any(u => u.ReuploadEnum == QCChanllengeReuploadEnum.QCAgreeUpload)))) @@ -1078,6 +1077,23 @@ namespace IRaCIS.Core.Application.Image.QA #endregion + public void VerifyIsCanQC(SubjectVisit? subjectVisit, Guid? sujectVisitId = null) + { + if (sujectVisitId != null) + { + subjectVisit = _subjectVisitRepository.FirstOrDefaultAsync(t => t.Id == sujectVisitId).Result.IfNullThrowException(); + } + + if (subjectVisit.PreliminaryAuditUserId != null) + { + throw new BusinessValidationFailedException("当前访视已审核通过,不允许操作"); + } + + if (subjectVisit.CurrentActionUserId != _userInfo.Id) + { + throw new BusinessValidationFailedException("当前领取人已不是自己,不允许操作"); + } + } #region 临床数据签名 领取、 设置紧急、RequestToQC QC通过、不通过 @@ -1094,9 +1110,9 @@ namespace IRaCIS.Core.Application.Image.QA public async Task ObtainOrCancelQCTask(Guid trialId, Guid subjectVisitId, bool obtaionOrCancel) { - var dbSubjectVisit = await _subjectVisitRepository.FirstOrDefaultAsync(t => t.Id == subjectVisitId); + var dbSubjectVisit = (await _subjectVisitRepository.FirstOrDefaultAsync(t => t.Id == subjectVisitId)).IfNullThrowException(); - if (dbSubjectVisit == null) return Null404NotFound(dbSubjectVisit); + VerifyIsCanQC(dbSubjectVisit); var trialConfig = await _trialRepository .Select(t => new { TrialId = t.Id, t.QCProcessEnum, t.IsImageConsistencyVerification })