Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing Details

Test_IRC_Net8
he 2025-04-09 10:59:42 +08:00
commit 4e66ea43d7
11 changed files with 19591 additions and 9 deletions

View File

@ -17357,6 +17357,23 @@
<param name="qaDialogCommand"></param>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.Application.Image.QA.QCOperationService.RequestImageBack(System.Guid)">
<summary>
CRC IQC 申请影像回退
</summary>
<param name="subjectVisitId"></param>
<returns></returns>
<exception cref="T:IRaCIS.Core.Infrastructure.BusinessValidationFailedException"></exception>
</member>
<member name="M:IRaCIS.Core.Application.Image.QA.QCOperationService.AuditImageBack(System.Guid,System.Boolean)">
<summary>
PM 审核CRC IQC 申请影像回退
</summary>
<param name="subjectVisitId"></param>
<param name="isAgree"></param>
<returns></returns>
<exception cref="T:IRaCIS.Core.Infrastructure.BusinessValidationFailedException"></exception>
</member>
<member name="M:IRaCIS.Core.Application.Image.QA.QCOperationService.AddCheckChallengeReply(IRaCIS.Core.Application.Contracts.DTO.CheckChallengeDialogCommand)">
<summary>
一致性核查 质疑的添加/回复

View File

@ -2552,6 +2552,7 @@ public class VisitTaskService(IRepository<VisitTask> _visitTaskRepository,
//回退后,回退状态恢复
sv.RequestBackState = RequestBackStateEnum.NotRequest;
sv.ImageBackState = ImageBackStateEnum.None;
sv.IsCheckBack = false;
sv.CheckBackTime = null;
sv.CheckState = CheckStateEnum.None;

View File

@ -96,6 +96,8 @@ namespace IRaCIS.Core.Application.ViewModel
public int State { get; set; }
public Guid? PublishLogId { get; set; }
public List<BatchAddInternationalizationDto> AddList { get; set; }
}

View File

@ -143,6 +143,7 @@ namespace IRaCIS.Core.Application.Service
mapItem.InternationalizationType = batchAdd.InternationalizationType;
mapItem.State = batchAdd.State;
mapItem.PublishLogId = batchAdd.PublishLogId;
var verifyExp1 = new EntityVerifyExp<Internationalization>()
{

View File

@ -2108,6 +2108,7 @@ namespace IRaCIS.Core.Application.Contracts
public DateTime? ReviewAuditTime { get; set; }
public DateTime? PreliminaryAuditTime { get; set; }
public ImageBackStateEnum ImageBackState { get; set; }
public DateTime? AuditTime => QCProcessEnum == TrialQCProcess.SingleAudit ? PreliminaryAuditTime : (QCProcessEnum == TrialQCProcess.DoubleAudit ? ReviewAuditTime : null);
}

View File

@ -3,6 +3,7 @@ using IRaCIS.Core.Application.Contracts.DTO;
using IRaCIS.Core.Application.Filter;
using IRaCIS.Core.Application.Helper;
using IRaCIS.Core.Application.Service.Inspection.DTO;
using IRaCIS.Core.Domain.Models;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Infrastructure;
using Medallion.Threading;
@ -38,6 +39,7 @@ namespace IRaCIS.Core.Application.Image.QA
IRepository<ReadingQuestionCriterionTrial> _readingQuestionCriterionTrialRepository,
IDistributedLockProvider _distributedLockProvider, IReadingClinicalDataService _readingClinicalDataService,
IOSSService _oSSService,
IRepository<ReadingClinicalData> _readingClinicalDataReposiotry,
IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer, IWebHostEnvironment _hostEnvironment) : BaseService, IQCOperationService
{
@ -239,6 +241,137 @@ namespace IRaCIS.Core.Application.Image.QA
#endregion
#region CRC IQC 申请退回
/// <summary>
/// CRC IQC 申请影像回退
/// </summary>
/// <param name="subjectVisitId"></param>
/// <returns></returns>
/// <exception cref="BusinessValidationFailedException"></exception>
[HttpPut]
public async Task<IResponseOutput> RequestImageBack(Guid subjectVisitId)
{
if (!_subjectVisitRepository.Any(t => t.Id == subjectVisitId && t.CheckState < CheckStateEnum.CVPassed && t.SubmitState == SubmitStateEnum.Submitted))
{
//一致性核查通过前已提交的影像才允许进行回退
throw new BusinessValidationFailedException(_localizer["QCOperation_ShouldBeforeCheckPassed"]);
}
if (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator)
{
await _subjectVisitRepository.UpdatePartialFromQueryAsync(t => t.Id == subjectVisitId, u => new SubjectVisit() { ImageBackState = ImageBackStateEnum.CRCRequestBack }, true);
}
if (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.IQC)
{
await _subjectVisitRepository.UpdatePartialFromQueryAsync(t => t.Id == subjectVisitId, u => new SubjectVisit() { ImageBackState = ImageBackStateEnum.IQCRequestBack }, true);
}
return ResponseOutput.Ok();
}
/// <summary>
/// PM 审核CRC IQC 申请影像回退
/// </summary>
/// <param name="subjectVisitId"></param>
/// <param name="isAgree"></param>
/// <returns></returns>
/// <exception cref="BusinessValidationFailedException"></exception>
[HttpPut]
public async Task<IResponseOutput> AuditImageBack(Guid subjectVisitId, bool isAgree)
{
var sv = (await _subjectVisitRepository.FirstOrDefaultAsync(t => t.Id == subjectVisitId)).IfNullThrowException();
if (sv.ImageBackState != ImageBackStateEnum.CRCRequestBack && sv.ImageBackState != ImageBackStateEnum.IQCRequestBack)
{
//当前访视状态不在影像申请回退状态,不允许审核通过
throw new BusinessValidationFailedException(_localizer["QCOperation_NotInRequestImageBackState"]);
}
if (isAgree)
{
if (sv.SubmitState == SubmitStateEnum.Submitted && sv.CheckState < CheckStateEnum.CVPassed)
{
sv.ImageBackState = ImageBackStateEnum.PMAgreeBack;
}
else
{
//一致性核查通过前已提交的影像才允许进行回退
throw new BusinessValidationFailedException(_localizer["QCOperation_ShouldBeforeCheckPassed"]);
}
#region 回退处理
//需要重新产生任务
sv.IsVisitTaskGenerated = false;
sv.IsPMBackOrReReading = true;
sv.AuditState = AuditStateEnum.None;
sv.SubmitState = SubmitStateEnum.ToSubmit;
sv.ReadingStatus = ReadingStatusEnum.ImageNotSubmit;
//回退后,回退状态恢复
sv.RequestBackState = RequestBackStateEnum.NotRequest;
sv.IsCheckBack = false;
sv.CheckBackTime = null;
sv.CheckState = CheckStateEnum.None;
sv.CheckChallengeState = CheckChanllengeTypeEnum.None;
sv.SVENDTC = null;
sv.SVSTDTC = null;
sv.PreliminaryAuditTime = null;
sv.SubmitTime = null;
sv.ReviewAuditTime = null;
sv.CurrentActionUserExpireTime = null;
sv.IsTake = false;
sv.CurrentActionUserId = null;
sv.PreliminaryAuditUserId = null;
sv.ReviewAuditUserId = null;
if (sv.IsBaseLine)
{
await _readingClinicalDataReposiotry.UpdatePartialFromQueryAsync(t => t.ReadingId == sv.Id && (t.ClinicalDataTrialSet.ClinicalDataLevel == ClinicalLevel.Subject || t.ClinicalDataTrialSet.ClinicalDataLevel == ClinicalLevel.SubjectVisit), c => new ReadingClinicalData() { IsSign = false, ReadingClinicalDataState = ReadingClinicalDataStatus.HaveUploaded });
}
else
{
await _readingClinicalDataReposiotry.UpdatePartialFromQueryAsync(t => t.ReadingId == sv.Id && t.ClinicalDataTrialSet.ClinicalDataLevel == ClinicalLevel.SubjectVisit, c => new ReadingClinicalData()
{
IsSign = false,
ReadingClinicalDataState = ReadingClinicalDataStatus.HaveUploaded,
IsBlind = null,
IsComplete = null
});
}
await _trialQCQuestionAnswerRepository.BatchDeleteNoTrackingAsync(t => t.SubjectVisitId == subjectVisitId);
#endregion
}
else
{
sv.ImageBackState = ImageBackStateEnum.PMNotAgreeBack;
}
await _subjectVisitRepository.SaveChangesAsync();
return ResponseOutput.Ok();
}
#endregion
#region 一致性核查
/// <summary>
@ -1698,7 +1831,7 @@ namespace IRaCIS.Core.Application.Image.QA
//删除 软删除的物理文件
var instancePathList = await _dicomInstanceRepository.Where(t => (t.DicomSerie.IsDeleted || t.IsDeleted) && t.SubjectVisitId == subjectVisitId, false, true)
.Select(t => t.Path).ToListAsync();
var noneDicomFileList = await _noneDicomStudyFileRepository.Where(t => (t.NoneDicomStudy.IsDeleted ||t.IsDeleted) && t.NoneDicomStudy.SubjectVisitId == subjectVisitId, false, true)
var noneDicomFileList = await _noneDicomStudyFileRepository.Where(t => (t.NoneDicomStudy.IsDeleted || t.IsDeleted) && t.NoneDicomStudy.SubjectVisitId == subjectVisitId, false, true)
.Select(t => t.Path).ToListAsync();

View File

@ -19,4 +19,17 @@ namespace IRaCIS.Core.Domain.Share
PM_NotAgree=3,
}
public enum ImageBackStateEnum
{
None=0,
CRCRequestBack=1,
IQCRequestBack=2,
PMAgreeBack=3,
PMNotAgreeBack = 4,
}
}

View File

@ -161,6 +161,7 @@ public class SubjectVisit : BaseFullDeleteAuditEntity
public DateTime? CheckPassedTime { get; set; }
[Comment("计划外上一访视")]
public Guid? OutPlanPreviousVisitId { get; set; }
[Comment("一致性核查 回退")]
public RequestBackStateEnum RequestBackState { get; set; }
public bool IsQCConfirmedReupload { get; set; }
@ -180,5 +181,8 @@ public class SubjectVisit : BaseFullDeleteAuditEntity
public Guid? SubmitUserId { get; set; }
public ReadingStatusEnum ReadingStatus { get; set; }
[Comment("影像上传 回退")]
public ImageBackStateEnum ImageBackState { get; set; }
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,110 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace IRaCIS.Core.Infra.EFCore.Migrations
{
/// <inheritdoc />
public partial class SVImageBack : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AlterColumn<int>(
name: "RequestBackState",
table: "SubjectVisit",
type: "int",
nullable: false,
comment: "一致性核查 回退",
oldClrType: typeof(int),
oldType: "int");
migrationBuilder.AddColumn<int>(
name: "ImageBackState",
table: "SubjectVisit",
type: "int",
nullable: false,
defaultValue: 0,
comment: "影像上传 回退");
migrationBuilder.CreateIndex(
name: "IX_EnrollReadingCriterion_TrialReadingCriterionId",
table: "EnrollReadingCriterion",
column: "TrialReadingCriterionId");
migrationBuilder.CreateIndex(
name: "IX_EnrollReadingCategory_TrialReadingCriterionId",
table: "EnrollReadingCategory",
column: "TrialReadingCriterionId");
migrationBuilder.CreateIndex(
name: "IX_DoctorCriterionFile_TrialReadingCriterionId",
table: "DoctorCriterionFile",
column: "TrialReadingCriterionId");
migrationBuilder.AddForeignKey(
name: "FK_DoctorCriterionFile_ReadingQuestionCriterionTrial_TrialReadingCriterionId",
table: "DoctorCriterionFile",
column: "TrialReadingCriterionId",
principalTable: "ReadingQuestionCriterionTrial",
principalColumn: "Id");
migrationBuilder.AddForeignKey(
name: "FK_EnrollReadingCategory_ReadingQuestionCriterionTrial_TrialReadingCriterionId",
table: "EnrollReadingCategory",
column: "TrialReadingCriterionId",
principalTable: "ReadingQuestionCriterionTrial",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "FK_EnrollReadingCriterion_ReadingQuestionCriterionTrial_TrialReadingCriterionId",
table: "EnrollReadingCriterion",
column: "TrialReadingCriterionId",
principalTable: "ReadingQuestionCriterionTrial",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "FK_DoctorCriterionFile_ReadingQuestionCriterionTrial_TrialReadingCriterionId",
table: "DoctorCriterionFile");
migrationBuilder.DropForeignKey(
name: "FK_EnrollReadingCategory_ReadingQuestionCriterionTrial_TrialReadingCriterionId",
table: "EnrollReadingCategory");
migrationBuilder.DropForeignKey(
name: "FK_EnrollReadingCriterion_ReadingQuestionCriterionTrial_TrialReadingCriterionId",
table: "EnrollReadingCriterion");
migrationBuilder.DropIndex(
name: "IX_EnrollReadingCriterion_TrialReadingCriterionId",
table: "EnrollReadingCriterion");
migrationBuilder.DropIndex(
name: "IX_EnrollReadingCategory_TrialReadingCriterionId",
table: "EnrollReadingCategory");
migrationBuilder.DropIndex(
name: "IX_DoctorCriterionFile_TrialReadingCriterionId",
table: "DoctorCriterionFile");
migrationBuilder.DropColumn(
name: "ImageBackState",
table: "SubjectVisit");
migrationBuilder.AlterColumn<int>(
name: "RequestBackState",
table: "SubjectVisit",
type: "int",
nullable: false,
oldClrType: typeof(int),
oldType: "int",
oldComment: "一致性核查 回退");
}
}
}

View File

@ -17,7 +17,7 @@ namespace IRaCIS.Core.Infra.EFCore.Migrations
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "8.0.10")
.HasAnnotation("ProductVersion", "8.0.14")
.HasAnnotation("Relational:MaxIdentifierLength", 128);
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
@ -1808,6 +1808,8 @@ namespace IRaCIS.Core.Infra.EFCore.Migrations
b.HasIndex("DoctorId");
b.HasIndex("TrialReadingCriterionId");
b.ToTable("DoctorCriterionFile", t =>
{
t.HasComment("医生 - 项目标准签名文档");
@ -2322,6 +2324,8 @@ namespace IRaCIS.Core.Infra.EFCore.Migrations
b.HasIndex("EnrollId");
b.HasIndex("TrialReadingCriterionId");
b.ToTable("EnrollReadingCategory", t =>
{
t.HasComment("医生 - 项目阅片标准阅片类型配置表");
@ -2354,6 +2358,8 @@ namespace IRaCIS.Core.Infra.EFCore.Migrations
b.HasIndex("EnrollId");
b.HasIndex("TrialReadingCriterionId");
b.ToTable("EnrollReadingCriterion", t =>
{
t.HasComment("医生 - 项目阅片标准参与一致性分析配置表");
@ -8886,6 +8892,10 @@ namespace IRaCIS.Core.Infra.EFCore.Migrations
b.Property<Guid?>("ForwardUserId")
.HasColumnType("uniqueidentifier");
b.Property<int>("ImageBackState")
.HasColumnType("int")
.HasComment("影像上传 回退");
b.Property<bool>("InPlan")
.HasColumnType("bit");
@ -8955,7 +8965,8 @@ namespace IRaCIS.Core.Infra.EFCore.Migrations
.HasColumnType("int");
b.Property<int>("RequestBackState")
.HasColumnType("int");
.HasColumnType("int")
.HasComment("一致性核查 回退");
b.Property<DateTime?>("ReviewAuditTime")
.HasColumnType("datetime2");
@ -14989,9 +15000,15 @@ namespace IRaCIS.Core.Infra.EFCore.Migrations
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("IRaCIS.Core.Domain.Models.ReadingQuestionCriterionTrial", "TrialReadingCriterion")
.WithMany()
.HasForeignKey("TrialReadingCriterionId");
b.Navigation("CreateUserRole");
b.Navigation("Doctor");
b.Navigation("TrialReadingCriterion");
});
modelBuilder.Entity("IRaCIS.Core.Domain.Models.DoctorDictionary", b =>
@ -15131,9 +15148,17 @@ namespace IRaCIS.Core.Infra.EFCore.Migrations
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("IRaCIS.Core.Domain.Models.ReadingQuestionCriterionTrial", "TrialReadingCriterion")
.WithMany()
.HasForeignKey("TrialReadingCriterionId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("CreateUserRole");
b.Navigation("Enroll");
b.Navigation("TrialReadingCriterion");
});
modelBuilder.Entity("IRaCIS.Core.Domain.Models.EnrollReadingCriterion", b =>
@ -15150,9 +15175,17 @@ namespace IRaCIS.Core.Infra.EFCore.Migrations
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("IRaCIS.Core.Domain.Models.ReadingQuestionCriterionTrial", "TrialReadingCriterion")
.WithMany()
.HasForeignKey("TrialReadingCriterionId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("CreateUserRole");
b.Navigation("Enroll");
b.Navigation("TrialReadingCriterion");
});
modelBuilder.Entity("IRaCIS.Core.Domain.Models.EventStoreRecord", b =>