Compare commits

...

14 Commits

Author SHA1 Message Date
hang a7394e7119 指派其他质控-uat-13
continuous-integration/drone/push Build is passing Details
2025-07-16 10:30:55 +08:00
hang a93d81de0d 指派其他质控-uat-12 2025-07-16 10:30:51 +08:00
hang 6aafe02c6c 指派其他质控-uat-11 2025-07-16 10:30:48 +08:00
hang 1511ef1608 修改QC复核 -二次提交-uat-10 2025-07-16 10:30:43 +08:00
hang 1141439c8e 修改QC复核 -二次提交-uat-9 2025-07-16 10:30:32 +08:00
hang 559663082b 修改QC复核 -二次提交-uat-8 2025-07-16 10:26:30 +08:00
hang 3a298518f9 修改QC复核 -二次提交-uat-7 2025-07-16 10:26:25 +08:00
hang 7f20232401 修改QC复核 -二次提交-uat-6 2025-07-16 10:26:21 +08:00
hang 20b0849b40 修改QC复核 -二次提交-uat-5 2025-07-16 10:26:16 +08:00
hang db951e9195 修改QC复核 -二次提交-uat-4 2025-07-16 10:26:13 +08:00
hang d5d78a99d2 QC复核 -二次提交-uat-3 2025-07-16 10:26:08 +08:00
hang 1609a7a88a QC复核 -二次提交-uat-3 2025-07-16 10:26:03 +08:00
hang 289831fce8 QC复核 -二次提交-uat-2 2025-07-16 10:25:59 +08:00
hang dde058be18 QC 审核提交--迁移uat 2025-07-16 10:25:26 +08:00
20 changed files with 293 additions and 48 deletions

View File

@ -52,7 +52,7 @@ namespace IRaCIS.Core.API.Controllers
/// <param name="opt"></param> /// <param name="opt"></param>
/// <returns></returns> /// <returns></returns>
[HttpPost, Route("Inspection/ReadingImageTask/SubmitOncologyReadingInfo")] [HttpPost, Route("Inspection/ReadingImageTask/SubmitOncologyReadingInfo")]
[TrialGlobalLimit( "AfterStopCannNotOpt" )] [TrialGlobalLimit("AfterStopCannNotOpt")]
[UnitOfWork] [UnitOfWork]
public async Task<IResponseOutput> SetOncologyReadingInfo(DataInspectionDto<SubmitOncologyReadingInfoInDto> opt) public async Task<IResponseOutput> SetOncologyReadingInfo(DataInspectionDto<SubmitOncologyReadingInfoInDto> opt)
@ -69,7 +69,7 @@ namespace IRaCIS.Core.API.Controllers
/// <param name="opt"></param> /// <param name="opt"></param>
/// <returns></returns> /// <returns></returns>
[HttpPost, Route("Inspection/ReadingImageTask/SubmitDicomVisitTask")] [HttpPost, Route("Inspection/ReadingImageTask/SubmitDicomVisitTask")]
[TrialGlobalLimit( "AfterStopCannNotOpt" )] [TrialGlobalLimit("AfterStopCannNotOpt")]
[UnitOfWork] [UnitOfWork]
public async Task<IResponseOutput> SubmitDicomVisitTask(DataInspectionDto<SubmitDicomVisitTaskInDto> opt) public async Task<IResponseOutput> SubmitDicomVisitTask(DataInspectionDto<SubmitDicomVisitTaskInDto> opt)
@ -88,7 +88,7 @@ namespace IRaCIS.Core.API.Controllers
/// <param name="opt"></param> /// <param name="opt"></param>
/// <returns></returns> /// <returns></returns>
[HttpPost, Route("Inspection/ReadingImageTask/SubmitGlobalReadingInfo")] [HttpPost, Route("Inspection/ReadingImageTask/SubmitGlobalReadingInfo")]
[TrialGlobalLimit( "AfterStopCannNotOpt" )] [TrialGlobalLimit("AfterStopCannNotOpt")]
[UnitOfWork] [UnitOfWork]
public async Task<IResponseOutput> SubmitGlobalReadingInfo(DataInspectionDto<SubmitGlobalReadingInfoInDto> opt) public async Task<IResponseOutput> SubmitGlobalReadingInfo(DataInspectionDto<SubmitGlobalReadingInfoInDto> opt)
@ -107,7 +107,7 @@ namespace IRaCIS.Core.API.Controllers
/// <param name="opt"></param> /// <param name="opt"></param>
/// <returns></returns> /// <returns></returns>
[HttpPost, Route("Inspection/configTrialBasicInfo/TrialReadingInfoSign")] [HttpPost, Route("Inspection/configTrialBasicInfo/TrialReadingInfoSign")]
[TrialGlobalLimit( "AfterStopCannNotOpt" )] [TrialGlobalLimit("AfterStopCannNotOpt")]
[UnitOfWork] [UnitOfWork]
public async Task<IResponseOutput> TrialReadingInfoSign(DataInspectionDto<TrialReadingInfoSignInDto> opt) public async Task<IResponseOutput> TrialReadingInfoSign(DataInspectionDto<TrialReadingInfoSignInDto> opt)
@ -126,7 +126,7 @@ namespace IRaCIS.Core.API.Controllers
/// <param name="opt"></param> /// <param name="opt"></param>
/// <returns></returns> /// <returns></returns>
[HttpPost, Route("Inspection/ReadingMedicalReview/FinishMedicalReview")] [HttpPost, Route("Inspection/ReadingMedicalReview/FinishMedicalReview")]
[TrialGlobalLimit( "AfterStopCannNotOpt" )] [TrialGlobalLimit("AfterStopCannNotOpt")]
[UnitOfWork] [UnitOfWork]
public async Task<IResponseOutput> FinishMedicalReview(DataInspectionDto<FinishMedicalReviewInDto> opt) public async Task<IResponseOutput> FinishMedicalReview(DataInspectionDto<FinishMedicalReviewInDto> opt)
@ -143,7 +143,7 @@ namespace IRaCIS.Core.API.Controllers
/// <param name="opt"></param> /// <param name="opt"></param>
/// <returns></returns> /// <returns></returns>
[HttpPost, Route("Inspection/ReadingMedicineQuestion/ConfirmReadingMedicineQuestion")] [HttpPost, Route("Inspection/ReadingMedicineQuestion/ConfirmReadingMedicineQuestion")]
[TrialGlobalLimit( "AfterStopCannNotOpt" )] [TrialGlobalLimit("AfterStopCannNotOpt")]
[UnitOfWork] [UnitOfWork]
public async Task<IResponseOutput> ConfirmReadingMedicineQuestion(DataInspectionDto<ConfirmReadingMedicineQuestionInDto> opt) public async Task<IResponseOutput> ConfirmReadingMedicineQuestion(DataInspectionDto<ConfirmReadingMedicineQuestionInDto> opt)
@ -161,7 +161,7 @@ namespace IRaCIS.Core.API.Controllers
/// <param name="opt"></param> /// <param name="opt"></param>
/// <returns></returns> /// <returns></returns>
[HttpPost, Route("Inspection/ReadingImageTask/SubmitVisitTaskQuestions")] [HttpPost, Route("Inspection/ReadingImageTask/SubmitVisitTaskQuestions")]
[TrialGlobalLimit( "AfterStopCannNotOpt" )] [TrialGlobalLimit("AfterStopCannNotOpt")]
[UnitOfWork] [UnitOfWork]
public async Task<IResponseOutput> SubmitVisitTaskQuestions(DataInspectionDto<SubmitVisitTaskQuestionsInDto> opt) public async Task<IResponseOutput> SubmitVisitTaskQuestions(DataInspectionDto<SubmitVisitTaskQuestionsInDto> opt)
@ -179,7 +179,7 @@ namespace IRaCIS.Core.API.Controllers
/// <param name="opt"></param> /// <param name="opt"></param>
/// <returns></returns> /// <returns></returns>
[HttpPost, Route("Inspection/ClinicalAnswer/CRCSignClinicalData")] [HttpPost, Route("Inspection/ClinicalAnswer/CRCSignClinicalData")]
[TrialGlobalLimit( "AfterStopCannNotOpt" )] [TrialGlobalLimit("AfterStopCannNotOpt")]
[UnitOfWork] [UnitOfWork]
public async Task<IResponseOutput> CRCSignClinicalData(DataInspectionDto<CRCSignClinicalDataInDto> opt) public async Task<IResponseOutput> CRCSignClinicalData(DataInspectionDto<CRCSignClinicalDataInDto> opt)
@ -197,7 +197,7 @@ namespace IRaCIS.Core.API.Controllers
/// <param name="opt"></param> /// <param name="opt"></param>
/// <returns></returns> /// <returns></returns>
[HttpPost, Route("Inspection/ClinicalAnswer/CRCConfirmClinical")] [HttpPost, Route("Inspection/ClinicalAnswer/CRCConfirmClinical")]
[TrialGlobalLimit( "AfterStopCannNotOpt" )] [TrialGlobalLimit("AfterStopCannNotOpt")]
[UnitOfWork] [UnitOfWork]
public async Task<IResponseOutput> CRCConfirmClinical(DataInspectionDto<CRCConfirmClinicalInDto> opt) public async Task<IResponseOutput> CRCConfirmClinical(DataInspectionDto<CRCConfirmClinicalInDto> opt)
@ -214,7 +214,7 @@ namespace IRaCIS.Core.API.Controllers
/// <param name="opt"></param> /// <param name="opt"></param>
/// <returns></returns> /// <returns></returns>
[HttpPost, Route("Inspection/ClinicalAnswer/CRCCancelConfirmClinical")] [HttpPost, Route("Inspection/ClinicalAnswer/CRCCancelConfirmClinical")]
[TrialGlobalLimit( "AfterStopCannNotOpt" )] [TrialGlobalLimit("AfterStopCannNotOpt")]
[UnitOfWork] [UnitOfWork]
public async Task<IResponseOutput> CRCCancelConfirmClinical(DataInspectionDto<CRCCancelConfirmClinicalInDto> opt) public async Task<IResponseOutput> CRCCancelConfirmClinical(DataInspectionDto<CRCCancelConfirmClinicalInDto> opt)
@ -232,7 +232,7 @@ namespace IRaCIS.Core.API.Controllers
/// <param name="opt"></param> /// <param name="opt"></param>
/// <returns></returns> /// <returns></returns>
[HttpPost, Route("Inspection/ClinicalAnswer/PMConfirmClinical")] [HttpPost, Route("Inspection/ClinicalAnswer/PMConfirmClinical")]
[TrialGlobalLimit( "AfterStopCannNotOpt" )] [TrialGlobalLimit("AfterStopCannNotOpt")]
[UnitOfWork] [UnitOfWork]
public async Task<IResponseOutput> PMConfirmClinical(DataInspectionDto<CRCConfirmClinicalInDto> opt) public async Task<IResponseOutput> PMConfirmClinical(DataInspectionDto<CRCConfirmClinicalInDto> opt)
@ -250,7 +250,7 @@ namespace IRaCIS.Core.API.Controllers
/// <param name="opt"></param> /// <param name="opt"></param>
/// <returns></returns> /// <returns></returns>
[HttpPost, Route("Inspection/ReadingClinicalData/SignConsistencyAnalysisReadingClinicalData")] [HttpPost, Route("Inspection/ReadingClinicalData/SignConsistencyAnalysisReadingClinicalData")]
[TrialGlobalLimit( "AfterStopCannNotOpt" )] [TrialGlobalLimit("AfterStopCannNotOpt")]
[UnitOfWork] [UnitOfWork]
public async Task<IResponseOutput> SignConsistencyAnalysisReadingClinicalData(DataInspectionDto<SignConsistencyAnalysisReadingClinicalDataInDto> opt) public async Task<IResponseOutput> SignConsistencyAnalysisReadingClinicalData(DataInspectionDto<SignConsistencyAnalysisReadingClinicalDataInDto> opt)
@ -267,7 +267,7 @@ namespace IRaCIS.Core.API.Controllers
/// <param name="opt"></param> /// <param name="opt"></param>
/// <returns></returns> /// <returns></returns>
[HttpPost, Route("Inspection/ClinicalAnswer/SubmitClinicalFormAndSign")] [HttpPost, Route("Inspection/ClinicalAnswer/SubmitClinicalFormAndSign")]
[TrialGlobalLimit( "AfterStopCannNotOpt" )] [TrialGlobalLimit("AfterStopCannNotOpt")]
[UnitOfWork] [UnitOfWork]
public async Task<IResponseOutput> SubmitClinicalFormAndSign(DataInspectionDto<SubmitClinicalFormInDto> opt) public async Task<IResponseOutput> SubmitClinicalFormAndSign(DataInspectionDto<SubmitClinicalFormInDto> opt)
@ -284,7 +284,7 @@ namespace IRaCIS.Core.API.Controllers
/// <param name="opt"></param> /// <param name="opt"></param>
/// <returns></returns> /// <returns></returns>
[HttpPost, Route("Inspection/ReadingImageTask/SubmitJudgeVisitTaskResult")] [HttpPost, Route("Inspection/ReadingImageTask/SubmitJudgeVisitTaskResult")]
[TrialGlobalLimit( "AfterStopCannNotOpt" )] [TrialGlobalLimit("AfterStopCannNotOpt")]
[UnitOfWork] [UnitOfWork]
public async Task<IResponseOutput> SubmitJudgeVisitTaskResult(DataInspectionDto<SaveJudgeVisitTaskResult> opt) public async Task<IResponseOutput> SubmitJudgeVisitTaskResult(DataInspectionDto<SaveJudgeVisitTaskResult> opt)
@ -303,7 +303,7 @@ namespace IRaCIS.Core.API.Controllers
/// <returns></returns> /// <returns></returns>
[HttpPost, Route("Inspection/configTrialBasicInfo/ConfigTrialBasicInfoConfirm")] [HttpPost, Route("Inspection/configTrialBasicInfo/ConfigTrialBasicInfoConfirm")]
[UnitOfWork] [UnitOfWork]
[TrialGlobalLimit( "BeforeOngoingCantOpt" )] [TrialGlobalLimit("BeforeOngoingCantOpt")]
public async Task<IResponseOutput> ConfigTrialBasicInfoConfirm(DataInspectionDto<BasicTrialConfig> opt) public async Task<IResponseOutput> ConfigTrialBasicInfoConfirm(DataInspectionDto<BasicTrialConfig> opt)
{ {
@ -345,7 +345,7 @@ namespace IRaCIS.Core.API.Controllers
/// <returns></returns> /// <returns></returns>
[HttpPost, Route("Inspection/configTrialBasicInfo/ConfigTrialUrgentInfoConfirm")] [HttpPost, Route("Inspection/configTrialBasicInfo/ConfigTrialUrgentInfoConfirm")]
[UnitOfWork] [UnitOfWork]
[TrialGlobalLimit( "BeforeOngoingCantOpt" )] [TrialGlobalLimit("BeforeOngoingCantOpt")]
public async Task<IResponseOutput> ConfigTrialUrgentInfoConfirm(DataInspectionDto<TrialUrgentConfig> opt) public async Task<IResponseOutput> ConfigTrialUrgentInfoConfirm(DataInspectionDto<TrialUrgentConfig> opt)
{ {
opt.Data.IsTrialUrgentConfirmed = true; opt.Data.IsTrialUrgentConfirmed = true;
@ -358,7 +358,7 @@ namespace IRaCIS.Core.API.Controllers
[HttpPost, Route("Inspection/configTrialBasicInfo/ConfigTrialPACSInfoConfirm")] [HttpPost, Route("Inspection/configTrialBasicInfo/ConfigTrialPACSInfoConfirm")]
[UnitOfWork] [UnitOfWork]
[TrialGlobalLimit( "BeforeOngoingCantOpt" )] [TrialGlobalLimit("BeforeOngoingCantOpt")]
public async Task<IResponseOutput> ConfigTrialPACSInfoConfirm(DataInspectionDto<TrialPACSConfig> opt) public async Task<IResponseOutput> ConfigTrialPACSInfoConfirm(DataInspectionDto<TrialPACSConfig> opt)
{ {
opt.Data.IsTrialPACSConfirmed = true; opt.Data.IsTrialPACSConfirmed = true;
@ -374,7 +374,7 @@ namespace IRaCIS.Core.API.Controllers
/// <returns></returns> /// <returns></returns>
[HttpPost, Route("Inspection/configTrialBasicInfo/TrialConfigSignatureConfirm")] [HttpPost, Route("Inspection/configTrialBasicInfo/TrialConfigSignatureConfirm")]
[UnitOfWork] [UnitOfWork]
[TrialGlobalLimit( "AfterStopCannNotOpt" )] [TrialGlobalLimit("AfterStopCannNotOpt")]
public async Task<IResponseOutput> TrialConfigSignatureConfirm(DataInspectionDto<SignConfirmDTO> opt) public async Task<IResponseOutput> TrialConfigSignatureConfirm(DataInspectionDto<SignConfirmDTO> opt)
{ {
@ -391,7 +391,7 @@ namespace IRaCIS.Core.API.Controllers
/// <returns></returns> /// <returns></returns>
[HttpPost, Route("Inspection/ReadingCriterion/ResetAndAsyncCriterion")] [HttpPost, Route("Inspection/ReadingCriterion/ResetAndAsyncCriterion")]
[UnitOfWork] [UnitOfWork]
[TrialGlobalLimit( "AfterStopCannNotOpt" )] [TrialGlobalLimit("AfterStopCannNotOpt")]
public async Task<IResponseOutput> ResetAndAsyncCriterion(DataInspectionDto<ResetAndAsyncCriterionInDto> opt) public async Task<IResponseOutput> ResetAndAsyncCriterion(DataInspectionDto<ResetAndAsyncCriterionInDto> opt)
{ {
@ -409,7 +409,7 @@ namespace IRaCIS.Core.API.Controllers
/// <param name="opt"></param> /// <param name="opt"></param>
/// <returns></returns> /// <returns></returns>
[HttpPost, Route("Inspection/QCOperation/CRCRequestToQC")] [HttpPost, Route("Inspection/QCOperation/CRCRequestToQC")]
[TrialGlobalLimit( "AfterStopCannNotOpt" )] [TrialGlobalLimit("AfterStopCannNotOpt")]
[UnitOfWork] [UnitOfWork]
public async Task<IResponseOutput> CRCRequestToQC(DataInspectionDto<CRCRequestToQCCommand> opt) public async Task<IResponseOutput> CRCRequestToQC(DataInspectionDto<CRCRequestToQCCommand> opt)
{ {
@ -424,21 +424,31 @@ namespace IRaCIS.Core.API.Controllers
/// 设置QC 通过或者不通过 7:QC failed 8QC passed /// 设置QC 通过或者不通过 7:QC failed 8QC passed
/// </summary> /// </summary>
[HttpPost, Route("Inspection/QCOperation/QCPassedOrFailed")] [HttpPost, Route("Inspection/QCOperation/QCPassedOrFailed")]
[TrialGlobalLimit( "AfterStopCannNotOpt" )] [TrialGlobalLimit("AfterStopCannNotOpt")]
[UnitOfWork] [UnitOfWork]
public async Task<IResponseOutput> QCPassedOrFailed(DataInspectionDto<QCPassedOrFailedDto> opt) public async Task<IResponseOutput> QCPassedOrFailed(DataInspectionDto<QCPassedOrFailedDto> opt)
{ {
var singid = await _inspectionService.RecordSing(opt.SignInfo); var singid = await _inspectionService.RecordSing(opt.SignInfo);
var result = await _qCOperationService.QCPassedOrFailed(opt.Data.trialId, opt.Data.subjectVisitId, opt.Data.auditState); if (opt.Data.IsSecondPass != null)
await _inspectionService.CompletedSign(singid, result); {
return result; 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;
}
} }
/// <summary> /// <summary>
/// 一致性核查 回退 对话记录不清除 只允许PM回退 /// 一致性核查 回退 对话记录不清除 只允许PM回退
/// </summary> /// </summary>
[HttpPost, Route("Inspection/QCOperation/CheckBack")] [HttpPost, Route("Inspection/QCOperation/CheckBack")]
[TrialGlobalLimit( "AfterStopCannNotOpt" )] [TrialGlobalLimit("AfterStopCannNotOpt")]
[UnitOfWork] [UnitOfWork]
public async Task<IResponseOutput> CheckBack(DataInspectionDto<IDDto> opt) public async Task<IResponseOutput> CheckBack(DataInspectionDto<IDDto> opt)
{ {
@ -455,7 +465,7 @@ namespace IRaCIS.Core.API.Controllers
/// <param name="opt"></param> /// <param name="opt"></param>
/// <returns></returns> /// <returns></returns>
[HttpPost, Route("Inspection/ReadClinicalData/ReadClinicalDataSign")] [HttpPost, Route("Inspection/ReadClinicalData/ReadClinicalDataSign")]
[TrialGlobalLimit( "AfterStopCannNotOpt" )] [TrialGlobalLimit("AfterStopCannNotOpt")]
[UnitOfWork] [UnitOfWork]
public async Task<IResponseOutput> ReadClinicalDataSign(DataInspectionDto<ReadingClinicalDataSignIndto> opt) public async Task<IResponseOutput> ReadClinicalDataSign(DataInspectionDto<ReadingClinicalDataSignIndto> opt)
{ {
@ -470,7 +480,7 @@ namespace IRaCIS.Core.API.Controllers
/// CRC 设置已经重传完成 /// CRC 设置已经重传完成
/// </summary> /// </summary>
[HttpPost, Route("Inspection/QCOperation/SetReuploadFinished")] [HttpPost, Route("Inspection/QCOperation/SetReuploadFinished")]
[TrialGlobalLimit( "AfterStopCannNotOpt" )] [TrialGlobalLimit("AfterStopCannNotOpt")]
[UnitOfWork] [UnitOfWork]
public async Task<IResponseOutput> SetReuploadFinished(DataInspectionDto<CRCReuploadFinishedCommand> opt) public async Task<IResponseOutput> SetReuploadFinished(DataInspectionDto<CRCReuploadFinishedCommand> opt)
{ {
@ -486,7 +496,7 @@ namespace IRaCIS.Core.API.Controllers
/// <param name="opt"></param> /// <param name="opt"></param>
/// <returns></returns> /// <returns></returns>
[HttpPost, Route("Inspection/TrialConfig/updateTrialState")] [HttpPost, Route("Inspection/TrialConfig/updateTrialState")]
[TrialGlobalLimit( "BeforeOngoingCantOpt")] [TrialGlobalLimit("BeforeOngoingCantOpt")]
[UnitOfWork] [UnitOfWork]
public async Task<IResponseOutput> UpdateTrialState(DataInspectionDto<UpdateTrialStateDto> opt) public async Task<IResponseOutput> UpdateTrialState(DataInspectionDto<UpdateTrialStateDto> opt)
{ {
@ -502,7 +512,7 @@ namespace IRaCIS.Core.API.Controllers
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
[HttpPost, Route("Inspection/TrialDocument/userConfirm")] [HttpPost, Route("Inspection/TrialDocument/userConfirm")]
[TrialGlobalLimit( "BeforeOngoingCantOpt", "SignSystemDocNoTrialId", "AfterStopCannNotOpt" )] [TrialGlobalLimit("BeforeOngoingCantOpt", "SignSystemDocNoTrialId", "AfterStopCannNotOpt")]
[UnitOfWork] [UnitOfWork]
public async Task<IResponseOutput> UserConfirm(DataInspectionDto<UserConfirmCommand> opt) public async Task<IResponseOutput> UserConfirm(DataInspectionDto<UserConfirmCommand> opt)
{ {
@ -519,10 +529,10 @@ namespace IRaCIS.Core.API.Controllers
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
[HttpPost, Route("Inspection/VisitTask/ConfirmReReading")] [HttpPost, Route("Inspection/VisitTask/ConfirmReReading")]
[TrialGlobalLimit( "AfterStopCannNotOpt" )] [TrialGlobalLimit("AfterStopCannNotOpt")]
[UnitOfWork] [UnitOfWork]
public async Task<IResponseOutput> ConfirmReReading(DataInspectionDto<ConfirmReReadingCommand> opt, [FromServices] IVisitTaskService _visitTaskService) public async Task<IResponseOutput> ConfirmReReading(DataInspectionDto<ConfirmReReadingCommand> opt, [FromServices] IVisitTaskService _visitTaskService)
{ {
var singId = await _inspectionService.RecordSing(opt.SignInfo); var singId = await _inspectionService.RecordSing(opt.SignInfo);
var result = await _visitTaskService.ConfirmReReading(opt.Data); var result = await _visitTaskService.ConfirmReReading(opt.Data);

View File

@ -1116,7 +1116,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
HtmlPath = k.HtmlPath, HtmlPath = k.HtmlPath,
Path = k.Path, Path = k.Path,
InstanceNumber = k.InstanceNumber, InstanceNumber = k.InstanceNumber,
FileSize=k.FileSize,
}).ToList() }).ToList()
}) })
}); });

View File

@ -199,6 +199,8 @@ namespace IRaCIS.Core.Application.Service.Inspection.DTO
public Guid subjectVisitId { get; set; } public Guid subjectVisitId { get; set; }
public AuditStateEnum auditState { get; set; } public AuditStateEnum auditState { get; set; }
public bool? IsSecondPass { get; set; }
} }
public class SetSeriesStateDto public class SetSeriesStateDto

View File

@ -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 public class TrialVisitQADTO
@ -270,6 +276,7 @@ namespace IRaCIS.Core.Application.Contracts.DTO
public QARelationInfo RelationInfo { get; set; } = new QARelationInfo(); public QARelationInfo RelationInfo { get; set; } = new QARelationInfo();
public List<SecondReviewDto> SecondReviewList { get; set; }
} }

View File

@ -1949,6 +1949,7 @@ namespace IRaCIS.Core.Application.Contracts
public class QCQuestionAnswer public class QCQuestionAnswer
{ {
public Guid? AnswerId { get; set; }
public Guid Id { get; set; } public Guid Id { get; set; }
public string QuestionName { get; set; } = String.Empty; public string QuestionName { get; set; } = String.Empty;
public bool IsRequired { get; set; } public bool IsRequired { get; set; }
@ -1977,6 +1978,8 @@ namespace IRaCIS.Core.Application.Contracts
// 1代表第一个人QC数据 2 代表第二个人QC数据 // 1代表第一个人QC数据 2 代表第二个人QC数据
public CurrentQC CurrentQCEnum { get; set; } public CurrentQC CurrentQCEnum { get; set; }
public DateTime? SecondReviewTime { get; set; }
} }
public class ForwardQuery : PageInput public class ForwardQuery : PageInput
@ -2130,6 +2133,8 @@ namespace IRaCIS.Core.Application.Contracts
public class QCVisitBasicListViewModel public class QCVisitBasicListViewModel
{ {
public SecondReviewState SecondReviewState { get; set; }
public bool IsSubjectQuit { get; set; }
public ChallengeStateEnum ChallengeState { get; set; } public ChallengeStateEnum ChallengeState { get; set; }
public bool? IsConfirmedClinicalData { get; set; } public bool? IsConfirmedClinicalData { get; set; }
public bool IsQCConfirmedReupload { get; set; } public bool IsQCConfirmedReupload { get; set; }

View File

@ -35,6 +35,8 @@ namespace IRaCIS.Core.Application.Contracts
public DateTime UpdateTime { get; set; } public DateTime UpdateTime { get; set; }
public Guid UpdateUserId { get; set; } public Guid UpdateUserId { get; set; }
public bool IsQuestionQCAuditPassed { get; set; }
} }
public class QCQuestionFilterSelect public class QCQuestionFilterSelect

View File

@ -13,7 +13,7 @@ namespace IRaCIS.Core.Application.Image.QA
Task<IResponseOutput> QCPassedOrFailed(Guid trialId, Guid subjectVisitId, [FromRoute] AuditStateEnum auditState); Task<IResponseOutput> QCPassedOrFailed(Guid trialId, Guid subjectVisitId, [FromRoute] AuditStateEnum auditState);
Task<IResponseOutput> SetCheckPass(SetCheckPassDt data); Task<IResponseOutput> SetCheckPass(SetCheckPassDt data);
Task<IResponseOutput> QCSecondReviewPassedOrFailed(Guid trialId, Guid subjectVisitId, bool isSecondPass);
Task<IResponseOutput> AddCheckChallengeReply(CheckChallengeDialogCommand checkDialogCommand); Task<IResponseOutput> AddCheckChallengeReply(CheckChallengeDialogCommand checkDialogCommand);

View File

@ -7,6 +7,8 @@ using IRaCIS.Core.Infrastructure;
using IRaCIS.Core.Infrastructure.Extention; using IRaCIS.Core.Infrastructure.Extention;
using MassTransit.Initializers; using MassTransit.Initializers;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using NPOI.SS.Formula.Functions;
using System.Linq;
namespace IRaCIS.Core.Application.Image.QA namespace IRaCIS.Core.Application.Image.QA
{ {
@ -24,6 +26,7 @@ namespace IRaCIS.Core.Application.Image.QA
IRepository<NoneDicomStudy> _noneDicomStudyRepository, IRepository<NoneDicomStudy> _noneDicomStudyRepository,
IRepository<QCChallenge> _qcChallengeRepository, IRepository<QCChallenge> _qcChallengeRepository,
IRepository<SubjectVisitImageBackRecord> _subjectVisitImageBackRecordReposiotry, IRepository<SubjectVisitImageBackRecord> _subjectVisitImageBackRecordReposiotry,
IRepository<UserRole> _userRoleReposiotry,
IReadingImageTaskService _IReadingImageTaskService, IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer) : BaseService, IQCListService IReadingImageTaskService _IReadingImageTaskService, IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer) : BaseService, IQCListService
{ {
@ -409,10 +412,50 @@ namespace IRaCIS.Core.Application.Image.QA
var qacheckList = await GetQCQuestionAnswerList(subjectVisitId, sv.TrialId, trialQCProcess, currentQCType); var qacheckList = await GetQCQuestionAnswerList(subjectVisitId, sv.TrialId, trialQCProcess, currentQCType);
List<SecondReviewDto> secondReviewList = new List<SecondReviewDto>();
if (sv.SecondReviewState != SecondReviewState.None)
{
var trialConfirmTime = _trialRepository.Where(t => t.Id == sv.TrialId).Select(t => t.QCQuestionConfirmedTime).FirstOrDefault();
secondReviewList = (from answer in _trialQCQuestionAnswerRepository.Where(t => t.SubjectVisitId == subjectVisitId && t.CurrentQCEnum == CurrentQC.SecondReview).Where(t => t.SecondReviewTime != null)
join userRole in _userRoleReposiotry.Where() on answer.UpdateUserId equals userRole.Id
select new SecondReviewDto { SecondReviewTime = answer.SecondReviewTime, SignTime = answer.UpdateTime, FullName = userRole.FullName, UserName = userRole.UserName })
.Distinct().ToList();
var secondReviewTimeList = secondReviewList.Select(t => t.SecondReviewTime).Distinct().ToList();
//首次加入
if (!secondReviewTimeList.Contains(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 return new TrialVisitQADTO
{ {
QCQuestionAnswerList = qacheckList, QCQuestionAnswerList = qacheckList,
SecondReviewList = secondReviewList,
IsHaveStudyClinicalData = await _clinicalDataTrialSetRepository.AnyAsync(x => x.IsConfirm && x.TrialId == sv.TrialId && x.ClinicalDataLevel == ClinicalLevel.Study), IsHaveStudyClinicalData = await _clinicalDataTrialSetRepository.AnyAsync(x => x.IsConfirm && x.TrialId == sv.TrialId && x.ClinicalDataLevel == ClinicalLevel.Study),
StudyList = temp.StudyList, StudyList = temp.StudyList,
ExistsManual = (await _IReadingImageTaskService.GetManualList(new GetManualListInDto() { TrialId = sv.TrialId })).Count() > 0, ExistsManual = (await _IReadingImageTaskService.GetManualList(new GetManualListInDto() { TrialId = sv.TrialId })).Count() > 0,
@ -432,11 +475,50 @@ namespace IRaCIS.Core.Application.Image.QA
[HttpPost] [HttpPost]
public async Task<List<QCQuestionAnswer>> GetQCQuestionAnswer(GetQCQuestionAnswerInDto inDto) public async Task<List<QCQuestionAnswer>> GetQCQuestionAnswer(GetQCQuestionAnswerInDto inDto)
{ {
var questionAnswerlist = await (from data in _trialQCQuestionRepository.Where(x => x.TrialId == inDto.TrialId && x.IsEnable) var subjectVisitId = inDto.SubjectVisitId;
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
List<QCQuestionAnswer> questionAnswerlist = new List<QCQuestionAnswer>();
//判断当前访视质控是否完成,再判断复审是完成查看,还是添加编辑
var sv = await _subjectVisitRepository.Where(t => t.Id == subjectVisitId).FirstNotNullAsync();
if (sv.SecondReviewState == SecondReviewState.None && sv.AuditState == AuditStateEnum.QCPassed)
{
//现在之前历史质控的展示要从答案为主表取数据,添加和编辑按照之前方式
questionAnswerlist = await _trialQCQuestionAnswerRepository.Where(x => x.SubjectVisitId == inDto.SubjectVisitId && x.QCProcessEnum == inDto.QCProcessEnum && x.CurrentQCEnum == inDto.CurrentQCEnum)
.Select(data => new QCQuestionAnswer()
{
AnswerId=data.Id,
Answer = data.Answer,
ShowOrder = data.TrialQCQuestionConfigure.ShowOrder,
QuestionName = data.TrialQCQuestionConfigure.QuestionName,
Id = data.TrialQCQuestionConfigure.Id,
IsRequired = data.TrialQCQuestionConfigure.IsRequired,
ParentId = data.TrialQCQuestionConfigure.ParentId,
ParentTriggerValue = data.TrialQCQuestionConfigure.ParentTriggerValue,
Type = data.TrialQCQuestionConfigure.Type,
TypeValue = data.TrialQCQuestionConfigure.TypeValue
}).OrderBy(t => t.ShowOrder).ToListAsync();
}
else
{
var secondReviewTime = inDto.SecondReviewTime != null ? (DateTime)inDto.SecondReviewTime : DateTime.Now;
#region 之前编辑和审核通过后展示都是通过这个接口
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)
.Where(t => inDto.CurrentQCEnum == CurrentQC.SecondReview ? t.SecondReviewTime >= secondReviewTime && t.SecondReviewTime <= secondReviewTime.AddSeconds(1) : true)
on data.Id equals answer.TrialQCQuestionConfigureId into answertemp
from leftanswer in answertemp.DefaultIfEmpty() from leftanswer in answertemp.DefaultIfEmpty()
select new QCQuestionAnswer() select new QCQuestionAnswer()
{ {
AnswerId= leftanswer.Id,
Answer = leftanswer.Answer, Answer = leftanswer.Answer,
ShowOrder = data.ShowOrder, ShowOrder = data.ShowOrder,
QuestionName = data.QuestionName, QuestionName = data.QuestionName,
@ -447,6 +529,17 @@ namespace IRaCIS.Core.Application.Image.QA
Type = data.Type, Type = data.Type,
TypeValue = data.TypeValue TypeValue = data.TypeValue
}).OrderBy(t => t.ShowOrder).ToListAsync(); }).OrderBy(t => t.ShowOrder).ToListAsync();
#endregion
}
var result = questionAnswerlist.Where(x => x.ParentId == null).OrderBy(t => t.ShowOrder).ToList(); var result = questionAnswerlist.Where(x => x.ParentId == null).OrderBy(t => t.ShowOrder).ToList();
result.ForEach(x => result.ForEach(x =>

View File

@ -727,9 +727,17 @@ namespace IRaCIS.Core.Application.Image.QA
//[Authorize(Policy = IRaCISPolicy.IQC)] //[Authorize(Policy = IRaCISPolicy.IQC)]
public async Task<IResponseOutput> AddOrUpdateQCQuestionAnswerList(QCQuestionAnswerCommand[] qcQuestionAnswerCommands, Guid trialId, Guid subjectVisitId, [FromRoute] TrialQCProcess trialQCProcess, [FromRoute] CurrentQC currentQCType) public async Task<IResponseOutput> 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 }, true);
}
//验证是否能操作 //验证是否能操作
await VerifyIsCanQCAsync(null, subjectVisitId); await VerifyIsCanQCAsync(null, subjectVisitId);
var trialConfirmTime = _trialRepository.Where(t => t.Id == trialId).Select(t => t.QCQuestionConfirmedTime).FirstOrDefault();
//更新 //更新
if (qcQuestionAnswerCommands.Any(t => t.Id != null)) if (qcQuestionAnswerCommands.Any(t => t.Id != null))
{ {
@ -774,11 +782,13 @@ namespace IRaCIS.Core.Application.Image.QA
{ {
var addlist = _mapper.Map<List<TrialQCQuestionAnswer>>(qcQuestionAnswerCommands); var addlist = _mapper.Map<List<TrialQCQuestionAnswer>>(qcQuestionAnswerCommands);
addlist.ForEach(t => { t.TrialId = trialId; t.SubjectVisitId = subjectVisitId; t.CurrentQCEnum = currentQCType; t.QCProcessEnum = trialQCProcess; });
addlist.ForEach(t => { t.TrialId = trialId; t.SubjectVisitId = subjectVisitId; t.CurrentQCEnum = currentQCType; t.QCProcessEnum = trialQCProcess; t.SecondReviewTime = currentQCType == CurrentQC.SecondReview ? trialConfirmTime : null; });
await _trialQCQuestionAnswerRepository.AddRangeAsync(addlist); await _trialQCQuestionAnswerRepository.AddRangeAsync(addlist);
return ResponseOutput.Result(await _trialQCQuestionAnswerRepository.SaveChangesAsync()); return ResponseOutput.Ok(await _trialQCQuestionAnswerRepository.SaveChangesAsync());
} }
@ -1173,7 +1183,7 @@ namespace IRaCIS.Core.Application.Image.QA
[HttpPut("{trialId:guid}/{subjectVisitId:guid}")] [HttpPut("{trialId:guid}/{subjectVisitId:guid}")]
//[Authorize(Policy = IRaCISPolicy.IQC)] //[Authorize(Policy = IRaCISPolicy.IQC)]
[TrialGlobalLimit("AfterStopCannNotOpt")] [TrialGlobalLimit("AfterStopCannNotOpt")]
public async Task<IResponseOutput> ReplaceQCTaskActionUser(Guid trialId, Guid subjectVisitId) public async Task<IResponseOutput> ReplaceQCTaskActionUser(Guid trialId, Guid subjectVisitId, Guid? replaceUserRoleId)
{ {
var dbSubjectVisit = (await _subjectVisitRepository.FirstOrDefaultAsync(t => t.Id == subjectVisitId)).IfNullThrowException(); var dbSubjectVisit = (await _subjectVisitRepository.FirstOrDefaultAsync(t => t.Id == subjectVisitId)).IfNullThrowException();
@ -1187,7 +1197,7 @@ namespace IRaCIS.Core.Application.Image.QA
dbSubjectVisit.IsTake = true; dbSubjectVisit.IsTake = true;
dbSubjectVisit.CurrentActionUserId = _userInfo.UserRoleId; dbSubjectVisit.CurrentActionUserId = replaceUserRoleId == null || replaceUserRoleId == Guid.Empty ? _userInfo.UserRoleId : replaceUserRoleId;
dbSubjectVisit.CurrentActionUserExpireTime = DateTime.Now.AddHours(1); dbSubjectVisit.CurrentActionUserExpireTime = DateTime.Now.AddHours(1);
@ -2077,8 +2087,43 @@ namespace IRaCIS.Core.Application.Image.QA
} }
public async Task<IResponseOutput> 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();
}
/// <summary> /// <summary>
/// 设置、取消 访视紧急 /// 设置、取消 访视紧急

View File

@ -472,6 +472,7 @@ namespace IRaCIS.Core.Application.Service
CreateMap<TrialQCQuestion, TrialQCQuestionAddOrEdit>(); CreateMap<TrialQCQuestion, TrialQCQuestionAddOrEdit>();
CreateMap<TrialQCQuestion, TrialQCQuestionConfigureView>() CreateMap<TrialQCQuestion, TrialQCQuestionConfigureView>()
.ForMember(d => d.IsQuestionQCAuditPassed, u => u.MapFrom(s => s.TrialQCQuestionAnswerList.Any(c => c.TrialQCQuestionConfigureId == s.Id && c.SubjectVisit.AuditState == AuditStateEnum.QCPassed)))
.ForMember(d => d.ParentShowOrder, u => u.MapFrom(s => s.ParentQCQuestion.ShowOrder)); .ForMember(d => d.ParentShowOrder, u => u.MapFrom(s => s.ParentQCQuestion.ShowOrder));
CreateMap<TrialQCQuestionSelect, TrialQCQuestionConfigureView>(); CreateMap<TrialQCQuestionSelect, TrialQCQuestionConfigureView>();

View File

@ -139,5 +139,16 @@ namespace IRaCIS.Core.Application.Contracts.DTO
} }
public class TrialSelectUserBasicInfo
{
public Guid UserRoleId { get; set; }
public string FullName { get; set; }
public string UserName { get; set; }
public string Email { get; set; }
public string Phone { get; set; }
}
} }

View File

@ -6,6 +6,7 @@ using IRaCIS.Core.Application.Helper;
using IRaCIS.Core.Application.Interfaces; using IRaCIS.Core.Application.Interfaces;
using IRaCIS.Core.Application.Service.Reading.Dto; using IRaCIS.Core.Application.Service.Reading.Dto;
using IRaCIS.Core.Application.ViewModel; using IRaCIS.Core.Application.ViewModel;
using IRaCIS.Core.Domain.Models;
using IRaCIS.Core.Domain.Share; using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Infra.EFCore.Common; using IRaCIS.Core.Infra.EFCore.Common;
using IRaCIS.Core.Infrastructure; using IRaCIS.Core.Infrastructure;
@ -41,6 +42,7 @@ namespace IRaCIS.Core.Application
IRepository<SystemBasicData> _systemBasicDataRepository, IRepository<SystemBasicData> _systemBasicDataRepository,
IRepository<SubjectVisit> _subjectVisitRepository, IRepository<SubjectVisit> _subjectVisitRepository,
IRepository<Enroll> _enrollRepository, IRepository<Enroll> _enrollRepository,
IRepository<TrialQCQuestionAnswer> _qcQuestionAnswerRepository,
IRepository<TrialStateChange> _trialStateChangeRepository, IRepository<TrialStateChange> _trialStateChangeRepository,
IRepository<ReadingTableQuestionTrial> _readingTableQuestionTrialRepository, IRepository<ReadingTableQuestionTrial> _readingTableQuestionTrialRepository,
IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer, IFusionCache _fusionCache) : BaseService, ITrialConfigService IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer, IFusionCache _fusionCache) : BaseService, ITrialConfigService
@ -837,9 +839,22 @@ namespace IRaCIS.Core.Application
{ {
await _trialRepository.UpdatePartialFromQueryAsync(t => t.Id == signConfirmDTO.TrialId, u => new Trial() { IsTrialUrgentConfirmed = true }); await _trialRepository.UpdatePartialFromQueryAsync(t => t.Id == signConfirmDTO.TrialId, u => new Trial() { IsTrialUrgentConfirmed = true });
} }
else else if (signConfirmDTO.SignCode == ((int)SignEnum.TrialQCQuestionConfirmUpdate).ToString())
{
await _trialRepository.UpdatePartialFromQueryAsync(t => t.Id == signConfirmDTO.TrialId, u => new Trial() { QCQuestionConfirmedTime = null, QCQuestionConfirmedUserId = null, IsQCQuestionConfirmed = false });
}
else if (signConfirmDTO.SignCode == ((int)SignEnum.SecondReviewConfirm).ToString())
{
var trialConfirmTime = _trialRepository.Where(t => t.Id == signConfirmDTO.TrialId).Select(t => t.QCQuestionConfirmedTime).FirstOrDefault();
if (signConfirmDTO.SignCode == ((int)SignEnum.TrialQCQuestionConfirm).ToString()) //重复二次复核签名
await _subjectVisitRepository.BatchUpdateNoTrackingAsync(t => t.TrialId == signConfirmDTO.TrialId && t.AuditState == AuditStateEnum.QCPassed
&& !t.TrialQCQuestionAnswerList.Any(t => t.SecondReviewTime == trialConfirmTime), u => new SubjectVisit() { SecondReviewState = SecondReviewState.WaitAudit });
//删除复审中间临时数据
await _qcQuestionAnswerRepository.BatchDeleteNoTrackingAsync(t => t.SubjectVisit.TrialId == signConfirmDTO.TrialId && t.SubjectVisit.SecondReviewState != SecondReviewState.AuditPassed && t.CurrentQCEnum == CurrentQC.SecondReview);
}
else if (signConfirmDTO.SignCode == ((int)SignEnum.TrialQCQuestionConfirm).ToString())
{ {
var trialConfig = (await _trialRepository var trialConfig = (await _trialRepository
@ -884,9 +899,9 @@ namespace IRaCIS.Core.Application
IsConfirm = true IsConfirm = true
}); });
await _trialRepository.UpdatePartialFromQueryAsync(t => t.Id == signConfirmDTO.TrialId, u => new Trial() { QCQuestionConfirmedTime = DateTime.Now, QCQuestionConfirmedUserId = _userInfo.UserRoleId, IsQCQuestionConfirmed = true }); await _trialRepository.UpdatePartialFromQueryAsync(t => t.Id == signConfirmDTO.TrialId, u => new Trial() { QCQuestionConfirmedTime = DateTime.Now, QCQuestionConfirmedUserId = _userInfo.UserRoleId, IsQCQuestionConfirmed = true });
await _trialRepository.SaveChangesAsync();
} }
await _trialRepository.SaveChangesAsync();
return ResponseOutput.Ok(); return ResponseOutput.Ok();

View File

@ -56,8 +56,8 @@ namespace IRaCIS.Core.Application.Service
IsDeleted = t.IsDeleted, IsDeleted = t.IsDeleted,
UserTypeId = t.UserRole.UserTypeRole.Id, UserTypeId = t.UserRole.UserTypeRole.Id,
UserTypeShortName = t.UserRole.UserTypeRole.UserTypeShortName, UserTypeShortName = t.UserRole.UserTypeRole.UserTypeShortName,
CreateTime=t.CreateTime, CreateTime = t.CreateTime,
UpdateTime=t.UpdateTime, UpdateTime = t.UpdateTime,
}).ToList(), }).ToList(),
}).ToPagedListAsync(inQuery); }).ToPagedListAsync(inQuery);
@ -315,7 +315,24 @@ namespace IRaCIS.Core.Application.Service
} }
public async Task<List<TrialSelectUserBasicInfo>> GetTrialUserRoleList(Guid trialId, UserTypeEnum? userTypeEnum)
{
var list = await _trialIdentityUserRepository.Where(t => t.TrialId == trialId)
.SelectMany(t => t.TrialUserRoleList)
.WhereIf(userTypeEnum != null, t => t.UserRole.UserTypeEnum == userTypeEnum)
.Where(t => t.UserRole.Id != _userInfo.UserRoleId)//iQC 指派过滤自己
.Select(t => new TrialSelectUserBasicInfo()
{
FullName = t.TrialUser.IdentityUser.FullName,
UserRoleId = t.UserRole.Id,
UserName = t.TrialUser.IdentityUser.UserName,
Phone = t.TrialUser.IdentityUser.Phone,
Email = t.TrialUser.IdentityUser.EMail
})
.ToListAsync();
return list;
}
} }
} }

View File

@ -29,6 +29,13 @@ namespace IRaCIS.Core.Domain.Share
TrialQCQuestionConfirm=107, TrialQCQuestionConfirm=107,
//重置质控问题配置
TrialQCQuestionConfirmUpdate=112,
SecondReviewConfirm = 113,
} }
} }

View File

@ -19,4 +19,14 @@ namespace IRaCIS.Core.Domain.Share
} }
public enum SecondReviewState
{
None = 0,
WaitAudit=1,
AuditPassed=2,
AuditFailed=3,
}
} }

View File

@ -14,7 +14,11 @@
First = 1, First = 1,
Second = 2 Second = 2,
//二次复核,只会一个人
SecondReview=3,
} }

View File

@ -108,6 +108,7 @@ public abstract class BaseFullAuditEntity : Entity, IAuditUpdate, IAuditAdd
[ForeignKey("CreateUserId")] [ForeignKey("CreateUserId")]
[JsonIgnore] [JsonIgnore]
public UserRole CreateUserRole { get; set; } public UserRole CreateUserRole { get; set; }
} }
public abstract class BaseFullDeleteAuditEntity : Entity, IAuditUpdate, IAuditAdd, ISoftDelete public abstract class BaseFullDeleteAuditEntity : Entity, IAuditUpdate, IAuditAdd, ISoftDelete
{ {

View File

@ -8,6 +8,9 @@ public class TrialQCQuestionAnswer : BaseFullAuditEntity
#region 导航属性 #region 导航属性
[JsonIgnore] [JsonIgnore]
public TrialQCQuestion TrialQCQuestionConfigure { get; set; } public TrialQCQuestion TrialQCQuestionConfigure { get; set; }
[JsonIgnore]
public SubjectVisit SubjectVisit { get; set; }
#endregion #endregion
public Guid TrialId { get; set; } public Guid TrialId { get; set; }
@ -20,4 +23,7 @@ public class TrialQCQuestionAnswer : BaseFullAuditEntity
public Guid SubjectVisitId { get; set; } public Guid SubjectVisitId { get; set; }
public Guid TrialQCQuestionConfigureId { get; set; } public Guid TrialQCQuestionConfigureId { get; set; }
public DateTime? SecondReviewTime { get; set; }
} }

View File

@ -6,6 +6,8 @@ namespace IRaCIS.Core.Domain.Models;
public class SubjectVisit : BaseFullDeleteAuditEntity public class SubjectVisit : BaseFullDeleteAuditEntity
{ {
#region 导航属性 #region 导航属性
[JsonIgnore]
public List<TrialQCQuestionAnswer> TrialQCQuestionAnswerList { get; set; }
[JsonIgnore] [JsonIgnore]
public TrialSite TrialSite { get; set; } public TrialSite TrialSite { get; set; }
@ -72,7 +74,7 @@ public class SubjectVisit : BaseFullDeleteAuditEntity
public List<SubjectCriteriaEvaluationVisitFilter> SubjectCriteriaEvaluationVisitFilterList { get; set; } public List<SubjectCriteriaEvaluationVisitFilter> SubjectCriteriaEvaluationVisitFilterList { get; set; }
[JsonIgnore] [JsonIgnore]
public List<SubjectVisitImageBackRecord> SubjectVisitImageBackRecordList { get; set; } public List<SubjectVisitImageBackRecord> SubjectVisitImageBackRecordList { get; set; }
#endregion #endregion
public Guid TrialSiteId { get; set; } public Guid TrialSiteId { get; set; }
@ -185,7 +187,7 @@ public class SubjectVisit : BaseFullDeleteAuditEntity
public Guid? SubmitUserId { get; set; } public Guid? SubmitUserId { get; set; }
public ReadingStatusEnum ReadingStatus { get; set; } public ReadingStatusEnum ReadingStatus { get; set; }
public SecondReviewState SecondReviewState { get; set; }
} }
[Comment("受试者访视影像回退记录表")] [Comment("受试者访视影像回退记录表")]

View File

@ -198,6 +198,13 @@ namespace IRaCIS.Core.Infra.EFCore.Common
extraIdentification = oldentity.IsConfigureEmail ? "/EmailUpdate" : "/EmailSave"; extraIdentification = oldentity.IsConfigureEmail ? "/EmailUpdate" : "/EmailSave";
break; break;
case "configTrialBasicInfo/TrialConfigSignatureConfirm":
if (entity.IsQCQuestionConfirmed == false)
{
extraIdentification = $"/ConfirmReset";
}
break;
} }