diff --git a/IRaCIS.Core.API/appsettings.Test_IRC.json b/IRaCIS.Core.API/appsettings.Test_IRC.json
index fa496f94e..0f43fe7f1 100644
--- a/IRaCIS.Core.API/appsettings.Test_IRC.json
+++ b/IRaCIS.Core.API/appsettings.Test_IRC.json
@@ -117,7 +117,7 @@
// 转换PDF服务配置
"ThirdPdfUrl": "http://106.14.89.110:30088/api/v1/convert/file/pdf",
//MFA免验证发送天数
- "UserMFAVerifyDays": 1
+ "UserMFAVerifyMinutes": 1440
},
// 邮件服务配置(用于系统通知、找回密码、错误报警等)
"SystemEmailSendConfig": {
diff --git a/IRaCIS.Core.Application/BusinessFilter/_Config/_AppSettings.cs b/IRaCIS.Core.Application/BusinessFilter/_Config/_AppSettings.cs
index aa433b847..cb1ff82a8 100644
--- a/IRaCIS.Core.Application/BusinessFilter/_Config/_AppSettings.cs
+++ b/IRaCIS.Core.Application/BusinessFilter/_Config/_AppSettings.cs
@@ -38,7 +38,7 @@ public class ServiceVerifyConfigOption
public string ThirdPdfUrl { get; set; }
- public int UserMFAVerifyDays { get; set; } = 1;
+ public int UserMFAVerifyMinutes { get; set; } = 1440;
}
diff --git a/IRaCIS.Core.Application/Helper/CacheHelper.cs b/IRaCIS.Core.Application/Helper/CacheHelper.cs
index 4d340bb5e..850d7be88 100644
--- a/IRaCIS.Core.Application/Helper/CacheHelper.cs
+++ b/IRaCIS.Core.Application/Helper/CacheHelper.cs
@@ -61,8 +61,8 @@ public static class CacheKeys
///
public static string StartRestTime(Guid userId) => $"{userId}StartRestTime";
-
- public static string UserMFAVerifyPass(Guid userId) => $"UserMFAVerifyPass:{userId}";
+ //每个用户 每个浏览器独立时间
+ public static string UserMFAVerifyPass(Guid userId,string browserFingerprint) => $"UserMFAVerifyPass:{userId}:{browserFingerprint}";
}
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 64853942e..2cb56ec0e 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..29fd17424
--- /dev/null
+++ b/IRaCIS.Core.Application/Service/Common/Export/RESISTExportService.cs
@@ -0,0 +1,1183 @@
+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
+ .WhereIf(inQuery.TrialReadingCriterionId != null, t => t.Id == inQuery.TrialReadingCriterionId)
+ .WhereIf(inQuery.CriterionType != null, 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/MailService.cs b/IRaCIS.Core.Application/Service/Common/MailService.cs
index 5d99c60bb..9c00c1be9 100644
--- a/IRaCIS.Core.Application/Service/Common/MailService.cs
+++ b/IRaCIS.Core.Application/Service/Common/MailService.cs
@@ -989,7 +989,7 @@ namespace IRaCIS.Core.Application.Service
};
- await GetEmailSubejctAndHtmlInfoAndBuildAsync(EmailBusinessScenario.SiteSurvey_CheckUser, messageToSend, emailConfigFunc);
+ await GetEmailSubejctAndHtmlInfoAndBuildAsync(EmailBusinessScenario.SiteSurvey_UpdateUser, messageToSend, emailConfigFunc);
await SendEmailHelper.SendEmailAsync(messageToSend, _systemEmailConfig);
}
diff --git a/IRaCIS.Core.Application/Service/Common/_MapConfig.cs b/IRaCIS.Core.Application/Service/Common/_MapConfig.cs
index d66a5887a..1059c599a 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
@@ -115,6 +116,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/Management/UserService.cs b/IRaCIS.Core.Application/Service/Management/UserService.cs
index 78e34ca93..77b1c03ab 100644
--- a/IRaCIS.Core.Application/Service/Management/UserService.cs
+++ b/IRaCIS.Core.Application/Service/Management/UserService.cs
@@ -861,7 +861,7 @@ namespace IRaCIS.Core.Application.Service
if (isRemember)
{
- await _fusionCache.SetAsync(CacheKeys.UserMFAVerifyPass(identityUserId), _userInfo.BrowserFingerprint, TimeSpan.FromDays(_serviceVerifyConfigConfig.UserMFAVerifyDays));
+ await _fusionCache.SetAsync(CacheKeys.UserMFAVerifyPass(identityUserId, _userInfo.BrowserFingerprint), _userInfo.BrowserFingerprint, TimeSpan.FromMinutes(_serviceVerifyConfigConfig.UserMFAVerifyMinutes));
}
@@ -1107,9 +1107,9 @@ namespace IRaCIS.Core.Application.Service
var userAgreementList = await _userAgreementRepository.Where(t => t.IsCurrentVersion).OrderByDescending(t => t.CreateTime).ToListAsync();
- var userAgreement= userAgreementList.FirstOrDefault(t => t.UserAgreementTypeEnum == UserAgreementType.UserAgreement);
+ var userAgreement = userAgreementList.FirstOrDefault(t => t.UserAgreementTypeEnum == UserAgreementType.UserAgreement);
- if (userAgreement!=null&& loginUser.UserAgreementId!= userAgreement.Id)
+ if (userAgreement != null && loginUser.UserAgreementId != userAgreement.Id)
{
await _identityUserRepository.BatchUpdateNoTrackingAsync(x => x.Id == loginUser.IdentityUserId, x => new IdentityUser()
{
@@ -1119,13 +1119,13 @@ namespace IRaCIS.Core.Application.Service
var obj = new
{
UserAgreementTypeEnum = UserAgreementType.UserAgreement,
- FileVersion=userAgreement.FileVersion,
- UserAgreementId=userAgreement.Id,
- IsEn_Us= _userInfo.IsEn_Us,
+ FileVersion = userAgreement.FileVersion,
+ UserAgreementId = userAgreement.Id,
+ IsEn_Us = _userInfo.IsEn_Us,
};
-
- await _userLogRepository.AddAsync(new UserLog() { IP = _userInfo.IP, ActionIdentityUserId = loginUser.IdentityUserId, ActionUserName = loginUser.UserName, OptType = UserOptType.AcceptUserAgreement, JsonObj= obj.ToJsonStr() }, true);
+
+ await _userLogRepository.AddAsync(new UserLog() { IP = _userInfo.IP, ActionIdentityUserId = loginUser.IdentityUserId, ActionUserName = loginUser.UserName, OptType = UserOptType.AcceptUserAgreement, JsonObj = obj.ToJsonStr() }, true);
}
@@ -1176,7 +1176,7 @@ namespace IRaCIS.Core.Application.Service
if (_verifyConfig.CurrentValue.OpenLoginMFA)
{
- if ((await _fusionCache.GetOrDefaultAsync(CacheKeys.UserMFAVerifyPass(identityUserId), "")) == _userInfo.BrowserFingerprint)
+ if ((await _fusionCache.GetOrDefaultAsync(CacheKeys.UserMFAVerifyPass(identityUserId, _userInfo.BrowserFingerprint), "")) == _userInfo.BrowserFingerprint)
{
userLoginReturnModel.IsMFA = false;
}
@@ -1196,9 +1196,10 @@ namespace IRaCIS.Core.Application.Service
//修改密码 || 90天修改密码再mfa 之前
if (userLoginReturnModel.BasicInfo.IsFirstAdd || userLoginReturnModel.BasicInfo.NeedChangePassWord)
{
+ //移动到上面去了
//userLoginReturnModel.JWTStr = _tokenService.GetToken(userLoginReturnModel.BasicInfo);
}
- else
+ else if (userLoginReturnModel.IsMFA == true)
{
//正常登录才发送邮件
await SendMFAEmail(new SendMfaCommand() { IdentityUserId = identityUserId, MFAType = UserMFAType.Login });
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 529e6fed3..291619cb4 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..ba0c6bf88 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";
+
}