From 9158f28998272d0d6946e5f1c07f4f5e08110ef9 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Tue, 25 Nov 2025 09:56:51 +0800 Subject: [PATCH 01/13] =?UTF-8?q?=E5=8C=BB=E5=AD=A6=E5=AE=A1=E6=A0=B8?= =?UTF-8?q?=E5=AF=B9=E8=AF=9D=E5=AF=BC=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../IRaCIS.Core.Application.xml | 13 ++ .../Service/Common/ExcelExportService.cs | 160 ++++++++++++++++++ .../Service/QC/DTO/QCListViewModel.cs | 8 + .../Service/QC/_MapConfig.cs | 5 +- .../Reading/Dto/ReadingMedicalReviewDto.cs | 2 + 5 files changed, 186 insertions(+), 2 deletions(-) diff --git a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml index 2fbc18fdc..12edfd5d1 100644 --- a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml +++ b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml @@ -900,6 +900,14 @@ + + + 获取医学审核对话拼接内容 + + + + + 影像下载记录表 @@ -9187,6 +9195,11 @@ 任务Id + + + 单位 + + 保存表格问题标记 diff --git a/IRaCIS.Core.Application/Service/Common/ExcelExportService.cs b/IRaCIS.Core.Application/Service/Common/ExcelExportService.cs index 82f8a9eb3..6d302a3f4 100644 --- a/IRaCIS.Core.Application/Service/Common/ExcelExportService.cs +++ b/IRaCIS.Core.Application/Service/Common/ExcelExportService.cs @@ -22,6 +22,8 @@ using System.ComponentModel.Design; using System.Globalization; using System.IO; using System.Linq; +using System.Reflection; +using System.Text; using static IRaCIS.Core.Application.Service.ExcelExportHelper; using IDictionaryService = IRaCIS.Application.Interfaces.IDictionaryService; using TrialIdentityUser = IRaCIS.Core.Domain.Models.TrialIdentityUser; @@ -32,6 +34,8 @@ namespace IRaCIS.Core.Application.Service.Common [ApiExplorerSettings(GroupName = "Common")] public class ExcelExportService(IRepository _trialUserRoleRepository, IRepository _visitTaskRepository, + IRepository _dictionaryRepository, + IRepository _internationalizationRepository, IRepository _readingQuestionCriterionTrialRepository, IRepository _systemDocNeedConfirmedUserTypeRepository, IRepository _dicomStudyRepository, @@ -1758,6 +1762,80 @@ namespace IRaCIS.Core.Application.Service.Common var list = taskMedicalReviewQueryable.OrderBy(t => t.TrialSiteCode).ThenBy(t => t.SubjectCode).ThenBy(t => t.VisitTaskNum).ToList(); + #region 处理翻译对话 by he wen tao + + Dictionary i18NKeys = new Dictionary() + { + { "Msg1","trials:medicalFeedback:message:msg1"}, + { "Msg2","trials:medicalFeedback:message:msg2"}, + { "Msg3","trials:medicalFeedback:message:msg3"}, + { "Msg4", "trials:medicalFeedback:message:msg4"}, + { "Msg5", "trials:medicalFeedback:message:msg5"}, + { "CloseReasonEnum", "trials:medicalFeedback:title:closeReasonEnum"}, + { "IsEndorse", "trials:medicalFeedback:title:isEndorse"}, + { "Reason", "trials:medicalFeedback:title:reason"}, + { "IsRequestReread", "trials:medicalFeedback:title:isRequestReread"}, + }; + + var i18Values = i18NKeys.Select(x => x.Value).ToList(); + var i18nList = await _internationalizationRepository.Where(x => i18Values.Contains(x.Code)) + .Select(x => new + { + Code = x.Code, + Value = _userInfo.IsEn_Us ? x.Value : x.ValueCN + }).ToListAsync(); + + List dictionaryCodeList = new List() + { + "AuditAdvice", + "MedicalDialogCloseEnum", + "MedicalReviewDoctorUserIdea", + "YesOrNo", + }; + + var dictionadParents = await _dictionaryRepository.Where(x => dictionaryCodeList.Contains(x.Parent.Code)) + .Select(x => new + { + ParentCode = x.Parent.Code, + Code = x.Code, + Value = _userInfo.IsEn_Us ? x.Value : x.ValueCN + }).ToListAsync(); + + JointMedicalReviewI18n i18N = new JointMedicalReviewI18n() { }; + foreach (var kv in i18NKeys) + { + PropertyInfo? pi = i18N.GetType().GetProperty(kv.Key); + if (pi != null && pi.CanWrite) + { + var value = i18nList.Where(x => x.Code == kv.Value).Select(x => x.Value).FirstOrDefault() ?? string.Empty; + object safeValue = Convert.ChangeType(value, pi.PropertyType); + pi.SetValue(i18N, safeValue); + } + } + foreach (var item in dictionaryCodeList) + { + PropertyInfo? pi = i18N.GetType().GetProperty(item); + if (pi != null && pi.CanWrite) + { + var value = dictionadParents.Where(x => x.ParentCode == item).ToDictionary(x => x.Code, x => x.Value); + object safeValue = Convert.ChangeType(value, pi.PropertyType); + pi.SetValue(i18N, safeValue); + } + } + + + foreach (var item in list) + { + foreach (var dialog in item.DialogList) + { + dialog.ResultContent = JointMedicalReviewDialog(dialog, i18N); + } + } + + + #endregion + + var exportInfo = (await _trialRepository.Where(t => t.Id == inQuery.TrialId).IgnoreQueryFilters().ProjectTo(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException(); exportInfo.List = ExportExcelConverterDate.ConvertToClientTimeInObject(list, _userInfo.TimeZoneId); @@ -1767,6 +1845,88 @@ namespace IRaCIS.Core.Application.Service.Common return await ExcelExportHelper.DataExportAsync(StaticData.Export.TrialMedicalReviewList_Export, exportInfo, $"{exportInfo.ResearchProgramNo}", _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(TaskMedicalReviewExportDto)); } + /// + /// 获取医学审核对话拼接内容 + /// + /// + /// + /// + private string JointMedicalReviewDialog(GetMedicalReviewDialogOutDto record, JointMedicalReviewI18n i18NAndDic) + { + StringBuilder str = new StringBuilder() { }; + var userTypes = new List() { 14, 30 }; + + // 这里userTypes.Contains(record.UserTypeEnumInt) 可以提出来 但是还是按照前端写吧 免得不好对照 + + // v-if="[14, 30].includes(record.UserTypeEnumInt) && record.Questioning + if (userTypes.Contains(record.UserTypeEnumInt) && record.Questioning.IsNotNullOrEmpty()) + { + // + str.AppendLine(i18NAndDic.Msg1); + + str.AppendLine(record.Questioning); + + if (record.FileList.Count() > 0) + { + str.AppendLine(i18NAndDic.Msg2); + record.FileList.ForEach(x => + { + str.AppendLine(x.FileName); + }); + } + + str.AppendLine(i18NAndDic.Msg3); + + str.AppendLine(i18NAndDic.AuditAdvice[record.AuditAdviceEnum.GetEnumInt()]); + + str.AppendLine(i18NAndDic.Msg4); + } + + //v-if="[14, 30].includes(record.UserTypeEnumInt) && record.MedicalDialogCloseEnum!== null" + if (userTypes.Contains(record.UserTypeEnumInt) && record.MedicalDialogCloseEnum != null) + { + str.AppendLine(i18NAndDic.CloseReasonEnum + i18NAndDic.MedicalDialogCloseEnum[record.MedicalDialogCloseEnum.Value.GetEnumInt()]); + } + + // v-if="[14, 30].includes(record.UserTypeEnumInt) && record.Content + if (userTypes.Contains(record.UserTypeEnumInt) && record.Content.IsNotNullOrEmpty()) + { + str.AppendLine(record.Content); + } + + // v-if="[13].includes(record.UserTypeEnumInt)" + + if (13 == record.UserTypeEnumInt) + { + str.AppendLine(i18NAndDic.IsEndorse + i18NAndDic.MedicalReviewDoctorUserIdea[record.DoctorUserIdeaEnum.GetEnumInt()]); + + // v-if="record.DoctorUserIdeaEnum===2" + if ((int)record.DoctorUserIdeaEnum == 2) + { + str.AppendLine(i18NAndDic.Reason + record.DisagreeReason); + } + + // record.MedicalDialogCloseEnum!== null + + if (record.MedicalDialogCloseEnum != null) + { + str.AppendLine(i18NAndDic.IsRequestReread + i18NAndDic.YesOrNo[record.IsApplyHeavyReading.ToString()]); + } + + // v-if="record.FileList && record.FileList.length > 0" + + if (record.FileList.Count() > 0) + { + record.FileList.ForEach(x => + { + str.AppendLine(x.FileName); + }); + } + } + + return str.ToString(); + + } /// /// 影像下载记录表 diff --git a/IRaCIS.Core.Application/Service/QC/DTO/QCListViewModel.cs b/IRaCIS.Core.Application/Service/QC/DTO/QCListViewModel.cs index 526f366ab..1c2629107 100644 --- a/IRaCIS.Core.Application/Service/QC/DTO/QCListViewModel.cs +++ b/IRaCIS.Core.Application/Service/QC/DTO/QCListViewModel.cs @@ -1,6 +1,7 @@ using IRaCIS.Core.API._ServiceExtensions.NewtonsoftJson; using IRaCIS.Core.Application.Contracts.DTO; using IRaCIS.Core.Application.Helper; +using IRaCIS.Core.Application.Service.Reading.Dto; using IRaCIS.Core.Domain.Share; using MiniExcelLibs.Attributes; using Newtonsoft.Json; @@ -989,6 +990,13 @@ namespace IRaCIS.Core.Application.Contracts /// [DictionaryTranslateAttribute("YesOrNo")] public bool IsInvalid { get; set; } + + + + public List DialogList { get; set; } + + public string DialogStr => string.Join("\n\n", DialogList.OrderBy(t => t.CreateTime).Select(c => c.CreateUserName + " (" + ExportExcelConverterDate.DateTimeInternationalToString(c.CreateTime) + ") :" + c.ResultContent)); + } public class TrialImageDownloadExportDto diff --git a/IRaCIS.Core.Application/Service/QC/_MapConfig.cs b/IRaCIS.Core.Application/Service/QC/_MapConfig.cs index 3af58e72a..f94b1bb1f 100644 --- a/IRaCIS.Core.Application/Service/QC/_MapConfig.cs +++ b/IRaCIS.Core.Application/Service/QC/_MapConfig.cs @@ -179,13 +179,14 @@ namespace IRaCIS.Core.Application.Service .ForMember(o => o.MedicalNo, t => t.MapFrom(u => u.VisitTask.Subject.MedicalNo)) .ForMember(o => o.DoctorUserName, t => t.MapFrom(u => u.VisitTask.DoctorUser.UserName)) .ForMember(o => o.MedicalManagerUserName, t => t.MapFrom(u => u.MedicalManagerUser.UserName)) - .ForMember(o => o.QuestionContent, t => t.MapFrom(u => string.Join("\n\n", u.ReadingMedicalReviewDialogList.Where(t => t.IsHaveQuestion).Select(t => t.Questioning)))); + .ForMember(o => o.QuestionContent, t => t.MapFrom(u => string.Join("\n\n", u.ReadingMedicalReviewDialogList.Where(t => t.IsHaveQuestion).Select(t => t.Questioning)))) + .ForMember(o => o.DialogList, t => t.MapFrom(u => u.ReadingMedicalReviewDialogList)); CreateMap() .ForMember(o => o.TrialReadingCriterionName, t => t.MapFrom(u => u.TrialReadingCriterion.CriterionName)) .ForMember(o => o.TrialSiteCode, t => t.MapFrom(u => u.IsSelfAnalysis == true ? u.BlindTrialSiteCode : u.Subject.TrialSite.TrialSiteCode)) .ForMember(o => o.SubjectCode, t => t.MapFrom(u => u.IsSelfAnalysis == true ? u.BlindSubjectCode : u.Subject.Code)) - + ; diff --git a/IRaCIS.Core.Application/Service/Reading/Dto/ReadingMedicalReviewDto.cs b/IRaCIS.Core.Application/Service/Reading/Dto/ReadingMedicalReviewDto.cs index 4f7939d5a..b50c85548 100644 --- a/IRaCIS.Core.Application/Service/Reading/Dto/ReadingMedicalReviewDto.cs +++ b/IRaCIS.Core.Application/Service/Reading/Dto/ReadingMedicalReviewDto.cs @@ -343,6 +343,8 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto public List FileList { get; set; } = new List(); + //存储最后翻译的内容 + public string ResultContent { get; set; } } From f19fc0e92f98154362c77b9c861453ecfc550be1 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Thu, 27 Nov 2025 10:56:05 +0800 Subject: [PATCH 02/13] =?UTF-8?q?ivus-=E5=AF=BC=E8=A1=A8=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Attribute/DictionaryTranslateAttribute.cs | 12 + .../Service/Common/ExcelExportService.cs | 5 + .../Service/Common/IVUS_OCTExportService.cs | 1017 +++++++++++++++++ .../Service/Common/_MapConfig.cs | 4 + IRaCIS.Core.Domain.Share/Reading/ReadEnum.cs | 29 +- .../_IRaCIS/ObjectExtension.cs | 7 + .../_IRaCIS/_Config/_StaticData.cs | 4 + 7 files changed, 1077 insertions(+), 1 deletion(-) create mode 100644 IRaCIS.Core.Application/Service/Common/IVUS_OCTExportService.cs diff --git a/IRaCIS.Core.Application/Helper/FileDocProcess/Attribute/DictionaryTranslateAttribute.cs b/IRaCIS.Core.Application/Helper/FileDocProcess/Attribute/DictionaryTranslateAttribute.cs index 051b72909..e54a72747 100644 --- a/IRaCIS.Core.Application/Helper/FileDocProcess/Attribute/DictionaryTranslateAttribute.cs +++ b/IRaCIS.Core.Application/Helper/FileDocProcess/Attribute/DictionaryTranslateAttribute.cs @@ -60,4 +60,16 @@ namespace IRaCIS.Core.Application.Helper } } + + [AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = false)] + public class DateTimeTranaslateAttribute : Attribute + { + public string Formart { get; set; } + + public DateTimeTranaslateAttribute(string formart) + { + Formart = formart; + + } + } } diff --git a/IRaCIS.Core.Application/Service/Common/ExcelExportService.cs b/IRaCIS.Core.Application/Service/Common/ExcelExportService.cs index 6d302a3f4..203ec15a3 100644 --- a/IRaCIS.Core.Application/Service/Common/ExcelExportService.cs +++ b/IRaCIS.Core.Application/Service/Common/ExcelExportService.cs @@ -2765,6 +2765,11 @@ namespace IRaCIS.Core.Application.Service.Common if (criterion.CriterionType == CriterionType.OCT) { list.Add(new ExportDocumentDes() { Code = StaticData.Export.OCT_ReadingLession_Export, ExportCatogory = ExportResult.OCT_ReadingLession_Export }); + list.Add(new ExportDocumentDes() { Code = StaticData.Export.OCT_CDISC_Export, ExportCatogory = ExportResult.OCT_CDISC_Export }); + } + if (criterion.CriterionType == CriterionType.IVUS) + { + list.Add(new ExportDocumentDes() { Code = StaticData.Export.IVUS_CDISC_Export, ExportCatogory = ExportResult.IVUS_CDISC_Export }); } if (criterion.CriterionGroup != CriterionGroup.Tumor) diff --git a/IRaCIS.Core.Application/Service/Common/IVUS_OCTExportService.cs b/IRaCIS.Core.Application/Service/Common/IVUS_OCTExportService.cs new file mode 100644 index 000000000..8796c4f77 --- /dev/null +++ b/IRaCIS.Core.Application/Service/Common/IVUS_OCTExportService.cs @@ -0,0 +1,1017 @@ +using IRaCIS.Application.Contracts; +using IRaCIS.Application.Interfaces; +using IRaCIS.Core.Application.Helper; +using IRaCIS.Core.Application.ViewModel; +using IRaCIS.Core.Domain.Share; +using IRaCIS.Core.Infra.EFCore.Common; +using IRaCIS.Core.Infrastructure.Extention; +using MassTransit; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Mvc; +using MiniExcelLibs; +using MiniExcelLibs.OpenXml; +using NPOI.SS.Formula.Functions; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace IRaCIS.Core.Application.Service.Common; + +#region 模型 + +/// +/// 公共影像导表基类(IVUS / OCT 通用) +/// +public class IVUS_OCTBaseDto +{ + /// 研究标识符 + public string ResearchProgramNo { get; set; } + + /// 中心编号 + public string TrialSiteCode { get; set; } + + /// 受试者标识符 + public string SubjectCode { get; set; } + + /// 受试者唯一标识 + public string USUBJID => ResearchProgramNo + "_" + SubjectCode; + + /// 访视名称 + public string? VisitName { get; set; } + + /// 阅片人角色 + [DictionaryTranslateAttribute("ArmEnum")] + public Arm ArmEnum { get; set; } + + /// 拍片日期 + [DateTimeTranaslateAttribute("yyyy-MM-dd")] + public DateTime? LatestScanDate { get; set; } + + [DateTimeTranaslateAttribute("yyyy-MM-dd")] + public DateTime? EarliestScanDate { get; set; } + + /// 阅片完成时间 + [DateTimeTranaslateAttribute("yyyy-MM-dd")] + public DateTime? SignTime { get; set; } + + /// + /// 访视编号 VISITNUM + /// + public decimal? VisitNum { get; set; } + + public string TaskName { get; set; } + + public string UserName { get; set; } + + public Guid VisitTaskId { get; set; } + + public string CriterionName { get; set; } + #region 查询 导出 + public List LesionList { get; set; } = new List(); + + public List QuestionAnswerList { get; set; } + + public List GlobalResultList { get; set; } + + + 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 + [DictionaryTranslateAttribute("ArmEnum")] + public Arm? JudgeArmEnum { get; set; } + [DictionaryTranslate("YesOrNo")] + public bool? IsJudgeSelect { get; set; } + //在当前访视触发裁判,或者在截止日期小于等于当前访视的阅片期触发裁判 + [DictionaryTranslate("YesOrNo")] + public bool? IsTrigerJudge { get; set; } + + //裁判选择原因(如果是访视点裁判,则仅在所选阅片人对应访视 显示;如果是阅片期裁判,则在所选阅片人 阅片期内的所有访视 显示此原因) + public string JudgeNote { get; set; } = string.Empty; + /// 访视点备注 + public string VisitNote { get; set; } + + #endregion + + +} + + +/// +/// IVUS 导表模型 +/// +public class IvusExportDto : IVUS_OCTBaseDto +{ + /// 靶段 + public string TARGETV { get; set; } + + /// 斑块编号 + public string PLAQUE { get; set; } + + /// 外弹力膜面积 + public string EEM { get; set; } + + /// 管腔面积 + public string LUMEN { get; set; } + + /// 外弹力膜与管腔面积差值 + public string PA { get; set; } + + /// 回撤中的图像帧数 + public string PFC { get; set; } + + /// 分析图像帧数 + public string FC { get; set; } + + /// 总外弹力膜面积 (如无可不填) + public string TOTALEEM { get; set; } + + /// 总 PA (如无可不填) + public string TOTALPA { get; set; } + + /// PAV (如无可不填) + public string PAV { get; set; } +} + +/// +/// OCT 导表模型 +/// +public class OctExportDto : IVUS_OCTBaseDto +{ + /// 靶段 + public string TARGETV { get; set; } + + /// 斑块编号 + public string PLAQUE { get; set; } + + /// 测量标识 + public string TestID { get; set; } + + /// 测量参数名称 + public string TESTCD { get; set; } + + /// 测量参数值 + public string ORRES { get; set; } + + /// 测量值单位 + public string ORRESU { get; set; } + + /// 斑块类型 + public string PLATYPE { get; set; } + + /// 最小纤维帽厚度 + public string MINFCT { get; set; } + + /// 平均纤维帽厚度 + public string AVGMFCT { get; set; } + + /// 脂质角度平均值 + public string LAMEAN { get; set; } + + /// 脂质角度最大值 + public string LAMAX { get; set; } + + /// 巨噬细胞浸润 + public string MACRI { get; set; } + + /// 巨噬细胞浸润角度 + public string MIARC { get; set; } + + /// 微通道 + public string MC { get; set; } + + /// 胆固醇结晶 + public string CCS { get; set; } +} + + + +#endregion + +[ApiExplorerSettings(GroupName = "Common")] +public class IVUS_OCTExportService(IRepository _readingQuestionCriterionTrialRepository, IRepository _visitTaskRepository, + IRepository _subjectVisitTaskRepository, + IMapper _mapper, IUserInfo _userInfo, IRepository _commonDocumentRepository, IStringLocalizer _localizer, IWebHostEnvironment _hostEnvironment) : BaseService +{ + + private IQueryable GetCIDSCQueryable(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 IVUS_OCTBaseDto() + { + ResearchProgramNo = t.Trial.ResearchProgramNo, + SubjectCode = t.Subject.Code, + UserName = t.DoctorUser.UserName, + ArmEnum = t.ArmEnum, + + TaskName = t.TaskName, + SignTime = t.SignTime, + JudgeSignTime = t.ReadingCategory == ReadingCategory.Judge ? t.SignTime : null, + SourceSubjectVisitId = t.SourceSubjectVisitId, + VisitTaskNum = t.VisitTaskNum, + VisitNum = t.VisitTaskNum, + VisitName = t.SourceSubjectVisit.VisitName, + EarliestScanDate = t.SourceSubjectVisit.EarliestScanDate, + 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 || t.GlobalAnswerType == GlobalAnswerType.UpdateType).Select(t => new TumorGlobalQuestionAnserInfo() + { + TaskId = t.TaskId, + GlobalAnswerType = t.GlobalAnswerType, + 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, + ValueType = c.ReadingQuestionTrial.ValueType, + Unit = c.ReadingQuestionTrial.Unit + }).ToList(), + + LesionList = t.LesionList.OrderBy(t => t.RowMark).Select(c => new TumorLessionInfo() + { + Id = c.Id, + OrganInfoId = c.OrganInfoId, + 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 _trialOrganRepository, + [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 = GetCIDSCQueryable(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 = new List() { "ArmEnum", "ValueUnit" } + .Distinct().ToArray(); + + //翻译字典 + var translateDataList = await _dictionaryService.GetBasicDataSelect(dicNameList); + + var ivusList = new List(); + + var octList = new List(); + + var exportCode = string.Empty; + + var data = new object(); + + #endregion + + + foreach (var task in taskList) + { + + if (task.ReadingCategory == ReadingCategory.Judge || task.ReadingCategory == ReadingCategory.Global) + { + continue; + } + + if (criterion.CriterionType == CriterionType.IVUS) + { + //一个斑块一条记录 + foreach (var lesion in task.LesionList.Where(t => t.LessionType == LesionType.MatchValues)) + { + var ivus = _mapper.Map(task); + + //靶段 + ivus.TARGETV = task.QuestionAnswerList.Where(t => t.QuestionName == "靶段").FirstOrDefault()?.QuestionValue ?? string.Empty; + + + //斑块编号 + ivus.PLAQUE = lesion.LessionAnswerList.Where(t => t.QuestionMark == QuestionMark.PlaqueNumber).FirstOrDefault()?.QuestionValue ?? string.Empty; + + //外弹力膜面积 + ivus.EEM = lesion.LessionAnswerList.Where(t => t.QuestionMark == QuestionMark.ElasticArea).FirstOrDefault()?.QuestionValue ?? string.Empty; + //管腔面积 + ivus.LUMEN = lesion.LessionAnswerList.Where(t => t.QuestionMark == QuestionMark.LumenArea).FirstOrDefault()?.QuestionValue ?? string.Empty; + + //外弹力膜与管腔面积差值 + ivus.PA = lesion.LessionAnswerList.Where(t => t.QuestionMark == QuestionMark.ElasticAreaDiffValue).FirstOrDefault()?.QuestionValue ?? string.Empty; + + + //回撤中的图像帧数 + ivus.PFC = task.QuestionAnswerList.Where(t => t.QuestionName == "回撤中的图像帧数").FirstOrDefault()?.QuestionValue ?? string.Empty; + + //分析图像帧数 + ivus.FC = task.QuestionAnswerList.Where(t => t.QuestionName == "分析图像帧数").FirstOrDefault()?.QuestionValue ?? string.Empty; + + var findStatLession = task.LesionList.FirstOrDefault(t => t.LessionType == LesionType.PatchDataStatistics && t.LessionAnswerList.Any(t => t.QuestionMark == QuestionMark.PlaqueNumber && t.QuestionValue == ivus.PLAQUE)); + var findPAVLession = task.LesionList.FirstOrDefault(t => t.LessionType == LesionType.PAV && t.LessionAnswerList.Any(t => t.QuestionMark == QuestionMark.PlaqueNumber && t.QuestionValue == ivus.PLAQUE)); + + + //EEM求和 + ivus.TOTALEEM = findStatLession?.LessionAnswerList.Where(t => t.QuestionMark == QuestionMark.EEMSum).FirstOrDefault()?.QuestionValue ?? string.Empty; + + //(EEM-Lumen)求和 + ivus.TOTALPA = findStatLession?.LessionAnswerList.Where(t => t.QuestionMark == QuestionMark.EEMSubtractLumenSum).FirstOrDefault()?.QuestionValue ?? string.Empty; + //冠状动脉粥样硬化体积百分比(PAV) + + ivus.TOTALPA = findPAVLession?.LessionAnswerList.Where(t => t.QuestionMark == QuestionMark.PAV).FirstOrDefault()?.QuestionValue ?? string.Empty; + + ivusList.Add(ivus); + + } + + + + } + else if (criterion.CriterionType == CriterionType.OCT) + { + //找到所有的斑块编号 排序 + + var noList = task.LesionList.Where(t => t.LessionType == LesionType.FCT).SelectMany(t => t.LessionAnswerList.Where(a => a.QuestionMark == QuestionMark.PlaqueNumber) + .Select(a => a.QuestionValue)).Where(v => !string.IsNullOrEmpty(v)).Distinct() + .OrderBy(v => int.Parse(v)) // 按数字排序 + .ToList(); // 最终是字符串列表 + + + foreach (var pNo in noList) + { + var pNoIndex = 0; + //一个斑块 一次测量(FCT 脂质角度)一条记录 + foreach (var fctLesion in task.LesionList.Where(t => t.LessionType == LesionType.FCT + && t.LessionAnswerList.Any(t => t.QuestionMark == QuestionMark.PlaqueNumber && t.QuestionValue == pNo))) + { + pNoIndex++; + + var findFct1= fctLesion?.LessionAnswerList.Where(t => t.QuestionMark == QuestionMark.FirstFCT).FirstOrDefault(); + + if (findFct1 != null) + { + var oct = CreatOCT(task, pNo); + + // 测量标识 + + oct.TestID = $"{(task.ArmEnum == Arm.DoubleReadingArm1 ? "R1" : "R2")}_{pNo}_L_{pNoIndex}"; + + // 测量参数名称 + + oct.TESTCD = "FCTMV1"; + + // 测量参数值 + oct.ORRES = findFct1?.QuestionValue??string.Empty; + + // 测量值单位 + oct.ORRESU = translateDataList["ValueUnit"].Where(t => t.Code.ToLower() == ((int?)findFct1.Unit)?.ToString().ToLower()).Select(t => isEn_Us ? t.Value : t.ValueCN).FirstOrDefault() ?? String.Empty; + + octList.Add(oct); + } + + var findFct2 = fctLesion?.LessionAnswerList.Where(t => t.QuestionMark == QuestionMark.SecondFCT).FirstOrDefault(); + + if (findFct2 != null) + { + var oct = CreatOCT(task, pNo); + + // 测量标识 + + oct.TestID = $"{(task.ArmEnum == Arm.DoubleReadingArm1 ? "R1" : "R2")}_{pNo}_L_{pNoIndex}"; + + // 测量参数名称 + + oct.TESTCD = "FCTMV2"; + + // 测量参数值 + oct.ORRES = findFct2?.QuestionValue ?? string.Empty; + + // 测量值单位 + oct.ORRESU = translateDataList["ValueUnit"].Where(t => t.Code.ToLower() == ((int?)findFct2.Unit)?.ToString().ToLower()).Select(t => isEn_Us ? t.Value : t.ValueCN).FirstOrDefault() ?? String.Empty; + + octList.Add(oct); + } + + var findFct3 = fctLesion?.LessionAnswerList.Where(t => t.QuestionMark == QuestionMark.ThirdFCT).FirstOrDefault(); + + if (findFct3 != null) + { + var oct = CreatOCT(task, pNo); + + // 测量标识 + + oct.TestID = $"{(task.ArmEnum == Arm.DoubleReadingArm1 ? "R1" : "R2")}_{pNo}_L_{pNoIndex}"; + + // 测量参数名称 + + oct.TESTCD = "FCTMV3"; + + // 测量参数值 + oct.ORRES = findFct3?.QuestionValue ?? string.Empty; + + // 测量值单位 + oct.ORRESU = translateDataList["ValueUnit"].Where(t => t.Code.ToLower() == ((int?)findFct3.Unit)?.ToString().ToLower()).Select(t => isEn_Us ? t.Value : t.ValueCN).FirstOrDefault() ?? String.Empty; + + octList.Add(oct); + } + + + var avgFct = fctLesion?.LessionAnswerList.Where(t => t.QuestionMark == QuestionMark.AvgFCT).FirstOrDefault(); + + if (avgFct != null) + { + var oct = CreatOCT(task, pNo); + + // 测量标识 + + oct.TestID = $"{(task.ArmEnum == Arm.DoubleReadingArm1 ? "R1" : "R2")}_{pNo}_L_{pNoIndex}"; + + // 测量参数名称 + + oct.TESTCD = "AVGFCT"; + + // 测量参数值 + oct.ORRES = avgFct?.QuestionValue ?? string.Empty; + + // 测量值单位 + oct.ORRESU = translateDataList["ValueUnit"].Where(t => t.Code.ToLower() == ((int?)avgFct.Unit)?.ToString().ToLower()).Select(t => isEn_Us ? t.Value : t.ValueCN).FirstOrDefault() ?? String.Empty; + + octList.Add(oct); + } + + } + + var lNoIndex = 0; + //纸质角度 + foreach (var liLesion in task.LesionList.Where(t => t.LessionType == LesionType.LipidAngle + && t.LessionAnswerList.Any(t => t.QuestionMark == QuestionMark.PlaqueNumber && t.QuestionValue == pNo))) + { + lNoIndex++; + + var findAngle = liLesion?.LessionAnswerList.Where(t => t.QuestionMark == QuestionMark.LipidAngle).FirstOrDefault(); + + if (findAngle != null) + { + var oct = CreatOCT(task, pNo); + + // 测量标识 + + oct.TestID = $"{(task.ArmEnum == Arm.DoubleReadingArm1 ? "R1" : "R2")}_{pNo}_A_{lNoIndex}"; + + // 测量参数名称 + + oct.TESTCD = "LIPIDA"; + + // 测量参数值 + oct.ORRES = findAngle?.QuestionValue ?? string.Empty; + + // 测量值单位 + oct.ORRESU = translateDataList["ValueUnit"].Where(t => t.Code.ToLower() == ((int?)findAngle.Unit)?.ToString().ToLower()).Select(t => isEn_Us ? t.Value : t.ValueCN).FirstOrDefault() ?? String.Empty; + + octList.Add(oct); + } + } + } + + + + + } + + + + } + + + + var exportInfo = (await _trialRepository.Where(t => t.Id == inQuery.TrialId).IgnoreQueryFilters().ProjectTo(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException(); + exportInfo.CriterionName = criterion.CriterionName; + + + + + if (criterion.CriterionType == CriterionType.IVUS) + { + exportCode = StaticData.Export.IVUS_CDISC_Export; + + data = ivusList; + + data = await TranslateDataList(new { List = data }, _dictionaryService, typeof(IvusExportDto)); + } + else if (criterion.CriterionType == CriterionType.OCT) + { + exportCode = StaticData.Export.OCT_CDISC_Export; + + data = octList; + + data = await TranslateDataList(new { List = data }, _dictionaryService, typeof(OctExportDto)); + } + + var (physicalPath, fileName) = await FileStoreHelper.GetCommonDocPhysicalFilePathAsync(_hostEnvironment, _commonDocumentRepository, exportCode); + + var exportFileNamePrefix = $"{exportInfo.ResearchProgramNo}_{exportInfo.CriterionName}"; + + var fileDownloadName = $"{(string.IsNullOrEmpty(exportFileNamePrefix) ? "" : exportFileNamePrefix + "_")}{Path.GetFileNameWithoutExtension(fileName)}_{DateTime.Now.ToString("yyyyMMddHHmmss")}.xlsx"; + + return await DataExportAsync(data, fileDownloadName, physicalPath); + + + + + } + + private OctExportDto CreatOCT(IVUS_OCTBaseDto task, string pNo) + { + var oct = _mapper.Map(task); + + + + //靶段 + oct.TARGETV = task.QuestionAnswerList.Where(t => t.QuestionName == "靶段").FirstOrDefault()?.QuestionValue ?? string.Empty; + + //斑块编号 + oct.PLAQUE = pNo; + + var findLession = task.LesionList.Where(t => t.LessionType == LesionType.PatchDataStatistics + && t.LessionAnswerList.Any(t => t.QuestionMark == QuestionMark.PlaqueNumber && t.QuestionValue == pNo)).FirstOrDefault(); + + // 斑块类型 + oct.PLATYPE = findLession?.LessionAnswerList.Where(t => t.QuestionMark == QuestionMark.Undetermined).FirstOrDefault()?.QuestionValue ?? string.Empty; + // 匹配动脉段最小FCT + oct.MINFCT = findLession?.LessionAnswerList.Where(t => t.QuestionMark == QuestionMark.MiniMumFCT).FirstOrDefault()?.QuestionValue ?? string.Empty; + // 平均最小FCT + oct.AVGMFCT = findLession?.LessionAnswerList.Where(t => t.QuestionMark == QuestionMark.AvgMinFCT).FirstOrDefault()?.QuestionValue ?? string.Empty; + // 脂质角度平均值 + oct.LAMEAN = findLession?.LessionAnswerList.Where(t => t.QuestionMark == QuestionMark.AvgLipidAngle).FirstOrDefault()?.QuestionValue ?? string.Empty; + // 脂质角度最大值 + oct.LAMAX = findLession?.LessionAnswerList.Where(t => t.QuestionMark == QuestionMark.MaxAvgLipidAngle).FirstOrDefault()?.QuestionValue ?? string.Empty; + // 巨噬细胞浸润 + oct.MACRI = findLession?.LessionAnswerList.Where(t => t.QuestionMark == QuestionMark.MacrophageInfiltration).FirstOrDefault()?.QuestionValue ?? string.Empty; + // 巨噬细胞浸润角度 + oct.MIARC = findLession?.LessionAnswerList.Where(t => t.QuestionMark == QuestionMark.MacrophageExtensionAngle).FirstOrDefault()?.QuestionValue ?? string.Empty; + // 微通道 + oct.MC = findLession?.LessionAnswerList.Where(t => t.QuestionMark == QuestionMark.Microchannels).FirstOrDefault()?.QuestionValue ?? string.Empty; + // 胆固醇结晶 + oct.CCS = findLession?.LessionAnswerList.Where(t => t.QuestionMark == QuestionMark.CholesterolCrystallization).FirstOrDefault()?.QuestionValue ?? string.Empty; + + return oct; + } + + public static async Task TranslateDataList(object data, IDictionaryService _dictionaryService, Type translateType, CriterionType? criterionType = null) + { + var isEn_US = CultureInfo.CurrentCulture.Name == StaticData.CultureInfo.en_US; + + var needTranslatePropertyList = translateType.GetProperties().Where(t => t.IsDefined(typeof(DictionaryTranslateAttribute), true)) + .SelectMany(c => + c.GetCustomAttributes(typeof(DictionaryTranslateAttribute), false).Select(f => (DictionaryTranslateAttribute?)f).Where(t => t?.CriterionType == criterionType || t?.CriterionType == null) + .Select(k => new { c.Name, k.DicParentCode, k.IsTranslateDenpendOtherProperty, k.DependPropertyName, k.DependPropertyValueStr }) + ).ToList(); + + var needFormartPropertyList = translateType.GetProperties().Where(t => t.IsDefined(typeof(DateTimeTranaslateAttribute), true)) + .SelectMany(c => + c.GetCustomAttributes(typeof(DateTimeTranaslateAttribute), false).Select(f => (DateTimeTranaslateAttribute?)f) + .Select(k => new { c.Name, k.Formart }) + ).ToList(); + + var dic = data.ConvertToDictionary(); + + //翻译字典 + var translateDataList = await _dictionaryService.GetBasicDataSelect(needTranslatePropertyList.Select(t => t.DicParentCode).Distinct().ToArray()); + + foreach (var key in dic.Keys) + { + //是数组 那么找到对应的属性 进行翻译 + if (dic[key] != null && dic[key].GetType().GetInterfaces().Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IList<>))) + { + + var newObjList = new List(); + var no = 1; + + foreach (var item in dic[key] as IList) + { + var itemDic = item.ConvertToDictionary(); + + + foreach (var needTranslateProperty in needTranslatePropertyList) + { + if (itemDic.Keys.Any(t => t == needTranslateProperty.Name)) + { + //翻译的属性依赖其他属性 + if (needTranslateProperty.IsTranslateDenpendOtherProperty) + { + if (itemDic[needTranslateProperty.DependPropertyName]?.ToString().ToLower() == needTranslateProperty.DependPropertyValueStr.ToLower()) + { + var beforeValue = itemDic[needTranslateProperty.Name]?.ToString(); + + itemDic[needTranslateProperty.Name] = translateDataList[needTranslateProperty.DicParentCode].Where(t => t.Code.ToLower() == beforeValue?.ToLower()).Select(t => isEn_US ? t.Value : t.ValueCN).FirstOrDefault() ?? String.Empty; + } + } + //普通翻译 或者某一标准翻译 + else + { + var beforeValue = itemDic[needTranslateProperty.Name]?.ToString(); + + + itemDic[needTranslateProperty.Name] = translateDataList[needTranslateProperty.DicParentCode].Where(t => t.Code.ToLower() == beforeValue?.ToLower()).Select(t => isEn_US ? t.Value : t.ValueCN).FirstOrDefault() ?? String.Empty; + } + } + } + + //根据设置翻译时间 + foreach (var needFormartProperty in needFormartPropertyList) + { + if (itemDic.Keys.Any(t => t == needFormartProperty.Name)) + { + var value = itemDic[needFormartProperty.Name]; + if (value != null && DateTime.TryParse(value.ToString(), out var dt)) + { + itemDic[needFormartProperty.Name] = dt.ToString(needFormartProperty.Formart); + } + } + } + + itemDic.Add("No", no++); + + + newObjList.Add(itemDic); + } + + dic[key] = newObjList; + + } + + } + + return dic; + } + + + public static async Task DataExportAsync(object data, string fileDownloadName, string physicalPath) + { + + //模板路径 + 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 = fileDownloadName + }; + } + + + private List DealJudgeMark(ArbitrationRule arbitrationRule, bool isGlobalReading, IEnumerable list) where T : IVUS_OCTBaseDto + { + //处理访视任务的裁判标记 + 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.Union(judegeList).OrderBy(t => t.SubjectCode).ThenBy(t => t.VisitTaskNum).ThenBy(t => t.ArmEnum).ToList(); + } + +} diff --git a/IRaCIS.Core.Application/Service/Common/_MapConfig.cs b/IRaCIS.Core.Application/Service/Common/_MapConfig.cs index 1059c599a..cd499bc0a 100644 --- a/IRaCIS.Core.Application/Service/Common/_MapConfig.cs +++ b/IRaCIS.Core.Application/Service/Common/_MapConfig.cs @@ -120,6 +120,10 @@ namespace IRaCIS.Core.Application.Service CreateMap(); CreateMap(); CreateMap(); + + CreateMap(); + CreateMap(); + } } diff --git a/IRaCIS.Core.Domain.Share/Reading/ReadEnum.cs b/IRaCIS.Core.Domain.Share/Reading/ReadEnum.cs index 8a53e9235..645fa7dd9 100644 --- a/IRaCIS.Core.Domain.Share/Reading/ReadEnum.cs +++ b/IRaCIS.Core.Domain.Share/Reading/ReadEnum.cs @@ -544,6 +544,10 @@ namespace IRaCIS.Core.Domain.Share TumorCDISC_Export=20, + IVUS_CDISC_Export = 21, + + OCT_CDISC_Export = 22, + } @@ -2383,10 +2387,33 @@ public enum SUVChangeVSBaseline MaxAvgLipidAngle = 1020, /// - /// 待定指标 + /// 斑块类型 /// Undetermined = 1021, + /// + /// 巨噬细胞浸润 + /// + MacrophageInfiltration = 1022, + + /// + /// 巨噬细胞延伸角度 + /// + MacrophageExtensionAngle = 1023, + + /// + /// 微通道 + /// + Microchannels = 1024, + + /// + /// 胆固醇结晶 + /// + CholesterolCrystallization = 1025, + + + + /// /// 第一次测量 /// diff --git a/IRaCIS.Core.Infrastructure/_IRaCIS/ObjectExtension.cs b/IRaCIS.Core.Infrastructure/_IRaCIS/ObjectExtension.cs index 56be0b871..a73efa88c 100644 --- a/IRaCIS.Core.Infrastructure/_IRaCIS/ObjectExtension.cs +++ b/IRaCIS.Core.Infrastructure/_IRaCIS/ObjectExtension.cs @@ -1,6 +1,7 @@ using IRaCIS.Core.API._ServiceExtensions.NewtonsoftJson; using Newtonsoft.Json; using System; +using System.Collections; using System.Collections.Generic; using System.Reflection; @@ -75,6 +76,12 @@ namespace IRaCIS.Core.Infrastructure.Extention foreach (PropertyInfo property in properties) { + if (typeof(IEnumerable).IsAssignableFrom(property.PropertyType) + && property.PropertyType != typeof(string)) + { + continue; + } + string propertyName = property.Name; object propertyValue = property.GetValue(obj); // 如果属性的类型是枚举,将其值保留为整数 diff --git a/IRaCIS.Core.Infrastructure/_IRaCIS/_Config/_StaticData.cs b/IRaCIS.Core.Infrastructure/_IRaCIS/_Config/_StaticData.cs index f320c92b6..c1f6aa1b4 100644 --- a/IRaCIS.Core.Infrastructure/_IRaCIS/_Config/_StaticData.cs +++ b/IRaCIS.Core.Infrastructure/_IRaCIS/_Config/_StaticData.cs @@ -312,6 +312,10 @@ public static class StaticData public const string TumorCDISC_Export = "TumorCDISC_Export"; + public const string IVUS_CDISC_Export = "IVUS_CDISC_Export"; + + public const string OCT_CDISC_Export = "OCT_CDISC_Export"; + } From 050a0875feb8c0e6264b14967d8888300a6b79b6 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Wed, 26 Nov 2025 09:05:34 +0800 Subject: [PATCH 03/13] =?UTF-8?q?uat-=E6=A0=87=E6=B3=A8-7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ImageAndDoc/DownloadAndUploadService.cs | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/IRaCIS.Core.Application/Service/ImageAndDoc/DownloadAndUploadService.cs b/IRaCIS.Core.Application/Service/ImageAndDoc/DownloadAndUploadService.cs index 2ae8d7279..8f1f2eee5 100644 --- a/IRaCIS.Core.Application/Service/ImageAndDoc/DownloadAndUploadService.cs +++ b/IRaCIS.Core.Application/Service/ImageAndDoc/DownloadAndUploadService.cs @@ -898,7 +898,8 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc //靶段标注上传,查看访视级别,上传绑定访视级别 if (inQuery.IsImageSegmentLabel == true) { - var list = _noneDicomStudyReposiotry.Where(t => t.SubjectId == subjectId && t.SubjectVisitId == inQuery.SubjectVisitId) + var list = _noneDicomStudyReposiotry.Where(t => t.SubjectId == subjectId) + .WhereIf(inQuery.SubjectVisitId != null, t => t.SubjectVisitId == inQuery.SubjectVisitId) //.WhereIf(info.IsImageFilter, t => ("|" + info.CriterionModalitys + "|").Contains("|" + t.Modality + "|")) .Select(u => new TaskNoneDicomStudyDTO() { @@ -1248,7 +1249,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc var dicomStudyList = list.Where(item => item.DicomStudyList.Count > 0) .Select(item => new SubjectVisitMarkStudyDto { - SourceSubjectVisitId=item.SourceSubjectVisitId, + SourceSubjectVisitId = item.SourceSubjectVisitId, VisitTaskId = item.VisitTaskId, SubjectId = item.SubjectId, SubjectCode = item.SubjectCode, @@ -1542,10 +1543,10 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc from leftVisitTask in cc.DefaultIfEmpty() select new ImageDownloadDto() { - TrialId=sv.TrialId, - SubjectId=sv.SubjectId, - TrialSiteCode=sv.TrialSite.TrialSiteCode, - VisitId=sv.Id, + TrialId = sv.TrialId, + SubjectId = sv.SubjectId, + TrialSiteCode = sv.TrialSite.TrialSiteCode, + VisitId = sv.Id, SubjectCode = inQuery.SubjectCode, VisitName = sv.VisitName, @@ -2209,7 +2210,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc { TrialId = t.TrialId, SubjectId = t.Id, - SubjectCode=t.Code, + SubjectCode = t.Code, IsUrgent = t.IsUrgent, VisitCount = t.SubjectVisitList.Where(t => t.SubmitState == SubmitStateEnum.Submitted).Count(), MarkVisitCount = t.SubjectVisitList.Where(t => t.SubmitState == SubmitStateEnum.Submitted).Count(t => t.TaskStudyList.Any()), @@ -2218,7 +2219,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc MarkDicomStudyCount = t.SubjectVisitList.Where(t => t.SubmitState == SubmitStateEnum.Submitted).SelectMany(t => t.TaskStudyList).Count(), NoneDicomStudyCount = t.SubjectVisitList.Where(t => t.SubmitState == SubmitStateEnum.Submitted).SelectMany(t => t.NoneDicomStudyList).Count(), - MarkNoneDicomStudyCount = t.SubjectVisitList.Where(t => t.SubmitState == SubmitStateEnum.Submitted).SelectMany(t => t.NoneDicomStudyList).Where(t=>t.ImageLabelNoneDicomFileList.Any()).Count(), + MarkNoneDicomStudyCount = t.SubjectVisitList.Where(t => t.SubmitState == SubmitStateEnum.Submitted).SelectMany(t => t.NoneDicomStudyList).Where(t => t.ImageLabelNoneDicomFileList.Any()).Count(), }).ToPagedListAsync(inQuery); return ResponseOutput.Ok(list); From 03d61347ca4c5a3c346d55e9d48f7bf69f757a67 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Wed, 26 Nov 2025 10:10:33 +0800 Subject: [PATCH 04/13] =?UTF-8?q?uat-=E6=A0=87=E6=B3=A8-8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Service/ImageAndDoc/DTO/UnionStudyViewDodel.cs | 3 +-- .../Service/ImageAndDoc/DownloadAndUploadService.cs | 7 ++++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/IRaCIS.Core.Application/Service/ImageAndDoc/DTO/UnionStudyViewDodel.cs b/IRaCIS.Core.Application/Service/ImageAndDoc/DTO/UnionStudyViewDodel.cs index 19226cbe3..8cf9ea30f 100644 --- a/IRaCIS.Core.Application/Service/ImageAndDoc/DTO/UnionStudyViewDodel.cs +++ b/IRaCIS.Core.Application/Service/ImageAndDoc/DTO/UnionStudyViewDodel.cs @@ -269,8 +269,7 @@ namespace IRaCIS.Core.Application.Contracts public AddOrUpdateStudyDto Study { get; set; } - [NotDefault] - public Guid VisitTaskId { get; set; } + public Guid? VisitTaskId { get; set; } public bool? IsImageSegmentLabel { get; set; } } diff --git a/IRaCIS.Core.Application/Service/ImageAndDoc/DownloadAndUploadService.cs b/IRaCIS.Core.Application/Service/ImageAndDoc/DownloadAndUploadService.cs index 8f1f2eee5..cb08f677d 100644 --- a/IRaCIS.Core.Application/Service/ImageAndDoc/DownloadAndUploadService.cs +++ b/IRaCIS.Core.Application/Service/ImageAndDoc/DownloadAndUploadService.cs @@ -548,9 +548,11 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc var @uploadLock = _distributedLockProvider.CreateLock($"UploadTaskDicom"); + var visiTaskId = incommand.VisitTaskId.Value; + using (await @uploadLock.AcquireAsync()) { - if (_fusionCache.GetOrDefault(CacheKeys.TrialTaskStudyUidDBLock(incommand.TrialId, incommand.VisitTaskId, incommand.Study.StudyInstanceUid)) != Guid.Empty) + if (_fusionCache.GetOrDefault(CacheKeys.TrialTaskStudyUidDBLock(incommand.TrialId, visiTaskId, incommand.Study.StudyInstanceUid)) != Guid.Empty) { //---当前已有人正在上传和归档该检查! return ResponseOutput.NotOk(I18n.T("UploadDownLoad_ArchiveInProgress")); @@ -558,7 +560,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc else { //在事务未完成前 防止前端重复提交 - await _fusionCache.SetAsync(CacheKeys.TrialTaskStudyUidDBLock(incommand.TrialId, incommand.VisitTaskId, incommand.Study.StudyInstanceUid), _userInfo.UserRoleId, TimeSpan.FromMinutes(1)); + await _fusionCache.SetAsync(CacheKeys.TrialTaskStudyUidDBLock(incommand.TrialId, visiTaskId, incommand.Study.StudyInstanceUid), _userInfo.UserRoleId, TimeSpan.FromMinutes(1)); } } @@ -570,7 +572,6 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc svId = _dicomStudyRepository.Where(t => t.TrialId == incommand.TrialId && t.StudyInstanceUid == incommand.Study.StudyInstanceUid).Select(t => t.SubjectVisitId).FirstOrDefault(); } - var visiTaskId = incommand.VisitTaskId; var modalitys = string.Empty; From 95bf613263c26f983cccb367bb6a4c373fa282ba Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Wed, 26 Nov 2025 10:39:25 +0800 Subject: [PATCH 05/13] =?UTF-8?q?=E9=9D=9Edicom=E6=A3=80=E6=9F=A5=E9=A2=84?= =?UTF-8?q?=E8=A7=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Service/ImageAndDoc/NoneDicomStudyService.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/IRaCIS.Core.Application/Service/ImageAndDoc/NoneDicomStudyService.cs b/IRaCIS.Core.Application/Service/ImageAndDoc/NoneDicomStudyService.cs index 8f7d4b85e..7015c731e 100644 --- a/IRaCIS.Core.Application/Service/ImageAndDoc/NoneDicomStudyService.cs +++ b/IRaCIS.Core.Application/Service/ImageAndDoc/NoneDicomStudyService.cs @@ -45,7 +45,7 @@ namespace IRaCIS.Core.Application.Contracts var isViewDelete = !isQCFinished; IQueryable noneDicomStudyQueryable = default; - if (visitTaskId == null) + if (visitTaskId == null || visitTaskId == Guid.Empty) { //质控过程中,需要忽略过滤质控设置删除的检查,以及设置删除的文件,质控通过后才 noneDicomStudyQueryable = _noneDicomStudyRepository.Where(t => t.SubjectVisitId == subjectVisitId, ignoreQueryFilters: isViewDelete) From 658f437f73ac7a55d3b2fa213268399a3bb118f4 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Wed, 26 Nov 2025 10:47:44 +0800 Subject: [PATCH 06/13] =?UTF-8?q?uat-=E6=A0=87=E6=B3=A8-10?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ImageAndDoc/DownloadAndUploadService.cs | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/IRaCIS.Core.Application/Service/ImageAndDoc/DownloadAndUploadService.cs b/IRaCIS.Core.Application/Service/ImageAndDoc/DownloadAndUploadService.cs index cb08f677d..97fcac6a4 100644 --- a/IRaCIS.Core.Application/Service/ImageAndDoc/DownloadAndUploadService.cs +++ b/IRaCIS.Core.Application/Service/ImageAndDoc/DownloadAndUploadService.cs @@ -548,7 +548,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc var @uploadLock = _distributedLockProvider.CreateLock($"UploadTaskDicom"); - var visiTaskId = incommand.VisitTaskId.Value; + var visiTaskId = incommand.VisitTaskId ?? Guid.Empty; using (await @uploadLock.AcquireAsync()) { @@ -806,8 +806,8 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc } finally { - await _fusionCache.RemoveAsync(CacheKeys.TrialTaskStudyUidDBLock(incommand.TrialId, incommand.VisitTaskId, incommand.Study.StudyInstanceUid)); - await _fusionCache.RemoveAsync(CacheKeys.TrialTaskStudyUidUploading(incommand.TrialId, incommand.VisitTaskId, incommand.Study.StudyInstanceUid)); + await _fusionCache.RemoveAsync(CacheKeys.TrialTaskStudyUidDBLock(incommand.TrialId, visiTaskId, incommand.Study.StudyInstanceUid)); + await _fusionCache.RemoveAsync(CacheKeys.TrialTaskStudyUidUploading(incommand.TrialId, visiTaskId, incommand.Study.StudyInstanceUid)); } @@ -869,7 +869,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc /// /// [HttpPost] - public async Task> GetIRUploadTaskNoneDicomStudyList(IRUploadStudyQuery inQuery) + public async Task>> GetIRUploadTaskNoneDicomStudyList(IRUploadStudyQuery inQuery) { var subjectCode = inQuery.SubjectCode; var subjectId = inQuery.SubjectId; @@ -896,6 +896,9 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc var info = await _readingQuestionCriterionTrialRepository.Where(t => t.Id == inQuery.TrialReadingCriterionId) .Select(t => new { t.IsImageFilter, t.CriterionModalitys, t.IsReadingTaskViewInOrder }).FirstNotNullAsync(); + var config = await _subjectRepository.Where(t => t.Id == subjectId).Select(t => new { t.Trial.ImageFormatList, t.Trial.StudyNameList, t.Trial.IsShowStudyName }).FirstOrDefaultAsync(); + + //靶段标注上传,查看访视级别,上传绑定访视级别 if (inQuery.IsImageSegmentLabel == true) { @@ -952,7 +955,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc item.UploadedFileList = noneDicomStudyList.Where(t => t.OriginNoneDicomStudyId == item.Id).ToList(); } - return list; + return ResponseOutput.Ok(list, config); } else { @@ -1020,11 +1023,11 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc item.UploadedFileList = taskNoneDicomStudyList.Where(t => t.OriginNoneDicomStudyId == item.Id).ToList(); } - return list; + return ResponseOutput.Ok(list, config); } - + } From 71e867156fe022affc3f19bd4acd7ba32e9560f4 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Wed, 26 Nov 2025 13:45:47 +0800 Subject: [PATCH 07/13] =?UTF-8?q?uat-=E6=A0=87=E6=B3=A8-11?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Service/ImageAndDoc/DTO/UnionStudyViewDodel.cs | 5 +++-- .../Service/ImageAndDoc/DownloadAndUploadService.cs | 13 ++++++++----- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/IRaCIS.Core.Application/Service/ImageAndDoc/DTO/UnionStudyViewDodel.cs b/IRaCIS.Core.Application/Service/ImageAndDoc/DTO/UnionStudyViewDodel.cs index 8cf9ea30f..f1e0f3060 100644 --- a/IRaCIS.Core.Application/Service/ImageAndDoc/DTO/UnionStudyViewDodel.cs +++ b/IRaCIS.Core.Application/Service/ImageAndDoc/DTO/UnionStudyViewDodel.cs @@ -505,8 +505,9 @@ namespace IRaCIS.Core.Application.Contracts public class IRTaskUploadedDicomStudyQuery { - [NotDefault] - public Guid VisitTaskId { get; set; } + public Guid? VisitTaskId { get; set; } + + public Guid? SubjectVisitId { get; set; } } public class IRUploadTaskDicomStudyDto : DicomStudyBasicInfo diff --git a/IRaCIS.Core.Application/Service/ImageAndDoc/DownloadAndUploadService.cs b/IRaCIS.Core.Application/Service/ImageAndDoc/DownloadAndUploadService.cs index 97fcac6a4..5c9ab031e 100644 --- a/IRaCIS.Core.Application/Service/ImageAndDoc/DownloadAndUploadService.cs +++ b/IRaCIS.Core.Application/Service/ImageAndDoc/DownloadAndUploadService.cs @@ -548,7 +548,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc var @uploadLock = _distributedLockProvider.CreateLock($"UploadTaskDicom"); - var visiTaskId = incommand.VisitTaskId ?? Guid.Empty; + var visiTaskId = incommand.VisitTaskId ?? Guid.Empty; using (await @uploadLock.AcquireAsync()) { @@ -1027,7 +1027,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc } - + } @@ -1701,11 +1701,14 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc [HttpPost] public async Task GetTaskUploadedDicomStudyList(IRTaskUploadedDicomStudyQuery inQuery) { - var info = await _visitTaskRepository.Where(t => t.Id == inQuery.VisitTaskId) + var info = await _visitTaskRepository + .WhereIf(inQuery.VisitTaskId != null, t => t.Id == inQuery.VisitTaskId)//正常后处理 .Select(t => new { t.TrialReadingCriterion.IsImageFilter, t.TrialReadingCriterion.CriterionModalitys }).FirstNotNullAsync(); - var query = _taskStudyRepository.Where(t => t.VisitTaskId == inQuery.VisitTaskId) - .Where(t => info.IsImageFilter ? ("|" + info.CriterionModalitys + "|").Contains("|" + t.ModalityForEdit + "|") : true) + var query = _taskStudyRepository + .WhereIf(inQuery.VisitTaskId != null, t => t.Id == inQuery.VisitTaskId)//正常后处理 + .WhereIf(inQuery.SubjectVisitId != null, t => t.SubjectVisitId == inQuery.SubjectVisitId)//靶段标注处理的影像 + .WhereIf( info.IsImageFilter && inQuery.VisitTaskId != null, t => ("|" + info.CriterionModalitys + "|").Contains("|" + t.ModalityForEdit + "|") ) .Select(t => new { StudyId = t.Id, From 00255e902c50287f9090f0eac1e5a7411fc1d4a8 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Wed, 26 Nov 2025 15:49:09 +0800 Subject: [PATCH 08/13] =?UTF-8?q?uat-=E6=A0=87=E6=B3=A8-12?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Service/ImageAndDoc/DownloadAndUploadService.cs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/IRaCIS.Core.Application/Service/ImageAndDoc/DownloadAndUploadService.cs b/IRaCIS.Core.Application/Service/ImageAndDoc/DownloadAndUploadService.cs index 5c9ab031e..191510bfe 100644 --- a/IRaCIS.Core.Application/Service/ImageAndDoc/DownloadAndUploadService.cs +++ b/IRaCIS.Core.Application/Service/ImageAndDoc/DownloadAndUploadService.cs @@ -174,6 +174,8 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc .Select(t => new StudyBasicInfo() { Id = t.Id, + SubjectVisitId=t.SubjectVisitId, + StudyInstanceUid = t.StudyInstanceUid, ModalityForEdit = t.ModalityForEdit, BodyPartExamined = t.BodyPartExamined, @@ -194,6 +196,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc UploadStudyList = u.TaskStudyList.Select(t => new StudyBasicInfo() { Id = t.Id, + SubjectVisitId=t.SubjectVisitId, StudyInstanceUid = t.StudyInstanceUid, ModalityForEdit = t.ModalityForEdit, BodyPartExamined = t.BodyPartExamined, @@ -1343,8 +1346,11 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc foreach (var item in list) { - item.DicomStudyList.Where(t => inQuery.IsImageSegmentLabel == false ? t.ModalityForEdit == "XA" : true).ToList() - .AddRange(preDicomStudyList.Where(t => t.SubjectVisitId == item.SourceSubjectVisitId).ToList()); + var dicomList = item.DicomStudyList.Where(t => inQuery.IsImageSegmentLabel == false ? t.ModalityForEdit == "XA" : true).ToList(); + + dicomList.AddRange(preDicomStudyList.Where(t => t.SubjectVisitId == item.SourceSubjectVisitId).ToList()); + + item.DicomStudyList = dicomList; item.NoneDicomStudyList = _mapper.Map>(preNoneDicomStudyList.Where(t => t.SubjectVisitId == item.SourceSubjectVisitId).ToList()); } From 6705cf0fc0353a62e849cbd6a8b47fce05ae3e78 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Wed, 26 Nov 2025 16:45:08 +0800 Subject: [PATCH 09/13] =?UTF-8?q?uat-=E6=A0=87=E6=B3=A8-13?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Helper/DicomDIRHelper.cs | 2 + .../ImageAndDoc/DownloadAndUploadService.cs | 14 ++++- .../ImageAndDoc/NoneDicomStudyService.cs | 20 +++++-- .../Service/Visit/SubjectVisitService.cs | 56 +++++++++++++++---- 4 files changed, 72 insertions(+), 20 deletions(-) diff --git a/IRaCIS.Core.Application/Helper/DicomDIRHelper.cs b/IRaCIS.Core.Application/Helper/DicomDIRHelper.cs index a9a32d2eb..580154c9c 100644 --- a/IRaCIS.Core.Application/Helper/DicomDIRHelper.cs +++ b/IRaCIS.Core.Application/Helper/DicomDIRHelper.cs @@ -13,6 +13,8 @@ namespace IRaCIS.Core.Application.Helper public class StudyDIRInfo { + public bool IsTaskStudy { get; set; } + public Guid SubjectVisitId { get; set; } // Study public Guid DicomStudyId { get; set; } diff --git a/IRaCIS.Core.Application/Service/ImageAndDoc/DownloadAndUploadService.cs b/IRaCIS.Core.Application/Service/ImageAndDoc/DownloadAndUploadService.cs index 191510bfe..7088fe68c 100644 --- a/IRaCIS.Core.Application/Service/ImageAndDoc/DownloadAndUploadService.cs +++ b/IRaCIS.Core.Application/Service/ImageAndDoc/DownloadAndUploadService.cs @@ -989,7 +989,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc StudyCode = ns.StudyCode, //靶段标注 阅片IR 上传时IsImageSegmentLabel == false ,正常后处理上传IsImageSegmentLabel 该字段为空 - FileList = (inQuery.IsImageSegmentLabel == false ? ns.NoneDicomFileList : ns.ImageLabelNoneDicomFileList) + FileList = (inQuery.IsImageSegmentLabel == false ? ns.ImageLabelNoneDicomFileList : ns.NoneDicomFileList) .Select(t => new NoneDicomFileInfo() { FileType = t.FileType, @@ -1489,6 +1489,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc var taskDirInfolist = _taskInstanceRepository.Where(t => t.SubjectVisitId != null) .Where(t => subjectVisitIdList.Contains((Guid)t.SubjectVisitId)).Select(t => new StudyDIRInfo() { + IsTaskStudy=true, SubjectVisitId = (Guid)t.SubjectVisitId, DicomStudyId = t.TaskStudy.Id, @@ -1532,6 +1533,8 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc { var visitId = item.First().SubjectVisitId; + var isTaskStudy = item.First().IsTaskStudy; + var ossFolder = $"{pathInfo.TrialId}/Image/{pathInfo.SubjectId}/{visitId}/{item.Key.StudyInstanceUid}"; var isSucess = await SafeBussinessHelper.RunAsync(async () => await DicomDIRHelper.GenerateStudyDIRAndUploadAsync(item.ToList(), dirDic, ossFolder, _oSSService)); @@ -1539,7 +1542,14 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc if (isSucess) { - await _dicomStudyRepository.BatchUpdateNoTrackingAsync(t => t.Id == item.Key.DicomStudyId, u => new DicomStudy() { StudyDIRPath = $"/{ossFolder}/DICOMDIR" }); + if (isTaskStudy) + { + await _taskStudyRepository.BatchUpdateNoTrackingAsync(t => t.Id == item.Key.DicomStudyId, u => new TaskStudy() { StudyDIRPath = $"/{ossFolder}/DICOMDIR" }); + } + else + { + await _dicomStudyRepository.BatchUpdateNoTrackingAsync(t => t.Id == item.Key.DicomStudyId, u => new DicomStudy() { StudyDIRPath = $"/{ossFolder}/DICOMDIR" }); + } } } diff --git a/IRaCIS.Core.Application/Service/ImageAndDoc/NoneDicomStudyService.cs b/IRaCIS.Core.Application/Service/ImageAndDoc/NoneDicomStudyService.cs index 7015c731e..361d8fba9 100644 --- a/IRaCIS.Core.Application/Service/ImageAndDoc/NoneDicomStudyService.cs +++ b/IRaCIS.Core.Application/Service/ImageAndDoc/NoneDicomStudyService.cs @@ -57,14 +57,22 @@ namespace IRaCIS.Core.Application.Contracts } else { - var taskinfo = await _visitTaskRepository.Where(x => x.Id == visitTaskId).Select(t => new { t.BlindSubjectCode, t.TrialReadingCriterionId, t.TrialReadingCriterion.IsImageFilter, t.TrialReadingCriterion.CriterionModalitys }).FirstNotNullAsync(); + var taskinfo = await _visitTaskRepository.Where(x => x.Id == visitTaskId).Select(t => new { t.BlindSubjectCode, t.TrialReadingCriterionId, t.TrialReadingCriterion.CriterionType, t.TrialReadingCriterion.IsImageFilter, t.TrialReadingCriterion.CriterionModalitys }).FirstNotNullAsync(); + + if (taskinfo.CriterionType == CriterionType.IVUS || taskinfo.CriterionType == CriterionType.OCT) + { + + } + else + { + noneDicomStudyQueryable = _noneDicomStudyRepository.Where(t => t.TaskNoneDicomFileList.Any(t => t.VisitTaskId == visitTaskId), ignoreQueryFilters: isViewDelete) + .WhereIf(isReading, t => t.IsReading && t.IsDeleted == false) + .Where(t => taskinfo.IsImageFilter ? ("|" + taskinfo.CriterionModalitys + "|").Contains("|" + t.Modality + "|") : true) + .WhereIf(nonedicomStudyId != null, t => t.Id == nonedicomStudyId) + .ProjectTo(_mapper.ConfigurationProvider, new { isFilterZip = isFilterZip, visiTaskId = visitTaskId, isReading = isReading }); + } - noneDicomStudyQueryable = _noneDicomStudyRepository.Where(t => t.TaskNoneDicomFileList.Any(t => t.VisitTaskId == visitTaskId), ignoreQueryFilters: isViewDelete) - .WhereIf(isReading, t => t.IsReading && t.IsDeleted == false) - .Where(t => taskinfo.IsImageFilter ? ("|" + taskinfo.CriterionModalitys + "|").Contains("|" + t.Modality + "|") : true) - .WhereIf(nonedicomStudyId != null, t => t.Id == nonedicomStudyId) - .ProjectTo(_mapper.ConfigurationProvider, new { isFilterZip = isFilterZip, visiTaskId = visitTaskId, isReading = isReading }); } diff --git a/IRaCIS.Core.Application/Service/Visit/SubjectVisitService.cs b/IRaCIS.Core.Application/Service/Visit/SubjectVisitService.cs index 819c5878e..15c906698 100644 --- a/IRaCIS.Core.Application/Service/Visit/SubjectVisitService.cs +++ b/IRaCIS.Core.Application/Service/Visit/SubjectVisitService.cs @@ -224,27 +224,42 @@ namespace IRaCIS.Core.Application.Services var isImageFilter = false; var criterionModalitys = ""; + var criterionType = CriterionType.NoCriterion; + + var isVisitTask = false; + + bool? isImageSegmentLabel = null; if (visitTaskId != null && visitTaskId != Guid.Empty) { + isVisitTask = true; var info = await _visitTaskRepository.Where(t => t.Id == visitTaskId) - .Select(t => new { t.TrialReadingCriterion.IsImageFilter, t.TrialReadingCriterion.CriterionModalitys }).FirstNotNullAsync(); + .Select(t => new { t.TrialReadingCriterion.IsImageFilter, t.TrialReadingCriterion.CriterionModalitys, t.TrialReadingCriterion.CriterionType }).FirstNotNullAsync(); isImageFilter = info.IsImageFilter; criterionModalitys = info.CriterionModalitys; + + criterionType = info.CriterionType; + + if (criterionType == CriterionType.OCT || criterionType == CriterionType.IVUS) + { + isImageSegmentLabel = true; + } } var studyList = await _dicomStudyRepository.Where(t => t.TrialId == trialId && t.SubjectVisitId == sujectVisitId).IgnoreQueryFilters() - .Where(t => isImageFilter ? ("|" + criterionModalitys + "|").Contains("|" + t.ModalityForEdit + "|") : true) - .WhereIf(isReading == 1 || isQCFinished, s => s.IsDeleted == false) - .Select(k => new VisitStudyDTO() - { - InstanceCount = k.InstanceCount, - Modalities = k.Modalities, - //SeriesCount = k.SeriesCount, - StudyCode = k.StudyCode, - StudyId = k.Id - }).ToListAsync(); + .Where(t => isImageFilter ? ("|" + criterionModalitys + "|").Contains("|" + t.ModalityForEdit + "|") : true) + .WhereIf(isReading == 1 || isQCFinished, s => s.IsDeleted == false) + //预览靶段标注上传的影像 影像后处理 上传了新的影像 还要原始dsa + .WhereIf(isImageSegmentLabel == true && isVisitTask && (criterionType == CriterionType.OCT || criterionType == CriterionType.IVUS), t => t.ModalityForEdit == "XA") + .Select(k => new VisitStudyDTO() + { + InstanceCount = k.InstanceCount, + Modalities = k.Modalities, + //SeriesCount = k.SeriesCount, + StudyCode = k.StudyCode, + StudyId = k.Id + }).ToListAsync(); var studyIds = studyList.Select(t => t.StudyId).ToList(); @@ -287,12 +302,29 @@ namespace IRaCIS.Core.Application.Services t.InstanceCount = t.SeriesList.SelectMany(t => t.InstanceInfoList).Count(); } + //预览靶段标注上传的影像 + if (isImageSegmentLabel == true && isVisitTask) + { + var taskStudyList = await _taskStudyRepository.Where(t => t.SubjectVisitId == sujectVisitId) + .WhereIf(isImageFilter, t => ("|" + criterionModalitys + "|").Contains("|" + t.ModalityForEdit + "|")) + .ProjectTo(_mapper.ConfigurationProvider).ToListAsync(); + + foreach (var study in taskStudyList) + { + study.SeriesList = study.SeriesList.OrderBy(s => s.SeriesNumber).ThenBy(s => s.SeriesTime).ToList(); + + study.InstanceCount = study.SeriesList.SelectMany(t => t.InstanceInfoList).Count(); + } + + studyList.AddRange(taskStudyList); + } return studyList.Where(x => x.SeriesList.Count() > 0).ToList(); - //return ResponseOutput.Ok(studyList.Where(t => t.SeriesList.Count > 0).ToList()); + + } From 139438133dc7bed99002e86cf769d7b07cce7dde Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Wed, 26 Nov 2025 17:44:52 +0800 Subject: [PATCH 10/13] =?UTF-8?q?uat-=E6=A0=87=E6=B3=A8-14?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ImageAndDoc/NoneDicomStudyService.cs | 36 ++++++++++++++----- .../Service/QC/DTO/NoneDicomStudyViewModel.cs | 5 +++ .../Service/QC/_MapConfig.cs | 7 ++++ 3 files changed, 40 insertions(+), 8 deletions(-) diff --git a/IRaCIS.Core.Application/Service/ImageAndDoc/NoneDicomStudyService.cs b/IRaCIS.Core.Application/Service/ImageAndDoc/NoneDicomStudyService.cs index 361d8fba9..67e38daa5 100644 --- a/IRaCIS.Core.Application/Service/ImageAndDoc/NoneDicomStudyService.cs +++ b/IRaCIS.Core.Application/Service/ImageAndDoc/NoneDicomStudyService.cs @@ -4,6 +4,7 @@ // 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。 //-------------------------------------------------------------------- using IRaCIS.Core.Application.Filter; +using IRaCIS.Core.Application.Service.Reading.Dto; using IRaCIS.Core.Domain.Models; using IRaCIS.Core.Domain.Share; using Medallion.Threading; @@ -34,7 +35,8 @@ namespace IRaCIS.Core.Application.Contracts [FromQuery] Guid? nonedicomStudyId, [FromQuery] bool isFilterZip, [FromQuery] Guid? visitTaskId, - [FromQuery] bool isReading) + [FromQuery] bool isReading, + [FromQuery] bool? isImageSegmentLabel) { var qcAuditState = await _subjectVisitRepository.Where(s => s.Id == subjectVisitId).Select(t => t.AuditState).FirstOrDefaultAsync(); @@ -47,21 +49,39 @@ namespace IRaCIS.Core.Application.Contracts IQueryable noneDicomStudyQueryable = default; if (visitTaskId == null || visitTaskId == Guid.Empty) { - //质控过程中,需要忽略过滤质控设置删除的检查,以及设置删除的文件,质控通过后才 - noneDicomStudyQueryable = _noneDicomStudyRepository.Where(t => t.SubjectVisitId == subjectVisitId, ignoreQueryFilters: isViewDelete) - .WhereIf(nonedicomStudyId != null, t => t.Id == nonedicomStudyId) - .WhereIf(isReading, t => t.IsReading && t.IsDeleted == false) + if (visitTaskId == null) + { + + //质控过程中,需要忽略过滤质控设置删除的检查,以及设置删除的文件,质控通过后才 + noneDicomStudyQueryable = _noneDicomStudyRepository.Where(t => t.SubjectVisitId == subjectVisitId, ignoreQueryFilters: isViewDelete) + .WhereIf(nonedicomStudyId != null, t => t.Id == nonedicomStudyId) + .WhereIf(isReading, t => t.IsReading && t.IsDeleted == false) + .ProjectTo(_mapper.ConfigurationProvider, new { isFilterZip = isFilterZip, isReading = isReading }); + } + else + { + //靶段标注上传后查看影像 + + noneDicomStudyQueryable = _noneDicomStudyRepository.Where(t => true, ignoreQueryFilters: isViewDelete) + .WhereIf(isReading, t => t.IsReading && t.IsDeleted == false) + .WhereIf(nonedicomStudyId != null, t => t.Id == nonedicomStudyId) + .ProjectTo(_mapper.ConfigurationProvider, new { isFilterZip = isFilterZip, isReading = isReading }); + + } - .ProjectTo(_mapper.ConfigurationProvider, new { isFilterZip = isFilterZip, isReading = isReading }); } else { var taskinfo = await _visitTaskRepository.Where(x => x.Id == visitTaskId).Select(t => new { t.BlindSubjectCode, t.TrialReadingCriterionId, t.TrialReadingCriterion.CriterionType, t.TrialReadingCriterion.IsImageFilter, t.TrialReadingCriterion.CriterionModalitys }).FirstNotNullAsync(); - if (taskinfo.CriterionType == CriterionType.IVUS || taskinfo.CriterionType == CriterionType.OCT) + if (taskinfo.CriterionType == CriterionType.IVUS || taskinfo.CriterionType == CriterionType.OCT && isImageSegmentLabel == true) { - + //后处理原始影像预览 + noneDicomStudyQueryable = _noneDicomStudyRepository.Where(t => true, ignoreQueryFilters: isViewDelete) + .WhereIf(isReading, t => t.IsReading && t.IsDeleted == false) + .WhereIf(nonedicomStudyId != null, t => t.Id == nonedicomStudyId) + .ProjectTo(_mapper.ConfigurationProvider, new { isFilterZip = isFilterZip, visiTaskId = visitTaskId, isReading = isReading }); } else { diff --git a/IRaCIS.Core.Application/Service/QC/DTO/NoneDicomStudyViewModel.cs b/IRaCIS.Core.Application/Service/QC/DTO/NoneDicomStudyViewModel.cs index 7162e8c3e..1a673eb78 100644 --- a/IRaCIS.Core.Application/Service/QC/DTO/NoneDicomStudyViewModel.cs +++ b/IRaCIS.Core.Application/Service/QC/DTO/NoneDicomStudyViewModel.cs @@ -31,6 +31,11 @@ namespace IRaCIS.Core.Application.Contracts { } + public class ImageLabelNoneDicomStudyView : NoneDicomStudyView + { + + } + ///NoneDicomStudyQuery 列表查询参数模型 public class NoneDicomStudyQuery { diff --git a/IRaCIS.Core.Application/Service/QC/_MapConfig.cs b/IRaCIS.Core.Application/Service/QC/_MapConfig.cs index f94b1bb1f..665a24f11 100644 --- a/IRaCIS.Core.Application/Service/QC/_MapConfig.cs +++ b/IRaCIS.Core.Application/Service/QC/_MapConfig.cs @@ -755,6 +755,13 @@ namespace IRaCIS.Core.Application.Service .OrderBy(t => t.CreateTime).ThenBy(t => t.FileName))) .ForMember(d => d.CodeView, u => u.MapFrom(s => s.StudyCode)); + CreateMap() + .ForMember(d => d.NoneDicomStudyFileList, u => u.MapFrom(s => + s.ImageLabelNoneDicomFileList.Where(t => isFilterZip ? !t.FileType.Contains(StaticData.FileType.Zip) : true) + .Where(t => isReading ? t.IsReading && t.IsDeleted == false : true) + .OrderBy(t => t.CreateTime).ThenBy(t => t.FileName))) + .ForMember(d => d.CodeView, u => u.MapFrom(s => s.StudyCode)); + CreateMap() .ForMember(d => d.SubjectCode, u => u.MapFrom(s => s.SubjectVisit.Subject.Code)) From 4f91874b829125423150bff81779b5a1831900a4 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Thu, 27 Nov 2025 10:38:48 +0800 Subject: [PATCH 11/13] =?UTF-8?q?uat-=E6=A0=87=E6=B3=A8-15?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ImageAndDoc/DownloadAndUploadService.cs | 24 +++++++++---------- .../ImageAndDoc/NoneDicomStudyService.cs | 7 +++--- .../Service/Visit/SubjectVisitService.cs | 4 ++-- 3 files changed, 18 insertions(+), 17 deletions(-) diff --git a/IRaCIS.Core.Application/Service/ImageAndDoc/DownloadAndUploadService.cs b/IRaCIS.Core.Application/Service/ImageAndDoc/DownloadAndUploadService.cs index 7088fe68c..9453074da 100644 --- a/IRaCIS.Core.Application/Service/ImageAndDoc/DownloadAndUploadService.cs +++ b/IRaCIS.Core.Application/Service/ImageAndDoc/DownloadAndUploadService.cs @@ -174,8 +174,8 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc .Select(t => new StudyBasicInfo() { Id = t.Id, - SubjectVisitId=t.SubjectVisitId, - + SubjectVisitId = t.SubjectVisitId, + StudyInstanceUid = t.StudyInstanceUid, ModalityForEdit = t.ModalityForEdit, BodyPartExamined = t.BodyPartExamined, @@ -196,7 +196,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc UploadStudyList = u.TaskStudyList.Select(t => new StudyBasicInfo() { Id = t.Id, - SubjectVisitId=t.SubjectVisitId, + SubjectVisitId = t.SubjectVisitId, StudyInstanceUid = t.StudyInstanceUid, ModalityForEdit = t.ModalityForEdit, BodyPartExamined = t.BodyPartExamined, @@ -255,7 +255,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc OrginalStudyList = u.SourceSubjectVisit.StudyList .Where(t => u.TrialReadingCriterion.IsImageFilter ? ("|" + u.TrialReadingCriterion.CriterionModalitys + "|").Contains("|" + t.ModalityForEdit + "|") : true) - .Where(t => inQuery.IsImageSegmentLabel == false ? t.ModalityForEdit == "XA" : true) + .Where(t => inQuery.IsImageSegmentLabel == false ? t.ModalityForEdit == "XA" || t.ModalityForEdit == "OCT" : true) .Select(t => new StudyBasicInfo() { Id = t.Id, @@ -1346,7 +1346,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc foreach (var item in list) { - var dicomList = item.DicomStudyList.Where(t => inQuery.IsImageSegmentLabel == false ? t.ModalityForEdit == "XA" : true).ToList(); + var dicomList = item.DicomStudyList.Where(t => inQuery.IsImageSegmentLabel == false ? t.ModalityForEdit == "XA" || t.ModalityForEdit == "OCT" : true).ToList(); dicomList.AddRange(preDicomStudyList.Where(t => t.SubjectVisitId == item.SourceSubjectVisitId).ToList()); @@ -1446,7 +1446,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc var dirInfolist = _subjectRepository.Where(t => t.Id == inQuery.SubjectId).SelectMany(t => t.SubjectVisitList.Where(t => subjectVisitIdList.Contains(t.Id))).SelectMany(t => t.StudyList) .Where(t => isQueryDicom ? inQuery.DicomStudyIdList.Contains(t.Id) : false) .Where(t => info.IsImageFilter ? ("|" + info.CriterionModalitys + "|").Contains("|" + t.ModalityForEdit + "|") : true) - .Where(t => inQuery.IsImageSegmentLabel == false ? t.ModalityForEdit == "XA" : true) + .Where(t => inQuery.IsImageSegmentLabel == false ? t.ModalityForEdit == "XA" || t.ModalityForEdit == "OCT" : true) .SelectMany(t => t.InstanceList.Where(t => t.IsReading && t.DicomSerie.IsReading)) .Select(t => new StudyDIRInfo() { @@ -1489,7 +1489,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc var taskDirInfolist = _taskInstanceRepository.Where(t => t.SubjectVisitId != null) .Where(t => subjectVisitIdList.Contains((Guid)t.SubjectVisitId)).Select(t => new StudyDIRInfo() { - IsTaskStudy=true, + IsTaskStudy = true, SubjectVisitId = (Guid)t.SubjectVisitId, DicomStudyId = t.TaskStudy.Id, @@ -1573,7 +1573,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc TaskBlindName = leftVisitTask.TaskBlindName, StudyList = sv.StudyList.Where(t => isQueryDicom ? inQuery.DicomStudyIdList.Contains(t.Id) : false) .Where(t => info.IsImageFilter ? ("|" + info.CriterionModalitys + "|").Contains("|" + t.ModalityForEdit + "|") : true) - .Where(t => inQuery.IsImageSegmentLabel == false ? t.ModalityForEdit == "XA" : true) + .Where(t => inQuery.IsImageSegmentLabel == false ? t.ModalityForEdit == "XA" || t.ModalityForEdit == "OCT" : true) .Select(u => new DownloadDicomStudyDto() { PatientId = u.PatientId, @@ -1722,9 +1722,9 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc .Select(t => new { t.TrialReadingCriterion.IsImageFilter, t.TrialReadingCriterion.CriterionModalitys }).FirstNotNullAsync(); var query = _taskStudyRepository - .WhereIf(inQuery.VisitTaskId != null, t => t.Id == inQuery.VisitTaskId)//正常后处理 - .WhereIf(inQuery.SubjectVisitId != null, t => t.SubjectVisitId == inQuery.SubjectVisitId)//靶段标注处理的影像 - .WhereIf( info.IsImageFilter && inQuery.VisitTaskId != null, t => ("|" + info.CriterionModalitys + "|").Contains("|" + t.ModalityForEdit + "|") ) + .WhereIf(inQuery.VisitTaskId != null, t => t.VisitTaskId == inQuery.VisitTaskId)//正常后处理 + .WhereIf(inQuery.VisitTaskId == null && inQuery.SubjectVisitId != null, t => t.SubjectVisitId == inQuery.SubjectVisitId)//靶段标注处理的影像 + .WhereIf(info.IsImageFilter && inQuery.VisitTaskId != null, t => ("|" + info.CriterionModalitys + "|").Contains("|" + t.ModalityForEdit + "|")) .Select(t => new { StudyId = t.Id, @@ -2226,7 +2226,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc [HttpPost] public async Task>> GetTrialSubjectVisitMarkList(SubjectVisitMarkQuery inQuery) { - var list = await _subjectRepository.Where(t => t.TrialId == inQuery.TrialId) + var list = await _subjectRepository.Where(t => t.TrialId == inQuery.TrialId && t.SubjectDoctorList.Any()) .WhereIf(inQuery.SubjectCode.IsNotNullOrEmpty(), t => t.Code.Contains(inQuery.SubjectCode)) .WhereIf(inQuery.IsUrgent != null, t => t.IsUrgent == inQuery.IsUrgent) .Select(t => new SubjectVisitMarkDTO() diff --git a/IRaCIS.Core.Application/Service/ImageAndDoc/NoneDicomStudyService.cs b/IRaCIS.Core.Application/Service/ImageAndDoc/NoneDicomStudyService.cs index 67e38daa5..bf23ed095 100644 --- a/IRaCIS.Core.Application/Service/ImageAndDoc/NoneDicomStudyService.cs +++ b/IRaCIS.Core.Application/Service/ImageAndDoc/NoneDicomStudyService.cs @@ -62,7 +62,7 @@ namespace IRaCIS.Core.Application.Contracts { //靶段标注上传后查看影像 - noneDicomStudyQueryable = _noneDicomStudyRepository.Where(t => true, ignoreQueryFilters: isViewDelete) + noneDicomStudyQueryable = _noneDicomStudyRepository.Where(t => t.SubjectVisitId == subjectVisitId, ignoreQueryFilters: isViewDelete) .WhereIf(isReading, t => t.IsReading && t.IsDeleted == false) .WhereIf(nonedicomStudyId != null, t => t.Id == nonedicomStudyId) .ProjectTo(_mapper.ConfigurationProvider, new { isFilterZip = isFilterZip, isReading = isReading }); @@ -75,12 +75,13 @@ namespace IRaCIS.Core.Application.Contracts { var taskinfo = await _visitTaskRepository.Where(x => x.Id == visitTaskId).Select(t => new { t.BlindSubjectCode, t.TrialReadingCriterionId, t.TrialReadingCriterion.CriterionType, t.TrialReadingCriterion.IsImageFilter, t.TrialReadingCriterion.CriterionModalitys }).FirstNotNullAsync(); - if (taskinfo.CriterionType == CriterionType.IVUS || taskinfo.CriterionType == CriterionType.OCT && isImageSegmentLabel == true) + if ((taskinfo.CriterionType == CriterionType.IVUS || taskinfo.CriterionType == CriterionType.OCT) && isImageSegmentLabel == false) { //后处理原始影像预览 - noneDicomStudyQueryable = _noneDicomStudyRepository.Where(t => true, ignoreQueryFilters: isViewDelete) + noneDicomStudyQueryable = _noneDicomStudyRepository.Where(t => t.SubjectVisitId == subjectVisitId, ignoreQueryFilters: isViewDelete) .WhereIf(isReading, t => t.IsReading && t.IsDeleted == false) .WhereIf(nonedicomStudyId != null, t => t.Id == nonedicomStudyId) + .Where(t => taskinfo.IsImageFilter ? ("|" + taskinfo.CriterionModalitys + "|").Contains("|" + t.Modality + "|") : true) .ProjectTo(_mapper.ConfigurationProvider, new { isFilterZip = isFilterZip, visiTaskId = visitTaskId, isReading = isReading }); } else diff --git a/IRaCIS.Core.Application/Service/Visit/SubjectVisitService.cs b/IRaCIS.Core.Application/Service/Visit/SubjectVisitService.cs index 15c906698..e353005a0 100644 --- a/IRaCIS.Core.Application/Service/Visit/SubjectVisitService.cs +++ b/IRaCIS.Core.Application/Service/Visit/SubjectVisitService.cs @@ -251,7 +251,7 @@ namespace IRaCIS.Core.Application.Services .Where(t => isImageFilter ? ("|" + criterionModalitys + "|").Contains("|" + t.ModalityForEdit + "|") : true) .WhereIf(isReading == 1 || isQCFinished, s => s.IsDeleted == false) //预览靶段标注上传的影像 影像后处理 上传了新的影像 还要原始dsa - .WhereIf(isImageSegmentLabel == true && isVisitTask && (criterionType == CriterionType.OCT || criterionType == CriterionType.IVUS), t => t.ModalityForEdit == "XA") + .WhereIf(isImageSegmentLabel == true && isVisitTask && (criterionType == CriterionType.OCT || criterionType == CriterionType.IVUS), t => t.ModalityForEdit == "XA" || t.ModalityForEdit == "OCT") .Select(k => new VisitStudyDTO() { InstanceCount = k.InstanceCount, @@ -516,7 +516,7 @@ namespace IRaCIS.Core.Application.Services .WhereIf(taskInfo.IsImageFilter == true, t => ("|" + taskInfo.CriterionModalitys + "|").Contains("|" + t.ModalityForEdit + "|")) .WhereIf(isManualGenerate, t => t.SubjectCriteriaEvaluationVisitStudyFilterList.Any(t => t.TrialReadingCriterionId == taskInfo.TrialReadingCriterionId && t.IsConfirmed && t.IsReading)) //影像后处理 上传了新的影像 还要原始dsa - .WhereIf(taskInfo.TaskStudyCount > 0 && (taskInfo.CriterionType == CriterionType.OCT || taskInfo.CriterionType == CriterionType.IVUS), t => t.ModalityForEdit == "XA") + .WhereIf(taskInfo.TaskStudyCount > 0 && (taskInfo.CriterionType == CriterionType.OCT || taskInfo.CriterionType == CriterionType.IVUS), t => t.ModalityForEdit == "XA" || t.ModalityForEdit == "OCT") .WhereIf(taskInfo.TaskStudyCount > 0 && (taskInfo.CriterionType != CriterionType.OCT || taskInfo.CriterionType != CriterionType.IVUS), t => false) .Select(k => new VisitStudyDTO() { From d9eaa06de330a389ec3f1396894c2de761a94b8a Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Thu, 27 Nov 2025 15:20:56 +0800 Subject: [PATCH 12/13] =?UTF-8?q?=E4=B8=AD=E5=BF=83=E8=B0=83=E7=A0=94?= =?UTF-8?q?=E8=BF=94=E5=9B=9E=E7=A9=BA=E5=AF=B9=E8=B1=A1=EF=BC=8C=E6=96=B9?= =?UTF-8?q?=E4=BE=BF=E5=89=8D=E7=AB=AF=E6=B8=B2=E6=9F=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SiteSurvey/TrialSiteSurveyService.cs | 29 ++++++++++--------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/IRaCIS.Core.Application/Service/SiteSurvey/TrialSiteSurveyService.cs b/IRaCIS.Core.Application/Service/SiteSurvey/TrialSiteSurveyService.cs index 3e318a5e3..656a49355 100644 --- a/IRaCIS.Core.Application/Service/SiteSurvey/TrialSiteSurveyService.cs +++ b/IRaCIS.Core.Application/Service/SiteSurvey/TrialSiteSurveyService.cs @@ -753,26 +753,29 @@ namespace IRaCIS.Core.Application.Contracts /// 直接查询相关所有数据 /// /// - [HttpGet("{trialId:guid}/{trialSiteSurveyId:guid}")] - public async Task GetSiteSurveyInfo(Guid trialSiteSurveyId, Guid trialId) + [HttpGet("{trialId:guid}")] + public async Task GetSiteSurveyInfo(Guid? trialSiteSurveyId, Guid trialId) { + LoginReturnDTO result = new LoginReturnDTO(); - //有可能填表人提交了,但是此时PM手动对人员信息进行了更改,此时需要将数据同步下(选择在这里同步是因为 不想改动 中心人员哪里的两个接口的逻辑) - var find = await _trialSiteSurveyRepository.FirstOrDefaultAsync(t => t.Id == trialSiteSurveyId, true); - - - if (find.State != TrialSiteSurveyEnum.PMCreatedAndLock && find.IsDeleted != true) + if (trialSiteSurveyId != null) { - var userList = await _trialSiteUserRoleRepository.Where(t => t.TrialId == find.TrialId && t.TrialSiteId == find.TrialSiteId, false, true).ProjectTo(_mapper.ConfigurationProvider).ToListAsync(); + //有可能填表人提交了,但是此时PM手动对人员信息进行了更改,此时需要将数据同步下(选择在这里同步是因为 不想改动 中心人员哪里的两个接口的逻辑) + var find = await _trialSiteSurveyRepository.FirstOrDefaultAsync(t => t.Id == trialSiteSurveyId, true); - await UnlockSyncSiteUserAsync(find.TrialId, find.TrialSiteId, find.Id, userList); + if (find.State != TrialSiteSurveyEnum.PMCreatedAndLock && find.IsDeleted != true) + { + var userList = await _trialSiteUserRoleRepository.Where(t => t.TrialId == find.TrialId && t.TrialSiteId == find.TrialSiteId, false, true).ProjectTo(_mapper.ConfigurationProvider).ToListAsync(); + + + await UnlockSyncSiteUserAsync(find.TrialId, find.TrialSiteId, find.Id, userList); + } + + result = await _trialSiteSurveyRepository.Where(t => t.Id == trialSiteSurveyId && t.TrialId == trialId).IgnoreQueryFilters() + .ProjectTo(_mapper.ConfigurationProvider, new { isEn_Us = _userInfo.IsEn_Us }).FirstOrDefaultAsync().IfNullThrowException(); } - - var result = await _trialSiteSurveyRepository.Where(t => t.Id == trialSiteSurveyId && t.TrialId == trialId).IgnoreQueryFilters() - .ProjectTo(_mapper.ConfigurationProvider, new { isEn_Us = _userInfo.IsEn_Us }).FirstOrDefaultAsync().IfNullThrowException(); - var siteSurveryConfig = _trialSiteSurveyRepository.Where(t => t.Id == trialSiteSurveyId).IgnoreQueryFilters().Select(t => t.Trial.TrialExtraConfigJsonStr).FirstOrDefault() ?? string.Empty; result.SiteSurveyFiledConfig = JsonConvert.DeserializeObject(siteSurveryConfig) ?? new TrialExtraConfig(); From 9a5221ef7d676845b4255511919f225767d9c218 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Thu, 27 Nov 2025 17:31:56 +0800 Subject: [PATCH 13/13] =?UTF-8?q?=E8=B0=83=E6=95=B4ivus=E5=AF=BC=E8=A1=A8?= =?UTF-8?q?=E4=BD=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Service/Common/Export/CDISCExportBaseModel.cs | 1 - .../Service/Common/{ => Export}/IVUS_OCTExportService.cs | 0 2 files changed, 1 deletion(-) rename IRaCIS.Core.Application/Service/Common/{ => Export}/IVUS_OCTExportService.cs (100%) diff --git a/IRaCIS.Core.Application/Service/Common/Export/CDISCExportBaseModel.cs b/IRaCIS.Core.Application/Service/Common/Export/CDISCExportBaseModel.cs index 9e6623357..0bf2ef489 100644 --- a/IRaCIS.Core.Application/Service/Common/Export/CDISCExportBaseModel.cs +++ b/IRaCIS.Core.Application/Service/Common/Export/CDISCExportBaseModel.cs @@ -10,7 +10,6 @@ using System.Threading.Tasks; namespace IRaCIS.Core.Application.Service.Common; - public class TumorCommonQustionInfo { //问题标识,肿瘤评估用于区分是什么问题 diff --git a/IRaCIS.Core.Application/Service/Common/IVUS_OCTExportService.cs b/IRaCIS.Core.Application/Service/Common/Export/IVUS_OCTExportService.cs similarity index 100% rename from IRaCIS.Core.Application/Service/Common/IVUS_OCTExportService.cs rename to IRaCIS.Core.Application/Service/Common/Export/IVUS_OCTExportService.cs