diff --git a/IRaCIS.Core.API/Controllers/InspectionController.cs b/IRaCIS.Core.API/Controllers/InspectionController.cs
index 56187a561..5d0206baa 100644
--- a/IRaCIS.Core.API/Controllers/InspectionController.cs
+++ b/IRaCIS.Core.API/Controllers/InspectionController.cs
@@ -52,7 +52,7 @@ namespace IRaCIS.Core.API.Controllers
///
///
[HttpPost, Route("Inspection/ReadingImageTask/SubmitOncologyReadingInfo")]
- [TrialGlobalLimit( "AfterStopCannNotOpt" )]
+ [TrialGlobalLimit("AfterStopCannNotOpt")]
[UnitOfWork]
public async Task SetOncologyReadingInfo(DataInspectionDto opt)
@@ -69,7 +69,7 @@ namespace IRaCIS.Core.API.Controllers
///
///
[HttpPost, Route("Inspection/ReadingImageTask/SubmitDicomVisitTask")]
- [TrialGlobalLimit( "AfterStopCannNotOpt" )]
+ [TrialGlobalLimit("AfterStopCannNotOpt")]
[UnitOfWork]
public async Task SubmitDicomVisitTask(DataInspectionDto opt)
@@ -88,7 +88,7 @@ namespace IRaCIS.Core.API.Controllers
///
///
[HttpPost, Route("Inspection/ReadingImageTask/SubmitGlobalReadingInfo")]
- [TrialGlobalLimit( "AfterStopCannNotOpt" )]
+ [TrialGlobalLimit("AfterStopCannNotOpt")]
[UnitOfWork]
public async Task SubmitGlobalReadingInfo(DataInspectionDto opt)
@@ -107,7 +107,7 @@ namespace IRaCIS.Core.API.Controllers
///
///
[HttpPost, Route("Inspection/configTrialBasicInfo/TrialReadingInfoSign")]
- [TrialGlobalLimit( "AfterStopCannNotOpt" )]
+ [TrialGlobalLimit("AfterStopCannNotOpt")]
[UnitOfWork]
public async Task TrialReadingInfoSign(DataInspectionDto opt)
@@ -126,7 +126,7 @@ namespace IRaCIS.Core.API.Controllers
///
///
[HttpPost, Route("Inspection/ReadingMedicalReview/FinishMedicalReview")]
- [TrialGlobalLimit( "AfterStopCannNotOpt" )]
+ [TrialGlobalLimit("AfterStopCannNotOpt")]
[UnitOfWork]
public async Task FinishMedicalReview(DataInspectionDto opt)
@@ -143,7 +143,7 @@ namespace IRaCIS.Core.API.Controllers
///
///
[HttpPost, Route("Inspection/ReadingMedicineQuestion/ConfirmReadingMedicineQuestion")]
- [TrialGlobalLimit( "AfterStopCannNotOpt" )]
+ [TrialGlobalLimit("AfterStopCannNotOpt")]
[UnitOfWork]
public async Task ConfirmReadingMedicineQuestion(DataInspectionDto opt)
@@ -161,7 +161,7 @@ namespace IRaCIS.Core.API.Controllers
///
///
[HttpPost, Route("Inspection/ReadingImageTask/SubmitVisitTaskQuestions")]
- [TrialGlobalLimit( "AfterStopCannNotOpt" )]
+ [TrialGlobalLimit("AfterStopCannNotOpt")]
[UnitOfWork]
public async Task SubmitVisitTaskQuestions(DataInspectionDto opt)
@@ -179,7 +179,7 @@ namespace IRaCIS.Core.API.Controllers
///
///
[HttpPost, Route("Inspection/ClinicalAnswer/CRCSignClinicalData")]
- [TrialGlobalLimit( "AfterStopCannNotOpt" )]
+ [TrialGlobalLimit("AfterStopCannNotOpt")]
[UnitOfWork]
public async Task CRCSignClinicalData(DataInspectionDto opt)
@@ -197,7 +197,7 @@ namespace IRaCIS.Core.API.Controllers
///
///
[HttpPost, Route("Inspection/ClinicalAnswer/CRCConfirmClinical")]
- [TrialGlobalLimit( "AfterStopCannNotOpt" )]
+ [TrialGlobalLimit("AfterStopCannNotOpt")]
[UnitOfWork]
public async Task CRCConfirmClinical(DataInspectionDto opt)
@@ -214,7 +214,7 @@ namespace IRaCIS.Core.API.Controllers
///
///
[HttpPost, Route("Inspection/ClinicalAnswer/CRCCancelConfirmClinical")]
- [TrialGlobalLimit( "AfterStopCannNotOpt" )]
+ [TrialGlobalLimit("AfterStopCannNotOpt")]
[UnitOfWork]
public async Task CRCCancelConfirmClinical(DataInspectionDto opt)
@@ -232,7 +232,7 @@ namespace IRaCIS.Core.API.Controllers
///
///
[HttpPost, Route("Inspection/ClinicalAnswer/PMConfirmClinical")]
- [TrialGlobalLimit( "AfterStopCannNotOpt" )]
+ [TrialGlobalLimit("AfterStopCannNotOpt")]
[UnitOfWork]
public async Task PMConfirmClinical(DataInspectionDto opt)
@@ -250,7 +250,7 @@ namespace IRaCIS.Core.API.Controllers
///
///
[HttpPost, Route("Inspection/ReadingClinicalData/SignConsistencyAnalysisReadingClinicalData")]
- [TrialGlobalLimit( "AfterStopCannNotOpt" )]
+ [TrialGlobalLimit("AfterStopCannNotOpt")]
[UnitOfWork]
public async Task SignConsistencyAnalysisReadingClinicalData(DataInspectionDto opt)
@@ -267,7 +267,7 @@ namespace IRaCIS.Core.API.Controllers
///
///
[HttpPost, Route("Inspection/ClinicalAnswer/SubmitClinicalFormAndSign")]
- [TrialGlobalLimit( "AfterStopCannNotOpt" )]
+ [TrialGlobalLimit("AfterStopCannNotOpt")]
[UnitOfWork]
public async Task SubmitClinicalFormAndSign(DataInspectionDto opt)
@@ -284,7 +284,7 @@ namespace IRaCIS.Core.API.Controllers
///
///
[HttpPost, Route("Inspection/ReadingImageTask/SubmitJudgeVisitTaskResult")]
- [TrialGlobalLimit( "AfterStopCannNotOpt" )]
+ [TrialGlobalLimit("AfterStopCannNotOpt")]
[UnitOfWork]
public async Task SubmitJudgeVisitTaskResult(DataInspectionDto opt)
@@ -303,7 +303,7 @@ namespace IRaCIS.Core.API.Controllers
///
[HttpPost, Route("Inspection/configTrialBasicInfo/ConfigTrialBasicInfoConfirm")]
[UnitOfWork]
- [TrialGlobalLimit( "BeforeOngoingCantOpt" )]
+ [TrialGlobalLimit("BeforeOngoingCantOpt")]
public async Task ConfigTrialBasicInfoConfirm(DataInspectionDto opt)
{
@@ -345,7 +345,7 @@ namespace IRaCIS.Core.API.Controllers
///
[HttpPost, Route("Inspection/configTrialBasicInfo/ConfigTrialUrgentInfoConfirm")]
[UnitOfWork]
- [TrialGlobalLimit( "BeforeOngoingCantOpt" )]
+ [TrialGlobalLimit("BeforeOngoingCantOpt")]
public async Task ConfigTrialUrgentInfoConfirm(DataInspectionDto opt)
{
opt.Data.IsTrialUrgentConfirmed = true;
@@ -358,7 +358,7 @@ namespace IRaCIS.Core.API.Controllers
[HttpPost, Route("Inspection/configTrialBasicInfo/ConfigTrialPACSInfoConfirm")]
[UnitOfWork]
- [TrialGlobalLimit( "BeforeOngoingCantOpt" )]
+ [TrialGlobalLimit("BeforeOngoingCantOpt")]
public async Task ConfigTrialPACSInfoConfirm(DataInspectionDto opt)
{
opt.Data.IsTrialPACSConfirmed = true;
@@ -374,7 +374,7 @@ namespace IRaCIS.Core.API.Controllers
///
[HttpPost, Route("Inspection/configTrialBasicInfo/TrialConfigSignatureConfirm")]
[UnitOfWork]
- [TrialGlobalLimit( "AfterStopCannNotOpt" )]
+ [TrialGlobalLimit("AfterStopCannNotOpt")]
public async Task TrialConfigSignatureConfirm(DataInspectionDto opt)
{
@@ -391,7 +391,7 @@ namespace IRaCIS.Core.API.Controllers
///
[HttpPost, Route("Inspection/ReadingCriterion/ResetAndAsyncCriterion")]
[UnitOfWork]
- [TrialGlobalLimit( "AfterStopCannNotOpt" )]
+ [TrialGlobalLimit("AfterStopCannNotOpt")]
public async Task ResetAndAsyncCriterion(DataInspectionDto opt)
{
@@ -409,7 +409,7 @@ namespace IRaCIS.Core.API.Controllers
///
///
[HttpPost, Route("Inspection/QCOperation/CRCRequestToQC")]
- [TrialGlobalLimit( "AfterStopCannNotOpt" )]
+ [TrialGlobalLimit("AfterStopCannNotOpt")]
[UnitOfWork]
public async Task CRCRequestToQC(DataInspectionDto opt)
{
@@ -424,21 +424,31 @@ namespace IRaCIS.Core.API.Controllers
/// 设置QC 通过或者不通过 7:QC failed 8:QC passed
///
[HttpPost, Route("Inspection/QCOperation/QCPassedOrFailed")]
- [TrialGlobalLimit( "AfterStopCannNotOpt" )]
+ [TrialGlobalLimit("AfterStopCannNotOpt")]
[UnitOfWork]
public async Task QCPassedOrFailed(DataInspectionDto opt)
{
var singid = await _inspectionService.RecordSing(opt.SignInfo);
- var result = await _qCOperationService.QCPassedOrFailed(opt.Data.trialId, opt.Data.subjectVisitId, opt.Data.auditState);
- await _inspectionService.CompletedSign(singid, result);
- return result;
+ if (opt.Data.IsSecondPass != null)
+ {
+ var result = await _qCOperationService.QCSecondReviewPassedOrFailed(opt.Data.trialId, opt.Data.subjectVisitId, (bool)opt.Data.IsSecondPass);
+ await _inspectionService.CompletedSign(singid, result);
+ return result;
+ }
+ else
+ {
+ var result = await _qCOperationService.QCPassedOrFailed(opt.Data.trialId, opt.Data.subjectVisitId, opt.Data.auditState);
+ await _inspectionService.CompletedSign(singid, result);
+ return result;
+ }
+
}
///
/// 一致性核查 回退 对话记录不清除 只允许PM回退
///
[HttpPost, Route("Inspection/QCOperation/CheckBack")]
- [TrialGlobalLimit( "AfterStopCannNotOpt" )]
+ [TrialGlobalLimit("AfterStopCannNotOpt")]
[UnitOfWork]
public async Task CheckBack(DataInspectionDto opt)
{
@@ -455,7 +465,7 @@ namespace IRaCIS.Core.API.Controllers
///
///
[HttpPost, Route("Inspection/ReadClinicalData/ReadClinicalDataSign")]
- [TrialGlobalLimit( "AfterStopCannNotOpt" )]
+ [TrialGlobalLimit("AfterStopCannNotOpt")]
[UnitOfWork]
public async Task ReadClinicalDataSign(DataInspectionDto opt)
{
@@ -470,7 +480,7 @@ namespace IRaCIS.Core.API.Controllers
/// CRC 设置已经重传完成
///
[HttpPost, Route("Inspection/QCOperation/SetReuploadFinished")]
- [TrialGlobalLimit( "AfterStopCannNotOpt" )]
+ [TrialGlobalLimit("AfterStopCannNotOpt")]
[UnitOfWork]
public async Task SetReuploadFinished(DataInspectionDto opt)
{
@@ -486,7 +496,7 @@ namespace IRaCIS.Core.API.Controllers
///
///
[HttpPost, Route("Inspection/TrialConfig/updateTrialState")]
- [TrialGlobalLimit( "BeforeOngoingCantOpt")]
+ [TrialGlobalLimit("BeforeOngoingCantOpt")]
[UnitOfWork]
public async Task UpdateTrialState(DataInspectionDto opt)
{
@@ -502,7 +512,7 @@ namespace IRaCIS.Core.API.Controllers
///
///
[HttpPost, Route("Inspection/TrialDocument/userConfirm")]
- [TrialGlobalLimit( "BeforeOngoingCantOpt", "SignSystemDocNoTrialId", "AfterStopCannNotOpt" )]
+ [TrialGlobalLimit("BeforeOngoingCantOpt", "SignSystemDocNoTrialId", "AfterStopCannNotOpt")]
[UnitOfWork]
public async Task UserConfirm(DataInspectionDto opt)
{
@@ -519,10 +529,10 @@ namespace IRaCIS.Core.API.Controllers
///
///
[HttpPost, Route("Inspection/VisitTask/ConfirmReReading")]
- [TrialGlobalLimit( "AfterStopCannNotOpt" )]
+ [TrialGlobalLimit("AfterStopCannNotOpt")]
[UnitOfWork]
- public async Task ConfirmReReading(DataInspectionDto opt, [FromServices] IVisitTaskService _visitTaskService)
+ public async Task ConfirmReReading(DataInspectionDto opt, [FromServices] IVisitTaskService _visitTaskService)
{
var singId = await _inspectionService.RecordSing(opt.SignInfo);
var result = await _visitTaskService.ConfirmReReading(opt.Data);
diff --git a/IRaCIS.Core.Application/Service/Inspection/DTO/InspectionModel.cs b/IRaCIS.Core.Application/Service/Inspection/DTO/InspectionModel.cs
index 187c35e81..7d932a84d 100644
--- a/IRaCIS.Core.Application/Service/Inspection/DTO/InspectionModel.cs
+++ b/IRaCIS.Core.Application/Service/Inspection/DTO/InspectionModel.cs
@@ -199,6 +199,8 @@ namespace IRaCIS.Core.Application.Service.Inspection.DTO
public Guid subjectVisitId { get; set; }
public AuditStateEnum auditState { get; set; }
+
+ public bool? IsSecondPass { get; set; }
}
public class SetSeriesStateDto
diff --git a/IRaCIS.Core.Application/Service/QC/DTO/QARecordViewModel.cs b/IRaCIS.Core.Application/Service/QC/DTO/QARecordViewModel.cs
index f0a760fe5..3f34cfa0a 100644
--- a/IRaCIS.Core.Application/Service/QC/DTO/QARecordViewModel.cs
+++ b/IRaCIS.Core.Application/Service/QC/DTO/QARecordViewModel.cs
@@ -251,7 +251,13 @@ namespace IRaCIS.Core.Application.Contracts.DTO
}
-
+ public class SecondReviewDto
+ {
+ public DateTime? SecondReviewTime { get; set; }
+ public string FullName { get; set; }
+ public string UserName { get; set; }
+ public DateTime? SignTime { get; set; }
+ }
public class TrialVisitQADTO
@@ -270,7 +276,7 @@ namespace IRaCIS.Core.Application.Contracts.DTO
public QARelationInfo RelationInfo { get; set; } = new QARelationInfo();
- public List SecondReviewTimeList { get; set; }
+ public List SecondReviewList { get; set; }
}
diff --git a/IRaCIS.Core.Application/Service/QC/Interface/IQCOperationService.cs b/IRaCIS.Core.Application/Service/QC/Interface/IQCOperationService.cs
index 4b9093508..59d99ad3f 100644
--- a/IRaCIS.Core.Application/Service/QC/Interface/IQCOperationService.cs
+++ b/IRaCIS.Core.Application/Service/QC/Interface/IQCOperationService.cs
@@ -13,7 +13,7 @@ namespace IRaCIS.Core.Application.Image.QA
Task QCPassedOrFailed(Guid trialId, Guid subjectVisitId, [FromRoute] AuditStateEnum auditState);
Task SetCheckPass(SetCheckPassDt data);
-
+ Task QCSecondReviewPassedOrFailed(Guid trialId, Guid subjectVisitId, bool isSecondPass);
Task AddCheckChallengeReply(CheckChallengeDialogCommand checkDialogCommand);
diff --git a/IRaCIS.Core.Application/Service/QC/QCListService.cs b/IRaCIS.Core.Application/Service/QC/QCListService.cs
index 06755a396..c701f578f 100644
--- a/IRaCIS.Core.Application/Service/QC/QCListService.cs
+++ b/IRaCIS.Core.Application/Service/QC/QCListService.cs
@@ -410,29 +410,49 @@ namespace IRaCIS.Core.Application.Image.QA
var temp = await GetVisitQCStudyAndSeriesList(subjectVisitId);
- var qacheckList = await GetQCQuestionAnswerList(subjectVisitId, sv.TrialId, trialQCProcess, currentQCType);
+ //var qacheckList = await GetQCQuestionAnswerList(subjectVisitId, sv.TrialId, trialQCProcess, currentQCType);
+
+ List secondReviewList = new List();
- List secondReviewTimeList = new List();
if (sv.SecondReviewState != SecondReviewState.None)
{
- secondReviewTimeList = _trialQCQuestionAnswerRepository.Where(t => t.SubjectVisitId == subjectVisitId && t.CurrentQCEnum == CurrentQC.SecondReview).Where(t => t.SecondReviewTime != null)
- .Select(t => t.SecondReviewTime).Distinct().ToList();
-
var trialConfirmTime = _trialRepository.Where(t => t.Id == sv.TrialId).Select(t => t.QCQuestionConfirmedTime).FirstOrDefault();
+ secondReviewList = _trialQCQuestionAnswerRepository.Where(t => t.SubjectVisitId == subjectVisitId && t.CurrentQCEnum == CurrentQC.SecondReview).Where(t => t.SecondReviewTime != null)
+ .Select(t => new SecondReviewDto { SecondReviewTime = t.SecondReviewTime, SignTime = t.UpdateTime, FullName = t.UpdateUserRole.FullName, UserName = t.UpdateUserRole.UserName }).Distinct().ToList();
+
+ var secondReviewTimeList = secondReviewList.Select(t => t.SecondReviewTime).Distinct().ToList();
+
+ //首次加入
if (!secondReviewTimeList.Contains(trialConfirmTime))
{
- secondReviewTimeList.Add(trialConfirmTime);
+ secondReviewList.Add(new SecondReviewDto() { SecondReviewTime = trialConfirmTime });
}
-
+ else
+ {
+ if (sv.SecondReviewState == SecondReviewState.WaitAudit)
+ {
+ foreach (var item in secondReviewList)
+ {
+ if (item.SecondReviewTime == trialConfirmTime)
+ {
+ item.SignTime = null;
+ item.FullName = "";
+ item.UserName = "";
+ }
+ }
+ }
+ }
+ secondReviewList = secondReviewList.OrderByDescending(t => t.SecondReviewTime).ToList();
}
+
return new TrialVisitQADTO
{
- QCQuestionAnswerList = qacheckList,
+ //QCQuestionAnswerList = qacheckList,
- SecondReviewTimeList = secondReviewTimeList,
+ SecondReviewList = secondReviewList,
IsHaveStudyClinicalData = await _clinicalDataTrialSetRepository.AnyAsync(x => x.IsConfirm && x.TrialId == sv.TrialId && x.ClinicalDataLevel == ClinicalLevel.Study),
StudyList = temp.StudyList,
diff --git a/IRaCIS.Core.Application/Service/QC/QCOperationService.cs b/IRaCIS.Core.Application/Service/QC/QCOperationService.cs
index 704d3b11e..92fc776e0 100644
--- a/IRaCIS.Core.Application/Service/QC/QCOperationService.cs
+++ b/IRaCIS.Core.Application/Service/QC/QCOperationService.cs
@@ -727,9 +727,15 @@ namespace IRaCIS.Core.Application.Image.QA
//[Authorize(Policy = IRaCISPolicy.IQC)]
public async Task AddOrUpdateQCQuestionAnswerList(QCQuestionAnswerCommand[] qcQuestionAnswerCommands, Guid trialId, Guid subjectVisitId, [FromRoute] TrialQCProcess trialQCProcess, [FromRoute] CurrentQC currentQCType)
{
+ if (currentQCType == CurrentQC.SecondReview)
+ {
+ //二次复核自动领取,如果有人先领取了,那么后续不能操作
+ await _subjectVisitRepository.UpdatePartialFromQueryAsync(t => t.Id == subjectVisitId && t.CurrentActionUserId == null, u => new SubjectVisit() { CurrentActionUserId = _userInfo.UserRoleId });
+ }
//验证是否能操作
await VerifyIsCanQCAsync(null, subjectVisitId);
+
var trialConfirmTime = _trialRepository.Where(t => t.Id == trialId).Select(t => t.QCQuestionConfirmedTime).FirstOrDefault();
//更新
@@ -2081,8 +2087,43 @@ namespace IRaCIS.Core.Application.Image.QA
}
+ public async Task QCSecondReviewPassedOrFailed(Guid trialId, Guid subjectVisitId, bool isSecondPass)
+ {
+ if (!await _trialUserRoleRepository.AnyAsync(t => t.TrialId == trialId && t.UserId == _userInfo.UserRoleId))
+ {
+ //---您已经被移出项目,没有操作权限。
+ return ResponseOutput.NotOk(_localizer["QCOperation_RemoveItem"]);
+ }
+ var sv = await _subjectVisitRepository.FirstOrDefaultAsync(t => t.Id == subjectVisitId);
+
+ await VerifyIsCanQCAsync(sv);
+
+ var trialConfirmTime = _trialRepository.Where(t => t.Id == sv.TrialId).Select(t => t.QCQuestionConfirmedTime).FirstOrDefault();
+
+ if (sv.SecondReviewState == SecondReviewState.WaitAudit)
+ {
+ if (isSecondPass)
+ {
+ sv.SecondReviewState = SecondReviewState.AuditPassed;
+
+ }
+ else
+ {
+ sv.SecondReviewState = SecondReviewState.AuditFailed;
+ }
+
+ await _trialQCQuestionAnswerRepository.BatchUpdateNoTrackingAsync(t => t.SubjectVisitId == sv.Id && t.CurrentQCEnum == CurrentQC.SecondReview && t.SecondReviewTime == trialConfirmTime, u => new TrialQCQuestionAnswer()
+ {
+ UpdateUserId = _userInfo.UserRoleId,
+ UpdateTime = DateTime.Now
+ });
+ }
+ await _subjectVisitRepository.SaveChangesAsync();
+
+ return ResponseOutput.Ok();
+ }
///
/// 设置、取消 访视紧急
diff --git a/IRaCIS.Core.Domain/BaseModel/Entity.cs b/IRaCIS.Core.Domain/BaseModel/Entity.cs
index 55847a041..8fc614e3e 100644
--- a/IRaCIS.Core.Domain/BaseModel/Entity.cs
+++ b/IRaCIS.Core.Domain/BaseModel/Entity.cs
@@ -108,6 +108,11 @@ public abstract class BaseFullAuditEntity : Entity, IAuditUpdate, IAuditAdd
[ForeignKey("CreateUserId")]
[JsonIgnore]
public UserRole CreateUserRole { get; set; }
+
+
+ [ForeignKey("CreateUserId")]
+ [JsonIgnore]
+ public UserRole UpdateUserRole { get; set; }
}
public abstract class BaseFullDeleteAuditEntity : Entity, IAuditUpdate, IAuditAdd, ISoftDelete
{