From a70caefe010e8b2d6ac7db1813620c639df534f1 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Thu, 6 Nov 2025 15:05:09 +0800 Subject: [PATCH] =?UTF-8?q?=E8=82=BF=E7=98=A4CDISC=20=E5=AF=BC=E5=87=BA?= =?UTF-8?q?=E5=88=9D=E6=AD=A5=E6=8F=90=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FileDocProcess/ExcelExportHelper.cs | 31 + .../IRaCIS.Core.Application.xml | 325 +++++ .../Allocation/DTO/VisitTaskViewModel.cs | 2 + .../Service/Common/ExcelExportService.cs | 20 +- .../Common/Export/CDISCExportBaseModel.cs | 485 +++++++ .../Common/Export/RESISTExportService.cs | 1181 +++++++++++++++++ .../Service/Common/_MapConfig.cs | 5 + .../ReadingQuestionService.cs | 4 +- IRaCIS.Core.Domain.Share/Reading/ReadEnum.cs | 4 +- .../ReadingFormAnswer/ReadingNoneDicomMark.cs | 1 + .../ReadingTableAnswerRowInfo.cs | 12 + .../EntityConfigration/ImageConfigration.cs | 12 + .../_IRaCIS/_Config/_StaticData.cs | 2 + 13 files changed, 2074 insertions(+), 10 deletions(-) create mode 100644 IRaCIS.Core.Application/Service/Common/Export/CDISCExportBaseModel.cs create mode 100644 IRaCIS.Core.Application/Service/Common/Export/RESISTExportService.cs diff --git a/IRaCIS.Core.Application/Helper/FileDocProcess/ExcelExportHelper.cs b/IRaCIS.Core.Application/Helper/FileDocProcess/ExcelExportHelper.cs index a0305fc0b..87696b93e 100644 --- a/IRaCIS.Core.Application/Helper/FileDocProcess/ExcelExportHelper.cs +++ b/IRaCIS.Core.Application/Helper/FileDocProcess/ExcelExportHelper.cs @@ -1038,6 +1038,34 @@ public static class ExcelExportHelper + public static async Task MutiSheetDataExportAsync(string code, object data, string exportFileNamePrefix, IRepository _commonDocumentRepository, IWebHostEnvironment _hostEnvironment) + { + + var (physicalPath, fileName) = await FileStoreHelper.GetCommonDocPhysicalFilePathAsync(_hostEnvironment, _commonDocumentRepository, code); + + + //模板路径 + var tplPath = physicalPath; + + + var memoryStream = new MemoryStream(); + + var config = new OpenXmlConfiguration() + { + IgnoreTemplateParameterMissing = true, + }; + + await MiniExcel.SaveAsByTemplateAsync(memoryStream, tplPath, data, config); + + memoryStream.Seek(0, SeekOrigin.Begin); + + + return new FileStreamResult(memoryStream, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet") + { + FileDownloadName = $"{(string.IsNullOrEmpty(exportFileNamePrefix) ? "" : exportFileNamePrefix + "_")}{Path.GetFileNameWithoutExtension(fileName)}_{DateTime.Now.ToString("yyyyMMddHHmmss")}.xlsx" + }; + } + /// /// 导出文件模板 /// @@ -1119,4 +1147,7 @@ public static class ExcelExportHelper }; } + + + } \ No newline at end of file diff --git a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml index 1cfadd39f..02465e67b 100644 --- a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml +++ b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml @@ -981,6 +981,331 @@ + + + 方案编号 STUDYID + + + + + 域 DOMAIN TU TR RS + + + + + 取值类型 TUSPID TRSPID RSSPID + + + + + 受试者编号 USUBJID 实际展示TrialSiteSubjectCode + + + + + 供应商 TUNAM (Extensive Imaging) + + + + + 阅片人 TUEVAL TREVAL RSEVAL + + + + + 阅片人标识 TUEVALID TREVALID RSEVALID + + + + + 访视编号 VISITNUM + + + + + 访视名称 VISIT + + + + + 拍片日期 TUDTC TRDTC RSDTC + + + + + eCRF标识 TUREFID TRREFID RSREFID + + + + + RSCAT 阅片标准 + + + + + RSACPTFL 裁定标记 TUACPTFL + + + + + 序号 TUSEQ (同一个访视,所有阅片人选择病灶给个顺序号) + + + + + 链接ID TULNKID (阅片人角色_病灶编号)不同访视可以重复 + + + + + 肿瘤识别简称 TUTESTCD + + + + + 肿瘤识别全称 TUTEST + + + + + 肿瘤鉴定结果 TUORRES + + + + + 肿瘤识别结果类型 TUSTRESC + + + + + 部位 TULOC (对应病灶表的部位,需要国际化) + + + + + 鉴定方法 TUMETHOD (Modality?) + + + + + 部位描述 LOCTEXT + + + + + 每个subject 按照顺序编号 TRSEQ + + + + + TRGRPID 组ID 对应TU表肿瘤鉴定结果 TumorIdentificationResult + + + + + TRLNKID 链接ID 对应TU表的链接ID TumorNo(阅片人角色_病灶编号) + + + + + TRLNKGRP 链接组 ARM-任务名(访视名) 对应RS的链接组 + + + + + 肿瘤评估简称 TRTESTCD + + + + + 肿瘤评估全称 TRTEST + + + + + 原始测量 TRORRES + + + + + 原始单位 TRORRESU + + + + + 标准结果(字符) TRSTRESC + + + + + 标准结果(数值) TRORRESU + + + + + 标准单位 TRSTRESU + + + + + 完成状态 TRSTAT + + + + + 完成状态 TRMETHOD + + + + + 无法测量原因 TRREASND + + + + + RSSEQ 按照subject 的数据顺序编号 + + + + + RSLNKGRP 链接组 ARM_任务名(访视名) + + + + + RSTESTCD 疗效评估简称 + + + + + RSTEST 疗效评估全称 + + + + + RSORRES 响应评估原始结果 + + + + + RSSTRESC 标准疗效评估 + + + + + RSSTAT 完成状态 + + + + + RSREASND 无法评估原因 + + + + + REASASM 评估原因 + + + + + REASOVR 重新评估原因 + + + + + REASUPD 更新评估原因 + + + + + 关联域 RS:(访视点备注) 空:裁判选择原因 + + + + + COSEQ 序号 + + + + + IDVAR 标识变量 RSSEQ 空:裁判选择原因 + + + + + 标识 IDVARVAL RSSEQ具体的值 空:裁判选择原因 + + + + + COREF 备注引用 + + + + + 备注 COVAL + + + + + 裁决日期 CODTC + + + + + 取值类型 TUSPID + + + + + 肿瘤识别简称 TUTESTCD + + + + + 肿瘤识别全称 TUTEST + + + + + 肿瘤鉴定结果 TUORRES + + + + + 肿瘤识别结果类型 TUSTRESC + + + + + 取值类型 TRSPID + + + + + 肿瘤评估简称 TRTESTCD + + + + + 肿瘤评估全称 TRTEST + + + + + 取值类型 RSSPID + + + + + RSTESTCD 疗效评估简称 + + + + + RSTEST 疗效评估全称 + + 邮件日志 diff --git a/IRaCIS.Core.Application/Service/Allocation/DTO/VisitTaskViewModel.cs b/IRaCIS.Core.Application/Service/Allocation/DTO/VisitTaskViewModel.cs index 69cc6719f..4965a065e 100644 --- a/IRaCIS.Core.Application/Service/Allocation/DTO/VisitTaskViewModel.cs +++ b/IRaCIS.Core.Application/Service/Allocation/DTO/VisitTaskViewModel.cs @@ -490,6 +490,8 @@ namespace IRaCIS.Core.Application.ViewModel public int? RandomOrder { get; set; } public bool? IsRandomOrderList { get; set; } + + public CriterionType? CriterionType { get; set; } } diff --git a/IRaCIS.Core.Application/Service/Common/ExcelExportService.cs b/IRaCIS.Core.Application/Service/Common/ExcelExportService.cs index ece094738..8dfa3d4ca 100644 --- a/IRaCIS.Core.Application/Service/Common/ExcelExportService.cs +++ b/IRaCIS.Core.Application/Service/Common/ExcelExportService.cs @@ -2597,13 +2597,19 @@ namespace IRaCIS.Core.Application.Service.Common list.Add(new ExportDocumentDes() { Code = StaticData.Export.ReadingLession_Export, ExportCatogory = ExportResult.DetailedTableOfLesions }); } + if (criterion.CriterionType == CriterionType.RECIST1Point1) + { + list.Add(new ExportDocumentDes() { Code = StaticData.Export.TumorCDISC_Export, ExportCatogory = ExportResult.TumorCDISC_Export }); + } + if (criterion.CriterionType == CriterionType.OCT) { list.Add(new ExportDocumentDes() { Code = StaticData.Export.OCT_ReadingLession_Export, ExportCatogory = ExportResult.OCT_ReadingLession_Export }); } - //else if (criterion.CriterionType == CriterionType.SelfDefine) + + if (criterion.CriterionGroup != CriterionGroup.Tumor) { - list.Add(new ExportDocumentDes() { Code = StaticData.Export.CDISC_Reading_Export, ExportCatogory = ExportResult.CDISC }); + list.Add(new ExportDocumentDes() { Code = StaticData.Export.CDISC_Reading_Export, ExportCatogory = ExportResult.NoneTumorCDISC }); } switch (criterion.ArbitrationRule) @@ -2784,7 +2790,7 @@ namespace IRaCIS.Core.Application.Service.Common } // 非肿瘤标准 包括自定义,以及系统非肿瘤 会配置到表格层级 问题名称是 表格名称_表格子问题名 else if ( - criterion.CriterionGroup == CriterionGroup.Nontumorous && inQuery.ReadingExportType != ExportResult.CDISC + criterion.CriterionGroup == CriterionGroup.Nontumorous && inQuery.ReadingExportType != ExportResult.NoneTumorCDISC ) { @@ -2801,7 +2807,7 @@ namespace IRaCIS.Core.Application.Service.Common } // CDISC 导出 只管到 外层问题层级 和阅片结果表是保持一致 - else if (inQuery.ReadingExportType == ExportResult.CDISC) + else if (inQuery.ReadingExportType == ExportResult.NoneTumorCDISC) { if (criterion.CriterionGroup == CriterionGroup.Tumor) @@ -2869,7 +2875,7 @@ namespace IRaCIS.Core.Application.Service.Common #endregion - if (inQuery.ReadingExportType != ExportResult.CDISC) + if (inQuery.ReadingExportType != ExportResult.NoneTumorCDISC) { //最终EXCEL 列 var configCoumNameList = new List(); @@ -3025,7 +3031,7 @@ namespace IRaCIS.Core.Application.Service.Common #endregion #region 不管是list 还是taskList 最终处理的数据都是list 处理好数据后合并 - if (criterion.CriterionType == CriterionType.RECIST1Point1 || criterion.CriterionType == CriterionType.RECIST1Pointt1_MB + if (criterion.CriterionType == CriterionType.RECIST1Point1 || criterion.CriterionType == CriterionType.RECIST1Pointt1_MB || criterion.CriterionType == CriterionType.IRECIST1Point1 || criterion.CriterionType == CriterionType.mRECISTHCC) { //针对1.1 整体肿瘤评估 有的两列要合并一列 @@ -3475,7 +3481,7 @@ namespace IRaCIS.Core.Application.Service.Common string fileName = ""; - if (inQuery.ReadingExportType == ExportResult.CDISC) + if (inQuery.ReadingExportType == ExportResult.NoneTumorCDISC) { (memoryStream, fileName) = await ExcelExportHelper.DataExport_NpoiTestAsync(export_Template, exportInfo, _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(CommonEvaluationExport), criterion.CriterionType, dynamicColumnConfig); diff --git a/IRaCIS.Core.Application/Service/Common/Export/CDISCExportBaseModel.cs b/IRaCIS.Core.Application/Service/Common/Export/CDISCExportBaseModel.cs new file mode 100644 index 000000000..596324c51 --- /dev/null +++ b/IRaCIS.Core.Application/Service/Common/Export/CDISCExportBaseModel.cs @@ -0,0 +1,485 @@ +using IRaCIS.Core.Application.Contracts; +using IRaCIS.Core.Application.Helper; +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace IRaCIS.Core.Application.Service.Common; + + +public class TumorCommonQustionInfo +{ + //问题标识,肿瘤评估用于区分是什么问题 + public QuestionType? QuestionType { get; set; } + + public Guid QuestionId { get; set; } + public string QuestionName { get; set; } + + public string QuestionValue { get; set; } + + public string TranslateDicName { get; set; } + + public ValueUnit? Unit { get; set; } +} + +public class TumorLessionInfo +{ + public Guid Id { get; set; } + //病灶编号 + public string LessionCode { get; set; } + + public LesionType? LessionType { get; set; } + + public Guid? SplitRowId { get; set; } + + public string? DicomModality { get; set; } + + public string? NoneDicomModality { get; set; } + + //病灶答案 + public List LessionAnswerList { get; set; } +} + +public class TumorLessionAnswerInfo +{ + public QuestionMark? QuestionMark { get; set; } + + //病灶Id + public Guid RowId { get; set; } + + //如果是4 就取CustomUnit 否则就是字典翻译 + [Comment("单位")] + public ValueUnit? Unit { get; set; } + + + public int ShowOrder { get; set; } + + public Guid TableQuesionId { get; set; } + + public string QuestionName { get; set; } + + public string QuestionValue { get; set; } + + public string TranslateDicName { get; set; } +} + +public class TumorGlobalQuestionAnserInfo +{ + [Comment("原任务ID")] + public Guid TaskId { get; set; } + + + [Comment("问题答案")] + public string Answer { get; set; } = string.Empty; +} + +public class TumorExportBaseModel : TU_TR_RSBaseModel +{ + public List LesionList { get; set; } = new List(); + + public List QuestionAnswerList { get; set; } + + public List GlobalResultList { get; set; } + + #region 后续处理额外添加字段 + + public DateTime? JudgeSignTime { get; set; } + + public Guid? SourceSubjectVisitId { get; set; } + + public List SubjectCriterionReadingPeriodVisitNumList { get; set; } + + public decimal VisitTaskNum { get; set; } + + public ReadingTaskState ReadingTaskState { get; set; } + + public ReadingCategory ReadingCategory { get; set; } + + //裁判结果选择的访视或者全局任务Id + public Arm? JudgeArmEnum { get; set; } + + + + + //在当前访视触发裁判,或者在截止日期小于等于当前访视的阅片期触发裁判 + [DictionaryTranslateAttribute("YesOrNoAudit")] + public bool? IsTrigerJudge { get; set; } + + //(如果是访视点裁判,则仅在所选阅片人对应访视 显示;如果是阅片期裁判,则在所选阅片人 阅片期内的所有访视 显示此原因) + public string JudgeNote { get; set; } = string.Empty; + + public string VisitNote { get; set; } + #endregion + + +} + + +public class TU_TR_RSBaseModel +{ + /// + /// 方案编号 STUDYID + /// + public string ResearchProgramNo { get; set; } + + + + /// + /// 域 DOMAIN TU TR RS + /// + public string Domain { get; set; } + + + /// + /// 取值类型 TUSPID TRSPID RSSPID + /// + public string ValueType { get; set; } + + + /// + /// 受试者编号 USUBJID 实际展示TrialSiteSubjectCode + /// + + public string SubjectCode { get; set; } + + + /// + /// 供应商 TUNAM (Extensive Imaging) + /// + public string Vendor { get; set; } = "Extensive Imaging"; + + + /// + /// 阅片人 TUEVAL TREVAL RSEVAL + /// + public string UserName { get; set; } + + /// + /// 阅片人标识 TUEVALID TREVALID RSEVALID + /// + public Arm ArmEnum { get; set; } + + /// + /// 访视编号 VISITNUM + /// + public decimal? VisitNum { get; set; } + + /// + /// 访视名称 VISIT + /// + public string? VisitName { get; set; } + + /// + /// 拍片日期 TUDTC TRDTC RSDTC + /// + public DateTime? LatestScanDate { get; set; } + + /// + /// eCRF标识 TUREFID TRREFID RSREFID + /// + public Guid VisitTaskId { get; set; } + + + #region 移动位置 + + /// + /// RSCAT 阅片标准 + /// + public string CriterionName { get; set; } + + /// + /// RSACPTFL 裁定标记 TUACPTFL + /// + //裁判选择标记 + //根据裁判的任务结果 设置访视任务的这个字段 该字段表示 裁判认同该任务的结果 + public bool? IsJudgeSelect { get; set; } + + #endregion + + + + #region 额外翻译字段 + + + + public string IsJudgeSelectStr => IsJudgeSelect == true ? "Y" : ""; + + public string ArmEnumStr { get; set; } + public string LatestScanDateStr => LatestScanDate != null ? LatestScanDate?.ToString("yyyy-MM-dd")! : ""; + public string TrialSiteSubjectCode => ResearchProgramNo + SubjectCode; + #endregion +} + + +public class TU_Export : TU_TR_RSBaseModel +{ + + ///// + ///// 取值类型 TUSPID + ///// + //public string TUValueType { get; set; } + + + /// + /// 序号 TUSEQ (同一个访视,所有阅片人选择病灶给个顺序号) + /// + public int No { get; set; } + + + + /// + /// 链接ID TULNKID (阅片人角色_病灶编号)不同访视可以重复 + /// + public string ARM_TumorNo { get; set; } + + /// + /// 肿瘤识别简称 TUTESTCD + /// + public string TumorIdentificationSimple { get; set; } + + /// + /// 肿瘤识别全称 TUTEST + /// + public string TumorIdentificationFullName { get; set; } + + /// + /// 肿瘤鉴定结果 TUORRES + /// + public string TumorIdentificationResult { get; set; } + + /// + /// 肿瘤识别结果类型 TUSTRESC + /// + public string TumorIdentificationResultType { get; set; } + + + /// + /// 部位 TULOC (对应病灶表的部位,需要国际化) + /// + public string BodyPart { get; set; } + + /// + /// 鉴定方法 TUMETHOD (Modality?) + /// + public string IdentificationMethod { get; set; } + + + + ///// + ///// 裁定标记 TUACPTFL + ///// + //public bool? IsJudgeSelect { get; set; } + + + + /// + /// 部位描述 LOCTEXT + /// + public string BodyPartDes { get; set; } + + +} + + +public class TR_Export : TU_TR_RSBaseModel +{ + + ///// + ///// 取值类型 TRSPID + ///// + //public string TRValueType { get; set; } + + + /// + /// 每个subject 按照顺序编号 TRSEQ + /// + public int TRSEQ { get; set; } + + + /// + ///TRGRPID 组ID 对应TU表肿瘤鉴定结果 TumorIdentificationResult + /// + public string TRGRPID { get; set; } + + /// + /// TRLNKID 链接ID 对应TU表的链接ID TumorNo(阅片人角色_病灶编号) + /// + public string ARM_TumorNo { get; set; } + + /// + ///TRLNKGRP 链接组 ARM-任务名(访视名) 对应RS的链接组 + /// + public string ARM_VisitName { get; set; } + + + /// + /// 肿瘤评估简称 TRTESTCD + /// + public string TumorAssessmentSimpleName { get; set; } + + /// + /// 肿瘤评估全称 TRTEST + /// + public string TumorAssessmentFullName { get; set; } + + + /// + /// 原始测量 TRORRES + /// + public string OriginalMeasurements { get; set; } + + /// + /// 原始单位 TRORRESU + /// + public string OriginalUnit { get; set; } + + /// + /// 标准结果(字符) TRSTRESC + /// + public string StandardResult_Character => OriginalMeasurements; + + /// + /// 标准结果(数值) TRORRESU + /// + public string StandardResult_Numeric => double.TryParse(OriginalMeasurements, out _) ? OriginalMeasurements : ""; + + /// + /// 标准单位 TRSTRESU + /// + public string StandardUnit => OriginalUnit; + + + /// + /// 完成状态 TRSTAT + /// + public string CompletionStatus { get; set; } + + + /// + /// 完成状态 TRMETHOD + /// + public string IdentificationMethod { get; set; } + + + /// + /// 无法测量原因 TRREASND + /// + public string NotMeasuredReason { get; set; } + + + +} + + +public class RS_Export : TU_TR_RSBaseModel +{ + /// + /// RSSEQ 按照subject 的数据顺序编号 + /// + public int RSSEQ { get; set; } + + /// + /// RSLNKGRP 链接组 ARM_任务名(访视名) + /// + public string ARM_VisitName { get; set; } + + /// + /// RSTESTCD 疗效评估简称 + /// + public string EfficacyEvaluationSimpleName { get; set; } + + /// + /// RSTEST 疗效评估全称 + /// + public string EfficacyEvaluationName { get; set; } + + /// + /// RSORRES 响应评估原始结果 + /// + public string RespondEfficacyAssessment { get; set; } + /// + /// RSSTRESC 标准疗效评估 + /// + public string StandardEfficacyAssessment => RespondEfficacyAssessment; + + /// + /// RSSTAT 完成状态 + /// + public string CompletionStatus { get; set; } + /// + /// RSREASND 无法评估原因 + /// + public string NotAssessmentReason { get; set; } + + + + ///// + ///// 裁定标记 RSACPTFL + ///// + //public bool? IsJudgeSelect { get; set; } + + /// + /// REASASM 评估原因 + /// + public string AssessmentReason { get; set; } + /// + /// REASOVR 重新评估原因 + /// + public string ReAssessmentReason { get; set; } + + /// + /// REASUPD 更新评估原因 + /// + public string UpdateAssessmentReason { get; set; } + + + [JsonIgnore] + public bool? IsOveralResponse { get; set; } + +} + + +public class CO_Export : TU_TR_RSBaseModel +{ + /// + /// 关联域 RS:(访视点备注) 空:裁判选择原因 + /// + public string RDOMAIN { get; set; } + + /// + /// COSEQ 序号 + /// + public int COSEQ { get; set; } + + /// + /// IDVAR 标识变量 RSSEQ 空:裁判选择原因 + /// + public string IdentificationVariable { get; set; } + + /// + /// 标识 IDVARVAL RSSEQ具体的值 空:裁判选择原因 + /// + public string Identification { get; set; } + + /// + /// COREF 备注引用 + /// + public string RemarksQuote { get; set; } + + /// + /// 备注 COVAL + /// + public string Remarks { get; set; } + + /// + /// 裁决日期 CODTC + /// + public string CODTC { get; set; } + + + +} diff --git a/IRaCIS.Core.Application/Service/Common/Export/RESISTExportService.cs b/IRaCIS.Core.Application/Service/Common/Export/RESISTExportService.cs new file mode 100644 index 000000000..a551b46b6 --- /dev/null +++ b/IRaCIS.Core.Application/Service/Common/Export/RESISTExportService.cs @@ -0,0 +1,1181 @@ +using Amazon.Runtime.Internal.Transform; +using DocumentFormat.OpenXml.Bibliography; +using DocumentFormat.OpenXml.Office2021.DocumentTasks; +using DocumentFormat.OpenXml.Spreadsheet; +using IRaCIS.Application.Contracts; +using IRaCIS.Application.Interfaces; +using IRaCIS.Core.API._ServiceExtensions.NewtonsoftJson; +using IRaCIS.Core.Application.Contracts; +using IRaCIS.Core.Application.Service.Reading.Dto; +using IRaCIS.Core.Application.ViewModel; +using IRaCIS.Core.Domain.Models; +using IRaCIS.Core.Domain.Share; +using IRaCIS.Core.Infra.EFCore.Common; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Hosting; +using NetTopologySuite.Triangulate.Tri; +using NPOI.OpenXmlFormats.Spreadsheet; +using NPOI.SS.Formula.Functions; +using NPOI.Util; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using static IRaCIS.Core.Application.Service.ExcelExportHelper; + +namespace IRaCIS.Core.Application.Service.Common; + +#region 文档固定信息建模 + + +public class TUValueEnum +{ + + /// + /// 取值类型 TUSPID + /// + public string TUValueType { get; set; } + + /// + /// 肿瘤识别简称 TUTESTCD + /// + public string TumorIdentificationSimple { get; set; } + + /// + /// 肿瘤识别全称 TUTEST + /// + public string TumorIdentificationFullName { get; set; } + + /// + /// 肿瘤鉴定结果 TUORRES + /// + public string TumorIdentificationResult { get; set; } + + /// + /// 肿瘤识别结果类型 TUSTRESC + /// + public string TumorIdentificationResultType { get; set; } +} + + +public class TRValueEnum +{ + /// + /// 取值类型 TRSPID + /// + public string TRValueType { get; set; } + + /// + /// 肿瘤评估简称 TRTESTCD + /// + public string TumorAssessmentSimpleName { get; set; } + + /// + /// 肿瘤评估全称 TRTEST + /// + public string TumorAssessmentFullName { get; set; } + + +} + + +public class RSValueEnum +{ + + /// + /// 取值类型 RSSPID + /// + public string RSValueType { get; set; } + + + /// + /// RSTESTCD 疗效评估简称 + /// + public string EfficacyEvaluationSimpleName { get; set; } + + /// + /// RSTEST 疗效评估全称 + /// + public string EfficacyEvaluationName { get; set; } +} + +#endregion + + +public class RESIST_Lugano_TUFixed +{ + public static List TUValueList = new List() + { + new TUValueEnum(){TUValueType="01",TumorIdentificationSimple="TUMIDENT",TumorIdentificationFullName="Tumor Identification",TumorIdentificationResult="TARGET",TumorIdentificationResultType="TARGET"}, + new TUValueEnum(){TUValueType="01",TumorIdentificationSimple="TUMIDENT",TumorIdentificationFullName="Tumor Identification",TumorIdentificationResult="NON-TARGET",TumorIdentificationResultType="NON-TARGET"}, + new TUValueEnum(){TUValueType="01",TumorIdentificationSimple="TUMIDENT",TumorIdentificationFullName="Tumor Identification",TumorIdentificationResult="NEW",TumorIdentificationResultType="NEW"}, + new TUValueEnum(){TUValueType="02",TumorIdentificationSimple="TUSPLIT",TumorIdentificationFullName="Tumor Split",TumorIdentificationResult="TARGET",TumorIdentificationResultType="TARGET"} + } +; +} +#region RESIST 固定信息 + + +public class RESIST_TRFixed +{ + public static List TRValueList = new List() + { + //直径 + new TRValueEnum(){TRValueType="01",TumorAssessmentSimpleName="DIAMETER",TumorAssessmentFullName="Diameter"}, + + //状态 + new TRValueEnum(){TRValueType="02",TumorAssessmentSimpleName="LESSTATE",TumorAssessmentFullName="Lesion state"}, + //靶病灶直径之和 + new TRValueEnum(){TRValueType="03",TumorAssessmentSimpleName="SUMDIAM",TumorAssessmentFullName="Sum of target diameters"}, + + //非淋巴结靶病灶直径之和 + new TRValueEnum(){TRValueType="04",TumorAssessmentSimpleName="SUMNDIAM",TumorAssessmentFullName="Sum of non-nodal target diameters"}, + + new TRValueEnum(){TRValueType="05",TumorAssessmentSimpleName="ABSCBSOD",TumorAssessmentFullName="Absolute Change Baseline in SOD"}, + + new TRValueEnum(){TRValueType="06",TumorAssessmentSimpleName="PRECBSOD",TumorAssessmentFullName="Present Change Baseline in SOD"}, + + new TRValueEnum(){TRValueType="07",TumorAssessmentSimpleName="ABSCNSOD",TumorAssessmentFullName="Absolute Change Nadir in SOD"}, + new TRValueEnum(){TRValueType="08",TumorAssessmentSimpleName="PRECNSOD",TumorAssessmentFullName="Present Change Nadir in SOD"}, + new TRValueEnum(){TRValueType="09",TumorAssessmentSimpleName="NADIR",TumorAssessmentFullName="Nadir"}, + new TRValueEnum(){TRValueType="10",TumorAssessmentSimpleName="NONTLPRE",TumorAssessmentFullName="Presence of nodal target lesion with the increase of short axis greaterthan 5mm vs. "}, + new TRValueEnum(){TRValueType="11",TumorAssessmentSimpleName="PRENTFPV",TumorAssessmentFullName="Presence of nodal target lesion with the increase of short axis greaterthan 5mm vs. "}, + new TRValueEnum(){TRValueType="12",TumorAssessmentSimpleName="PRESTLNE",TumorAssessmentFullName="Presence of single target lesion assessed as NE"}, + + }; +} +public class RESIST_RSFixed +{ + public static List RSValueList = new List() + { + new RSValueEnum(){RSValueType="01",EfficacyEvaluationSimpleName="TRGRESP",EfficacyEvaluationName="Target response"}, + new RSValueEnum(){RSValueType="02",EfficacyEvaluationSimpleName="NTRGRESP",EfficacyEvaluationName="Non-target response"}, + new RSValueEnum(){RSValueType="03",EfficacyEvaluationSimpleName="NEWLPRES",EfficacyEvaluationName="New lesion present"}, + new RSValueEnum(){RSValueType="04",EfficacyEvaluationSimpleName="OVRLRESP",EfficacyEvaluationName="Overall response"} + }; +} + + + +#endregion + +#region Lugano + +public class Lugano_TRFixed +{ + public static List TRValueList = new List() + { + new TRValueEnum(){ TRValueType = "01", TumorAssessmentSimpleName = "LDIAM", TumorAssessmentFullName = "Longest Diameter" }, + new TRValueEnum(){ TRValueType = "02", TumorAssessmentSimpleName = "SVDIAM", TumorAssessmentFullName = "Shortest Vertical Diameter" }, + new TRValueEnum(){ TRValueType = "03", TumorAssessmentSimpleName = "PPD", TumorAssessmentFullName = "Product of Perpendicular Diameters" }, + new TRValueEnum(){ TRValueType = "04", TumorAssessmentSimpleName = "LESSTATE", TumorAssessmentFullName = "Lesion state" }, + new TRValueEnum(){ TRValueType = "05", TumorAssessmentSimpleName = "LESSUVMX", TumorAssessmentFullName = "Lesion SUVmax" }, + new TRValueEnum(){ TRValueType = "06", TumorAssessmentSimpleName = "PPDFNAD", TumorAssessmentFullName = "PPD for Nadir" }, + new TRValueEnum(){ TRValueType = "07", TumorAssessmentSimpleName = "PRECNPPD", TumorAssessmentFullName = "Present Change Nadir for PPD" }, + new TRValueEnum(){ TRValueType = "08", TumorAssessmentSimpleName = "LDIFNAD", TumorAssessmentFullName = "LDi for Nadir" }, + new TRValueEnum(){ TRValueType = "09", TumorAssessmentSimpleName = "SDIFNAD", TumorAssessmentFullName = "SDi for Nadir" }, + new TRValueEnum(){ TRValueType = "10", TumorAssessmentSimpleName = "ABSCNLDI", TumorAssessmentFullName = "Absolute Change Nadir in LDi" }, + new TRValueEnum(){ TRValueType = "11", TumorAssessmentSimpleName = "ABSCNSDI", TumorAssessmentFullName = "Absolute Change Nadir in SDi" }, + new TRValueEnum(){ TRValueType = "12", TumorAssessmentSimpleName = "NADIR", TumorAssessmentFullName = "Nadir" }, + new TRValueEnum(){ TRValueType = "13", TumorAssessmentSimpleName = "LIVESTAT", TumorAssessmentFullName = "Liver state" }, + new TRValueEnum(){ TRValueType = "14", TumorAssessmentSimpleName = "LOCOSTOP", TumorAssessmentFullName = "Location of Spleen Top" }, + new TRValueEnum(){ TRValueType = "15", TumorAssessmentSimpleName = "LOCOSBOT", TumorAssessmentFullName = "Location of Spleen Bottom" }, + new TRValueEnum(){ TRValueType = "16", TumorAssessmentSimpleName = "SPLVDIAM", TumorAssessmentFullName = "Spleen Vertical Diameter" }, + new TRValueEnum(){ TRValueType = "17", TumorAssessmentSimpleName = "SPLESTAT", TumorAssessmentFullName = "Spleen state" }, + new TRValueEnum(){ TRValueType = "18", TumorAssessmentSimpleName = "PETEXIST", TumorAssessmentFullName = "PET Image Existing" }, + new TRValueEnum(){ TRValueType = "19", TumorAssessmentSimpleName = "SUVMOMBP", TumorAssessmentFullName = "SUVmax of Mediastinal Blood Pool" }, + new TRValueEnum(){ TRValueType = "20", TumorAssessmentSimpleName = "SUVMOLBP", TumorAssessmentFullName = "SUVmax of Liver Blood Pool" }, + new TRValueEnum(){ TRValueType = "21", TumorAssessmentSimpleName = "LESMSUVM", TumorAssessmentFullName = "Lesions' Max(SUVmax)" }, + new TRValueEnum(){ TRValueType = "22", TumorAssessmentSimpleName = "LESOMSUV", TumorAssessmentFullName = "Lesion of Max(SUVmax)" }, + new TRValueEnum(){ TRValueType = "23", TumorAssessmentSimpleName = "P5PSSCOR", TumorAssessmentFullName = "PET 5PS Score" }, + new TRValueEnum(){ TRValueType = "24", TumorAssessmentSimpleName = "CHOSFBAS", TumorAssessmentFullName = "Change of SUV from Baseline" }, + new TRValueEnum(){ TRValueType = "25", TumorAssessmentSimpleName = "EVOFFABM", TumorAssessmentFullName = "Evidence of Focal FDG-avid Lesions Exists in the Bone Marrow" }, + new TRValueEnum(){ TRValueType = "26", TumorAssessmentSimpleName = "SPD", TumorAssessmentFullName = "Sum of Perpendicular Diameters" }, + new TRValueEnum(){ TRValueType = "27", TumorAssessmentSimpleName = "PRECSPDB", TumorAssessmentFullName = "Present Change of SPD from Baseline" }, + new TRValueEnum(){ TRValueType = "28", TumorAssessmentSimpleName = "PRECSPBA", TumorAssessmentFullName = "Present Change of Splenomegaly from Baseline" }, + new TRValueEnum(){ TRValueType = "29", TumorAssessmentSimpleName = "INSPVDNA", TumorAssessmentFullName = "Increase of Spleen Vertical Diameter Length from Nadir" }, + new TRValueEnum(){ TRValueType = "30", TumorAssessmentSimpleName = "INSPVDBA", TumorAssessmentFullName = "Increase of Spleen Vertical Diameter from Baseline" }, + new TRValueEnum(){ TRValueType = "31", TumorAssessmentSimpleName = "NASPVDI", TumorAssessmentFullName = "Nadir of Spleen Vertical Diameter" }, + }; + +} +public class Lugano_RSFixed +{ + public static List RSValueList = new List() + { + new RSValueEnum(){ RSValueType = "01", EfficacyEvaluationSimpleName = "TRGRESP", EfficacyEvaluationName = "Target response" }, + new RSValueEnum(){ RSValueType = "02", EfficacyEvaluationSimpleName = "NTRGRESP", EfficacyEvaluationName = "Non-target response" }, + new RSValueEnum(){ RSValueType = "03", EfficacyEvaluationSimpleName = "NEWLPRES", EfficacyEvaluationName = "New lesion present" }, + new RSValueEnum(){ RSValueType = "04", EfficacyEvaluationSimpleName = "LIVERESP", EfficacyEvaluationName = "Liver assessment" }, + new RSValueEnum(){ RSValueType = "05", EfficacyEvaluationSimpleName = "SPLERESP", EfficacyEvaluationName = "Spleen assessment" }, + new RSValueEnum(){ RSValueType = "06", EfficacyEvaluationSimpleName = "CMOVRESP", EfficacyEvaluationName = "CT/MRI overall assessment" }, + new RSValueEnum(){ RSValueType = "07", EfficacyEvaluationSimpleName = "PFDORESP", EfficacyEvaluationName = "Previous FDG-PET overall assessment" }, + new RSValueEnum(){ RSValueType = "08", EfficacyEvaluationSimpleName = "FDGORESP", EfficacyEvaluationName = "FDG-PET overall assessment" }, + new RSValueEnum(){ RSValueType = "09", EfficacyEvaluationSimpleName = "OVRLRESP", EfficacyEvaluationName = "Overall imaging assessment" }, + new RSValueEnum(){ RSValueType = "10", EfficacyEvaluationSimpleName = "CLINRESP", EfficacyEvaluationName = "Clinical assessment" }, + }; + +} +#endregion + + +[ApiExplorerSettings(GroupName = "Common")] +public class Tumor_CDISC_ExportService(IRepository _readingQuestionCriterionTrialRepository, IRepository _visitTaskRepository, + IRepository _subjectVisitTaskRepository, + IMapper _mapper, IUserInfo _userInfo, IRepository _commonDocumentRepository, IStringLocalizer _localizer, IWebHostEnvironment _hostEnvironment) : BaseService +{ + + private IQueryable GetTumor_CIDSCQueryable(VisitTaskQuery inQuery, ArbitrationRule arbitrationRule, Guid trialReadingCriterionId) + { + var isEn_Us = _userInfo.IsEn_Us; + + + var query = _visitTaskRepository.Where(t => t.TrialId == inQuery.TrialId && t.IsAnalysisCreate == false && (t.TaskState == TaskState.Effect || t.TaskState == TaskState.Freeze)) + + //访视和全局查询已签名完成的,裁判可以是未签名,未完成的 + .Where(t => (t.ReadingTaskState == ReadingTaskState.HaveSigned && (t.ReadingCategory == ReadingCategory.Visit || t.ReadingCategory == ReadingCategory.Global)) || t.ReadingCategory == ReadingCategory.Judge) + .WhereIf(inQuery.TrialReadingCriterionId != null, t => t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId) + .WhereIf(inQuery.TrialSiteId != null, t => t.Subject.TrialSiteId == inQuery.TrialSiteId) + + .WhereIf(inQuery.ArmEnum != null, t => t.ArmEnum == inQuery.ArmEnum) + .WhereIf(!string.IsNullOrEmpty(inQuery.TrialSiteCode), t => (t.BlindTrialSiteCode.Contains(inQuery.TrialSiteCode!) && t.IsAnalysisCreate) || (t.Subject.TrialSite.TrialSiteCode.Contains(inQuery.TrialSiteCode!) && t.IsAnalysisCreate == false)) + .WhereIf(!string.IsNullOrEmpty(inQuery.TaskName), t => t.TaskName.Contains(inQuery.TaskName) || t.TaskBlindName.Contains(inQuery.TaskName)) + .WhereIf(!string.IsNullOrEmpty(inQuery.SubjectCode), t => t.Subject.Code.Contains(inQuery.SubjectCode)) + .Select(t => new TumorExportBaseModel() + { + ResearchProgramNo = t.Trial.ResearchProgramNo, + SubjectCode = t.Subject.Code, + UserName = t.DoctorUser.UserName, + ArmEnum = t.ArmEnum, + + JudgeSignTime = t.ReadingCategory == ReadingCategory.Judge ? t.SignTime : null, + SourceSubjectVisitId = t.SourceSubjectVisitId, + VisitTaskNum = t.VisitTaskNum, + VisitNum = t.VisitTaskNum, + VisitName = t.SourceSubjectVisit.VisitName, + LatestScanDate = t.SourceSubjectVisit.LatestScanDate, + VisitTaskId = t.Id, + CriterionName = t.TrialReadingCriterion.CriterionName, + + + + ReadingCategory = t.ReadingCategory, + ReadingTaskState = t.ReadingTaskState, + + + //以最后为准,没法直接获取(涉及到全局,裁判) + SubjectCriterionReadingPeriodVisitNumList = t.Subject.ReadModuleList.Where(u => u.TrialReadingCriterionId == trialReadingCriterionId && u.ReadingSetType == ReadingSetType.ImageReading).Select(c => c.SubjectVisit.VisitNum).ToList(), + + IsJudgeSelect = null, + + JudgeArmEnum = t.JudgeResultTask.ArmEnum, + + IsTrigerJudge = arbitrationRule == ArbitrationRule.Visit ? t.JudgeVisitTaskId != null : + (arbitrationRule == ArbitrationRule.Reading ? + t.Subject.SubjectVisitTaskList.Any(c => c.TaskState == TaskState.Effect && c.IsAnalysisCreate == false && c.ReadingCategory == ReadingCategory.Judge && c.TrialReadingCriterionId == trialReadingCriterionId && t.VisitTaskNum < c.VisitTaskNum) : + false), + JudgeNote = t.ReadingCategory == ReadingCategory.Judge ? t.JudgeResultRemark : "", + + //全局 访视上修改会要求填写 + VisitNote = t.ReadingTaskQuestionAnswerList.Where(c => c.ReadingQuestionTrial.QuestionType == QuestionType.AdjustReason).FirstOrDefault()!.Answer, + + GlobalResultList = t.GlobalVisitResultList.Where(t => t.GlobalAnswerType == GlobalAnswerType.Reason).Select(t => new TumorGlobalQuestionAnserInfo() + { + TaskId = t.TaskId, + Answer = t.Answer + }).ToList(), + + + + QuestionAnswerList = t.ReadingTaskQuestionAnswerList + .OrderBy(u => u.ReadingQuestionTrial.ShowOrder) + .Select(c => new TumorCommonQustionInfo() + { + QuestionType = c.ReadingQuestionTrial.QuestionType, + QuestionId = c.ReadingQuestionTrial.Id, + QuestionName = isEn_Us ? c.ReadingQuestionTrial.QuestionEnName : c.ReadingQuestionTrial.QuestionName, + QuestionValue = c.IsGlobalChange ? c.GlobalChangeAnswer : c.Answer, + TranslateDicName = c.ReadingQuestionTrial.DictionaryCode, + Unit = c.ReadingQuestionTrial.Unit + }).ToList(), + + LesionList = t.LesionList.OrderBy(t => t.RowMark).Select(c => new TumorLessionInfo() + { + Id=c.Id, + LessionType = c.ReadingQuestionTrial.LesionType, + LessionCode = c.RowMark, + SplitRowId = c.SplitRowId, + DicomModality = c.DicomSeries.DicomStudy.ModalityForEdit, + NoneDicomModality = c.NoneDicomStudy.Modality, + + LessionAnswerList = c.LesionAnswerList.Select(k => new TumorLessionAnswerInfo() + { + + RowId = k.RowId, + TranslateDicName = k.ReadingTableQuestionTrial.DictionaryCode, + QuestionMark = k.ReadingTableQuestionTrial.QuestionMark, + TableQuesionId = k.ReadingTableQuestionTrial.Id, + QuestionName = isEn_Us ? k.ReadingTableQuestionTrial.QuestionEnName : k.ReadingTableQuestionTrial.QuestionName, + QuestionValue = k.Answer, + ShowOrder = k.ReadingTableQuestionTrial.ShowOrder, + Unit = k.ReadingTableQuestionTrial.Unit + + }).ToList(), + + }).ToList() + + }); + + return query; + } + + [HttpPost] + public async Task GetTumor_CDISC_Export(VisitTaskQuery inQuery, + [FromServices] IRepository _visitTaskReReadingRepository, + [FromServices] IDictionaryService _dictionaryService, + [FromServices] IRepository _trialReadingQuestionRepository, + [FromServices] IRepository _trialReadingTableQuestionRepository, + [FromServices] IRepository _trialRepository) + { + //每次查询必须是单标准的 + var criterion = await _readingQuestionCriterionTrialRepository.Where(t => t.CriterionType == inQuery.CriterionType) + .Select(t => new { t.Id, t.CriterionType, t.CriterionGroup, t.IsGlobalReading, t.IsArbitrationReading, t.IsOncologyReading, t.CriterionName, t.ArbitrationRule }).FirstNotNullAsync(); + + var arbitrationRule = criterion.ArbitrationRule; + + var isEn_Us = _userInfo.IsEn_Us; + + var query = GetTumor_CIDSCQueryable(inQuery, arbitrationRule, criterion.Id); + + //任务排序 + var taskList = await query.OrderBy(t => t.SubjectCode).ThenBy(t => t.VisitTaskNum).ThenBy(t => t.ArmEnum).ToListAsync(); + + //重阅信息 + var reReadingList = _visitTaskReReadingRepository.Where(t => t.TrialId == inQuery.TrialId && t.RequestReReadingType == RequestReReadingType.DocotorApply).Select(t => new + { + t.OriginalReReadingTask.VisitTaskNum, + t.OriginalReReadingTask.ArmEnum, + t.OriginalReReadingTask.DoctorUser.UserName, + t.RequestReReadingReason + }).ToList(); + + //处理裁判标记 + taskList = DealJudgeMark(criterion.ArbitrationRule, criterion.IsGlobalReading, taskList); + + + + #region 字典和各个表的数组准备 + + + + var dicNameList = taskList.SelectMany(t => t.QuestionAnswerList).Select(t => t.TranslateDicName) + .Union(taskList.SelectMany(t => t.LesionList).SelectMany(t => t.LessionAnswerList).Where(t => t.TranslateDicName.IsNotNullOrEmpty()).Select(c => c.TranslateDicName)) + .Union(new List() { "ArmEnum", "ValueUnit" }) + .Distinct().ToArray(); + + //翻译字典 + var translateDataList = await _dictionaryService.GetBasicDataSelect(dicNameList); + + //同一个访视,安装顺序编号 + Dictionary visitIndexNoDic = new Dictionary(); + // 同一个subject 安装顺序编号 + Dictionary tr_subjectIndexNoDic = new Dictionary(); + + Dictionary rs_subjectIndexNoDic = new Dictionary(); + + var tuList = new List(); + + var trList = new List(); + + var rsList = new List(); + + var coList = new List(); + + #endregion + + + foreach (var task in taskList) + { + + #region 初始化 + if (task.SourceSubjectVisitId == null) + { + continue; + } + + //处理按照访视维度 给出索引号 + var subjectVisitId = (Guid)task.SourceSubjectVisitId; + + if (!visitIndexNoDic.Keys.Contains(subjectVisitId)) + { + visitIndexNoDic.Add(subjectVisitId, 0); + } + + if (!tr_subjectIndexNoDic.Keys.Contains(task.SubjectCode)) + { + tr_subjectIndexNoDic.Add(task.SubjectCode, 0); + } + + if (!rs_subjectIndexNoDic.Keys.Contains(task.SubjectCode)) + { + rs_subjectIndexNoDic.Add(task.SubjectCode, 0); + } + + task.ArmEnumStr = translateDataList["ArmEnum"].Where(t => t.Code.ToLower() == ((int)task.ArmEnum).ToString().ToLower()).Select(t => isEn_Us ? t.Value : t.ValueCN).FirstOrDefault() ?? String.Empty; + #endregion + + + + foreach (var lesion in task.LesionList) + { + + #region tu 表处理部分 + + var tu = CreatNewTUExport(task, lesion, visitIndexNoDic, translateDataList, isEn_Us); + + + Fill_Resisit_Lugano_TUExport(tu, lesion); + + tuList.Add(tu); + + #endregion + + #region tr 处理部分1 病灶状态和测量值 + + var targetMarks = new List() { QuestionMark.State }; + + if (lesion.LessionAnswerList.Any(t => t.QuestionMark == QuestionMark.IsLymph && t.QuestionValue == "1")) + { + targetMarks.AddRange(new List() { QuestionMark.ShortAxis, }); + } + else if (lesion.LessionAnswerList.FirstOrDefault(t => t.QuestionMark == QuestionMark.MajorAxis)?.QuestionValue.IsNotNullOrEmpty() == true) + { + targetMarks.AddRange(new List() { QuestionMark.MajorAxis }); + } + + + //状态 和长径、短径 + foreach (var lessionAnswer in lesion.LessionAnswerList.Where(t => targetMarks.Any(c => c == t.QuestionMark))) + { + + var tr = CreatNewTRExport(task, tr_subjectIndexNoDic, tu); + + + //填充固定信息 + Fill_TR_Resist_Fixed_Value(tr, lessionAnswer, translateDataList, isEn_Us); + + trList.Add(tr); + } + + + #endregion + + + + } + + foreach (var questionAnswer in task.QuestionAnswerList) + { + + #region TR 处理部分2 访视级别,自动计算 + + var trValueTypeIndex = Get_Resist_TR_Visit_Index(task, questionAnswer); + + if (trValueTypeIndex != -1) + { + var tr = CreatNewTRExport(task, tr_subjectIndexNoDic); + + if (questionAnswer.TranslateDicName.IsNotNullOrEmpty()) + { + tr.OriginalMeasurements = translateDataList[questionAnswer.TranslateDicName].Where(t => t.Code.ToLower() == questionAnswer.QuestionValue?.ToLower()).Select(t => isEn_Us ? t.Value : t.ValueCN).FirstOrDefault() ?? String.Empty; + } + else + { + tr.OriginalMeasurements = questionAnswer.QuestionValue; + } + + tr.OriginalUnit = translateDataList["ValueUnit"].Where(t => t.Code.ToLower() == ((int?)questionAnswer.Unit)?.ToString().ToLower()).Select(t => isEn_Us ? t.Value : t.ValueCN).FirstOrDefault() ?? String.Empty; + + + //填充固定信息 + Fill_TR_IndexValue(tr, trValueTypeIndex, RESIST_TRFixed.TRValueList); + + trList.Add(tr); + } + + #endregion + + #region rs 处理部分 只有非基线 + + //非基线 + if (task.VisitNum > 0) + { + + var rsValueTypeIndex = Get_Resist_RS_VisitFixed_Index(task, questionAnswer); + + if (rsValueTypeIndex != -1) + { + var rs = CreatNewRSExport(task, questionAnswer, rs_subjectIndexNoDic, translateDataList, isEn_Us); + + Fill_RS_IndexValue(rs, rsValueTypeIndex, RESIST_RSFixed.RSValueList); + + + if (questionAnswer.TranslateDicName.IsNotNullOrEmpty()) + { + rs.RespondEfficacyAssessment = translateDataList[questionAnswer.TranslateDicName].Where(t => t.Code.ToLower() == questionAnswer.QuestionValue?.ToLower()).Select(t => isEn_Us ? t.Value : t.ValueCN).FirstOrDefault() ?? String.Empty; + } + else + { + rs.RespondEfficacyAssessment = questionAnswer.QuestionValue; + } + + if (questionAnswer.QuestionType == QuestionType.Tumor) + { + rs.AssessmentReason = task.VisitNote; + + rs.IsOveralResponse = true; + + } + + var findTask = reReadingList.FirstOrDefault(t => t.UserName == rs.UserName && t.ArmEnum == rs.ArmEnum && t.VisitTaskNum == rs.VisitNum); + + if (findTask != null) + { + rs.ReAssessmentReason = findTask.RequestReReadingReason; + } + + + rsList.Add(rs); + } + + } + + #endregion + } + + + #region co 处理部分 + + //非基线 + if (task.VisitNum > 0) + { + //整体肿瘤评估结果备注 + var rs_Tumor = rsList.Where(t => t.VisitTaskId == task.VisitTaskId && t.IsOveralResponse == true).FirstOrDefault(); + + if (rs_Tumor != null) + { + var co = CreatNewCOExport(task, coList.Count + 1); + co.RDOMAIN = "RS"; + co.IdentificationVariable = "RSSEQ"; + co.Identification = rs_Tumor.RSSEQ.ToString(); + co.RemarksQuote = $"{co.ArmEnum} {co.VisitName}"; + co.Remarks = task.VisitNote; + + coList.Add(co); + } + + if (task.IsTrigerJudge == true && task.IsJudgeSelect == true) + { + var co = CreatNewCOExport(task, coList.Count + 1); + + co.RemarksQuote = $"{co.ArmEnum} {co.VisitName}"; + co.Remarks = task.JudgeNote; + co.CODTC = task.JudgeSignTime?.ToString("yyyy-MM-dd"); + + coList.Add(co); + } + + } + + + #endregion + } + + #region 全局更新数据--rs 全局更新原因 + + foreach (var task in taskList.Where(t => t.ReadingCategory == ReadingCategory.Global)) + { + var globalReson = task.GlobalResultList.FirstOrDefault(); + + if (globalReson != null) + { + + foreach (var item in rsList.Where(t => t.VisitTaskId == globalReson.TaskId)) + { + item.UpdateAssessmentReason = globalReson.Answer; + } + } + + } + #endregion + + + + + var exportInfo = (await _trialRepository.Where(t => t.Id == inQuery.TrialId).IgnoreQueryFilters().ProjectTo(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException(); + exportInfo.CriterionName = criterion.CriterionName; + + ////找到只有一个人阅片的受试者 和访视 + //var exceptVisit = taskList.Where(t => t.ReadingCategory == ReadingCategory.Visit) + // .GroupBy(t => new { t.SubjectCode, t.VisitName }).Where(g => g.Count() == 1).Select(g => new { g.Key.SubjectCode, g.Key.VisitName }).ToList(); + + ////去除只有一个人阅片的数据 + //taskList = taskList.Where(t => !exceptVisit.Any(ev => ev.SubjectCode == t.SubjectCode && ev.VisitName == t.VisitName)).ToList(); + + //var sheets = new Dictionary + //{ + // ["TU - Tumor Identification"] = tuList, + // ["TR – Tumor Results"] = trList, + // ["RS – Disease Response"] = rsList, + // ["CO – Comments"] = coList, + //}; + + var sheets = new + { + TUList = tuList, + TRList = trList, + RSList = rsList, + COList = coList, + }; + + return await ExcelExportHelper.MutiSheetDataExportAsync(StaticData.Export.TumorCDISC_Export, sheets, $"{exportInfo.ResearchProgramNo}_{exportInfo.CriterionName}", _commonDocumentRepository, _hostEnvironment); + + + + + } + + + private CO_Export CreatNewCOExport(TumorExportBaseModel task, int index) + { + var co = _mapper.Map(task); + co.Domain = "CO"; + co.COSEQ = index; + + return co; + } + + private RS_Export CreatNewRSExport(TumorExportBaseModel task, TumorCommonQustionInfo questionAnswer, Dictionary subjectIndexNoDic, Dictionary> translateDataList, bool isEn_Us) + { + subjectIndexNoDic[task.SubjectCode]++; + + var rs = _mapper.Map(task); + rs.Domain = "RS"; + + rs.RSSEQ = subjectIndexNoDic[task.SubjectCode]; + + rs.ARM_VisitName = $"{task.ArmEnumStr}_{task.VisitName}"; + + + return rs; + } + + private TR_Export CreatNewTRExport(TumorExportBaseModel task, Dictionary subjectIndexNoDic, TU_Export? tu = null) + { + subjectIndexNoDic[task.SubjectCode]++; + + var tr = _mapper.Map(task); + tr.Domain = "TR"; + + tr.TRSEQ = subjectIndexNoDic[task.SubjectCode]; + + if (tu != null) + { + tr.TRGRPID = tu.TumorIdentificationResult; + tr.ARM_TumorNo = tu.ARM_TumorNo; + tr.IdentificationMethod = tu.IdentificationMethod; + } + + tr.ARM_VisitName = $"{task.ArmEnumStr}_{task.VisitName}"; + + return tr; + + } + + private TU_Export CreatNewTUExport(TumorExportBaseModel task, TumorLessionInfo lesion, Dictionary visitIndexNoDic, Dictionary> translateDataList, bool isEn_Us) + { + var subjectVisitId = (Guid)task.SourceSubjectVisitId; + + visitIndexNoDic[subjectVisitId]++; + + + var tu = _mapper.Map(task); + + ////按照访视编号 + tu.No = visitIndexNoDic[subjectVisitId]; + tu.Domain = "TU"; + + tu.ARM_TumorNo = $"{task.ArmEnumStr}_{lesion.LessionCode}"; + + tu.IdentificationMethod = lesion.DicomModality.IsNotNullOrEmpty() ? lesion.DicomModality! : lesion.NoneDicomModality ?? ""; + + + var findBodyPart = lesion.LessionAnswerList.Where(t => t.QuestionMark == QuestionMark.Part).FirstOrDefault(); + + if (findBodyPart != null) + { + if (findBodyPart.TranslateDicName.IsNotNullOrEmpty()) + { + tu.BodyPart = translateDataList[findBodyPart.TranslateDicName].Where(t => t.Code.ToLower() == findBodyPart.QuestionValue?.ToLower()).Select(t => isEn_Us ? t.Value : t.ValueCN).FirstOrDefault() ?? String.Empty; + } + else + { + tu.BodyPart = findBodyPart.QuestionValue; + } + } + + var findBodyPartDes = lesion.LessionAnswerList.Where(t => t.QuestionMark == QuestionMark.BodyPartDescription).FirstOrDefault(); + + if (findBodyPartDes != null) + { + if (findBodyPartDes.TranslateDicName.IsNotNullOrEmpty()) + { + tu.BodyPartDes = translateDataList[findBodyPartDes.TranslateDicName].Where(t => t.Code.ToLower() == findBodyPartDes.QuestionValue?.ToLower()).Select(t => isEn_Us ? t.Value : t.ValueCN).FirstOrDefault() ?? String.Empty; + } + else + { + tu.BodyPartDes = findBodyPartDes.QuestionValue; + } + } + + return tu; + } + + + + #region Resist CDISC 文档逻辑 + + private int Get_Resist_RS_VisitFixed_Index(TumorExportBaseModel task, TumorCommonQustionInfo questionAnswer) + { + var rsValueTypeIndex = -1; + + switch (questionAnswer.QuestionType) + { + case QuestionType.TargetLesion: + rsValueTypeIndex = 0; + break; + case QuestionType.NoTargetLesion: + rsValueTypeIndex = 1; + break; + case QuestionType.NewLesions: + rsValueTypeIndex = 2; + break; + case QuestionType.Tumor: + rsValueTypeIndex = 3; + break; + + } + + return rsValueTypeIndex; + } + + private RS_Export Fill_RS_IndexValue(RS_Export rs, int rsValueTypeIndex, List RSValueList) + { + + rs.ValueType = RSValueList[rsValueTypeIndex].RSValueType; + rs.EfficacyEvaluationSimpleName = RSValueList[rsValueTypeIndex].EfficacyEvaluationSimpleName; + rs.EfficacyEvaluationName = RSValueList[rsValueTypeIndex].EfficacyEvaluationName; + + return rs; + } + + private int Get_Resist_TR_Visit_Index(TumorExportBaseModel task, TumorCommonQustionInfo questionAnswer) + { + var trValueTypeIndex = -1; + //非基线任务 + if (task.VisitTaskNum > 0) + { + switch (questionAnswer.QuestionType) + { + case QuestionType.SOD: + trValueTypeIndex = 2; + break; + case QuestionType.SumOfDiameter: + trValueTypeIndex = 3; + break; + case QuestionType.SODChange: + trValueTypeIndex = 4; + break; + case QuestionType.SODPercent: + trValueTypeIndex = 5; + break; + case QuestionType.LowestIncrease: + trValueTypeIndex = 6; + break; + case QuestionType.LowPercent: + trValueTypeIndex = 7; + break; + case QuestionType.LowVisit: + trValueTypeIndex = 8; + break; + case QuestionType.IsLymphTarget: + trValueTypeIndex = 9; + break; + case QuestionType.IsAddFive: + trValueTypeIndex = 10; + break; + case QuestionType.NETarget: + trValueTypeIndex = 11; + break; + + } + } + //基线任务 + else + { + switch (questionAnswer.QuestionType) + { + case QuestionType.SOD: + trValueTypeIndex = 2; + + break; + case QuestionType.SumOfDiameter: + trValueTypeIndex = 3; + break; + + case QuestionType.IsLymphTarget: + trValueTypeIndex = 9; + break; + case QuestionType.IsAddFive: + trValueTypeIndex = 10; + break; + case QuestionType.NETarget: + trValueTypeIndex = 11; + break; + } + } + + return trValueTypeIndex; + } + + private TR_Export Fill_TR_IndexValue(TR_Export tr, int trValueTypeIndex, List TRValueList) + { + tr.ValueType = TRValueList[trValueTypeIndex].TRValueType; + tr.TumorAssessmentSimpleName = TRValueList[trValueTypeIndex].TumorAssessmentSimpleName; + tr.TumorAssessmentFullName = TRValueList[trValueTypeIndex].TumorAssessmentFullName; + return tr; + } + + + private TR_Export Fill_TR_Resist_Fixed_Value(TR_Export tr, TumorLessionAnswerInfo lessionAnswer, Dictionary> translateDataList, bool isEn_Us) + { + var trValueTypeIndex = -1; + + if (lessionAnswer.QuestionMark == QuestionMark.State) + { + trValueTypeIndex = 1; + + + if (lessionAnswer.TranslateDicName.IsNotNullOrEmpty()) + { + tr.OriginalMeasurements = translateDataList[lessionAnswer.TranslateDicName].Where(t => t.Code.ToLower() == lessionAnswer.QuestionValue?.ToLower()).Select(t => isEn_Us ? t.Value : t.ValueCN).FirstOrDefault() ?? String.Empty; + + tr.OriginalUnit = "";//状态没有单位 + } + else + { + tr.OriginalMeasurements = lessionAnswer.QuestionValue; + tr.OriginalUnit = "";//状态没有单位 + } + + } + else + { + + + trValueTypeIndex = 0; + tr.OriginalMeasurements = lessionAnswer.QuestionValue; + tr.OriginalUnit = translateDataList["ValueUnit"].Where(t => t.Code.ToLower() == ((int?)lessionAnswer.Unit)?.ToString().ToLower()).Select(t => isEn_Us ? t.Value : t.ValueCN).FirstOrDefault() ?? String.Empty; + } + + + Fill_TR_IndexValue(tr, trValueTypeIndex, RESIST_TRFixed.TRValueList); + + + return tr; + } + + private TU_Export Fill_Resisit_Lugano_TUExport(TU_Export tu, TumorLessionInfo lesion) + { + var lesionTypeIndex = -1; + + //分裂的病灶 + if (lesion.SplitRowId != null) + { + lesionTypeIndex = 3; + } + else + { + + switch (lesion.LessionType) + { + case LesionType.TargetLesion: + lesionTypeIndex = 0; + break; + + case LesionType.NonTargetLesions: + lesionTypeIndex = 1; + break; + + case LesionType.NewLesions: + lesionTypeIndex = 2; + break; + } + } + + if (lesionTypeIndex != -1) + { + tu.ValueType = RESIST_Lugano_TUFixed.TUValueList[lesionTypeIndex].TUValueType; + tu.TumorIdentificationSimple = RESIST_Lugano_TUFixed.TUValueList[lesionTypeIndex].TumorIdentificationSimple; + tu.TumorIdentificationFullName = RESIST_Lugano_TUFixed.TUValueList[lesionTypeIndex].TumorIdentificationFullName; + tu.TumorIdentificationResult = RESIST_Lugano_TUFixed.TUValueList[lesionTypeIndex].TumorIdentificationResult; + tu.TumorIdentificationResultType = RESIST_Lugano_TUFixed.TUValueList[lesionTypeIndex].TumorIdentificationResultType; + } + + return tu; + } + + #endregion + + + + + public List DealJudgeMark(ArbitrationRule arbitrationRule, bool isGlobalReading, IEnumerable list) where T : TumorExportBaseModel + { + //处理访视任务的裁判标记 + var resultExceptJudgeList = list.Where(t => t.ReadingCategory != ReadingCategory.Judge).ToList(); + + var judegeList = list.Where(t => t.ReadingCategory == ReadingCategory.Judge).ToList(); + + if (arbitrationRule == ArbitrationRule.Visit) + { + + foreach (var item in resultExceptJudgeList) + { + var findJudge = judegeList.FirstOrDefault(t => t.SubjectCode == item.SubjectCode + && (t.VisitTaskNum - ReadingCommon.TaskNumDic[ReadingCategory.Judge]) == item.VisitTaskNum); + + if (findJudge != null) + { + if (findJudge.ReadingTaskState == ReadingTaskState.HaveSigned) + { + item.IsJudgeSelect = findJudge.JudgeArmEnum == item.ArmEnum ? true : false; + + item.JudgeNote = findJudge.JudgeArmEnum == item.ArmEnum ? findJudge.JudgeNote : string.Empty; + + item.JudgeSignTime = findJudge.JudgeArmEnum == item.ArmEnum ? findJudge.JudgeSignTime : null; + } + else + { + //默认也是null 其实不用赋值 + item.IsJudgeSelect = null; + } + } + else + { + + //两个人都做了 + if (resultExceptJudgeList.Where(t => t.VisitTaskNum == item.VisitTaskNum && t.SubjectCode == item.SubjectCode).Select(t => t.ArmEnum).Distinct().Count() == 2) + { + //如果没有产生裁判,默认选择R1 + if (item.ArmEnum == Arm.DoubleReadingArm1) + { + item.IsJudgeSelect = true; + } + else + { + item.IsJudgeSelect = false; + } + } + else + { + item.IsJudgeSelect = null; + item.IsTrigerJudge = null; + } + + + + } + } + + } + else if (arbitrationRule == ArbitrationRule.Reading) + { + //处理访视裁判标记 + foreach (var visitItem in resultExceptJudgeList.Where(t => t.ReadingCategory == ReadingCategory.Visit)) + { + ////默认设置为false 只处理为true 和 空的情况 + //visitItem.IsJudgeSelect = false; + + var subjectJudgeList = judegeList.Where(t => t.SubjectCode == visitItem.SubjectCode).ToList(); + + //阅片期访视号 + var subjectReadingPeriondVisitNumList = resultExceptJudgeList.Where(t => t.SubjectCode == visitItem.SubjectCode).FirstOrDefault()?.SubjectCriterionReadingPeriodVisitNumList; + + //两个人完成最大得任务号(访视+全局) + var subjectMaxFinishedTaskNum = resultExceptJudgeList.Where(t => t.SubjectCode == visitItem.SubjectCode) + .GroupBy(t => t.VisitTaskNum).Where(g => g.Count() == 2).Select(g => g.Key).DefaultIfEmpty().Max(); + + var addReadingPeriodNum = isGlobalReading ? ReadingCommon.TaskNumDic[ReadingCategory.Global] : 0; + + var finishedGlobalCount = 0; + + //没有配置阅片期 + if (subjectReadingPeriondVisitNumList == null) + { + finishedGlobalCount = 0; + } + else + { + //已完成的全局数量 + finishedGlobalCount = resultExceptJudgeList.Where(t => t.SubjectCode == visitItem.SubjectCode && subjectReadingPeriondVisitNumList.Any(c => (c + addReadingPeriodNum) == t.VisitTaskNum) + /*&& t.ReadingCategory == ReadingCategory.Global*/) + .Select(t => new { t.VisitTaskNum, t.ArmEnum }).Distinct() + .GroupBy(t => t.VisitTaskNum).Where(g => g.Count() == 2).Select(g => g.Key).Count(); + } + + + visitItem.IsJudgeSelect = null; + visitItem.IsTrigerJudge = null; + + if (finishedGlobalCount != 0) + { + //最大的全局是否产生裁判 + + var subjectMaxFinishedGlobalTaskNum = resultExceptJudgeList.Where(t => t.SubjectCode == visitItem.SubjectCode && subjectReadingPeriondVisitNumList.Any(c => (c + addReadingPeriodNum) == t.VisitTaskNum) + /*&& t.ReadingCategory == ReadingCategory.Global*/) + .Select(t => new { t.VisitTaskNum, t.ArmEnum }).Distinct() + .GroupBy(t => t.VisitTaskNum).Where(g => g.Count() == 2).Select(g => g.Key).DefaultIfEmpty().Max(); + + //最大的完成的全局是否产生裁判 + if (subjectJudgeList.Any(t => t.VisitTaskNum == (subjectMaxFinishedGlobalTaskNum + ReadingCommon.TaskNumDic[ReadingCategory.Judge]))) + { + + var maxJudge = subjectJudgeList.FirstOrDefault(t => t.VisitTaskNum == (subjectMaxFinishedGlobalTaskNum + ReadingCommon.TaskNumDic[ReadingCategory.Judge])); + + //最大裁判完成了 + if (maxJudge.ReadingTaskState == ReadingTaskState.HaveSigned) + { + if (visitItem.VisitTaskNum < maxJudge.VisitTaskNum) + { + //触发裁判 + visitItem.IsTrigerJudge = true; + + if (visitItem.ArmEnum == maxJudge.JudgeArmEnum) + { + visitItem.IsJudgeSelect = true; + visitItem.JudgeNote = maxJudge.JudgeNote; + + visitItem.JudgeSignTime = maxJudge.JudgeSignTime; + } + //裁判没选择的人设置为false + else + { + visitItem.IsJudgeSelect = false; + } + } + else + { + //后续访视 未知 默认都是null + + } + } + else + { + //找到当前未阅最大裁判之前的已完成的最大裁判任务 + var maxFinishedJudge = subjectJudgeList.Where(t => t.ReadingTaskState == ReadingTaskState.HaveSigned).OrderByDescending(t => t.VisitTaskNum).FirstOrDefault(); + + if (maxFinishedJudge == null) + { + // 为空 裁判选择标记默认就是null 不用处理 + + if (visitItem.VisitTaskNum < maxJudge.VisitTaskNum) + { + visitItem.IsTrigerJudge = true; + } + + } + else + { + if (visitItem.VisitTaskNum < maxFinishedJudge.VisitTaskNum) + { + visitItem.IsTrigerJudge = true; + + if (visitItem.ArmEnum == maxFinishedJudge.JudgeArmEnum) + { + visitItem.IsJudgeSelect = true; + visitItem.JudgeNote = maxFinishedJudge.JudgeNote; + visitItem.JudgeSignTime = maxFinishedJudge.JudgeSignTime; + } + //裁判没选择的人设置为false + else + { + visitItem.IsJudgeSelect = false; + } + } + else if (visitItem.VisitTaskNum > maxFinishedJudge.VisitTaskNum && visitItem.VisitTaskNum < maxJudge.VisitTaskNum) + { + //完成裁判 和未完成裁判之间的 裁判选择标记默认是null + + visitItem.IsTrigerJudge = true; + } + else + { + //在未完成全局裁判之后的访视 未知 默认都是null + + + } + + } + + } + + + } + else + { + //最大的完成的全局未产生裁判 + + if (visitItem.VisitTaskNum <= subjectMaxFinishedGlobalTaskNum) + { + visitItem.IsTrigerJudge = false; + + if (visitItem.ArmEnum == Arm.DoubleReadingArm1) + { + visitItem.IsJudgeSelect = true; + + } + else + { + visitItem.IsJudgeSelect = false; + } + } + else + { + //未产生裁判的全局之后的访视 两个标记都是null (后续可能还有全局,但是全局两个人没做完) + } + + + } + + + } + + + + } + } + else + { + foreach (var visitItem in resultExceptJudgeList.Where(t => t.ReadingCategory == ReadingCategory.Visit)) + { + visitItem.IsJudgeSelect = null; + visitItem.IsTrigerJudge = null; + } + + } + return resultExceptJudgeList; + } +} diff --git a/IRaCIS.Core.Application/Service/Common/_MapConfig.cs b/IRaCIS.Core.Application/Service/Common/_MapConfig.cs index 87414774d..58959b362 100644 --- a/IRaCIS.Core.Application/Service/Common/_MapConfig.cs +++ b/IRaCIS.Core.Application/Service/Common/_MapConfig.cs @@ -2,6 +2,7 @@ using IRaCIS.Application.Contracts; using IRaCIS.Core.Application.Contracts; using IRaCIS.Core.Application.Helper; +using IRaCIS.Core.Application.Service.Common; using IRaCIS.Core.Application.ViewModel; namespace IRaCIS.Core.Application.Service @@ -107,6 +108,10 @@ namespace IRaCIS.Core.Application.Service .ForMember(d => d.TrialSiteCode, u => u.MapFrom(s => s.Subject.TrialSite.TrialSiteCode)); + CreateMap(); + CreateMap(); + CreateMap(); + CreateMap(); } } diff --git a/IRaCIS.Core.Application/Service/Reading/ReadingCriterion/ReadingQuestionService.cs b/IRaCIS.Core.Application/Service/Reading/ReadingCriterion/ReadingQuestionService.cs index e416e4a53..fdae149b3 100644 --- a/IRaCIS.Core.Application/Service/Reading/ReadingCriterion/ReadingQuestionService.cs +++ b/IRaCIS.Core.Application/Service/Reading/ReadingCriterion/ReadingQuestionService.cs @@ -68,8 +68,8 @@ namespace IRaCIS.Core.Application.Service throw new BusinessValidationFailedException(_localizer["ReadingQuestion_CDISCCodeRepeat"]); } - if(inDto.QuestionList.Any(x=>x.ExportResult.Contains(ExportResult.CDISC)&&x.CDISCCode.IsNullOrEmpty()) - || inDto.TableQuestionList.Any(x => x.ExportResult.Contains(ExportResult.CDISC) && x.CDISCCode.IsNullOrEmpty()) + if(inDto.QuestionList.Any(x=>x.ExportResult.Contains(ExportResult.NoneTumorCDISC)&&x.CDISCCode.IsNullOrEmpty()) + || inDto.TableQuestionList.Any(x => x.ExportResult.Contains(ExportResult.NoneTumorCDISC) && x.CDISCCode.IsNullOrEmpty()) ) { throw new BusinessValidationFailedException(_localizer["ReadingQuestion_CDISCCodeCannotEmpty"]); diff --git a/IRaCIS.Core.Domain.Share/Reading/ReadEnum.cs b/IRaCIS.Core.Domain.Share/Reading/ReadEnum.cs index 97bb4eaf3..26c2dbed5 100644 --- a/IRaCIS.Core.Domain.Share/Reading/ReadEnum.cs +++ b/IRaCIS.Core.Domain.Share/Reading/ReadEnum.cs @@ -516,7 +516,7 @@ namespace IRaCIS.Core.Domain.Share /// /// CDISC导出 /// - CDISC = 8, + NoneTumorCDISC = 8, //访视一致率 @@ -525,6 +525,8 @@ namespace IRaCIS.Core.Domain.Share //阅片期一致率 ReadingPeriodJudgeRatio_Export = 18, + TumorCDISC_Export=20, + } diff --git a/IRaCIS.Core.Domain/Reading/ReadingFormAnswer/ReadingNoneDicomMark.cs b/IRaCIS.Core.Domain/Reading/ReadingFormAnswer/ReadingNoneDicomMark.cs index 1905d1565..b8ece835c 100644 --- a/IRaCIS.Core.Domain/Reading/ReadingFormAnswer/ReadingNoneDicomMark.cs +++ b/IRaCIS.Core.Domain/Reading/ReadingFormAnswer/ReadingNoneDicomMark.cs @@ -13,6 +13,7 @@ public class ReadingNoneDicomMark : BaseAddAuditEntity public Guid VisitTaskId { get; set; } public Guid? StudyId { get; set; } + public Guid? NoneDicomFileId { get; set; } [StringLength(1000)] diff --git a/IRaCIS.Core.Domain/Reading/ReadingFormAnswer/ReadingTableAnswerRowInfo.cs b/IRaCIS.Core.Domain/Reading/ReadingFormAnswer/ReadingTableAnswerRowInfo.cs index 2bdaaa87d..efd7e54ed 100644 --- a/IRaCIS.Core.Domain/Reading/ReadingFormAnswer/ReadingTableAnswerRowInfo.cs +++ b/IRaCIS.Core.Domain/Reading/ReadingFormAnswer/ReadingTableAnswerRowInfo.cs @@ -11,6 +11,18 @@ public class ReadingTableAnswerRowInfo : BaseFullDeleteAuditEntity [ForeignKey("InstanceId")] public DicomInstance Instance { get; set; } + + [JsonIgnore] + [ForeignKey("SeriesId")] + public DicomSeries DicomSeries { get; set; } + + /// + /// studyId 关联 dicom 和非dicom ,这里为了查询方便,默认查询非dicom dicom 通过序列查询 + /// + [JsonIgnore] + [ForeignKey("StudyId")] + public NoneDicomStudy NoneDicomStudy { get; set; } + [JsonIgnore] [ForeignKey("OrganInfoId")] public OrganInfo OrganInfo { get; set; } diff --git a/IRaCIS.Core.Infra.EFCore/EntityConfigration/ImageConfigration.cs b/IRaCIS.Core.Infra.EFCore/EntityConfigration/ImageConfigration.cs index f2e4ef204..93bb2349b 100644 --- a/IRaCIS.Core.Infra.EFCore/EntityConfigration/ImageConfigration.cs +++ b/IRaCIS.Core.Infra.EFCore/EntityConfigration/ImageConfigration.cs @@ -112,6 +112,18 @@ public class SCPInstanceConfigration : IEntityTypeConfiguration } +public class ReadingTableAnswerRowInfoConfigration : IEntityTypeConfiguration +{ + public void Configure(EntityTypeBuilder builder) + { + + + builder.HasOne(e => e.DicomSeries).WithMany().HasForeignKey(t => t.SeriesId).HasPrincipalKey(st => st.Id); + + builder.HasOne(e => e.Instance).WithMany().HasForeignKey(t => t.InstanceId).HasPrincipalKey(st => st.Id); + } +} + diff --git a/IRaCIS.Core.Infrastructure/_IRaCIS/_Config/_StaticData.cs b/IRaCIS.Core.Infrastructure/_IRaCIS/_Config/_StaticData.cs index 36f7273cf..84eb1bc26 100644 --- a/IRaCIS.Core.Infrastructure/_IRaCIS/_Config/_StaticData.cs +++ b/IRaCIS.Core.Infrastructure/_IRaCIS/_Config/_StaticData.cs @@ -309,6 +309,8 @@ public static class StaticData //一致性全量核查导出 public const string TrialConsistentFUllCheckList_Export = "TrialConsistentFUllCheckList_Export"; + public const string TumorCDISC_Export = "TumorCDISC_Export"; + }