From 1f9d29e005b5ce001d0dfec7bfdbb704d2ad9fde Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Mon, 24 Jun 2024 10:13:03 +0800 Subject: [PATCH 001/251] =?UTF-8?q?=E7=89=88=E6=9C=AC=E5=8E=86=E5=8F=B2?= =?UTF-8?q?=E5=8A=9F=E8=83=BD=E5=A2=9E=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Service/Common/DTO/PublishLogViewModel.cs | 19 ++++++++- .../Service/Common/PublishLogService.cs | 29 ++++++++++++-- .../Service/Common/_MapConfig.cs | 3 ++ IRaCIS.Core.Domain/Common/PublishLog.cs | 40 ++++++++----------- 4 files changed, 62 insertions(+), 29 deletions(-) diff --git a/IRaCIS.Core.Application/Service/Common/DTO/PublishLogViewModel.cs b/IRaCIS.Core.Application/Service/Common/DTO/PublishLogViewModel.cs index b76607051..5cd098251 100644 --- a/IRaCIS.Core.Application/Service/Common/DTO/PublishLogViewModel.cs +++ b/IRaCIS.Core.Application/Service/Common/DTO/PublishLogViewModel.cs @@ -26,6 +26,8 @@ namespace IRaCIS.Core.Application.ViewModel public string? UpdateContent { get; set; } + public int? State { get; set; } + } /// PublishLogAddOrEdit 列表查询参数模型 @@ -33,9 +35,24 @@ namespace IRaCIS.Core.Application.ViewModel { public Guid? Id { get; set; } public string Version { get; set; } - public DateTime PublishTime { get; set; } + public DateTime? PublishTime { get; set; } public string UpdateContent { get; set; } + //0 开发中 ,已发布 + public int State { get; set; } + + public bool IsCurrentVersion { get; set; } + + } + + + public class PublishVersionSelect + { + public Guid Id { get; set; } + public string Version { get; set; } + public int State { get; set; } + public DateTime? PublishTime { get; set; } + public bool IsCurrentVersion { get; set; } } diff --git a/IRaCIS.Core.Application/Service/Common/PublishLogService.cs b/IRaCIS.Core.Application/Service/Common/PublishLogService.cs index 5afb3aaf8..213c0b90a 100644 --- a/IRaCIS.Core.Application/Service/Common/PublishLogService.cs +++ b/IRaCIS.Core.Application/Service/Common/PublishLogService.cs @@ -9,6 +9,7 @@ using Microsoft.AspNetCore.Mvc; using IRaCIS.Core.Application.Interfaces; using IRaCIS.Core.Application.ViewModel; using IRaCIS.Application.Contracts; +using Microsoft.AspNetCore.Authorization; namespace IRaCIS.Core.Application.Service { @@ -31,8 +32,9 @@ namespace IRaCIS.Core.Application.Service { var publishLogQueryable = _publishLogRepository - .WhereIf(!string.IsNullOrEmpty(inQuery.Version) , t => t.Version.Contains(inQuery.Version)) + .WhereIf(!string.IsNullOrEmpty(inQuery.Version), t => t.Version.Contains(inQuery.Version)) .WhereIf(!string.IsNullOrEmpty(inQuery.UpdateContent), t => t.UpdateContent.Contains(inQuery.UpdateContent)) + .WhereIf(inQuery.State != null, t => t.State == inQuery.State) .ProjectTo(_mapper.ConfigurationProvider); var pageList = await publishLogQueryable @@ -50,11 +52,11 @@ namespace IRaCIS.Core.Application.Service { return ResponseOutput.NotOk("版本号不符合要求"); } - + var verifyExp1 = new EntityVerifyExp() { - VerifyExp = u => u.Version == addOrEditPublishLog.Version , - + VerifyExp = u => u.Version == addOrEditPublishLog.Version, + VerifyMsg = "发布编号不能重复" }; @@ -74,6 +76,25 @@ namespace IRaCIS.Core.Application.Service return ResponseOutput.Ok(); } + [AllowAnonymous] + public async Task GetCurrentPublishInfo() + { + var result = await _publishLogRepository.Where(t => t.IsCurrentVersion == true).ProjectTo(_mapper.ConfigurationProvider).FirstOrDefaultAsync(); + + if (result == null) + { + //系统当前版本未标记,请联系维护人员 + throw new QueryBusinessObjectNotExistException("系统当前版本未标记,请联系维护人员"); + } + + return result; + } + + + public async Task> GetPublishVersionSelect() + { + return await _publishLogRepository.ProjectTo(_mapper.ConfigurationProvider).OrderByDescending(t => t.State).ToListAsync(); + } } } diff --git a/IRaCIS.Core.Application/Service/Common/_MapConfig.cs b/IRaCIS.Core.Application/Service/Common/_MapConfig.cs index 18058ee40..743955f1a 100644 --- a/IRaCIS.Core.Application/Service/Common/_MapConfig.cs +++ b/IRaCIS.Core.Application/Service/Common/_MapConfig.cs @@ -78,6 +78,9 @@ namespace IRaCIS.Core.Application.Service CreateMap(); CreateMap().ReverseMap(); + CreateMap(); + + } } diff --git a/IRaCIS.Core.Domain/Common/PublishLog.cs b/IRaCIS.Core.Domain/Common/PublishLog.cs index 082edaef3..0a58ed3a3 100644 --- a/IRaCIS.Core.Domain/Common/PublishLog.cs +++ b/IRaCIS.Core.Domain/Common/PublishLog.cs @@ -17,48 +17,40 @@ namespace IRaCIS.Core.Domain.Models { - /// - /// Version - /// + [Required] public string Version { get; set; } - /// - /// PublishTime - /// + [Required] - public DateTime PublishTime { get; set; } + public DateTime? PublishTime { get; set; } - /// - /// UpdateContent - /// + [Required] public string UpdateContent { get; set; } - /// - /// CreateTime - /// + [Required] public DateTime CreateTime { get; set; } - /// - /// CreateUserId - /// + [Required] public Guid CreateUserId { get; set; } - /// - /// UpdateUserId - /// + [Required] public Guid UpdateUserId { get; set; } - /// - /// UpdateTime - /// + [Required] public DateTime UpdateTime { get; set; } - - } + + //0 开发中 ,已发布 + public int State { get; set; } + + public bool IsCurrentVersion { get; set; } + + + } } From ab84e66fe4eeac8a961d49bd9cbaab6fb89fbea1 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Mon, 24 Jun 2024 10:51:23 +0800 Subject: [PATCH 002/251] =?UTF-8?q?=E5=9B=BD=E9=99=85=E5=8C=96=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=EF=BC=8C=E5=A2=9E=E5=8A=A0=E6=89=B9=E9=87=8F=E6=9B=B4?= =?UTF-8?q?=E6=96=B0=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../IRaCIS.Core.Application.xml | 7 ++++++ .../DTO/InternationalizationViewModel.cs | 22 ++++++++++++++++--- .../Common/InternationalizationService.cs | 13 +++++++++++ .../Common/Internationalization.cs | 7 ++++++ 4 files changed, 46 insertions(+), 3 deletions(-) diff --git a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml index 851952723..fda29c5ae 100644 --- a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml +++ b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml @@ -738,6 +738,13 @@ + + + 批量更新状态和发布版本 + + + + PublishLogService diff --git a/IRaCIS.Core.Application/Service/Common/DTO/InternationalizationViewModel.cs b/IRaCIS.Core.Application/Service/Common/DTO/InternationalizationViewModel.cs index c6b7567b3..8aa5e7e0c 100644 --- a/IRaCIS.Core.Application/Service/Common/DTO/InternationalizationViewModel.cs +++ b/IRaCIS.Core.Application/Service/Common/DTO/InternationalizationViewModel.cs @@ -45,6 +45,9 @@ namespace IRaCIS.Core.Application.ViewModel public string FrontType { get; set; } = string.Empty; public int InternationalizationType { get; set; } + public string Module { get; set; } = string.Empty; + //关联版本历史记录表Id + public Guid? PublishLogId { get; set; } } public class BatchAddInternationalization @@ -64,16 +67,29 @@ namespace IRaCIS.Core.Application.ViewModel public string Value { get; set; } = string.Empty; public string FrontType { get; set; } = string.Empty; public string ValueCN { get; set; } = string.Empty; + + public string Module { get; set; } = string.Empty; + //关联版本历史记录表Id + public Guid? PublishLogId { get; set; } } public class BatchAddInternationalizationDto : BatchInternationalizationDto { - + } - public class InternationalizationSimpleDto: BatchInternationalizationDto + public class InternationalizationSimpleDto : BatchInternationalizationDto { - + + } + + public class BatchUpdateInfoCommand + { + public List IdList { get; set; } + + public Guid? PublishLogId { get; set; } + + public int State { get; set; } } } diff --git a/IRaCIS.Core.Application/Service/Common/InternationalizationService.cs b/IRaCIS.Core.Application/Service/Common/InternationalizationService.cs index ff6b43a4c..f3c18f9d3 100644 --- a/IRaCIS.Core.Application/Service/Common/InternationalizationService.cs +++ b/IRaCIS.Core.Application/Service/Common/InternationalizationService.cs @@ -202,6 +202,19 @@ namespace IRaCIS.Core.Application.Service return ResponseOutput.Ok(); } + /// + /// 批量更新状态和发布版本 + /// + /// + /// + [HttpPut] + public async Task BatchUpdateInternationalInfo(BatchUpdateInfoCommand inCommand) + { + await _internationalizationRepository.BatchUpdateNoTrackingAsync(t => inCommand.IdList.Contains(t.Id), t => new Internationalization() { State = inCommand.State, PublishLogId = inCommand.PublishLogId }); + + return ResponseOutput.Ok(); + } + } } diff --git a/IRaCIS.Core.Domain/Common/Internationalization.cs b/IRaCIS.Core.Domain/Common/Internationalization.cs index e4a7be5e9..6d7a9e864 100644 --- a/IRaCIS.Core.Domain/Common/Internationalization.cs +++ b/IRaCIS.Core.Domain/Common/Internationalization.cs @@ -45,6 +45,13 @@ namespace IRaCIS.Core.Domain.Models public string FrontType { get; set; }=string.Empty; + + public string Module { get; set; } = string.Empty; + //关联版本历史记录表Id + public Guid? PublishLogId { get; set; } + + + } } From f97565d9d83e775445467408443b664f0e0fdada Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Mon, 24 Jun 2024 16:07:41 +0800 Subject: [PATCH 003/251] =?UTF-8?q?=E5=8C=BB=E7=94=9F=E5=85=A5=E7=BB=84?= =?UTF-8?q?=EF=BC=8C=E6=B2=A1=E6=9C=89spm=E4=BF=AE=E6=94=B9=E9=80=BB?= =?UTF-8?q?=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.Application/Service/WorkLoad/EnrollService.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/IRaCIS.Core.Application/Service/WorkLoad/EnrollService.cs b/IRaCIS.Core.Application/Service/WorkLoad/EnrollService.cs index a0e71f568..9c0124c9b 100644 --- a/IRaCIS.Core.Application/Service/WorkLoad/EnrollService.cs +++ b/IRaCIS.Core.Application/Service/WorkLoad/EnrollService.cs @@ -194,6 +194,7 @@ namespace IRaCIS.Application.Services var trial = await _trialRepository.FirstOrDefaultAsync(t => t.Id == trialId); + var hasSPMOrCPM = await _repository.AnyAsync(t => t.TrialId == trialId && t.User.UserTypeEnum == UserTypeEnum.SPM || t.User.UserTypeEnum == UserTypeEnum.CPM); if (trial != null) { @@ -217,15 +218,14 @@ namespace IRaCIS.Application.Services { if (doctorIdArray.Contains(intoGroupItem.DoctorId)) { - intoGroupItem.EnrollStatus = EnrollStatus.HasCommittedToCRO; - //_enrollRepository.Update(intoGroupItem); + intoGroupItem.EnrollStatus = hasSPMOrCPM ? EnrollStatus.HasCommittedToCRO : EnrollStatus.InviteIntoGroup; await _enrollDetailRepository.AddAsync(new EnrollDetail() { TrialDetailId = trialDetail.Id, DoctorId = intoGroupItem.DoctorId, TrialId = trialId, - EnrollStatus = EnrollStatus.HasCommittedToCRO, + EnrollStatus = hasSPMOrCPM? EnrollStatus.HasCommittedToCRO :EnrollStatus.InviteIntoGroup, OptUserType = (int)SystemUserType.AdminUser, //后台用户 }); } From a4226d4e2f4111587df3dd13ac9d16f661475bf2 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Mon, 24 Jun 2024 16:28:20 +0800 Subject: [PATCH 004/251] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E7=AD=9B=E9=80=89?= =?UTF-8?q?=E6=9D=A1=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.Application/Service/WorkLoad/EnrollService.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/IRaCIS.Core.Application/Service/WorkLoad/EnrollService.cs b/IRaCIS.Core.Application/Service/WorkLoad/EnrollService.cs index 9c0124c9b..8fc2829a3 100644 --- a/IRaCIS.Core.Application/Service/WorkLoad/EnrollService.cs +++ b/IRaCIS.Core.Application/Service/WorkLoad/EnrollService.cs @@ -194,14 +194,14 @@ namespace IRaCIS.Application.Services var trial = await _trialRepository.FirstOrDefaultAsync(t => t.Id == trialId); - var hasSPMOrCPM = await _repository.AnyAsync(t => t.TrialId == trialId && t.User.UserTypeEnum == UserTypeEnum.SPM || t.User.UserTypeEnum == UserTypeEnum.CPM); + var hasSPMOrCPM = await _repository.Where(t => t.TrialId == trialId).AnyAsync(t=> t.User.UserTypeEnum == UserTypeEnum.SPM || t.User.UserTypeEnum == UserTypeEnum.CPM); if (trial != null) { if (commitState == 1) //确认提交CRO { //更新项目状态 - trial.TrialEnrollStatus = (int)TrialEnrollStatus.HasCommitCRO; + trial.TrialEnrollStatus = hasSPMOrCPM ? (int)TrialEnrollStatus.HasCommitCRO : (int)TrialEnrollStatus.HasConfirmedDoctorNames; //添加项目详细记录 var trialDetail = new TrialStatusDetail() From 96c4165cda59179d49b485a81df4f500df55ca19 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Mon, 24 Jun 2024 16:53:53 +0800 Subject: [PATCH 005/251] =?UTF-8?q?=E4=BF=AE=E6=94=B9=20=E7=95=8C=E9=9D=A2?= =?UTF-8?q?=E6=8E=A7=E5=88=B6bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Service/WorkLoad/EnrollService.cs | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/IRaCIS.Core.Application/Service/WorkLoad/EnrollService.cs b/IRaCIS.Core.Application/Service/WorkLoad/EnrollService.cs index 8fc2829a3..3b4b365b9 100644 --- a/IRaCIS.Core.Application/Service/WorkLoad/EnrollService.cs +++ b/IRaCIS.Core.Application/Service/WorkLoad/EnrollService.cs @@ -225,9 +225,23 @@ namespace IRaCIS.Application.Services TrialDetailId = trialDetail.Id, DoctorId = intoGroupItem.DoctorId, TrialId = trialId, - EnrollStatus = hasSPMOrCPM? EnrollStatus.HasCommittedToCRO :EnrollStatus.InviteIntoGroup, + EnrollStatus = hasSPMOrCPM ? EnrollStatus.HasCommittedToCRO : EnrollStatus.InviteIntoGroup, OptUserType = (int)SystemUserType.AdminUser, //后台用户 }); + + if (!hasSPMOrCPM) + { + await _enrollDetailRepository.AddAsync(new EnrollDetail() + { + TrialDetailId = trialDetail.Id, + DoctorId = intoGroupItem.DoctorId, + TrialId = trialId, + EnrollStatus = EnrollStatus.HasCommittedToCRO, + OptUserType = (int)SystemUserType.AdminUser, //后台用户 + }); + } + + } } From 20092d6757458cd4375ecb600d9fb29e8812fa7a Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Mon, 24 Jun 2024 17:21:15 +0800 Subject: [PATCH 006/251] =?UTF-8?q?=E5=8D=87=E7=BA=A7=E9=82=AE=E4=BB=B6?= =?UTF-8?q?=E5=8F=91=E9=80=81=E5=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.Application/IRaCIS.Core.Application.csproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/IRaCIS.Core.Application/IRaCIS.Core.Application.csproj b/IRaCIS.Core.Application/IRaCIS.Core.Application.csproj index 0c907fb89..ef903d453 100644 --- a/IRaCIS.Core.Application/IRaCIS.Core.Application.csproj +++ b/IRaCIS.Core.Application/IRaCIS.Core.Application.csproj @@ -78,9 +78,9 @@ - + - + From fb87f4d06ae6a817827346894d2900a126de3382 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Mon, 24 Jun 2024 17:26:20 +0800 Subject: [PATCH 007/251] =?UTF-8?q?=E7=89=88=E6=9C=AC=E9=80=80=E5=9B=9E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.Application/IRaCIS.Core.Application.csproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/IRaCIS.Core.Application/IRaCIS.Core.Application.csproj b/IRaCIS.Core.Application/IRaCIS.Core.Application.csproj index ef903d453..9563aa30a 100644 --- a/IRaCIS.Core.Application/IRaCIS.Core.Application.csproj +++ b/IRaCIS.Core.Application/IRaCIS.Core.Application.csproj @@ -78,9 +78,9 @@ - + - + From 97b97a164d143807aa426ddaab4492ff4b313ad8 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Mon, 24 Jun 2024 17:37:35 +0800 Subject: [PATCH 008/251] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=8F=91=E9=80=81?= =?UTF-8?q?=E9=82=AE=E4=BB=B6=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.Application/IRaCIS.Core.Application.csproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/IRaCIS.Core.Application/IRaCIS.Core.Application.csproj b/IRaCIS.Core.Application/IRaCIS.Core.Application.csproj index 9563aa30a..f230207ee 100644 --- a/IRaCIS.Core.Application/IRaCIS.Core.Application.csproj +++ b/IRaCIS.Core.Application/IRaCIS.Core.Application.csproj @@ -78,9 +78,9 @@ - + - + From de70f68640bb3d14aaafb31392849a7729ac5055 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Mon, 24 Jun 2024 17:46:37 +0800 Subject: [PATCH 009/251] =?UTF-8?q?=E5=8F=91=E9=80=81=E9=82=AE=E4=BB=B6?= =?UTF-8?q?=E7=89=88=E6=9C=AC=E9=80=80=E5=9B=9E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.Application/IRaCIS.Core.Application.csproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/IRaCIS.Core.Application/IRaCIS.Core.Application.csproj b/IRaCIS.Core.Application/IRaCIS.Core.Application.csproj index f230207ee..72dc549f8 100644 --- a/IRaCIS.Core.Application/IRaCIS.Core.Application.csproj +++ b/IRaCIS.Core.Application/IRaCIS.Core.Application.csproj @@ -78,9 +78,9 @@ - + - + From 73edbe8fd37a56a0ede5e2d05bb726d025b6d753 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Tue, 25 Jun 2024 09:17:28 +0800 Subject: [PATCH 010/251] =?UTF-8?q?=E5=88=A0=E6=8E=89=E9=82=AE=E4=BB=B6?= =?UTF-8?q?=E6=97=A5=E5=BF=97=E7=BB=84=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.API/IRaCIS.Core.API.csproj | 1 - IRaCIS.Core.API/_ServiceExtensions/Serilog/SerilogSetup.cs | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/IRaCIS.Core.API/IRaCIS.Core.API.csproj b/IRaCIS.Core.API/IRaCIS.Core.API.csproj index 4f364beff..f6e1614ef 100644 --- a/IRaCIS.Core.API/IRaCIS.Core.API.csproj +++ b/IRaCIS.Core.API/IRaCIS.Core.API.csproj @@ -79,7 +79,6 @@ - diff --git a/IRaCIS.Core.API/_ServiceExtensions/Serilog/SerilogSetup.cs b/IRaCIS.Core.API/_ServiceExtensions/Serilog/SerilogSetup.cs index 7da66607b..a010e8595 100644 --- a/IRaCIS.Core.API/_ServiceExtensions/Serilog/SerilogSetup.cs +++ b/IRaCIS.Core.API/_ServiceExtensions/Serilog/SerilogSetup.cs @@ -1,7 +1,7 @@ using Microsoft.AspNetCore.Builder; using Serilog; using Serilog.Events; -using Serilog.Sinks.Email; +//using Serilog.Sinks.Email; using System; using System.Net; From d3ab051a394b335f5e11ba06a1c484d62be66c13 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Tue, 25 Jun 2024 10:26:30 +0800 Subject: [PATCH 011/251] =?UTF-8?q?spm=20cpm=20=20=E8=BF=94=E5=9B=9E?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=AD=97=E6=AE=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.Application/Service/WorkLoad/EnrollService.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/IRaCIS.Core.Application/Service/WorkLoad/EnrollService.cs b/IRaCIS.Core.Application/Service/WorkLoad/EnrollService.cs index 3b4b365b9..6849dd81e 100644 --- a/IRaCIS.Core.Application/Service/WorkLoad/EnrollService.cs +++ b/IRaCIS.Core.Application/Service/WorkLoad/EnrollService.cs @@ -271,7 +271,7 @@ namespace IRaCIS.Application.Services } - return ResponseOutput.Result(await _enrollRepository.SaveChangesAsync()); + return ResponseOutput.Result(await _enrollRepository.SaveChangesAsync(), new {IsHaveSpmOrCPM=hasSPMOrCPM}); } //$"Cannot find trial {trialId}" return ResponseOutput.NotOk(_localizer["Enroll_NotFound", trialId]); From 9048963ea5ae76ef2806ed7253a009253321eb4c Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Tue, 25 Jun 2024 10:28:18 +0800 Subject: [PATCH 012/251] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=AD=97=E6=AE=B5?= =?UTF-8?q?=E5=90=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.Application/Service/WorkLoad/EnrollService.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/IRaCIS.Core.Application/Service/WorkLoad/EnrollService.cs b/IRaCIS.Core.Application/Service/WorkLoad/EnrollService.cs index 6849dd81e..1f1b427c9 100644 --- a/IRaCIS.Core.Application/Service/WorkLoad/EnrollService.cs +++ b/IRaCIS.Core.Application/Service/WorkLoad/EnrollService.cs @@ -271,7 +271,7 @@ namespace IRaCIS.Application.Services } - return ResponseOutput.Result(await _enrollRepository.SaveChangesAsync(), new {IsHaveSpmOrCPM=hasSPMOrCPM}); + return ResponseOutput.Result(await _enrollRepository.SaveChangesAsync(), new {IsHaveSPMOrCPM=hasSPMOrCPM}); } //$"Cannot find trial {trialId}" return ResponseOutput.NotOk(_localizer["Enroll_NotFound", trialId]); From 452535b56190578a968eaf371e8a561900561076 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Tue, 25 Jun 2024 10:52:16 +0800 Subject: [PATCH 013/251] =?UTF-8?q?=E4=B8=AD=E5=BF=83=E8=B0=83=E7=A0=94?= =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Service/SiteSurvey/TrialSiteSurveyService.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/IRaCIS.Core.Application/Service/SiteSurvey/TrialSiteSurveyService.cs b/IRaCIS.Core.Application/Service/SiteSurvey/TrialSiteSurveyService.cs index 2f4cdec0c..27779454a 100644 --- a/IRaCIS.Core.Application/Service/SiteSurvey/TrialSiteSurveyService.cs +++ b/IRaCIS.Core.Application/Service/SiteSurvey/TrialSiteSurveyService.cs @@ -726,15 +726,15 @@ namespace IRaCIS.Core.Application.Contracts t.Email, }).ToListAsync(); - var currentUserList = siteUserList.Where(t => t.TrialSiteSurveyId == trialSiteSurveyId).ToList(); + //var currentUserList = siteUserList.Where(t => t.TrialSiteSurveyId == trialSiteSurveyId).ToList(); - if (!currentUserList.Any(t => t.UserTypeEnum == UserTypeEnum.ClinicalResearchCoordinator)) + if (!siteUserList.Any(t => t.UserTypeEnum == UserTypeEnum.ClinicalResearchCoordinator || t.UserTypeEnum == UserTypeEnum.CRA)) { throw new BusinessValidationFailedException(_localizer["TrialSiteSurvey_MissingAccount"]); } - if (currentUserList.Where(t => t.IsGenerateAccount && t.UserTypeId != null).GroupBy(t => new { t.UserTypeId, t.Email }) + if (siteUserList.Where(t => t.IsGenerateAccount && t.UserTypeId != null).GroupBy(t => new { t.UserTypeId, t.Email }) .Any(g => g.Count() > 1)) { throw new BusinessValidationFailedException(_localizer["TrialSiteSurvey_DuplicateEmail"]); From be27376dde4214787e754a4c8e6c5bd04afc0049 Mon Sep 17 00:00:00 2001 From: he <109787524@qq.com> Date: Wed, 26 Jun 2024 09:10:20 +0800 Subject: [PATCH 014/251] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=20Lugano=202014=20Wi?= =?UTF-8?q?thout=20PET?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../LuganoWithoutPETCalculateService.cs | 3749 +++++++++++++++++ 1 file changed, 3749 insertions(+) create mode 100644 IRaCIS.Core.Application/Service/ReadingCalculate/LuganoWithoutPETCalculateService.cs diff --git a/IRaCIS.Core.Application/Service/ReadingCalculate/LuganoWithoutPETCalculateService.cs b/IRaCIS.Core.Application/Service/ReadingCalculate/LuganoWithoutPETCalculateService.cs new file mode 100644 index 000000000..672d3087a --- /dev/null +++ b/IRaCIS.Core.Application/Service/ReadingCalculate/LuganoWithoutPETCalculateService.cs @@ -0,0 +1,3749 @@ +using IRaCIS.Core.Application.Service.Reading.Dto; +using IRaCIS.Core.Domain.Share; +using Microsoft.AspNetCore.Mvc; +using IRaCIS.Core.Domain.Models; +using IRaCIS.Core.Application.Interfaces; +using IRaCIS.Core.Application.ViewModel; +using Panda.DynamicWebApi.Attributes; +using IRaCIS.Core.Infra.EFCore.Common; +using Microsoft.Extensions.Caching.Memory; + +using IRaCIS.Core.Infrastructure; +using MassTransit; +using System.Reflection.Metadata.Ecma335; +using System.Linq; +using NPOI.SS.Formula.Functions; +using DocumentFormat.OpenXml.Drawing.Charts; +using IRaCIS.Core.Application.Contracts; +using IRaCIS.Core.Application.Service.ReadingCalculate.Interface; +using DocumentFormat.OpenXml.Office2016.Drawing.ChartDrawing; + +namespace IRaCIS.Core.Application.Service.ReadingCalculate +{ + + [ApiExplorerSettings(GroupName = "Reading")] + public class LuganoWithoutPETCalculateService : BaseService, ICriterionCalculateService, ILuganoCalculateService + { + private readonly IRepository _readingTableQuestionAnswerRepository; + private readonly IRepository _visitTaskRepository; + private readonly IRepository _readingQuestionCriterionTrialRepository; + private readonly IRepository _readingTableQuestionTrialRepository; + private readonly IRepository _readingTaskQuestionMarkRepository; + private readonly IRepository _readingTableAnswerRowInfoRepository; + private readonly IRepository _readingGlobalTaskInfoRepository; + private readonly IRepository _readingQuestionTrialRepository; + private readonly IRepository _organInfoRepository; + private readonly IRepository _subjectVisitRepository; + private readonly IRepository _dicomStudyRepository; + private readonly IRepository _tumorAssessmentRepository; + private readonly ISubjectVisitService _subjectVisitService; + private readonly IGeneralCalculateService _generalCalculateService; + private readonly IRepository _readingTaskQuestionAnswerRepository; + + public LuganoWithoutPETCalculateService( + IRepository readingTableQuestionAnswerRepository, + IRepository visitTaskRepository, + IRepository readingQuestionCriterionTrialRepository, + IRepository readingTableQuestionTrialRepository, + IRepository readingTaskQuestionMarkRepository, + IRepository readingTableAnswerRowInfoRepository, + IRepository readingGlobalTaskInfoRepository, + IRepository readingQuestionTrialRepository, + IRepository organInfoRepository, + IRepository subjectVisitRepository, + IRepository dicomStudyRepository, + IRepository tumorAssessmentRepository, + ISubjectVisitService subjectVisitService, + IGeneralCalculateService generalCalculateService, + IRepository readingTaskQuestionAnswerRepository + ) + { + this._readingTableQuestionAnswerRepository = readingTableQuestionAnswerRepository; + this._visitTaskRepository = visitTaskRepository; + this._readingQuestionCriterionTrialRepository = readingQuestionCriterionTrialRepository; + this._readingTableQuestionTrialRepository = readingTableQuestionTrialRepository; + this._readingTaskQuestionMarkRepository = readingTaskQuestionMarkRepository; + this._readingTableAnswerRowInfoRepository = readingTableAnswerRowInfoRepository; + this._readingGlobalTaskInfoRepository = readingGlobalTaskInfoRepository; + this._readingQuestionTrialRepository = readingQuestionTrialRepository; + this._organInfoRepository = organInfoRepository; + this._subjectVisitRepository = subjectVisitRepository; + this._dicomStudyRepository = dicomStudyRepository; + this._tumorAssessmentRepository = tumorAssessmentRepository; + this._subjectVisitService = subjectVisitService; + this._generalCalculateService = generalCalculateService; + this._readingTaskQuestionAnswerRepository = readingTaskQuestionAnswerRepository; + } + + /// + /// 获取阅片的计算数据 + /// + /// + /// + public async Task GetReadingCalculationData(GetReadingCalculationDataInDto inDto) + { + ReadingCalculateDto readingData = await _generalCalculateService.GetReadingCalculateDto(inDto.VisitTaskId); + readingData.ComputationTrigger = ComputationTrigger.LiverBloodPool; + var baseLinePET5PS = 0m; + if (!readingData.IsBaseLine) + { + var baseLineTaskId = await GetBaseLineTaskId(readingData); + baseLinePET5PS = (await _readingTaskQuestionAnswerRepository.Where(x => x.VisitTaskId == baseLineTaskId && x.ReadingQuestionTrial.QuestionType == QuestionType.PET5PS).Select(x => x.Answer).FirstOrDefaultAsync()).IsNullOrEmptyReturn0(); + + } + return new + { + BaseLinePET5PS = baseLinePET5PS, + //计算的5ps评分 + CalculatePET5PS=await GetPET5PS(readingData), + + }; + } + + #region 临时对象 单个请求的生命周期 避免重复查询数据库 + + private List visitTaskAnswerList; + + /// + /// 获取Sod的值 + /// + private decimal? sODData; + + /// + /// 基线任务Id + /// + private Guid? BaseLineTaskId; + + /// + /// 影像是否无法融合 + /// + private bool? isUnableFuse; + + + private string nAString = "NA"; + #endregion + + #region 删除病灶获取起始病灶序号 + /// + /// 删除病灶获取起始病灶序号(RECIST1Point1 固定是1) + /// + /// + public async Task GetDeleteLesionStatrIndex(DeleteReadingRowAnswerInDto inDto) + { + return 1; + } + #endregion + + #region 获取阅片报告 + /// + /// 获取阅片报告 + /// + /// + /// + [HttpPost] + public async Task GetReadingReportEvaluation(GetReadingReportEvaluationInDto indto) + { + GetReadingReportEvaluationOutDto result = new GetReadingReportEvaluationOutDto(); + + result.CalculateResult = await this.GetReportVerify(new GetReportVerifyInDto() + { + VisitTaskId = indto.VisitTaskId + }); + + + var visitTaskInfo = await _visitTaskRepository.Where(x => x.Id == indto.VisitTaskId).FirstNotNullAsync(); + + result.ReadingTaskState = visitTaskInfo.ReadingTaskState; + var taskInfoList = await _generalCalculateService.GetReadingReportTaskList(indto.VisitTaskId); + + result.VisitTaskList = taskInfoList; + + var visitTaskIds = taskInfoList.Select(x => x.VisitTaskId).ToList(); + + var criterionId = visitTaskInfo.TrialReadingCriterionId; + var questionList = await _readingQuestionTrialRepository.Where(x => x.ReadingQuestionCriterionTrialId == criterionId && x.ShowQuestion != ShowQuestion.Hide).ToListAsync(); + var tableQuestionList = await _readingTableQuestionTrialRepository.Where(x => x.TrialCriterionId == criterionId).OrderBy(x => x.ShowOrder).ToListAsync(); + var tableAnsweRowInfos = await _readingTableAnswerRowInfoRepository.Where(x => x.VisitTaskId == indto.VisitTaskId).ProjectTo(_mapper.ConfigurationProvider).ToListAsync(); + result.LesionCountList = tableAnsweRowInfos.GroupBy(x => x.LesionType).Select(x => new LesionDto + { + LesionType = x.Key, + Count = x.ToList().Count() + }).ToList(); + var answers = await _readingTaskQuestionAnswerRepository.Where(x => visitTaskIds.Contains(x.VisitTaskId)).ToListAsync(); + var tableAnswers = await _readingTableQuestionAnswerRepository.Where(x => visitTaskIds.Contains(x.VisitTaskId)).ToListAsync(); + + var globalanswerList = await _readingGlobalTaskInfoRepository.Where(x => visitTaskIds.Contains(x.TaskId) && x.GlobalVisitTask.TaskState == TaskState.Effect && x.Answer != string.Empty).Select(x => new + { + x.TaskId, + x.GlobalVisitTask.VisitTaskNum, + x.QuestionId, + x.Answer + }).ToListAsync(); + + var alltableAnsweRowInfos = await _readingTableAnswerRowInfoRepository.Where(x => visitTaskIds.Contains(x.VisitTaskId)).ToListAsync(); + var organIds = alltableAnsweRowInfos.Where(x => x.OrganInfoId != null).Select(x => x.OrganInfoId).Distinct().ToList(); + var organInfos = await _organInfoRepository.Where(x => organIds.Contains(x.Id)).ToListAsync(); + + var needChangeType = new List() { + QuestionMark.Organ, + QuestionMark.Location, + QuestionMark.Part, + }; + + // 第一级 + + #region 构造问题 + List questions = questionList.Where(x => x.Type == ReadingQestionType.Group).OrderBy(x => x.ShowOrder).Select(x => new ReadingReportDto() + { + QuestionId = x.Id, + GroupName = x.GroupName, + GroupEnName = x.GroupEnName, + IsShowInDicom = x.IsShowInDicom, + Type = x.Type, + GroupId = x.GroupId, + QuestionType = x.QuestionType, + LesionType = x.LesionType, + QuestionGenre = x.QuestionGenre, + DataSource = x.DataSource, + DictionaryCode = x.DictionaryCode, + TypeValue = x.TypeValue, + QuestionName = x.QuestionName.LanguageName(x.QuestionEnName, _userInfo.IsEn_Us), + ShowOrder = x.ShowOrder, + ValueType = x.ValueType, + Unit = x.Unit, + CustomUnit = x.CustomUnit, + ReportLayType = ReportLayType.Group, + }).ToList(); + + // 分组 + foreach (var item in questions) + { + item.Childrens = questionList.Where(x => x.GroupId == item.QuestionId).OrderBy(x => x.ShowOrder).Select(x => new ReadingReportDto() + { + GroupName = x.GroupName, + QuestionId = x.Id, + IsShowInDicom = x.IsShowInDicom, + GroupEnName = x.GroupEnName, + QuestionName = x.QuestionName.LanguageName(x.QuestionEnName, _userInfo.IsEn_Us), + LesionType = x.LesionType, + QuestionGenre = x.QuestionGenre, + DataSource = x.DataSource, + DictionaryCode = x.DictionaryCode, + Type = x.Type, + QuestionType = x.QuestionType, + TypeValue = x.TypeValue, + ShowOrder = x.ShowOrder, + OrderMark = x.OrderMark, + ValueType = x.ValueType, + Unit = x.Unit, + CustomUnit = x.CustomUnit, + ReportLayType = ReportLayType.Question, + }).ToList(); + + // 问题 + foreach (var question in item.Childrens) + { + + foreach (var task in taskInfoList) + { + + var globalAnswer = globalanswerList.Where(x => x.TaskId == task.VisitTaskId && x.QuestionId == question.QuestionId).OrderByDescending(x => x.VisitTaskNum).FirstOrDefault(); + var answer = answers.Where(x => x.VisitTaskId == task.VisitTaskId && x.ReadingQuestionTrialId == question.QuestionId).FirstOrDefault(); + question.Answer.Add(new TaskQuestionAnswer() + { + Answer = answer == null ? string.Empty : answer.Answer, + IsGlobalChange = globalAnswer == null ? false : true, + GlobalChangeAnswer = globalAnswer == null ? string.Empty : globalAnswer.Answer, + TaskName = task.TaskName, + VisitTaskId = task.VisitTaskId, + + }); + } + + // 构造表格行数据 + + + var rowlist = tableAnsweRowInfos.Where(x => x.QuestionId == question.QuestionId).OrderBy(x => x.RowIndex).ToList(); + + + question.Childrens = rowlist.Select(x => new ReadingReportDto() + { + QuestionName = question.OrderMark + x.RowIndex.GetLesionMark(), + SplitOrMergeLesionName = x.MergeName.IsNullOrEmpty() ? x.SplitName : x.MergeName, + SplitOrMergeType = x.SplitOrMergeType, + LesionType = question.LesionType, + IsShowInDicom = question.IsShowInDicom, + IsCanEditPosition = x.IsCanEditPosition, + RowIndex = x.RowIndex, + BlindName = x.BlindName, + ReportLayType = ReportLayType.Lesions, + }).ToList(); + + + foreach (var row in question.Childrens) + { + // tableQuestion + row.Childrens = tableQuestionList.Where(x => x.ReadingQuestionId == question.QuestionId).Select(x => new ReadingReportDto() + { + QuestionName = x.QuestionName.LanguageName(x.QuestionEnName, _userInfo.IsEn_Us), + QuestionId = x.ReadingQuestionId, + TableQuestionId = x.Id, + Type = x.Type, + LesionType = question.LesionType, + TableQuestionType = x.TableQuestionType, + RowId = row.RowId, + IsShowInDicom = question.IsShowInDicom, + DataSource = x.DataSource, + DictionaryCode = x.DictionaryCode, + QuestionMark = x.QuestionMark, + TypeValue = x.TypeValue, + RowIndex = row.RowIndex, + ShowOrder = x.ShowOrder, + ValueType = x.ValueType, + Unit = x.Unit, + ReportLayType = ReportLayType.TableQuestion, + }).ToList(); + + + foreach (var tableQuestion in row.Childrens) + { + foreach (var task in taskInfoList) + { + var rowinfo = alltableAnsweRowInfos.Where(x => x.VisitTaskId == task.VisitTaskId && x.QuestionId == tableQuestion.QuestionId && x.RowIndex == tableQuestion.RowIndex).FirstOrDefault(); + var taskQuestionAnswer = new TaskQuestionAnswer() + { + Answer = tableAnswers.Where(x => x.VisitTaskId == task.VisitTaskId && x.QuestionId == tableQuestion.QuestionId && x.RowIndex == tableQuestion.RowIndex && x.TableQuestionId == tableQuestion.TableQuestionId).Select(x => x.Answer).FirstIsNullReturnEmpty(), + TaskName = task.TaskName, + VisitTaskId = task.VisitTaskId, + }; + if (rowinfo != null && rowinfo.OrganInfoId != null) + { + var organInfo = organInfos.Where(x => x.Id == rowinfo.OrganInfoId).FirstOrDefault(); + + + if (organInfo != null && needChangeType.Contains(tableQuestion.QuestionMark)) + { + if (_userInfo.IsEn_Us) + { + switch (tableQuestion.QuestionMark) + { + case QuestionMark.Organ: + taskQuestionAnswer.Answer = organInfo.TULOCEN; + + break; + case QuestionMark.Location: + if (organInfo.IsCanEditPosition) + { + + } + else + { + taskQuestionAnswer.Answer = organInfo.TULATEN; + + } + break; + case QuestionMark.Part: + + taskQuestionAnswer.Answer = organInfo.PartEN; + + break; + + } + + } + else + { + switch (tableQuestion.QuestionMark) + { + case QuestionMark.Organ: + taskQuestionAnswer.Answer = organInfo.TULOC; + break; + case QuestionMark.Location: + if (organInfo.IsCanEditPosition) + { + + } + else + { + taskQuestionAnswer.Answer = organInfo.TULAT; + + } + break; + case QuestionMark.Part: + taskQuestionAnswer.Answer = organInfo.Part; + break; + + } + } + + } + } + tableQuestion.Answer.Add(taskQuestionAnswer); + } + } + + + } + + + }; + } + #endregion + + + + result.TaskQuestions = questions; + + + + return result; + + } + #endregion + + + /// + /// 获取是否是最大suvmax 病灶 + /// + /// + /// + [HttpPost] + public async Task GetIsSuvMaxLesion(GetIsSuvMaxLesionInDto inDto) + { + ReadingCalculateDto readingData = await _generalCalculateService.GetReadingCalculateDto(inDto.VisitTaskId); + + var maxSuv = await GetSuvMax(readingData); + var rowInfo = readingData.QuestionInfo.SelectMany(x => x.TableRowInfoList).ToList(); + var tableQuestions = rowInfo.SelectMany(x => x.TableQuestionList).Where(x => x.RowId == inDto.RowId).ToList(); + + var lesionMaxSuv = tableQuestions.Where(x => x.QuestionMark == QuestionMark.SUVmax).Select(x => x.Answer.IsNullOrEmptyReturn0()).MaxOrDefault(); + + + return new GetIsSuvMaxLesionOutDto() + { + IsSuvMaxLesion = maxSuv == lesionMaxSuv + }; + + + } + + /// + /// 获取是否可选择不能融合影像 + /// + /// + /// + [HttpPost] + public async Task GetCanChooseNotMerge(GetCanChooseNotMergeInDto inDto) + { + ReadingCalculateDto readingData = await _generalCalculateService.GetReadingCalculateDto(inDto.VisitTaskId); + + List questionTypes = new List() { + QuestionType.LiverSUVmax, + QuestionType.MediastinumSUVmax, + QuestionType.SUVmax, + QuestionType.SUVmaxLesion, + }; + + var pet5ps = readingData.QuestionInfo.Where(x => x.QuestionType == QuestionType.PET5PS).Select(x => x.Answer).FirstOrDefault(); + + + GetCanChooseNotMergeOutDto getCanChooseNotMergeOutDto = new GetCanChooseNotMergeOutDto() + { + IsCanChooseNotMerge = !readingData.QuestionInfo.Any(x => questionTypes.Contains(x.QuestionType) && x.Answer != string.Empty) + + + }; + return getCanChooseNotMergeOutDto; + } + + /// + /// 测试计算 + /// + /// + /// + /// + [HttpPost] + public async Task TestCalculate(Guid visitTaskId, QuestionType type) + { + ReadingCalculateDto readingData = await _generalCalculateService.GetReadingCalculateDto(visitTaskId); + await ReadingCalculate(readingData, new List() { type }); + } + + /// + /// 获取最低PDD信息 + /// + /// + /// + [HttpPost] + public async Task GetLowPPDInfo(GetPPDInfoInDto inDto) + { + GetPPDInfoOutDto result = new GetPPDInfoOutDto(); + var taskinfo = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).ProjectTo(_mapper.ConfigurationProvider).FirstNotNullAsync(); + var visitTaskIds = await _visitTaskRepository.Where(x => x.ReadingCategory == ReadingCategory.Visit && + x.TrialReadingCriterionId == taskinfo.TrialReadingCriterionId && + x.IsAnalysisCreate == taskinfo.IsAnalysisCreate && + x.DoctorUserId == taskinfo.DoctorUserId && + x.IsSelfAnalysis == taskinfo.IsSelfAnalysis && + x.SubjectId == taskinfo.SubjectId && x.ReadingTaskState == ReadingTaskState.HaveSigned && x.ArmEnum == taskinfo.ArmEnum + && x.VisitTaskNum < taskinfo.VisitTaskNum && x.TaskState == TaskState.Effect + ).OrderByDescending(x => x.VisitTaskNum).Select(x => x.Id).ToListAsync(); + + var answerList = await _readingTableQuestionAnswerRepository.Where(x => visitTaskIds.Contains(x.VisitTaskId) + && x.QuestionId == inDto.QuestionId + && x.ReadingTableQuestionTrial.QuestionMark == QuestionMark.PPD && x.RowIndex == inDto.RowIndex) + .Select(x => new + { + x.Answer, + x.VisitTaskId, + }).ToListAsync(); + + var lowPddTaskid = answerList.Select(x => new + { + Answer = x.Answer.IsNullOrEmptyReturn0(), + x.VisitTaskId + }).OrderBy(x => x.Answer).Select(x => x.VisitTaskId).FirstOrDefault(); + + if (lowPddTaskid != default(Guid)) + { + var lowPPDAnswerList = await _readingTableQuestionAnswerRepository.Where(x => x.VisitTaskId == lowPddTaskid + && x.QuestionId == inDto.QuestionId + && x.RowIndex == inDto.RowIndex).Include(x => x.ReadingTableQuestionTrial) + .Select(x => new + { + x.Answer, + x.ReadingTableQuestionTrial.QuestionMark, + }).ToListAsync(); + + result.NadirPPD = lowPPDAnswerList.Where(x => x.QuestionMark == QuestionMark.PPD).Select(x => x.Answer).FirstOrDefault().IsNullOrEmptyReturn0(); + result.LowPPDLDi = lowPPDAnswerList.Where(x => x.QuestionMark == QuestionMark.MajorAxis).Select(x => x.Answer).FirstOrDefault().IsNullOrEmptyReturn0(); + result.LowPPDSDi = lowPPDAnswerList.Where(x => x.QuestionMark == QuestionMark.ShortAxis).Select(x => x.Answer).FirstOrDefault().IsNullOrEmptyReturn0(); + result.LowPPDVisit = await _visitTaskRepository.Where(x => x.Id == lowPddTaskid).Select(x => x.TaskBlindName).FirstOrDefaultAsync(); + } + + return result; + + } + + /// + /// 计算任务 + /// + /// + /// + [HttpPost] + public async Task CalculateTask(CalculateTaskInDto inDto) + { + ReadingCalculateDto readingData = await _generalCalculateService.GetReadingCalculateDto(inDto.VisitTaskId); + readingData.IsChangeOtherTask = inDto.IsChangeOtherTask; + readingData.ComputationTrigger = inDto.ComputationTrigger; + await ReadingCalculate(readingData); + } + + /// + /// 获取报告验证的信息(这里每个标准可能不一样 返回用object) + /// + /// + /// + public async Task GetReportVerify(GetReportVerifyInDto inDto) + { + var calculateDto = await _generalCalculateService.GetReadingCalculateDto(inDto.VisitTaskId); + return new GetReportVerifyOutDto() + { + TumorEvaluate = calculateDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.ImgOncology).Select(x => x.Answer).FirstOrDefault(), + IsExistDisease = await this.GetReportIsExistDisease(inDto.VisitTaskId), + + }; + } + + + + /// + /// 自动计算 + /// + /// + /// + /// + public async Task ReadingCalculate(ReadingCalculateDto inDto, List? calculateType = null) + { + + #region 计算 这里顺序非常重要 后面计算的值要依赖前面计算的结果 + var needAddList = new List(); + + + List calculateList = new List() + { + // 是否存在Pet + new ReadingCalculateData (){QuestionType=QuestionType.ExistPET,GetStringFun=GetExistPET ,ComputationTriggerList=new List(){ ComputationTrigger.InitialCalculation, } }, + + //垂直径乘积之和(SPD) + new ReadingCalculateData (){QuestionType=QuestionType.SPD,GetDecimalFun=GetSPD,ComputationTriggerList=new List(){ ComputationTrigger.InitialCalculation, ComputationTrigger.CTSave,ComputationTrigger.RemoveLesion,}}, + + // 与基线相比SPD变化的百分比 + new ReadingCalculateData (){QuestionType=QuestionType.SPDChange,GetStringFun=CompareBaselineSPD,ComputationTriggerList=new List(){ ComputationTrigger.InitialCalculation, ComputationTrigger.CTSave,ComputationTrigger.RemoveLesion,}}, + + // 脾脏垂直径 + new ReadingCalculateData (){QuestionType=QuestionType.SpleenLength,GetDecimalNullFun=GetSpleenLength,ComputationTriggerList=new List(){ ComputationTrigger.SplenicApexPosition,ComputationTrigger.PositionSpleenFloor,}}, + + // 与基线相比脾肿大增加的百分比 + new ReadingCalculateData (){QuestionType=QuestionType.SplenoncusChange,GetStringFun=GetSplenoncusChange,ComputationTriggerList=new List(){ ComputationTrigger.InitialCalculation, ComputationTrigger.SplenicApexPosition,ComputationTrigger.PositionSpleenFloor,}}, + + // 与最低点相比脾脏垂直径长度的增加值 + new ReadingCalculateData (){QuestionType=QuestionType.SplenoncusAdd,GetStringFun=GetSplenoncusAdd,ComputationTriggerList=new List(){ ComputationTrigger.InitialCalculation, ComputationTrigger.SplenicApexPosition,ComputationTrigger.PositionSpleenFloor,}}, + + // 与基线相比脾垂直径变化值 + new ReadingCalculateData (){QuestionType=QuestionType.SplenoncusDiameterChange,GetStringFun=GetSplenoncusDiameterChange,ComputationTriggerList=new List(){ ComputationTrigger.InitialCalculation, ComputationTrigger.SplenicApexPosition,ComputationTrigger.PositionSpleenFloor,}}, + + // 脾肿垂直径最低点访视 + new ReadingCalculateData (){QuestionType=QuestionType.LowestSplenoncusVisit,GetStringFun=GetLowestSplenoncusVisit,ComputationTriggerList=new List(){ ComputationTrigger.InitialCalculation, ComputationTrigger.SplenicApexPosition,ComputationTrigger.PositionSpleenFloor,}}, + + // 获取脾脏状态 + new ReadingCalculateData (){QuestionType=QuestionType.SplenicStatus,GetStringFun=GetSplenicStatus,ComputationTriggerList=new List(){ ComputationTrigger.SplenicApexPosition,ComputationTrigger.PositionSpleenFloor,}}, + + // 获取脾脏评估 + new ReadingCalculateData (){QuestionType=QuestionType.SplenicEvaluation,GetStringFun=GetSplenicEvaluation,ComputationTriggerList=new List(){ ComputationTrigger.InitialCalculation, ComputationTrigger.SplenicApexPosition,ComputationTrigger.PositionSpleenFloor,ComputationTrigger.SplenicEvaluation,}}, + + //靶病灶评估 + new ReadingCalculateData (){QuestionType=QuestionType.TargetLesion,GetStringFun=GetTargetLesionEvaluate,ComputationTriggerList=new List(){ ComputationTrigger.InitialCalculation, ComputationTrigger.CTSave,ComputationTrigger.MergeSave,ComputationTrigger.RemoveLesion,ComputationTrigger.MergeLesion,}}, + + //非靶病灶评估 + new ReadingCalculateData (){QuestionType=QuestionType.NoTargetLesion,GetStringFun=GetNoTargetLesionEvaluate,ComputationTriggerList=new List(){ ComputationTrigger.InitialCalculation, ComputationTrigger.CTSave,ComputationTrigger.MergeSave,ComputationTrigger.RemoveLesion,}}, + + //新病灶评估 + new ReadingCalculateData (){QuestionType=QuestionType.NewLesionEvaluation,GetStringFun=GetNewLesionEvaluate,ComputationTriggerList=new List(){ ComputationTrigger.InitialCalculation, ComputationTrigger.CTSave,ComputationTrigger.MergeSave,ComputationTrigger.RemoveLesion,}}, + + //获取肝脏评估 + new ReadingCalculateData (){QuestionType=QuestionType.LiverAssessment,GetStringFun=GetLiverAssessment,ComputationTriggerList=new List(){ ComputationTrigger.InitialCalculation, ComputationTrigger.LiverStatus,}}, + + // 骨髓中是否存在局灶性 FDG亲和病灶的证据 + new ReadingCalculateData (){QuestionType=QuestionType.EvidenceFocalFDG,GetStringFun=GetEvidenceFocalFDG,ComputationTriggerList=new List(){ ComputationTrigger.InitialCalculation, ComputationTrigger.ImageQuality, }}, + + //CT/MRI + new ReadingCalculateData (){QuestionType=QuestionType.CTandMRI,GetStringFun=CTMRIEvaluation,ComputationTriggerList=new List(){ ComputationTrigger.InitialCalculation, ComputationTrigger.LiverStatus,ComputationTrigger.SplenicApexPosition,ComputationTrigger.PositionSpleenFloor,ComputationTrigger.SplenicEvaluation,ComputationTrigger.CTSave,ComputationTrigger.MergeSave,ComputationTrigger.RemoveLesion,ComputationTrigger.MergeLesion,}}, + + //SUVmax + new ReadingCalculateData (){QuestionType=QuestionType.SUVmax,GetDecimalNullFun=GetSuvMax,ComputationTriggerList=new List(){ ComputationTrigger.MergeSave,ComputationTrigger.RemoveLesion,}}, + + // PET 5PS评分 + new ReadingCalculateData (){QuestionType=QuestionType.PET5PS,GetStringFun=GetPET5PS,ComputationTriggerList=new List(){ ComputationTrigger.InitialCalculation, ComputationTrigger.ImageQuality, ComputationTrigger.LiverBloodPool,ComputationTrigger.MediastinalPool,ComputationTrigger.MergeSave,ComputationTrigger.RemoveLesion,}}, + + // 修改PET 5PS评分备注 + new ReadingCalculateData (){QuestionType=QuestionType.PSScoreRemarks,GetStringFun=GetPET5PSRemark,ComputationTriggerList=new List(){ ComputationTrigger.LiverBloodPool,ComputationTrigger.MediastinalPool,ComputationTrigger.MergeSave,ComputationTrigger.RemoveLesion,}}, + + //与基线相比摄取值变化 + new ReadingCalculateData (){QuestionType=QuestionType.UptakeChange,GetStringFun=GetUptakeChange,ComputationTriggerList=new List(){ ComputationTrigger.InitialCalculation, ComputationTrigger.ImageQuality, ComputationTrigger.LiverBloodPool,ComputationTrigger.MediastinalPool,ComputationTrigger.MergeSave,ComputationTrigger.RemoveLesion,}}, + + // FDG-PET 评估结果 + new ReadingCalculateData (){QuestionType=QuestionType.FDGPET,GetStringFun=GetFDGPETOverallAssessment,ComputationTriggerList=new List(){ ComputationTrigger.InitialCalculation, ComputationTrigger.ImageQuality, ComputationTrigger.LiverBloodPool,ComputationTrigger.MediastinalPool,ComputationTrigger.MergeSave,ComputationTrigger.RemoveLesion,ComputationTrigger.PDGPET,}}, + + // 上一次 FDG-PET 评估结果 + new ReadingCalculateData (){QuestionType=QuestionType.LastFDGPET,GetStringFun=GetLastFDGPETOverallAssessment,ComputationTriggerList=new List(){ ComputationTrigger.InitialCalculation, ComputationTrigger.MergeSave,ComputationTrigger.RemoveLesion,}}, + + // 影像学整体肿瘤评估 + new ReadingCalculateData (){QuestionType=QuestionType.ImgOncology,GetStringFun=GetImgOncology,ComputationTriggerList=new List(){ ComputationTrigger.InitialCalculation, ComputationTrigger.ImageQuality, ComputationTrigger.LiverStatus,ComputationTrigger.SplenicApexPosition,ComputationTrigger.PositionSpleenFloor,ComputationTrigger.SplenicEvaluation,ComputationTrigger.LiverBloodPool,ComputationTrigger.MediastinalPool,ComputationTrigger.CTSave,ComputationTrigger.MergeSave,ComputationTrigger.RemoveLesion,ComputationTrigger.PDGPET,ComputationTrigger.MergeLesion,}}, + + + + // SUVmax所在病灶 + new ReadingCalculateData (){QuestionType=QuestionType.SUVmaxLesion,GetStringFun=GetSuvMaxFocus,ComputationTriggerList=new List(){ ComputationTrigger.MergeSave,ComputationTrigger.RemoveLesion,}}, + + + //是否存在疾病 + new ReadingCalculateData (){QuestionType=QuestionType.ExistDisease,GetStringFun=GetIsExistDisease,ComputationTriggerList=new List(){ ComputationTrigger.InitialCalculation, ComputationTrigger.CTSave,ComputationTrigger.MergeSave,ComputationTrigger.RemoveLesion,}}, + + + + ////靶病灶径线之和(SOD) + //new ReadingCalculateData (){QuestionType=QuestionType.SOD,GetDecimalNullFun=GetSODData}, + + ////非淋巴结靶病灶长径之和 + //new ReadingCalculateData (){QuestionType=QuestionType.SumOfDiameter,GetDecimalNullFun=GetSumOfDiameter}, + + ////与基线SOD相比变化量(mm) + // new ReadingCalculateData (){QuestionType=QuestionType.SODChange,GetDecimalNullFun=GetSODChange}, + + ////与基线访视相比SOD变化百分比 + // new ReadingCalculateData (){QuestionType=QuestionType.SODPercent,GetDecimalNullFun=GetSODPercent}, + + ////与整个访视期间SOD最低点相比增加的值(mm) //其他任务需要改 + // new ReadingCalculateData (){QuestionType=QuestionType.LowestIncrease,GetDecimalNullFun=GetLowestIncrease,/*ChangeAllTaskFun=ChangeAllLowestIncrease*/}, + + // //与整个访视期间SOD最低点相比增加的百分比 //其他任务需要改 + // new ReadingCalculateData (){QuestionType=QuestionType.LowPercent,GetDecimalNullFun=GetLowPercent,/*ChangeAllTaskFun=ChangeAllLowPercent*/}, + + ////整个访视期间SOD最低点访视名称 //其他任务需要改 + // new ReadingCalculateData (){QuestionType=QuestionType.LowVisit,GetStringFun=GetLowVisit,/*ChangeAllTaskFun=ChangeAllLowVisitName*/}, + + // //是否存在非淋巴结靶病灶 + // new ReadingCalculateData (){QuestionType=QuestionType.IsLymphTarget,GetStringFun=GetIsLymphTarget}, + + // //是否存在淋巴结靶病灶且该病灶比上一访视短径增加5MM以上 + // new ReadingCalculateData (){QuestionType=QuestionType.IsAddFive,GetStringFun=GetIsAddFive}, + + // //被评估为NE的单个靶病灶 + // new ReadingCalculateData (){QuestionType=QuestionType.NETarget,GetStringFun=GetNETarget}, + + + + // //脾脏评估 + //new ReadingCalculateData (){QuestionType=QuestionType.SplenicEvaluation,GetStringFun=GetNewLesionEvaluate}, + + // //整体肿瘤评估 + // new ReadingCalculateData (){QuestionType=QuestionType.Tumor,GetStringFun=GetTumor}, + + // //是否存在疾病 + // new ReadingCalculateData (){QuestionType=QuestionType.ExistDisease,GetStringFun=GetIsExistDisease}, + + }; + + // 没有靶病灶只计算最后几个 + //if (inDto.QuestionInfo.Where(x => x.LesionType == LesionType.TargetLesion).Sum(x => x.TableRowInfoList.Count()) == 0) + //{ + + // List questionTypes = new List() + // { + // QuestionType.TargetLesion, + // QuestionType.NoTargetLesion, + // QuestionType.NewLesions, + // QuestionType.Tumor, + // QuestionType.ExistDisease, + // }; + + // // 没有靶病灶就删除其他几个答案的值 + // var isNeedDeleteTypes = calculateList.Where(x => !questionTypes.Contains(x.QuestionType)).Select(x => x.QuestionType).ToList(); + + + // var isNeedDeleteIds = inDto.QuestionInfo.Where(x => x.QuestionType != null && isNeedDeleteTypes.Contains(x.QuestionType.Value)).Select(x => x.QuestionId).ToList(); + + // await _readingTaskQuestionAnswerRepository.BatchUpdateNoTrackingAsync(x => x.VisitTaskId == inDto.VisitTaskId && isNeedDeleteIds.Contains(x.ReadingQuestionTrialId), x => new ReadingTaskQuestionAnswer + // { + // Answer = string.Empty + // }); + + + + // calculateList = calculateList.Where(x => questionTypes.Contains(x.QuestionType)).ToList(); + + + + + + //} + + if (calculateType != null) + { + calculateList = calculateList.Where(x => calculateType.Contains(x.QuestionType)).ToList(); + } + + + calculateList = calculateList.Where(x => x.ComputationTriggerList.Contains(inDto.ComputationTrigger)).ToList(); + var typeNAList = new List + { + QuestionType.SODChange, + QuestionType.SODPercent, + QuestionType.LowestIncrease, + QuestionType.LowPercent, + }; + + foreach (var calculate in calculateList) + { + var item = inDto.QuestionInfo.FirstOrDefault(x => x.QuestionType == calculate.QuestionType); + + if (item != null) + { + //计算答案 + if (inDto.IsOnlyChangeAllTask == false) + { + + #region 计算答案 + if (calculate.GetDecimalFun != null) + { + item.Answer = (await calculate.GetDecimalFun(inDto)).ToString(); + + } + else if (calculate.GetDecimalNullFun != null) + { + var value = await calculate.GetDecimalNullFun(inDto); + item.Answer = value == null ? string.Empty : value.Value.ToString(); + } + else if (calculate.GetStringFun != null) + { + item.Answer = await calculate.GetStringFun(inDto); + } + #endregion + // 修改修约小数位数 + + List valueOfTypes = new List() { + + ValueOfType.Decimals, + ValueOfType.Percentage + }; + + if (inDto.DigitPlaces != -1) + { + try + { + + if (valueOfTypes.Contains(item.ValueType)) + { + item.Answer = decimal.Round(decimal.Parse(item.Answer ?? "0"), inDto.DigitPlaces).ToString("F" + inDto.DigitPlaces.ToString()); + } + } + catch (Exception) + { + + + } + } + + + + needAddList.Add(new ReadingTaskQuestionAnswer() + { + Answer = item.Answer, + ReadingQuestionTrialId = item.QuestionId, + }); + } + + // 修改全局 + if (inDto.IsChangeOtherTask && calculate.ChangeAllTaskFun != null) + { + await calculate.ChangeAllTaskFun(new ChangeAllTaskDto() + { + calculateDto = inDto, + QuestionId = item.QuestionId, + }); + } + + } + } + + + + var questionIds = needAddList.Select(x => x.ReadingQuestionTrialId).ToList(); + + await _readingTaskQuestionAnswerRepository.BatchDeleteNoTrackingAsync(x => questionIds.Contains(x.ReadingQuestionTrialId) && x.VisitTaskId == inDto.VisitTaskId); + needAddList.ForEach(x => + { + x.SubjectId = inDto.SubjectId; + x.ReadingQuestionCriterionTrialId = inDto.CriterionId; + x.VisitTaskId = inDto.VisitTaskId; + x.TrialId = inDto.TrialId; + x.SubjectId = inDto.SubjectId; + }); + + await _readingTaskQuestionAnswerRepository.AddRangeAsync(needAddList); + + await _readingTaskQuestionAnswerRepository.SaveChangesAsync(); + #endregion + + + } + + /// + /// 获取影像是否无法融合 + /// + /// + /// + public async Task ImageQualityIsUnableFuse(ReadingCalculateDto inDto) + { + if (isUnableFuse != null) + { + return isUnableFuse.Value; + } + else + { + var imageQualityProblem = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.ImageQualityProblem).Select(x => x.Answer).FirstOrDefault(); + isUnableFuse = imageQualityProblem == ((int)ImageQualityIssues.PETCTFailureFuse).ToString(); + return isUnableFuse.Value; + } + + } + + /// + /// 获取报告整体整体评估 + /// + /// + /// + public async Task GetReportTumor(Guid visitTaskId) + { + return await GetTumor(await _generalCalculateService.GetReadingCalculateDto(visitTaskId)); + } + + /// + /// 获取报告是否存在疾病 + /// + /// + /// + public async Task GetReportIsExistDisease(Guid visitTaskId) + { + return await GetIsExistDisease(await _generalCalculateService.GetReadingCalculateDto(visitTaskId)); + } + + /// + /// 验证访视提交 + /// + /// + /// + public async Task VerifyVisitTaskQuestions(VerifyVisitTaskQuestionsInDto inDto) + { + + if (await _readingTaskQuestionAnswerRepository.AnyAsync(x => x.ReadingQuestionTrial.QuestionType == QuestionType.ImageQualityAssessment && x.VisitTaskId == inDto.VisitTaskId && x.Answer == ImageQualityEvaluation.Abnormal.GetEnumInt())) + { + + return; + } + + + var taskinfo = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).FirstNotNullAsync(); + + + var tableAnswerList = await _readingTableQuestionAnswerRepository.Where(x => x.VisitTaskId == inDto.VisitTaskId && (x.Answer == string.Empty || x.Answer == null) + && x.ReadingTableQuestionTrial.QuestionMark == QuestionMark.State + ) + .Select(x => new + { + x.ReadingQuestionTrial.OrderMark, + x.RowIndex, + QuestionMark = x.ReadingTableQuestionTrial.QuestionMark, + Answer = x.Answer, + + }).ToListAsync(); + + + string errorMassage = string.Empty; + + var rowAnswerList = await _readingTableAnswerRowInfoRepository.Where(x => x.VisitTaskId == inDto.VisitTaskId && (x.MeasureData == string.Empty || x.MeasureData == null)) + .Select(x => new + { + x.ReadingQuestionTrial.OrderMark, + x.RowIndex, + x.Id, + }).ToListAsync(); + + + var unableEvaluateRowIds = await _readingTableQuestionAnswerRepository.Where(x => x.VisitTaskId == inDto.VisitTaskId && + (x.Answer == TargetState.UnableEvaluate.GetEnumInt() || x.Answer == TargetState.Loss.GetEnumInt()) + && x.ReadingTableQuestionTrial.QuestionMark == QuestionMark.State + ) + .Select(x => x.RowId).Distinct().ToListAsync(); + + + List measureDataList = rowAnswerList.Where(x => !unableEvaluateRowIds.Contains(x.Id)).Select(x => x.OrderMark + x.RowIndex.GetLesionMark()).ToList(); + + List stateIsNullList = tableAnswerList.Select(x => x.OrderMark + x.RowIndex.GetLesionMark()).ToList(); + + + List allExists = measureDataList.Intersect(stateIsNullList).ToList(); + measureDataList = measureDataList.Except(allExists).ToList(); + stateIsNullList = stateIsNullList.Except(allExists).ToList(); + + + if (measureDataList.Count() > 0) + { + errorMassage += _localizer["ReadingCalculate_NoMarker", string.Join(',', measureDataList)] + ","; + } + + + if (tableAnswerList.Count > 0) + { + errorMassage += _localizer["ReadingCalculate_StatusIsEmpty", string.Join(',', stateIsNullList)] + ","; + } + + if (allExists.Count > 0) + { + errorMassage += _localizer["ReadingCalculate_NoMarkerEmpty", string.Join(',', stateIsNullList)] + ","; + } + + // 判断是否有pet + if (await _readingTaskQuestionAnswerRepository.AnyAsync(x => x.ReadingQuestionTrial.QuestionType == QuestionType.ExistPET && x.VisitTaskId == inDto.VisitTaskId && x.Answer == ReadingYesOrNo.Yes.GetEnumInt())) + { + + List required = new List() { + QuestionType.LiverSUVmax, + QuestionType.MediastinumSUVmax, + QuestionType.SUVmax, + QuestionType.SUVmaxLesion, + QuestionType.PET5PS, + }; + if (taskinfo.VisitTaskNum != 0m) + { + required.Add(QuestionType.UptakeChange); + required.Add(QuestionType.EvidenceFocalFDG); + } + + if ((await _readingTaskQuestionAnswerRepository.CountAsync(x => required.Contains(x.ReadingQuestionTrial.QuestionType) && x.VisitTaskId == inDto.VisitTaskId && x.Answer != string.Empty)) != required.Count()) + { + if (taskinfo.VisitTaskNum != 0m) + { + errorMassage += _localizer["ReadingCalculate_LuganoPetVerification"]; + } + else + { + errorMassage += _localizer["ReadingCalculate_LuganoBaseLinePetVerification"]; + } + + } + } + + + if (errorMassage != string.Empty) + { + //errorMassage = errorMassage; + throw new BusinessValidationFailedException(errorMassage); + } + + + } + + /// + /// 计算融合靶病灶的状态 + /// + /// + /// + public async Task CalculateMergeTargetLesionStatus(CalculateTargetLesionStatusInDto inDto) + { + var taskInfo = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).FirstNotNullAsync(); + + // 找到靶病灶问题 + var targetQuestion = await _readingQuestionTrialRepository.Where(x => x.ReadingQuestionCriterionTrialId == taskInfo.TrialReadingCriterionId && x.LesionType == LesionType.TargetLesion).FirstOrDefaultAsync(); + if (targetQuestion != null) + { + // 找到状态问题 + var stateQuestion = await _readingTableQuestionTrialRepository.Where(x => x.ReadingQuestionId == targetQuestion.Id && x.QuestionMark == QuestionMark.State).FirstOrDefaultAsync(); + if (stateQuestion != null) + { + + //// 找到主病灶的状态 + //var state = await _readingTableQuestionAnswerRepository.Where(x => x.VisitTaskId == inDto.VisitTaskId && x.RowIndex == (int)Math.Floor(inDto.RowNumber) && x.TableQuestionId == stateQuestion.Id).Select(x => x.Answer).FirstOrDefaultAsync(); + + // 长径 + var majorAxis = (await _readingTableQuestionAnswerRepository.Where(x => + x.VisitTaskId == inDto.VisitTaskId && + x.RowIndex == inDto.RowNumber && + x.ReadingTableQuestionTrial.QuestionMark == QuestionMark.MajorAxis && + x.QuestionId == targetQuestion.Id + ).Select(x => x.Answer).FirstOrDefaultAsync()).IsNullOrEmptyReturn0(); + + // 短径 + var shortAxis = (await _readingTableQuestionAnswerRepository.Where(x => + x.VisitTaskId == inDto.VisitTaskId && + x.RowIndex == inDto.RowNumber && + x.ReadingTableQuestionTrial.QuestionMark == QuestionMark.ShortAxis && + x.QuestionId == targetQuestion.Id + ).Select(x => x.Answer).FirstOrDefaultAsync()).IsNullOrEmptyReturn0(); + + // 找到ppd问题 + var ppdQuestion = await _readingTableQuestionTrialRepository.Where(x => x.ReadingQuestionId == targetQuestion.Id && x.QuestionMark == QuestionMark.PPD).FirstOrDefaultAsync(); + + if (ppdQuestion != null) + { + var pPdAnswer = (await _readingTableQuestionAnswerRepository.Where(x => + x.VisitTaskId == inDto.VisitTaskId && + x.ReadingTableQuestionTrial.QuestionMark == QuestionMark.PPD && + x.QuestionId == targetQuestion.Id && + x.RowIndex == inDto.RowNumber + ).Select(x => x.Answer).FirstOrDefaultAsync()).IsNullOrEmptyReturn0(); + + + // 是否符合疾病进展 + var accord = false; + + var lowPPDInfo = await GetLowPPDInfo(new GetPPDInfoInDto() + { + RowIndex = inDto.RowNumber, + VisitTaskId = inDto.VisitTaskId, + QuestionId = inDto.QuestionId, + }); + + + if (lowPPDInfo.NadirPPD != 0) + { + //当前融合靶病灶LDi>15 mm && + //(当前融合靶病灶的ppd-最低点PPD)/最低点PPD ≥50 % + + if (majorAxis >= 15 && + (pPdAnswer - lowPPDInfo.NadirPPD) * 100 / lowPPDInfo.NadirPPD >= 50) + { + accord = true; + } + } + + // 符合疾病进展 + if (accord) + { + await _readingTableQuestionAnswerRepository.UpdatePartialFromQueryAsync(x => + x.VisitTaskId == inDto.VisitTaskId && + x.RowIndex == inDto.RowNumber && + x.ReadingTableQuestionTrial.QuestionMark == QuestionMark.State && + x.QuestionId == targetQuestion.Id, x => new ReadingTableQuestionAnswer() + { + Answer = TargetState.DiseaseProgression.GetEnumInt() + } + ); + } + //else if (state == TargetState.DiseaseProgression.GetEnumInt()) + //{ + // //await _readingTableQuestionAnswerRepository.UpdatePartialFromQueryAsync(x => + // // x.VisitTaskId == inDto.VisitTaskId && + // // x.RowIndex == inDto.RowNumber && + // // x.ReadingTableQuestionTrial.QuestionMark == QuestionMark.State && + // // x.QuestionId == targetQuestion.Id, x => new ReadingTableQuestionAnswer() + // // { + // // Answer = TargetState.Exist.GetEnumInt() + // // } + // // ); + //} + + + } + } + + } + } + + /// + /// 计算分裂靶病灶状态 + /// + /// + /// + public async Task CalculateTargetLesionStatus(CalculateTargetLesionStatusInDto inDto) + { + if (inDto.RowNumber % 1 != 0) + { + var taskInfo = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).FirstNotNullAsync(); + + // 找到靶病灶问题 + var targetQuestion = await _readingQuestionTrialRepository.Where(x => x.ReadingQuestionCriterionTrialId == taskInfo.TrialReadingCriterionId && x.LesionType == LesionType.TargetLesion).FirstOrDefaultAsync(); + if (targetQuestion != null) + { + // 找到状态问题 + var stateQuestion = await _readingTableQuestionTrialRepository.Where(x => x.ReadingQuestionId == targetQuestion.Id && x.QuestionMark == QuestionMark.State).FirstOrDefaultAsync(); + if (stateQuestion != null) + { + + // 找到主病灶的状态 + var state = await _readingTableQuestionAnswerRepository.Where(x => x.VisitTaskId == inDto.VisitTaskId && x.RowIndex == (int)Math.Floor(inDto.RowNumber) && x.TableQuestionId == stateQuestion.Id).Select(x => x.Answer).FirstOrDefaultAsync(); + + // 长径 + var majorAxis = (await _readingTableQuestionAnswerRepository.Where(x => + x.VisitTaskId == inDto.VisitTaskId && + x.RowIndex >= (int)Math.Floor(inDto.RowNumber) && x.RowIndex < ((int)Math.Floor(inDto.RowNumber) + 1) && + x.ReadingTableQuestionTrial.QuestionMark == QuestionMark.MajorAxis && + x.QuestionId == targetQuestion.Id + ).Select(x => x.Answer).ToListAsync()).Select(x => x.IsNullOrEmptyReturn0()).Sum(); + + // 短径 + var shortAxis = (await _readingTableQuestionAnswerRepository.Where(x => + x.VisitTaskId == inDto.VisitTaskId && + x.RowIndex >= (int)Math.Floor(inDto.RowNumber) && x.RowIndex < ((int)Math.Floor(inDto.RowNumber) + 1) && + x.ReadingTableQuestionTrial.QuestionMark == QuestionMark.ShortAxis && + x.QuestionId == targetQuestion.Id + ).Select(x => x.Answer).ToListAsync()).Select(x => x.IsNullOrEmptyReturn0()).Sum(); + + // 找到ppd问题 + var ppdQuestion = await _readingTableQuestionTrialRepository.Where(x => x.ReadingQuestionId == targetQuestion.Id && x.QuestionMark == QuestionMark.PPD).FirstOrDefaultAsync(); + + if (ppdQuestion != null) + { + var ppdAnswerList = await _readingTableQuestionAnswerRepository.Where(x => + x.VisitTaskId == inDto.VisitTaskId && + x.ReadingTableQuestionTrial.QuestionMark == QuestionMark.PPD && + x.QuestionId == targetQuestion.Id && + x.RowIndex >= (int)Math.Floor(inDto.RowNumber) && x.RowIndex < ((int)Math.Floor(inDto.RowNumber) + 1) + ).Select(x => x.Answer).ToListAsync(); + + var allPPd = ppdAnswerList.Select(x => x.IsNullOrEmptyReturn0()).Sum(); + + // 是否符合疾病进展 + var accord = false; + + var lowPPDInfo = await GetLowPPDInfo(new GetPPDInfoInDto() + { + RowIndex = (int)Math.Floor(inDto.RowNumber), + VisitTaskId = inDto.VisitTaskId, + QuestionId = inDto.QuestionId, + }); + + + if (lowPPDInfo.NadirPPD != 0) + { + //15mm < 当前靶病灶LDi≤20mm && + //&& 相比最低点PPD增加百分比 ≥50% && + //(相比PPD最低点LDi增加值 ≥5 mm + //or相比PPD最低点SDi增加值≥5 mm) + if (15 < majorAxis && majorAxis <= 20 && + (allPPd - lowPPDInfo.NadirPPD) * 100 / lowPPDInfo.NadirPPD >= 50 && + (majorAxis - lowPPDInfo.LowPPDLDi >= 5 || + shortAxis - lowPPDInfo.LowPPDSDi >= 5) + ) + { + accord = true; + } + + //当前靶病灶LDi>20 mm + //相比最低点PPD增加百分比 ≥50% + // (相比PPD最低点LDi增加值 ≥10 mm + // 或者相比PPD最低点SDi增加值Sdi ≥10 mm) + if (majorAxis > 20 && + (allPPd - lowPPDInfo.NadirPPD) * 100 / lowPPDInfo.NadirPPD >= 50 && + (majorAxis - lowPPDInfo.LowPPDLDi >= 10 || + shortAxis - lowPPDInfo.LowPPDSDi >= 10) + ) + { + accord = true; + } + + } + + // 符合疾病进展 + if (accord) + { + await _readingTableQuestionAnswerRepository.BatchUpdateNoTrackingAsync(x => + x.VisitTaskId == inDto.VisitTaskId && + x.RowIndex == (int)Math.Floor(inDto.RowNumber) && + x.ReadingTableQuestionTrial.QuestionMark == QuestionMark.State && + x.QuestionId == targetQuestion.Id, x => new ReadingTableQuestionAnswer() + { + Answer = TargetState.DiseaseProgression.GetEnumInt() + } + ); + } + else if (state == TargetState.DiseaseProgression.GetEnumInt()) + { + await _readingTableQuestionAnswerRepository.BatchUpdateNoTrackingAsync(x => + x.VisitTaskId == inDto.VisitTaskId && + x.RowIndex == (int)Math.Floor(inDto.RowNumber) && + x.ReadingTableQuestionTrial.QuestionMark == QuestionMark.State && + x.QuestionId == targetQuestion.Id, x => new ReadingTableQuestionAnswer() + { + Answer = TargetState.Exist.GetEnumInt() + } + ); + } + + await _readingTableQuestionAnswerRepository.SaveChangesAsync(); + + } + } + + } + + + } + } + + + + + + + /// + /// 获取分裂病灶的PPd之和 不包括当前的主病灶 + /// + /// + [HttpPost] + public async Task> GetSplitPPdSum(GetSplitPPdInDto inDto) + { + List result = new List(); + var taskInfo = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).FirstNotNullAsync(); + var targetQuestion = await _readingQuestionTrialRepository.Where(x => x.ReadingQuestionCriterionTrialId == taskInfo.TrialReadingCriterionId && x.LesionType == LesionType.TargetLesion).FirstOrDefaultAsync(); + if (targetQuestion != null) + { + var ppdAnswerList = await _readingTableQuestionAnswerRepository.Where(x => + x.VisitTaskId == inDto.VisitTaskId && + //x.ReadingTableQuestionTrial.QuestionMark == QuestionMark.PPD && + x.QuestionId == targetQuestion.Id) + .Select(x => new { + x.RowId, + x.RowIndex, + x.Answer, + x.ReadingTableQuestionTrial.QuestionMark, + }).ToListAsync(); + var answerList = ppdAnswerList.Select(x => new { + x.RowId, + x.RowIndex, + Answer = x.Answer.IsNullOrEmptyReturn0(), + x.QuestionMark, + }).ToList(); + var maxRowIndex = answerList.MaxOrDefault(x => x.RowIndex); + for (int i = 1; i < maxRowIndex; i++) + { + result.Add(new GetSplitPPdOutDto() + { + RowId = answerList.Where(x => x.RowIndex == i).Select(x => x.RowId).FirstOrDefault(), + RowIndex = answerList.Where(x => x.RowIndex == i).Select(x => x.RowIndex).FirstOrDefault().ToString(), + AllPPD = answerList.Where(x => x.QuestionMark == QuestionMark.PPD).Where(x => x.RowIndex > i && x.RowIndex < (i + 1)).Sum(x => x.Answer), + AllLDi = answerList.Where(x => x.QuestionMark == QuestionMark.MajorAxis).Where(x => x.RowIndex > i && x.RowIndex < (i + 1)).Sum(x => x.Answer), + AllSDi = answerList.Where(x => x.QuestionMark == QuestionMark.ShortAxis).Where(x => x.RowIndex > i && x.RowIndex < (i + 1)).Sum(x => x.Answer), + }); + } + } + return result; + } + + #region 将上一次的访视病灶添加到这一次 + + /// + /// 将上一次的访视病灶添加到这一次 + /// + /// + /// + public async Task AddTaskLesionAnswerFromLastTask(AddTaskLesionAnswerFromLastTaskInDto inDto) + { + var visitTaskId = inDto.VisitTaskId; + + var taskinfo = await _visitTaskRepository.Where(x => x.Id == visitTaskId).FirstNotNullAsync(); + + var baseLineVisitId = await _subjectVisitRepository.Where(x => x.SubjectId == taskinfo.SubjectId && x.IsBaseLine).Select(x => x.Id).FirstOrDefaultAsync(); + + + ReadingCalculateDto readingData = await _generalCalculateService.GetReadingCalculateDto(visitTaskId); + + await ReadingCalculate(readingData, new List() { QuestionType.ExistPET }); + + + // 判断当前任务是否是基线 + if (taskinfo.SourceSubjectVisitId != baseLineVisitId) + { + // 判断当前任务是是否有表格问题答案 + if (!(await _readingTableQuestionAnswerRepository.AnyAsync(x => x.VisitTaskId == visitTaskId))) + { + + var LastVisitTaskId = await _visitTaskRepository.Where(x => x.ReadingCategory == ReadingCategory.Visit && + x.TrialReadingCriterionId == taskinfo.TrialReadingCriterionId && + x.IsAnalysisCreate == taskinfo.IsAnalysisCreate && + x.DoctorUserId == taskinfo.DoctorUserId && + x.IsSelfAnalysis == taskinfo.IsSelfAnalysis && + x.SubjectId == taskinfo.SubjectId && x.ReadingTaskState == ReadingTaskState.HaveSigned && x.VisitTaskNum < taskinfo.VisitTaskNum && x.TaskState == TaskState.Effect && x.ArmEnum == taskinfo.ArmEnum + ).OrderByDescending(x => x.VisitTaskNum).Select(x => x.Id).FirstOrDefaultAsync(); + + + + var copyTableAnswers = await _readingTableQuestionAnswerRepository.Where(x => x.VisitTaskId == LastVisitTaskId).Select(x => new CopyTableAnswerDto() + { + Answer = x.Answer, + QuestionId = x.QuestionId, + RowId = x.RowId, + QuestionMark = x.ReadingTableQuestionTrial.QuestionMark, + TableQuestionId = x.TableQuestionId, + RowIndex = x.RowIndex, + TrialId = x.TrialId + }).ToListAsync(); + + var tableRowAnswers = await _readingTableAnswerRowInfoRepository.Where(x => x.VisitTaskId == LastVisitTaskId).OrderBy(x => x.RowIndex).ProjectTo(_mapper.ConfigurationProvider).ToListAsync(); + + + tableRowAnswers.ForEach(x => + { + + switch (x.SplitOrMergeType) + { + case SplitOrMergeType.Merge: + case SplitOrMergeType.Merged: + x.SplitOrMergeType = SplitOrMergeType.Merged; + break; + case SplitOrMergeType.MergeMain: + case SplitOrMergeType.MergeMained: + x.SplitOrMergeType = SplitOrMergeType.MergeMained; + break; + default: + x.SplitOrMergeType = null; + break; + } + x.VisitTaskId = visitTaskId; + x.IsCurrentTaskAdd = false; + x.Id = NewId.NextGuid(); + x.SeriesId = null; + x.InstanceId = null; + x.MeasureData = string.Empty; + x.PicturePath = string.Empty; + + + }); + + tableRowAnswers.ForEach(x => + { + x.SplitRowId = tableRowAnswers.Where(y => y.OriginalId == x.SplitRowId).FirstOrDefault()?.Id; + x.MergeRowId = tableRowAnswers.Where(y => y.OriginalId == x.MergeRowId).FirstOrDefault()?.Id; + + }); + + List needCopyMarks = new List() + { + + QuestionMark.IsLymph, + QuestionMark.Lesion, + QuestionMark.Organ, + QuestionMark.Location, + QuestionMark.Part, + QuestionMark.BodyPartDescription, + QuestionMark.LowPPDLDi, + QuestionMark.LowPPDSDi, + QuestionMark.NadirPPD, + QuestionMark.LowPPDVisit, + }; + + + + var rowIndexList = copyTableAnswers.Select(x => x.RowIndex).Distinct().ToList(); + // 找到靶病灶问题Id + var questionId = await _readingQuestionTrialRepository.Where(x => x.ReadingQuestionCriterionTrialId == taskinfo.TrialReadingCriterionId && x.LesionType == LesionType.TargetLesion).Select(x => x.Id).FirstNotNullAsync(); + + foreach (var item in rowIndexList) + { + var lowPPD = await this.GetLowPPDInfo(new GetPPDInfoInDto() { + + VisitTaskId = visitTaskId, + QuestionId = questionId, + RowIndex = item + }); + + copyTableAnswers.Where(x => x.RowIndex == item).ForEach(x => + { + + + switch (x.QuestionMark) + { + case QuestionMark.LowPPDLDi: + x.Answer = lowPPD.LowPPDLDi == null ? string.Empty : lowPPD.LowPPDLDi.Value.ToString(); + break; + case QuestionMark.LowPPDSDi: + x.Answer = lowPPD.LowPPDSDi == null ? string.Empty : lowPPD.LowPPDSDi.Value.ToString(); + break; + case QuestionMark.NadirPPD: + x.Answer = lowPPD.NadirPPD == null ? string.Empty : lowPPD.NadirPPD.Value.ToString(); + break; + case QuestionMark.LowPPDVisit: + x.Answer = lowPPD.LowPPDVisit == null ? string.Empty : lowPPD.LowPPDVisit.ToString(); + break; + + + } + + + }); + } + + var tableAnswers = new List(); + // 处理状态 + + var mergedRowIds = tableRowAnswers.Where(x => x.SplitOrMergeType == SplitOrMergeType.Merged).Select(x => x.Id).ToList(); + copyTableAnswers.ForEach(x => + { + var tableAnswer = new ReadingTableQuestionAnswer() + { + Id = NewId.NextGuid(), + Answer = needCopyMarks.Contains(x.QuestionMark) ? x.Answer : string.Empty, + QuestionId = x.QuestionId, + RowIndex = x.RowIndex, + RowId = tableRowAnswers.Where(y => y.OriginalId == x.RowId).Select(x => x.Id).FirstOrDefault(), + TableQuestionId = x.TableQuestionId, + TrialId = x.TrialId, + VisitTaskId = visitTaskId, + }; + if (mergedRowIds.Contains(tableAnswer.RowId) && x.QuestionMark == QuestionMark.State) + { + tableAnswer.Answer = TargetState.Loss.GetEnumInt(); + + } + tableAnswers.Add(tableAnswer); + }); + + var questionMarkList = await _readingTaskQuestionMarkRepository.Where(x => x.VisitTaskId == LastVisitTaskId).Select(x => new ReadingTaskQuestionMark() + { + VisitTaskId = visitTaskId, + FirstAddTaskId = x.FirstAddTaskId, + QuestionId = x.QuestionId, + QuestionType = x.QuestionType, + OrderMarkName = x.OrderMarkName, + + }).ToListAsync(); + questionMarkList.ForEach(x => { + x.Id = NewId.NextGuid(); + }); + + + var addList = _mapper.Map>(tableRowAnswers).OrderBy(x => x.RowIndex).ToList(); + + foreach (var item in addList) + { + await _readingTableAnswerRowInfoRepository.AddAsync(item); + await _readingTableQuestionAnswerRepository.SaveChangesAsync(); + } + await _readingTaskQuestionMarkRepository.AddRangeAsync(questionMarkList); + //await _readingTableAnswerRowInfoRepository.AddRangeAsync(addList); + await _readingTableQuestionAnswerRepository.AddRangeAsync(tableAnswers); + //addList.ForEach(x => + //{ + // x.MergeRow = null; + // x.SplitRow = null; + + //}); + await _readingTableQuestionAnswerRepository.SaveChangesAsync(); + + } + } + + return new AddTaskLesionAnswerFromLastTaskOutDto() + { + + IsBaseLine = taskinfo.SourceSubjectVisitId == baseLineVisitId, + }; + + } + #endregion + + #region 获取SOD + + /// + /// 获取SOD + /// + /// + /// 靶病灶径线之和(SOD) + /// 非淋巴结的长径 和淋巴结的短径 + /// + /// + public async Task GetSODData(ReadingCalculateDto inDto) + { + if (sODData != null) + { + return sODData.Value; + } + + var tableQuestion = inDto.QuestionInfo.Where(x => x.LesionType == LesionType.TargetLesion).SelectMany(x => x.TableRowInfoList).ToList(); + + if (tableQuestion.Count() == 0) + { + return null; + } + + decimal result = 0; + + foreach (var item in tableQuestion) + { + if (item.TableQuestionList.Any(x => x.QuestionMark == QuestionMark.IsLymph && x.Answer.EqEnum(YesOrNoOrNa.Yes))) + { + // 淋巴结的短径 + result += (item.TableQuestionList.Where(x => x.QuestionMark == QuestionMark.ShortAxis).Select(x => x.Answer).FirstOrDefault()).IsNullOrEmptyReturn0(); + } + + if (item.TableQuestionList.Any(x => x.QuestionMark == QuestionMark.IsLymph && x.Answer.EqEnum(YesOrNoOrNa.No))) + { + // 非淋巴结的长径 + result += item.TableQuestionList.Where(x => x.QuestionMark == QuestionMark.MajorAxis).Select(x => x.Answer).FirstOrDefault().IsNullOrEmptyReturn0(); + } + } + + sODData = result; + + return sODData.Value; + + + + } + #endregion + + #region 非淋巴结靶病灶长径之和 + /// + /// 非淋巴结靶病灶长径之和 + /// + /// + /// + public async Task GetSumOfDiameter(ReadingCalculateDto inDto) + { + var tableQuestion = inDto.QuestionInfo.Where(x => x.LesionType == LesionType.TargetLesion).SelectMany(x => x.TableRowInfoList).ToList(); + + if (tableQuestion.Count() == 0) + { + return null; + } + + decimal result = 0; + + foreach (var item in tableQuestion) + { + if (item.TableQuestionList.Any(x => x.QuestionMark == QuestionMark.IsLymph && x.Answer.EqEnum(YesOrNoOrNa.No))) + { + // 非淋巴结的长径 + result += item.TableQuestionList.Where(x => x.QuestionMark == QuestionMark.MajorAxis).Select(x => x.Answer).FirstOrDefault().IsNullOrEmptyReturn0(); + } + } + + + return result; + } + #endregion + + #region 与基线SOD相比变化量(mm) + /// + /// 与基线SOD相比变化量(mm) + /// + /// + /// + public async Task GetSODChange(ReadingCalculateDto inDto) + { + + var value = await GetSODData(inDto); + + if (value == null || inDto.IsBaseLine) + { + return null; + } + return value.NullChange0() - await GetBaseLineSOD(inDto); + } + #endregion + + #region 与基线访视相比SOD变化百分比 + /// + /// 与基线访视相比SOD变化百分比 + /// + /// + /// + public async Task GetSODPercent(ReadingCalculateDto inDto) + { + var thisSOD = await GetSODData(inDto); + + if (thisSOD == null || inDto.IsBaseLine) + { + return null; + } + + var baseLineSOD = await GetBaseLineSOD(inDto); + + if (baseLineSOD == 0) + { + return 100; + } + else + { + return (thisSOD.NullChange0() - baseLineSOD) * 100 / baseLineSOD; + } + } + #endregion + + #region 与整个访视期间SOD最低点相比增加的值(mm) + /// + /// 与整个访视期间SOD最低点相比增加的值(mm) + /// + /// + /// + /// 要更新之前的 + /// + /// + public async Task GetLowestIncrease(ReadingCalculateDto inDto) + { + var value = await GetSODData(inDto); + if (value == null || inDto.IsBaseLine) + { + return null; + } + var decimalAnswerList = await GetLowSODVisit(inDto); + var minSOD = decimalAnswerList.OrderBy(x => x.SOD).Select(x => x.SOD).FirstOrDefault(); + return value.NullChange0() - minSOD; + } + #endregion + + #region 与整个访视期间SOD最低点相比增加的百分比 + /// + /// 与整个访视期间SOD最低点相比增加的百分比 + /// + /// + /// + /// 要更新之前的 + /// + /// + public async Task GetLowPercent(ReadingCalculateDto inDto) + { + var thisSOD = await GetSODData(inDto); + if (thisSOD == null || inDto.IsBaseLine) + { + return null; + } + var decimalAnswerList = await GetLowSODVisit(inDto); + var minSOD = decimalAnswerList.OrderBy(x => x.SOD).Select(x => x.SOD).FirstOrDefault(); + + if (minSOD == 0) + { + return 100; + } + else + { + return (thisSOD.NullChange0() - minSOD) * 100 / minSOD; + } + + + } + #endregion + + #region 整个访视期间SOD最低点访视名称 + /// + /// 整个访视期间SOD最低点访视名称 + /// + /// + /// + /// 要更新之前的 + /// + /// + public async Task GetLowVisit(ReadingCalculateDto inDto) + { + if (inDto.IsBaseLine) + { + return nameof(YesOrNoOrNa.NA); + } + var targetCount = inDto.QuestionInfo.Where(x => x.LesionType == LesionType.TargetLesion).SelectMany(x => x.TableRowInfoList).Count(); + if (targetCount == 0) + { + return nameof(YesOrNoOrNa.NA); + } + + var decimalAnswerList = await GetLowSODVisit(inDto); + return decimalAnswerList.OrderBy(x => x.SOD).Select(x => x.BlindName).FirstOrDefault() ?? string.Empty; + } + #endregion + + #region 是否存在非淋巴结靶病灶 + /// + /// 是否存在非淋巴结靶病灶 + /// + /// + /// + public async Task GetIsLymphTarget(ReadingCalculateDto inDto) + { + var result = IsLymph.No.GetEnumInt(); + var tableQuestion = inDto.QuestionInfo.Where(x => x.LesionType == LesionType.TargetLesion).SelectMany(x => x.TableRowInfoList).ToList(); + + foreach (var item in tableQuestion) + { + if (item.TableQuestionList.Any(x => x.QuestionMark == QuestionMark.IsLymph && x.Answer.EqEnum(IsLymph.No))) + { + result = IsLymph.Yes.GetEnumInt(); + } + } + + + + return result; + } + #endregion + + #region 是否存在淋巴结靶病灶且该病灶比上一访视短径增加5MM以上 + /// + /// 是否存在淋巴结靶病灶且该病灶比上一访视短径增加5MM以上 + /// + /// + /// + public async Task GetIsAddFive(ReadingCalculateDto inDto) + { + if (inDto.IsBaseLine) + { + return YesOrNoOrNa.NA.GetEnumInt(); + } + var addFiveList = await GetIsAddFiveRowIndexs(inDto); + var isExists = addFiveList.Count() > 0 ? true : false; + + return isExists ? YesOrNoOrNa.Yes.GetEnumInt() : YesOrNoOrNa.No.GetEnumInt(); + + } + + /// + /// 获取存在淋巴结靶病灶且该病灶比上一访视短径增加5MM以上的病灶 + /// + /// + /// + public async Task> GetIsAddFiveRowIndexs(ReadingCalculateDto inDto) + { + List result = new List(); + var LastVisitTaskId = await this.GetLastVisitTaskId(inDto); + var questionIds = inDto.QuestionInfo.Where(x => x.LesionType == LesionType.TargetLesion).Select(x => x.QuestionId).ToList(); + var lastQuestionAsnwer = await _readingTableQuestionAnswerRepository.Where(x => x.VisitTaskId == LastVisitTaskId && questionIds.Contains(x.QuestionId)).Include(x => x.ReadingQuestionTrial).Include(x => x.ReadingTableQuestionTrial).ToListAsync(); + var rowIndexs = lastQuestionAsnwer.Where(x => x.ReadingTableQuestionTrial.QuestionMark == QuestionMark.IsLymph && x.Answer.EqEnum(YesOrNoOrNa.Yes)).Select(x => x.RowIndex).Distinct().OrderBy(x => x).ToList(); + var thisQuestionAsnwer = inDto.QuestionInfo.Where(x => x.LesionType == LesionType.TargetLesion).SelectMany(x => x.TableRowInfoList).ToList(); + foreach (var item in rowIndexs) + { + var lastValue = lastQuestionAsnwer.Where(x => x.RowIndex == item && x.ReadingTableQuestionTrial.QuestionMark == QuestionMark.ShortAxis).Select(x => x.Answer).FirstOrDefault().IsNullOrEmptyReturn0(); + + var thisRowData = thisQuestionAsnwer.Where(x => x.RowIndex == item).SelectMany(x => x.TableQuestionList).ToList(); + var thisValue = thisRowData.Where(x => x.QuestionMark == QuestionMark.ShortAxis).Select(x => x.Answer).FirstOrDefault().IsNullOrEmptyReturn0(); + + if (thisValue - lastValue >= 5) + { + result.Add(item); + } + } + + return result; + } + #endregion + + #region 被评估为NE的单个靶病灶 + /// + /// 被评估为NE的单个靶病灶 + /// + /// + /// + public async Task GetNETarget(ReadingCalculateDto inDto) + { + if (inDto.IsBaseLine) + { + return ExistOrNA.NA.GetEnumInt(); + } + + var result = inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.TargetLesion && x.Answer.EqEnum(TargetAssessment.NE)); + + return result ? ExistOrNA.Exist.GetEnumInt() : ExistOrNA.NotExist.GetEnumInt(); + } + #endregion + + #region 整体肿瘤评估 + + /// + /// 整体肿瘤评估 + /// + /// + /// + public async Task GetTumor(ReadingCalculateDto inDto) + { + + if (inDto.IsBaseLine) + { + return OverallAssessment.NA.GetEnumInt(); + } + + var targetLesion = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.TargetLesion).Select(x => x.Answer).FirstOrDefault(); + var noTargetLesion = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.NoTargetLesion).Select(x => x.Answer).FirstOrDefault(); + var newLesions = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.NewLesions).Select(x => x.Answer).FirstOrDefault(); + var result = await _tumorAssessmentRepository.Where(x => + x.TargetLesion == (TargetAssessment)int.Parse(targetLesion.IsNullOrEmpty() ? TargetAssessment.NA.GetEnumInt() : targetLesion) && + x.NonTargetLesions == (NoTargetAssessment)int.Parse(noTargetLesion.IsNullOrEmpty() ? NoTargetAssessment.NA.GetEnumInt() : noTargetLesion) && + x.NewLesion == (NewLesionAssessment)int.Parse(newLesions.IsNullOrEmpty() ? NewLesionAssessment.NA.GetEnumInt() : newLesions)).Select(x => x.OverallEfficacy).ToListAsync(); + + return result.Count == 0 ? OverallAssessment.NE.GetEnumInt() : result[0].GetEnumInt(); + } + #endregion + + #region 是否存在疾病 + /// + /// 是否存在疾病 + /// + /// + /// + public async Task GetIsExistDisease(ReadingCalculateDto inDto) + { + if (!inDto.IsBaseLine) + { + return string.Empty; + } + + var lesionCount = inDto.QuestionInfo.SelectMany(x => x.TableRowInfoList).Count(); + + return lesionCount > 0 ? ExistDisease.Yes.GetEnumInt() : ExistDisease.No.GetEnumInt(); + } + #endregion + + + #region 修改其他标准 + + + + + #region 修改整个访视期间SOD最低点相比增加的百分比 + + /// + /// 修改整个访视期间SOD最低点相比增加的百分比 + /// + /// + /// + //public async Task ChangeAllLowPercent(ChangeAllTaskDto inDto) + //{ + // var visitTaskList = await GetVisitTaskAnswerList(inDto.calculateDto); + + // var lowSod = (await GetLowSODVisit(inDto.calculateDto)).Select(x => x.SOD).OrderBy(x => x).FirstOrDefault(); + + // foreach (var item in visitTaskList.Where(x => x.VisitTaskId != inDto.calculateDto.BaseLineTaskId)) + // { + // decimal percent = 0; + // if (lowSod == 0) + // { + // percent = 100; + // } + // else + // { + // percent = decimal.Round((item.SOD - lowSod) * 100 / lowSod, 2); + // } + + // await _readingTaskQuestionAnswerRepository.BatchUpdateNoTrackingAsync(x => x.VisitTaskId == item.VisitTaskId && x.ReadingQuestionTrialId == inDto.QuestionId, x => new ReadingTaskQuestionAnswer() + // { + // Answer = percent.ToString() + // }); + // } + //} + + #endregion + + #region 修改最低方式点名称 + /// + /// 修改最低方式点名称 + /// + /// + /// + public async Task ChangeAllLowVisitName(ChangeAllTaskDto inDto) + { + // 找到所有访视任务的Id + + var visitTaskIds = await _visitTaskRepository.Where(x => x.IsAnalysisCreate == inDto.IsAnalysisCreate && + x.ReadingCategory == ReadingCategory.Visit && + x.TrialReadingCriterionId == inDto.calculateDto.TrialReadingCriterionId && + x.TaskState == TaskState.Effect && x.ReadingTaskState == ReadingTaskState.HaveSigned && x.ArmEnum == inDto.calculateDto.ArmEnum).Select(x => x.Id).ToListAsync(); + + var answer = (await GetLowSODVisit(inDto.calculateDto)).OrderBy(x => x.SOD).Select(x => x.BlindName).FirstOrDefault(); + visitTaskIds = visitTaskIds.Where(x => x != inDto.calculateDto.BaseLineTaskId).ToList(); + await this.ChangeAllVisitTaskAnswer(visitTaskIds, inDto.QuestionId, answer); + + } + #endregion + + + #endregion + + #region 通用方法 + + #region 修改所有访视任务的答案 + /// + /// 修改所有访视任务的答案 + /// + /// + /// + /// + /// + private async Task ChangeAllVisitTaskAnswer(List visitTaskGuids, Guid questionId, string answer) + { + await _readingTaskQuestionAnswerRepository.BatchUpdateNoTrackingAsync(x => visitTaskGuids.Contains(x.VisitTaskId) && x.ReadingQuestionTrialId == questionId, x => new ReadingTaskQuestionAnswer() + { + Answer = answer + }); + } + #endregion + + + #region 获取基线任务ID + + /// + /// 获取基线任务的Id + /// + /// + /// + private async Task GetBaseLineTaskId(ReadingCalculateDto inDto) + { + if (this.BaseLineTaskId == null) + { + this.BaseLineTaskId = await _visitTaskRepository.Where(x => x.SubjectId == inDto.SubjectId && x.ReadingCategory == ReadingCategory.Visit + && x.TrialReadingCriterionId == inDto.TrialReadingCriterionId && + + x.SourceSubjectVisit.IsBaseLine && x.TaskState == TaskState.Effect && + x.IsAnalysisCreate == inDto.IsAnalysisCreate + && x.DoctorUserId == inDto.DoctorUserId + && x.IsSelfAnalysis == inDto.IsSelfAnalysis && x.ArmEnum == inDto.ArmEnum) + .Select(x => x.Id).FirstOrDefaultAsync(); + } + + return this.BaseLineTaskId.Value; + + } + #endregion + + #region 获取基线SOD + /// + /// 获取基线SOD + /// + /// + /// + private async Task GetBaseLineSOD(ReadingCalculateDto inDto) + { + if (await _visitTaskRepository.AnyAsync(x => x.Id == inDto.VisitTaskId && x.SourceSubjectVisit.IsBaseLine && x.IsAnalysisCreate == inDto.IsAnalysisCreate && x.ArmEnum == inDto.ArmEnum)) + { + return 0; + } + + // 先找到基线的任务 + var baseLineTaskId = await _visitTaskRepository.Where(x => x.SubjectId == inDto.SubjectId && x.ReadingCategory == ReadingCategory.Visit + && x.TrialReadingCriterionId == inDto.TrialReadingCriterionId && + + x.SourceSubjectVisit.IsBaseLine && x.TaskState == TaskState.Effect && + x.IsAnalysisCreate == inDto.IsAnalysisCreate + && x.DoctorUserId == inDto.DoctorUserId + && x.IsSelfAnalysis == inDto.IsSelfAnalysis && x.ArmEnum == inDto.ArmEnum) + .Select(x => x.Id).FirstOrDefaultAsync(); + + + var baseLineSOD = (await _readingTaskQuestionAnswerRepository.Where(x => x.VisitTaskId == baseLineTaskId && x.ReadingQuestionTrial.QuestionType == QuestionType.SOD).Select(x => x.Answer).FirstOrDefaultAsync()).IsNullOrEmptyReturn0(); + return baseLineSOD; + } + #endregion + + + /// + /// 获取最低方式 + /// + /// + /// + public async Task> GetLowSODVisit(ReadingCalculateDto inDto) + { + var taskAnswerList = await GetVisitTaskAnswerList(inDto); + + taskAnswerList = taskAnswerList.Where(x => x.VisitTaskId != inDto.VisitTaskId).ToList(); + + var taskIds = taskAnswerList.Select(x => x.VisitTaskId).ToList(); + + // 排除无法评估 + var unableEvaluateTaskIds = await _readingTableQuestionAnswerRepository.Where(x => taskIds.Contains(x.VisitTaskId) && + x.ReadingTableQuestionTrial.QuestionMark == QuestionMark.State + && x.ReadingQuestionTrial.LesionType == LesionType.TargetLesion + && x.Answer == TargetState.UnableEvaluate.GetEnumInt() + ) + .Select(x => x.VisitTaskId).Distinct().ToListAsync(); + + taskAnswerList = taskAnswerList.Where(x => !unableEvaluateTaskIds.Contains(x.VisitTaskId)).ToList(); + return taskAnswerList.OrderBy(x => x.SOD).ToList(); + } + + #region 获取访视任务信息 + /// + /// 获取访视任务信息 + /// + /// + /// + public async Task> GetVisitTaskAnswerList(ReadingCalculateDto inDto) + { + if (visitTaskAnswerList == null) + { + // 查询的时候要把自己排除 因为查询出来的可能不是计算出的最新的 + visitTaskAnswerList = await _readingTaskQuestionAnswerRepository.Where(x => x.VisitTaskId != inDto.VisitTaskId && x.VisitTask.ReadingCategory == ReadingCategory.Visit + && x.VisitTask.IsAnalysisCreate == inDto.IsAnalysisCreate + && x.VisitTask.IsSelfAnalysis == inDto.IsSelfAnalysis + && x.VisitTask.VisitTaskNum < inDto.VisitTaskNum + && x.ReadingQuestionCriterionTrialId == inDto.TrialReadingCriterionId + && x.SubjectId == inDto.SubjectId && x.VisitTask.ReadingTaskState == ReadingTaskState.HaveSigned && x.VisitTask.ArmEnum == inDto.ArmEnum && x.VisitTask.TaskState == TaskState.Effect && x.ReadingQuestionTrial.QuestionType == QuestionType.SpleenLength) + .Select(x => new VisitTaskAnswerInfo + { + VisitTaskId = x.VisitTaskId, + QuestionId = x.ReadingQuestionTrialId, + VisitName = x.VisitTask.SourceSubjectVisit.VisitName, + BlindName = x.VisitTask.TaskBlindName, + + SpleenLength = x.Answer.IsNullOrEmptyReturn0(), + }).ToListAsync(); + + //// 这里是需要加上自己的 基线不用管 + //if (visitTaskAnswerList.Count > 0) + //{ + // visitTaskAnswerList.Add(new VisitTaskAnswerInfo() + // { + // VisitTaskId = inDto.VisitTaskId, + // BlindName = inDto.TaskBlindName, + // QuestionId = visitTaskAnswerList[0].QuestionId, + // VisitName = inDto.VisitName, + // SOD = (await GetSODData(inDto)).ToString().IsNullOrEmptyReturn0(), + // }); + //} + + + } + + return visitTaskAnswerList; + } + #endregion + + /// + /// 获取上一个访视任务Id + /// + /// + private async Task GetLastVisitTaskId(ReadingCalculateDto inDto) + { + // 拿到这一个访视 + var thisNum = await _subjectVisitRepository.Where(x => x.Id == inDto.SubjectVisitId).Select(x => x.VisitNum).FirstOrDefaultAsync(); + + // 先找到上一个访视 + var lastVisitId = await _subjectVisitRepository.Where(x => x.SubjectId == inDto.SubjectId && !x.IsLostVisit && x.VisitNum < thisNum).OrderByDescending(x => x.VisitNum).Select(x => x.Id).FirstOrDefaultAsync(); + + // 找到访视任务Id + + var LastVisitTaskId = await _visitTaskRepository.Where(x => x.ReadingCategory == ReadingCategory.Visit && + x.TrialReadingCriterionId == inDto.TrialReadingCriterionId && + x.TaskState == TaskState.Effect && + x.IsAnalysisCreate == inDto.IsAnalysisCreate + && x.SourceSubjectVisitId == lastVisitId && x.ArmEnum == inDto.ArmEnum).Select(x => x.Id).FirstOrDefaultAsync(); + + return LastVisitTaskId; + } + #endregion + + #region 计算阅片问题 外层问题 + + #region 获取SPD + + /// + /// 获取SPD + /// + /// + /// + public async Task GetSPD(ReadingCalculateDto inDto) + { + decimal result = 0; + var rowInfo = inDto.QuestionInfo.Where(x => x.LesionType == LesionType.TargetLesion).SelectMany(x => x.TableRowInfoList).ToList(); + + var tableQuestionList = rowInfo.SelectMany(x => x.TableQuestionList).ToList(); + + result = tableQuestionList.Where(x => x.QuestionMark == QuestionMark.PPD).Sum(x => x.Answer.IsNullOrEmptyReturn0()); + return result; + + } + + #endregion + + #region 脾脏垂直径 + /// + /// 获取脾脏垂直径 + /// + /// + /// + public async Task GetSpleenLength(ReadingCalculateDto inDto) + { + + // 脾尖答案 + var splenicTopAnswer = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.SplenicTopPosition).Select(x => x.Answer).FirstOrDefault(); + // 脾底答案 + var splenicBottomAnswer = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.SplenicBottomPosition).Select(x => x.Answer).FirstOrDefault(); + + decimal? spleenLength = null; + if (splenicTopAnswer != null && splenicBottomAnswer != null&& splenicTopAnswer != string.Empty && splenicBottomAnswer != string.Empty) + { + spleenLength = splenicTopAnswer.IsNullOrEmptyReturn0() - splenicBottomAnswer.IsNullOrEmptyReturn0(); + if (spleenLength < 0) + { + spleenLength = 0 - spleenLength; + } + return spleenLength; + } + + return spleenLength; + } + #endregion + + #region 与基线相比SPD变化的百分比 + /// + /// 与基线相比SPD变化的百分比 + /// + /// + /// + public async Task CompareBaselineSPD(ReadingCalculateDto inDto) + { + if (inDto.IsBaseLine) + { + return "NA"; + } + var baseLineTaskId = await GetBaseLineTaskId(inDto); + + var baseLineSpd = (await _readingTaskQuestionAnswerRepository.Where(x => x.VisitTaskId == baseLineTaskId && x.ReadingQuestionTrial.QuestionType == QuestionType.SPD).Select(x => x.Answer).FirstOrDefaultAsync()).IsNullOrEmptyReturn0(); + + var presentSpd = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.SPD).Select(x => x.Answer).FirstOrDefault().IsNullOrEmptyReturn0(); + if (baseLineSpd != 0) + { + return ReserveDecimal((presentSpd - baseLineSpd) * 100 / baseLineSpd, inDto.DigitPlaces); + } + else + { + return "NA"; + } + } + #endregion + + #region 与基线相比脾肿大增加的百分比 + /// + /// 与基线相比脾肿大增加的百分比 + /// [(当前垂直径-130)-(基线垂直径-130)]/(基线垂直径-130) + /// + /// + /// + public async Task GetSplenoncusChange(ReadingCalculateDto inDto) + { + if (inDto.IsBaseLine) + { + return "NA"; + } + + + var baseLineSpleenLength = await GetBaseLineSpleenLength(inDto); + + var presentSpleenLength = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.SpleenLength).Select(x => x.Answer).FirstOrDefault().IsNullOrEmptyReturn0(); + if (baseLineSpleenLength - 130 > 0 && presentSpleenLength > 130) + { + return ReserveDecimal((presentSpleenLength - 130 - (baseLineSpleenLength - 130)) * 100 / (baseLineSpleenLength - 130), inDto.DigitPlaces); + } + else + { + return "NA"; + } + } + #endregion + + #region 与最低点相比脾脏垂直径长度的增加值 + + /// + /// 与最低点相比脾脏垂直径长度的增加值 + /// + /// + /// + public async Task GetSplenoncusAdd(ReadingCalculateDto inDto) + { + var TaskAnswer = await GetVisitTaskAnswerList(inDto); + if (inDto.IsBaseLine) + { + return "NA"; + } + if (TaskAnswer.Count() == 0) + { + return "0"; + } + var presentSpd = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.SpleenLength).Select(x => x.Answer).FirstOrDefault().IsNullOrEmptyReturn0(); + var lowSplenoncus = TaskAnswer.OrderBy(x => x.SpleenLength).Select(x => x.SpleenLength).FirstOrDefault(); + return (presentSpd - lowSplenoncus).ToString(); + + + } + #endregion + + + #region 脾肿垂直径最低点访视 + + /// + /// 脾肿垂直径最低点访视 + /// + /// + /// + public async Task GetLowestSplenoncusVisit(ReadingCalculateDto inDto) + { + var taskAnswer = await GetVisitTaskAnswerList(inDto); + if (inDto.IsBaseLine) + { + return "NA"; + } + if (taskAnswer.Count() == 0) + { + return "NA"; + } + + var lowSplenoncus = taskAnswer.OrderBy(x => x.SpleenLength).FirstOrDefault(); + return lowSplenoncus.BlindName; + + + } + #endregion + + #region 获取脾脏状态 + + /// + /// 获取脾脏状态 + /// + /// + /// + /// + [HttpPost] + public async Task GetSplenicState(Guid visitTaskId, decimal spleenLength) + { + + var taskinfo = await _visitTaskRepository.Where(x => x.Id == visitTaskId).FirstNotNullAsync(); + ReadingCalculateDto inDto = await _generalCalculateService.GetReadingCalculateDto(visitTaskId); + var result = SpleenAssessment.NotEvaluable; + if (spleenLength < 0) + { + return SpleenAssessment.NotEvaluable.GetEnumInt(); + } + else if (0 < spleenLength && spleenLength <= 130) + { + return SpleenAssessment.Normal.GetEnumInt(); + + } + else if (inDto.IsBaseLine) + { + return SpleenAssessment.Swelling.GetEnumInt(); + } + + + var lowSpleenLength = await this.GetLowSpleenLength(taskinfo); + + + + + + var presentSpd = spleenLength; + var baseLineSpleenLength = await GetBaseLineSpleenLength(inDto); + + var baseLineTaskId = await GetBaseLineTaskId(inDto); + var baseLineState = await _readingTaskQuestionAnswerRepository.Where(x => x.VisitTaskId == baseLineTaskId && x.ReadingQuestionTrial.QuestionType == QuestionType.SplenicStatus).Select(x => x.Answer).FirstOrDefaultAsync(); + + + var differenceValue = presentSpd - baseLineSpleenLength; + + var differenceLowValue = presentSpd - lowSpleenLength; + + + decimal getPercentage() + { + decimal percentage = 0; + if (baseLineSpleenLength != 0) + { + percentage = differenceValue * 100 / (baseLineSpleenLength - 130); + } + return percentage; + } + + + + // 1、基线 垂直径> 130 mm + //2、与基线相比脾垂直径变化值≥10 mm + // 当前垂直径>130 mm + //与基线相比脾肿大增加的百分比 > 50% + if (baseLineSpleenLength > 130 && differenceValue >= 10 && spleenLength > 130 && getPercentage() > 50) + { + result = SpleenAssessment.Increase; + } + //1、基线垂直径≤130mm + //2、与基线相比脾垂直径变化值≥20 mm + //当前垂直径 > 130 mm + else if (baseLineSpleenLength <= 130 && differenceValue >= 20 && presentSpd > 130) + { + result = SpleenAssessment.Increase; + } + //1、基线 垂直径> 130 mm + //2、当前访视的前面访视中 存在垂直径≤130mm + //3、与最低点相比脾脏垂直径的增加值≥20 mm + //4、当前垂直径 > 130 mm + else if (baseLineSpleenLength > 130 && lowSpleenLength <= 130 && differenceLowValue >= 20 && presentSpd > 130) + { + result = SpleenAssessment.Increase; + } + // 当前垂直径≤130mm + else if (spleenLength <= 130) + { + result = SpleenAssessment.Normal; + } + //1、基线期 状态为“肿大” + // 当前垂直径>130 mm + //与基线相比脾肿大增加的百分比 < -50% + else if (baseLineState.EqEnum(SpleenAssessment.Swelling) && spleenLength > 130 && getPercentage() < -50) + { + result = SpleenAssessment.Remission; + } + else + { + result = SpleenAssessment.Stabilization; + } + return result.GetEnumInt(); + } + #endregion + + /// + /// 获取最低垂直径 + /// + /// + private async Task GetLowSpleenLength(VisitTask taskinfo) + { + var visitTaskIds = await _visitTaskRepository.Where(x => x.ReadingCategory == ReadingCategory.Visit && + x.TrialReadingCriterionId == taskinfo.TrialReadingCriterionId && + x.IsAnalysisCreate == taskinfo.IsAnalysisCreate && + x.DoctorUserId == taskinfo.DoctorUserId && + x.IsSelfAnalysis == taskinfo.IsSelfAnalysis && + x.SubjectId == taskinfo.SubjectId && x.ReadingTaskState == ReadingTaskState.HaveSigned && x.ArmEnum == taskinfo.ArmEnum + && x.VisitTaskNum < taskinfo.VisitTaskNum && x.TaskState == TaskState.Effect + ).OrderByDescending(x => x.VisitTaskNum).Select(x => x.Id).ToListAsync(); + + var questionId = await _readingQuestionTrialRepository.Where(x => x.ReadingQuestionCriterionTrialId == taskinfo.TrialReadingCriterionId && x.QuestionType == QuestionType.SpleenLength).Select(x => x.Id).FirstNotNullAsync(); + var answerList = await _readingTaskQuestionAnswerRepository.Where(x => visitTaskIds.Contains(x.VisitTaskId) + && x.ReadingQuestionTrialId == questionId) + .Select(x => new + { + x.Answer, + x.VisitTaskId, + }).ToListAsync(); + + var lowSpleenLength = answerList.Select(x => new + { + Answer = x.Answer.IsNullOrEmptyReturn0(), + x.VisitTaskId + }).OrderBy(x => x.Answer).Select(x => x.Answer).FirstOrDefault(); + + return lowSpleenLength; + } + + /// + /// 获取脾脏验证 + /// + /// + /// + [HttpPost] + public async Task GetSplenicVerify(Guid visitTaskId) + { + + ReadingCalculateDto inDto = await _generalCalculateService.GetReadingCalculateDto(visitTaskId); + + // 基线垂直径 + var baseLineSpleenLength = await GetBaseLineSpleenLength(inDto); + + var taskinfo = await _visitTaskRepository.Where(x => x.Id == visitTaskId).FirstNotNullAsync(); + + var baseLineTaskId = await GetBaseLineTaskId(inDto); + + // 最低垂直经 + var lowSpleenLength = await this.GetLowSpleenLength(taskinfo); + + // 基线状态 + var baseLineState = await _readingTaskQuestionAnswerRepository.Where(x => x.VisitTaskId == baseLineTaskId && x.ReadingQuestionTrial.QuestionType == QuestionType.SplenicStatus).Select(x => x.Answer).FirstOrDefaultAsync(); + + return new + { + + //基线垂直径 + BaseLineSpleenLength = baseLineSpleenLength, + // 最低垂直经 + LowSpleenLength = lowSpleenLength, + // 基线状态 + BaseLineState = baseLineState, + + // 脾脏状态 + SplenicStatus = await GetSplenicStatus(inDto), + }; + + } + + /// + /// 获取脾脏状态 + /// + /// + /// + public async Task GetSplenicStatus(ReadingCalculateDto inDto) + { + var spleenLength = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.SpleenLength).Select(x => x.Answer).FirstOrDefault(); + if (spleenLength == string.Empty) + { + return string.Empty; + } + else + { + return await GetSplenicState(inDto.VisitTaskId, spleenLength.IsNullOrEmptyReturn0()); + } + } + + #region 获取脾脏评估 + + /// + /// 获取脾脏评估 + /// + /// + /// + public async Task GetSplenicEvaluation(ReadingCalculateDto inDto) + { + + return inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.SplenicStatus).Select(x => x.Answer).FirstIsNullReturnEmpty(); + + //if (inDto.IsBaseLine) + //{ + // return SpleenAssessment.Stabilization.GetEnumInt(); + //} + + //var result = SpleenAssessment.Stabilization; + + + //var presentSpd = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.SpleenLength).Select(x => x.Answer).FirstOrDefault().IsNullOrEmptyReturn0(); + //var baseLineSpleenLength = await GetBaseLineSpleenLength(inDto); + + //var baseLineTaskId = await GetBaseLineTaskId(inDto); + //var baseLineState = await _readingTaskQuestionAnswerRepository.Where(x => x.VisitTaskId == baseLineTaskId && x.ReadingQuestionTrial.QuestionType == QuestionType.SplenicStatus).Select(x => x.Answer).FirstOrDefaultAsync(); + + + //var differenceValue = presentSpd - baseLineSpleenLength; + //decimal percentage = 0; + //if (baseLineSpleenLength != 0) + //{ + // percentage = differenceValue * 100 / baseLineSpleenLength; + //} + + //// 1、基线 垂直径> 130 mm + ////2、与基线相比脾垂直径变化值≥10 mm + ////与基线相比脾肿大增加的百分比 > 50% + //if (baseLineSpleenLength > 130 && differenceValue >= 10 && percentage > 50) + //{ + // result = SpleenAssessment.Increase; + //} + ////1、基线垂直径≤130mm + ////2、与基线相比脾垂直径变化值≥20 mm + ////当前垂直径 > 130 mm + //else if (baseLineSpleenLength <= 130 && differenceValue >= 20 && presentSpd > 130) + //{ + // result = SpleenAssessment.Increase; + //} + ////1、基线 垂直径> 130 mm + ////2、当前访视的前面访视中 存在垂直径≤130mm + ////3、与最低点相比脾脏垂直径的增加值≥20 mm + ////4、当前垂直径 > 130 mm + //else if (baseLineSpleenLength > 130 && presentSpd <= 130 && differenceValue >= 20 && presentSpd > 130) + //{ + // result = SpleenAssessment.Increase; + //} + //// 基线垂直径≤130mm + //else if (baseLineSpleenLength <= 130) + //{ + // result = SpleenAssessment.Normal; + //} + ////1、基线期 状态为“肿大” + ////与基线相比脾肿大增加的百分比 > 50% + //else if (baseLineState.EqEnum(SpleenState.Swelling) && percentage > 50) + //{ + // result = SpleenAssessment.Remission; + //} + //else + //{ + // result = SpleenAssessment.Remission; + //} + //return result.GetEnumInt(); + + + } + #endregion + + + #region PET 5PS + + /// + /// 获取PET5PS评分 + /// + /// + /// + public async Task GetPET5PS(ReadingCalculateDto inDto) + { + + // 如果是保存影像进来 PET-CT不能融合 就是NE + if (inDto.ComputationTrigger == ComputationTrigger.ImageQuality) + { + if (await ImageQualityIsUnableFuse(inDto)) + { + return PET5PSScore.NE.GetEnumInt(); + } + } + + + // 先在数据库查这几个值 + List needSearchTypes = new List() + { + QuestionType.SUVmax, + QuestionType.PET5PS, + }; + + var dataBaseDataList = await _readingTaskQuestionAnswerRepository.Where(x => x.VisitTaskId == inDto.VisitTaskId && needSearchTypes.Contains(x.ReadingQuestionTrial.QuestionType)).Select(x => new + { + x.Answer, + x.ReadingQuestionTrial.QuestionType + }).ToListAsync(); + + + // 数据库中最大SUVmax + var dataBaseSUVmax = dataBaseDataList.Where(x => x.QuestionType == QuestionType.SUVmax).Select(x => x.Answer).FirstIsNullReturnEmpty(); + + // 如果不是保存肝脏血池和纵隔血池 + if (inDto.ComputationTrigger != ComputationTrigger.InitialCalculation && inDto.ComputationTrigger != ComputationTrigger.LiverBloodPool && inDto.ComputationTrigger != ComputationTrigger.MediastinalPool&& dataBaseSUVmax == (await GetSuvMax(inDto)).ToString()) + { + + + return dataBaseDataList.Where(x => x.QuestionType == QuestionType.PET5PS).Select(x => x.Answer).FirstIsNullReturnEmpty(); + + } + + + + //if (inDto.IsBaseLine) + //{ + // return SpleenAssessment.Stabilization.GetEnumInt(); + //} + + else if (inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.ExistPET && x.Answer == ReadingYesOrNo.No.GetEnumInt())) + { + return PET5PSScore.NE.GetEnumInt(); + } + + + var existPET = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.ExistPET).Select(x => x.Answer).FirstOrDefault(); + if (existPET.EqEnum(ReadingYesOrNo.No)) + { + return PET5PSScore.NE.GetEnumInt(); + } + + + PET5PSScore result = PET5PSScore.X; + + // 最大Suvmax + var maxSUVmax = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.SUVmax).Select(x => x.Answer).FirstOrDefault().IsNullOrEmptyReturn0(); + + // 肝脏血池Suvmax + var LiverSUVmax = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.LiverSUVmax).Select(x => x.Answer).FirstOrDefault().IsNullOrEmptyReturn0(); + + // 纵膈血池 + var MediastinumSUVmax = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.MediastinumSUVmax).Select(x => x.Answer).FirstOrDefault().IsNullOrEmptyReturn0(); + + + if (existPET.EqEnum(ReadingYesOrNo.No)) + { + result = PET5PSScore.NE; + } + + // 本访视病灶的 max SUVmax(所有病灶中最大的)> 2 * 肝脏血池SUVmax + else if (maxSUVmax > 2 * LiverSUVmax && LiverSUVmax != 0m) + { + result = PET5PSScore.Five; + } + //本访视病灶的SUVmax(所有病灶中最大的)>肝脏血池SUVmax + else if (maxSUVmax > LiverSUVmax && LiverSUVmax != 0) + { + result = PET5PSScore.Four; + } + //纵隔血池SUVmax<本访视点病灶的max SUVmax(所有病灶中最大的)≤1*肝脏血池SUVmax + else if (MediastinumSUVmax < maxSUVmax && maxSUVmax <= LiverSUVmax && MediastinumSUVmax != 0) + { + result = PET5PSScore.Three; + } + //本访视点病灶的SUVmax(所有病灶中最大的)<=纵隔血池SUVmax + else if (maxSUVmax <= MediastinumSUVmax && maxSUVmax != 0) + { + result = PET5PSScore.Two; + } + //无需标记,自主选择 + else + { + return string.Empty; + } + + return result.GetEnumInt(); + } + #endregion + + #region 修改PET 5PS评分备注 + + /// + /// 获取PET5PS评分备注 + /// + /// + /// + public async Task GetPET5PSRemark(ReadingCalculateDto inDto) + { + List needSearchTypes = new List() + { + QuestionType.PET5PS, + QuestionType.PSScoreRemarks, + }; + + var dataBaseDataList = await _readingTaskQuestionAnswerRepository.Where(x => x.VisitTaskId == inDto.VisitTaskId && needSearchTypes.Contains(x.ReadingQuestionTrial.QuestionType)).Select(x => new + { + x.Answer, + x.ReadingQuestionTrial.QuestionType + }).ToListAsync(); ; + + + // 数据库中PET5PS + var pET5PS = dataBaseDataList.Where(x => x.QuestionType == QuestionType.PET5PS).Select(x => x.Answer).FirstIsNullReturnEmpty(); + + // 如果PET5PS没变 就不重新计算 + if (pET5PS == (await GetPET5PS(inDto)).ToString()) + { + return dataBaseDataList.Where(x => x.QuestionType == QuestionType.PSScoreRemarks).Select(x => x.Answer).FirstIsNullReturnEmpty(); + + } + else + { + return string.Empty; + } + + } + #endregion + + + #region 与基线相比摄取值变化 + + /// + /// 与基线相比摄取值变化 + /// + /// + /// + public async Task GetUptakeChange(ReadingCalculateDto inDto) + { + var existPET = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.ExistPET).Select(x => x.Answer).FirstOrDefault(); + if (await ImageQualityIsUnableFuse(inDto)|| existPET.EqEnum(ReadingYesOrNo.No)) + { + if (inDto.IsBaseLine) + { + return string.Empty; + } + else + { + return SUVChangeVSBaseline.NotEvaluable.GetEnumInt(); + } + + } + + //PET5ps评分改变时,才计算 + + List needSearchTypes = new List() + { + QuestionType.PET5PS, + QuestionType.UptakeChange, + }; + + var dataBaseDataList = await _readingTaskQuestionAnswerRepository.Where(x => x.VisitTaskId == inDto.VisitTaskId && needSearchTypes.Contains(x.ReadingQuestionTrial.QuestionType)).Select(x => new + { + x.Answer, + x.ReadingQuestionTrial.QuestionType + }).ToListAsync(); ; + + + // 数据库中PET5ps评分 + var dataBasePET5ps = dataBaseDataList.Where(x => x.QuestionType == QuestionType.PET5PS).Select(x => x.Answer).FirstIsNullReturnEmpty(); + + + if (dataBasePET5ps == await GetPET5PS(inDto)) + { + return dataBaseDataList.Where(x => x.QuestionType == QuestionType.UptakeChange).Select(x => x.Answer).FirstIsNullReturnEmpty(); + + } + + + if (inDto.IsBaseLine) + { + return SUVChangeVSBaseline.NA.GetEnumInt(); + } + + var result = SUVChangeVSBaseline.NotEvaluable; + var baseLineTaskId = await GetBaseLineTaskId(inDto); + + var PET5PS = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.PET5PS).Select(x => x.Answer).FirstOrDefault().IsNullOrEmptyReturn0(); + if (PET5PS == 0) + { + return string.Empty; + } + + var baseLinePET5PSValue = await _readingTaskQuestionAnswerRepository.Where(x => x.VisitTaskId == baseLineTaskId && x.ReadingQuestionTrial.QuestionType == QuestionType.PET5PS).Select(x => x.Answer).FirstOrDefaultAsync(); + + + var baseLinePET5PS = baseLinePET5PSValue.IsNullOrEmptyReturn0(); + + + + + + // 基线为NE或者X 为空 + if (baseLinePET5PSValue.EqEnum(PET5PSScore.X) || baseLinePET5PSValue.EqEnum(PET5PSScore.NE)) + { + return string.Empty; + } + + //本访视PET评分>基线PET评分 + else if (PET5PS > baseLinePET5PS) + { + result = SUVChangeVSBaseline.Increase; + } + + //本访视PET评分<基线PET评分 + else if (PET5PS < baseLinePET5PS) + { + result = SUVChangeVSBaseline.Decrease; + } + + //访视PET评分 等于 基线PET评分 + else if (PET5PS == baseLinePET5PS) + { + return string.Empty; + //result = SUVChangeVSBaseline.DidNotChange; + } + + return result.GetEnumInt(); + + } + #endregion + + /// + /// 获取上一次FDGPET 评估 + /// + /// + /// + public async Task GetLastFDGPETOverallAssessment(ReadingCalculateDto inDto) + { + if (inDto.IsBaseLine) + { + return FDGPETOverallAssessment.NA.GetEnumInt(); + } + + var lastTaskId = await GetLastVisitTaskId(inDto); + + + var answer = await _readingTaskQuestionAnswerRepository.Where(x => x.VisitTaskId == lastTaskId).Include(x => x.ReadingQuestionTrial).Where(x => x.ReadingQuestionTrial.QuestionType == QuestionType.FDGPET).Select(x => x.Answer).FirstOrDefaultAsync(); + return answer ?? string.Empty; + } + + #region FDG-PET总体评估结果 + + /// + /// FDG-PET总体评估结果 + /// + /// + /// + public async Task GetFDGPETOverallAssessment(ReadingCalculateDto inDto) + { + + // 如果是保存影像进来 PET-CT不能融合 就是NE + if (inDto.ComputationTrigger == ComputationTrigger.ImageQuality) + { + if (await ImageQualityIsUnableFuse(inDto)) + { + if (inDto.IsBaseLine) + { + return FDGPETOverallAssessment.NA.GetEnumInt(); + } + else + { + return FDGPETOverallAssessment.NE.GetEnumInt(); + } + } + } + + if (inDto.IsBaseLine) + { + return FDGPETOverallAssessment.NA.GetEnumInt(); + } + + var notExistPET = inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.ExistPET && x.Answer == ReadingYesOrNo.No.GetEnumInt()); + + + + if (notExistPET || (await ImageQualityIsUnableFuse(inDto))) + { + return FDGPETOverallAssessment.NE.GetEnumInt(); + } + + //FDGPETOverallAssessment result = FDGPETOverallAssessment.NA; + + // PET5PS + var pET5PS = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.PET5PS).Select(x => x.Answer).FirstOrDefault(); + + // UptakeChange + var uptakeChange = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.UptakeChange).Select(x => x.Answer).FirstOrDefault(); + + // EvidenceFocalFDG + var evidenceFocalFDG = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.EvidenceFocalFDG).Select(x => x.Answer).FirstOrDefault(); + + + return CalculationFDGPETOverallAssessment(pET5PS, uptakeChange, evidenceFocalFDG); + } + + + /// + /// 计算FDG-PET总体评估结果【测试】 + /// + /// PET5PS评分 + /// 与基线相比摄取值变化 + /// 骨髓中是否存在局灶性 FDG亲和病灶的证据 + /// + public string CalculationFDGPETOverallAssessment(string? pET5PS, string uptakeChange, string? evidenceFocalFDG) + { + List data = new List() { + + //NE NE NE NE + new CalculationDto(){ + Column1=ReadingCommon.EnumToString(new List() { PET5PSScore.NE }), + Column2=ReadingCommon.EnumToString(new List() { SUVChangeVSBaseline.NotEvaluable }), + Column3=ReadingCommon.EnumToString(new List() { FDGAffinityFociInBM.NE}), + Column4=ReadingCommon.EnumToString(new List() { FDGPETOverallAssessment.NE }), + }, + + //NE/5分/4分/3分/2分/1分/X NE/增大/减少/无明显变化 是,存在新的/复发的FDG高亲和性病灶 PMD + new CalculationDto(){ + Column1=ReadingCommon.EnumToString(new List() { PET5PSScore.NE,PET5PSScore.Five,PET5PSScore.Four,PET5PSScore.Three,PET5PSScore.Two,PET5PSScore.One,PET5PSScore.X, }), + Column2=ReadingCommon.EnumToString(new List() { SUVChangeVSBaseline.NotEvaluable,SUVChangeVSBaseline.Increase,SUVChangeVSBaseline.Decrease,SUVChangeVSBaseline.DidNotChange, }), + Column3=ReadingCommon.EnumToString(new List() { FDGAffinityFociInBM.YesHaveNew,}), + Column4=ReadingCommon.EnumToString(new List() { FDGPETOverallAssessment.PMD }), + }, + + //5分/4分 增大 NE/(是,存在新的/复发的FDG高亲和性病灶)/(是,存在持续的局灶性变化)/否 PMD + new CalculationDto(){ + Column1=ReadingCommon.EnumToString(new List() { PET5PSScore.Five,PET5PSScore.Four, }), + Column2=ReadingCommon.EnumToString(new List() { SUVChangeVSBaseline.Increase }), + Column3=ReadingCommon.EnumToString(new List() { FDGAffinityFociInBM.NE, FDGAffinityFociInBM.YesHaveNew, FDGAffinityFociInBM.YesSustain, FDGAffinityFociInBM.No}), + Column4=ReadingCommon.EnumToString(new List() { FDGPETOverallAssessment.PMD }), + }, + + //3分/2分/1分/X NE/增大/减少/无明显变化 否 CMR + new CalculationDto(){ + Column1=ReadingCommon.EnumToString(new List() { PET5PSScore.Three,PET5PSScore.Two,PET5PSScore.One,PET5PSScore.X, }), + Column2=ReadingCommon.EnumToString(new List() { SUVChangeVSBaseline.NotEvaluable,SUVChangeVSBaseline.Increase,SUVChangeVSBaseline.Decrease,SUVChangeVSBaseline.DidNotChange, }), + Column3=ReadingCommon.EnumToString(new List() { FDGAffinityFociInBM.No}), + Column4=ReadingCommon.EnumToString(new List() { FDGPETOverallAssessment.CMR }), + }, + + //3分/2分/1分/X NE/增大/减少/无明显变化 是,存在持续的局灶性变化 PMR + new CalculationDto(){ + Column1=ReadingCommon.EnumToString(new List() { PET5PSScore.Three,PET5PSScore.Two,PET5PSScore.One,PET5PSScore.X, }), + Column2=ReadingCommon.EnumToString(new List() { SUVChangeVSBaseline.NotEvaluable,SUVChangeVSBaseline.Increase,SUVChangeVSBaseline.Decrease,SUVChangeVSBaseline.DidNotChange, }), + Column3=ReadingCommon.EnumToString(new List() { FDGAffinityFociInBM.YesSustain }), + Column4=ReadingCommon.EnumToString(new List() { FDGPETOverallAssessment.PMR }), + }, + + //5分/4分 减少 否/是,存在持续的局灶性变化 PMR + new CalculationDto(){ + Column1=ReadingCommon.EnumToString(new List() { PET5PSScore.Five,PET5PSScore.Four }), + Column2=ReadingCommon.EnumToString(new List() { SUVChangeVSBaseline.Decrease }), + Column3=ReadingCommon.EnumToString(new List() { FDGAffinityFociInBM.No, FDGAffinityFociInBM.YesSustain}), + Column4=ReadingCommon.EnumToString(new List() { FDGPETOverallAssessment.PMR }), + }, + + //5分/4分 无明显变化 否/是,存在持续的局灶性变化 NMR + new CalculationDto(){ + Column1=ReadingCommon.EnumToString(new List() { PET5PSScore.Five,PET5PSScore.Four }), + Column2=ReadingCommon.EnumToString(new List() { SUVChangeVSBaseline.DidNotChange }), + Column3=ReadingCommon.EnumToString(new List() { FDGAffinityFociInBM.No, FDGAffinityFociInBM.YesSustain}), + Column4=ReadingCommon.EnumToString(new List() { FDGPETOverallAssessment.NMR }), + }, + }; + + + var resultdata = data.Where(x => + (x.NotEq.Contains(1) ? !x.Column1.Contains(pET5PS) : x.Column1.Contains(pET5PS) || x.Column1.Count() == 0) && + (x.NotEq.Contains(2) ? !x.Column2.Contains(uptakeChange) : x.Column2.Contains(uptakeChange) || x.Column2.Count() == 0) && + (x.NotEq.Contains(3) ? !x.Column3.Contains(evidenceFocalFDG) : x.Column3.Contains(evidenceFocalFDG) || x.Column3.Count() == 0)) + .Select(x => x.Column4.FirstOrDefault()) + .FirstOrDefault(); + return resultdata ?? string.Empty; + } + + #endregion + #region 骨髓中是否存在局灶性 FDG亲和病灶的证据 + + /// + /// 骨髓中是否存在局灶性 FDG亲和病灶的证据 + /// + /// + /// + public async Task GetEvidenceFocalFDG(ReadingCalculateDto inDto) + { + + if (await ImageQualityIsUnableFuse(inDto)|| inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.ExistPET && x.Answer == ReadingYesOrNo.No.GetEnumInt())) + { + if (inDto.IsBaseLine) + { + return string.Empty; + } + else + { + return FDGAffinityFociInBM.NE.GetEnumInt(); + } + } + else + { + return inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.EvidenceFocalFDG).Select(x => x.Answer).FirstOrDefault()??string.Empty; + } + } + #endregion + + #region 肝脏评估 + /// + /// 获取肝脏评估 + /// + /// + /// + public async Task GetLiverAssessment(ReadingCalculateDto inDto) + { + return inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.LiverState).Select(x => x.Answer).FirstIsNullReturnEmpty(); + } + #endregion + + #region SuvMax所在病灶 + + /// + /// SuvMax所在病灶 + /// + /// + /// + public async Task GetSuvMaxFocus(ReadingCalculateDto inDto) + { + var rowInfo = inDto.QuestionInfo.Where(x => x.LesionType == LesionType.TargetLesion).SelectMany(x => x.TableRowInfoList).ToList(); + + if (inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.ExistPET && x.Answer == ReadingYesOrNo.No.GetEnumInt()) + || !inDto.QuestionInfo.SelectMany(x => x.TableRowInfoList).Any(x => x.OtherMeasureData != null && x.OtherMeasureData != string.Empty)) + { + return string.Empty; + } + + var tableQuestions = rowInfo.SelectMany(x => x.TableQuestionList).ToList(); + + var maxSuv = tableQuestions.Where(x => x.QuestionMark == QuestionMark.SUVmax).Select(x =>new { + x.RowIndex, + Answer= x.Answer.IsNullOrEmptyReturn0(), + + + }).OrderByDescending(x=>x.Answer).FirstOrDefault(); + if (maxSuv == null|| maxSuv.Answer == 0m) + { + return "NE"; + } + else + { + var orderMark = inDto.QuestionInfo.Where(x => x.LesionType == LesionType.TargetLesion).FirstOrDefault()!.OrderMark; + return orderMark+ maxSuv.RowIndex.GetLesionMark(); + } + + + } + #endregion + + #region SuvMax + /// + /// 最大sum + /// + /// + /// + public async Task GetSuvMax(ReadingCalculateDto inDto) + { + + + + if (inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.ExistPET && x.Answer == ReadingYesOrNo.No.GetEnumInt()) + || !inDto.QuestionInfo.SelectMany(x => x.TableRowInfoList).Any(x => x.OtherMeasureData != null && x.OtherMeasureData != string.Empty)) + { + return null; + } + var rowInfo = inDto.QuestionInfo.SelectMany(x => x.TableRowInfoList).ToList(); + var tableQuestions = rowInfo.SelectMany(x => x.TableQuestionList).ToList(); + + var maxSuv = tableQuestions.Where(x => x.QuestionMark == QuestionMark.SUVmax).Select(x => x.Answer.IsNullOrEmptyReturn0()).MaxOrDefault(); + return maxSuv; + } + #endregion + + /// + /// 是否存在PET + /// + /// + /// + public async Task GetExistPET(ReadingCalculateDto inDto) + { + //var studyList = await this._subjectVisitService.GetReadingVisitStudyList(new Contracts.GetReadingVisitStudyListIndto() + //{ + // TrialId = inDto.TrialId, + // SujectVisitId = inDto.SubjectVisitId, + // VisitTaskId=inDto.VisitTaskId, + //}); + + var existPet=await _dicomStudyRepository.Where(x => x.TrialId == inDto.TrialId && x.SubjectVisitId == inDto.SubjectVisitId).AnyAsync(x => x.Modalities.Contains("PT")); + + return existPet ? ReadingYesOrNo.Yes.GetEnumInt() : ReadingYesOrNo.No.GetEnumInt(); + } + + #region 影像学整体肿瘤评估 + /// + /// 影像学整体肿瘤评估 + /// + /// + /// + public async Task GetImgOncology(ReadingCalculateDto inDto) + { + if (inDto.IsBaseLine) + { + return ImagingOverallAssessment_Lugano.NA.GetEnumInt(); + } + + //var imageQualityEvaluation = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.ImageQualityAssessment&&x.Answer.EqEnum(ImageQualityEvaluation.Abnormal)).FirstOrDefault(); + //if (imageQualityEvaluation != null) + //{ + // return ImagingOverallAssessment_Lugano.NE.GetEnumInt(); + //} + + // CTandMRI + var cTandMRIData = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.CTandMRI).Select(x => x.Answer).FirstOrDefault(); + + // FDGPET + var fDGPETData = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.FDGPET).Select(x => x.Answer).FirstOrDefault(); + + var baseLineTaskId = await GetBaseLineTaskId(inDto); + // lastFDGPET + var lastFDGPETData = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.LastFDGPET).Select(x => x.Answer).FirstOrDefault(); + + return CalculationGetImgOncology(cTandMRIData, fDGPETData, lastFDGPETData); + + } + + /// + /// 计算整体肿瘤评估 【测试】 + /// + /// CT/MRI总体评估 + /// FDG-PET总体评估 + /// 上一次 FDG-PET总体评估 + /// + public string CalculationGetImgOncology(string? cTandMRIData,string? fDGPETData,string? lastFDGPETData) + { + List data = new List() { + + //1、ND NE NE/NA ND + new CalculationDto(){ + Column1=ReadingCommon.EnumToString(new List() { CTMRIOverallAssessment.ND }), + Column2=ReadingCommon.EnumToString(new List() { FDGPETOverallAssessment.NE }), + Column3=ReadingCommon.EnumToString(new List() { FDGPETOverallAssessment.NE, FDGPETOverallAssessment.NA}), + Column4=ReadingCommon.EnumToString(new List() { ImagingOverallAssessment_Lugano.ND }), + }, + //2、ND/PD/CR/NE/PR/SD PMD PMD/CMR/PMR/NMR/NE/NA PMD/PD + new CalculationDto(){ + Column1=ReadingCommon.EnumToString(new List() { CTMRIOverallAssessment.ND, CTMRIOverallAssessment.PD,CTMRIOverallAssessment.CR,CTMRIOverallAssessment.NE,CTMRIOverallAssessment.PR,CTMRIOverallAssessment.SD}), + Column2=ReadingCommon.EnumToString(new List() { FDGPETOverallAssessment.PMD, }), + Column3=ReadingCommon.EnumToString(new List() {FDGPETOverallAssessment.PMD, FDGPETOverallAssessment.CMR,FDGPETOverallAssessment.PMR, FDGPETOverallAssessment.NMR, FDGPETOverallAssessment.NE, FDGPETOverallAssessment.NA }), + Column4=ReadingCommon.EnumToString(new List() { ImagingOverallAssessment_Lugano.PMDPD }), + }, + //3、ND/PD/CR/NE/PR/SD NE PMD PMD/PD + new CalculationDto(){ + Column1=ReadingCommon.EnumToString(new List() { CTMRIOverallAssessment.ND, CTMRIOverallAssessment.PD,CTMRIOverallAssessment.CR,CTMRIOverallAssessment.NE,CTMRIOverallAssessment.PR,CTMRIOverallAssessment.SD}), + Column2=ReadingCommon.EnumToString(new List() {FDGPETOverallAssessment.NE }), + Column3=ReadingCommon.EnumToString(new List() { FDGPETOverallAssessment.PMD, }), + Column4=ReadingCommon.EnumToString(new List() { ImagingOverallAssessment_Lugano.PMDPD }), + }, + //4、PD NE CMR/PMR/NMR/NE/NA PMD/PD + new CalculationDto(){ + Column1=ReadingCommon.EnumToString(new List() { CTMRIOverallAssessment.PD}), + Column2=ReadingCommon.EnumToString(new List() { FDGPETOverallAssessment.NE, }), + Column3=ReadingCommon.EnumToString(new List() { FDGPETOverallAssessment.CMR,FDGPETOverallAssessment.PMR, FDGPETOverallAssessment.NMR, FDGPETOverallAssessment.NE, FDGPETOverallAssessment.NA }), + Column4=ReadingCommon.EnumToString(new List() { ImagingOverallAssessment_Lugano.PMDPD }), + }, + //5、NE NE NE/NA NE + new CalculationDto(){ + Column1=ReadingCommon.EnumToString(new List() { CTMRIOverallAssessment.NE }), + Column2=ReadingCommon.EnumToString(new List() { FDGPETOverallAssessment.NE }), + Column3=ReadingCommon.EnumToString(new List() { FDGPETOverallAssessment.NE, FDGPETOverallAssessment.NA }), + Column4=ReadingCommon.EnumToString(new List() { ImagingOverallAssessment_Lugano.NE }), + }, + + //6、CR、PR、SD、NE、ND、PD CMR CMR/PMR/NMR/PMD/NE/NA CMR/CR + new CalculationDto(){ + Column1=ReadingCommon.EnumToString(new List() { CTMRIOverallAssessment.CR,CTMRIOverallAssessment.PR,CTMRIOverallAssessment.SD,CTMRIOverallAssessment.NE,CTMRIOverallAssessment.ND,CTMRIOverallAssessment.PD }), + Column2=ReadingCommon.EnumToString(new List() { FDGPETOverallAssessment.CMR }), + Column3=ReadingCommon.EnumToString(new List() { FDGPETOverallAssessment.CMR,FDGPETOverallAssessment.PMR, FDGPETOverallAssessment.NMR, FDGPETOverallAssessment.PMD, FDGPETOverallAssessment.NE, FDGPETOverallAssessment.NA }), + Column4=ReadingCommon.EnumToString(new List() { ImagingOverallAssessment_Lugano.CMRCR }), + }, + //7、CR NE NE/NA CMR/CR + new CalculationDto(){ + Column1=ReadingCommon.EnumToString(new List() { CTMRIOverallAssessment.CR }), + Column2=ReadingCommon.EnumToString(new List() { FDGPETOverallAssessment.NE }), + Column3=ReadingCommon.EnumToString(new List() { FDGPETOverallAssessment.NE, FDGPETOverallAssessment.NA,}), + Column4=ReadingCommon.EnumToString(new List() { ImagingOverallAssessment_Lugano.CMRCR }), + }, + + //8、CR、PR、SD、NE、ND NE CMR CMR/CR + new CalculationDto(){ + Column1=ReadingCommon.EnumToString(new List() { CTMRIOverallAssessment.CR,CTMRIOverallAssessment.PR,CTMRIOverallAssessment.SD,CTMRIOverallAssessment.NE,CTMRIOverallAssessment.ND }), + Column2=ReadingCommon.EnumToString(new List() { FDGPETOverallAssessment.NE }), + Column3=ReadingCommon.EnumToString(new List() { FDGPETOverallAssessment.CMR,}), + Column4=ReadingCommon.EnumToString(new List() { ImagingOverallAssessment_Lugano.CMRCR }), + }, + + + + + //9、ND/PD/CR/NE/PR/SD PMR PMD/CMR/PMR/NMR/NE PMR/PR + new CalculationDto(){ + Column1=ReadingCommon.EnumToString(new List() { CTMRIOverallAssessment.ND, CTMRIOverallAssessment.PD,CTMRIOverallAssessment.CR,CTMRIOverallAssessment.NE,CTMRIOverallAssessment.PR,CTMRIOverallAssessment.SD }), + Column2=ReadingCommon.EnumToString(new List() { FDGPETOverallAssessment.PMR }), + Column3=ReadingCommon.EnumToString(new List() { FDGPETOverallAssessment.PMD, FDGPETOverallAssessment.CMR,FDGPETOverallAssessment.PMR, FDGPETOverallAssessment.NMR, FDGPETOverallAssessment.NE,FDGPETOverallAssessment.NA, }), + Column4=ReadingCommon.EnumToString(new List() { ImagingOverallAssessment_Lugano.PMRPR }), + }, + //10、PR NE NE/NA PMR/PR + new CalculationDto(){ + Column1=ReadingCommon.EnumToString(new List() { CTMRIOverallAssessment.PR }), + Column2=ReadingCommon.EnumToString(new List() { FDGPETOverallAssessment.NE }), + Column3=ReadingCommon.EnumToString(new List() { FDGPETOverallAssessment.NE, FDGPETOverallAssessment.NA,}), + Column4=ReadingCommon.EnumToString(new List() { ImagingOverallAssessment_Lugano.PMRPR }), + }, + //11、CR/PR/SD/NE/ND NE PMR PMR/PR + new CalculationDto(){ + Column1=ReadingCommon.EnumToString(new List() { CTMRIOverallAssessment.CR,CTMRIOverallAssessment.PR,CTMRIOverallAssessment.SD,CTMRIOverallAssessment.NE,CTMRIOverallAssessment.ND }), + Column2=ReadingCommon.EnumToString(new List() { FDGPETOverallAssessment.NE }), + Column3=ReadingCommon.EnumToString(new List() { FDGPETOverallAssessment.PMR}), + Column4=ReadingCommon.EnumToString(new List() { ImagingOverallAssessment_Lugano.PMRPR }), + }, + //12、ND/PD/CR/NE/PR/SD NMR PMD/CMR/PMR/NMR/NE NMR/SD + new CalculationDto(){ + Column1=ReadingCommon.EnumToString(new List() { CTMRIOverallAssessment.ND,CTMRIOverallAssessment.PD,CTMRIOverallAssessment.CR,CTMRIOverallAssessment.NE,CTMRIOverallAssessment.PR,CTMRIOverallAssessment.SD }), + Column2=ReadingCommon.EnumToString(new List() { FDGPETOverallAssessment.NMR }), + Column3=ReadingCommon.EnumToString(new List() { FDGPETOverallAssessment.PMD, FDGPETOverallAssessment.CMR, FDGPETOverallAssessment.PMR, FDGPETOverallAssessment.NMR, FDGPETOverallAssessment.NE, FDGPETOverallAssessment.NA,}), + Column4=ReadingCommon.EnumToString(new List() { ImagingOverallAssessment_Lugano.NMRSD }), + }, + //13、CR/PR/SD/ND/NE NE NMR NMR/SD + new CalculationDto(){ + Column1=ReadingCommon.EnumToString(new List() { CTMRIOverallAssessment.CR, CTMRIOverallAssessment.PR, CTMRIOverallAssessment.SD, CTMRIOverallAssessment.ND, CTMRIOverallAssessment.NE }), + Column2=ReadingCommon.EnumToString(new List() { FDGPETOverallAssessment.NE }), + Column3=ReadingCommon.EnumToString(new List() { FDGPETOverallAssessment.NMR}), + Column4=ReadingCommon.EnumToString(new List() { ImagingOverallAssessment_Lugano.NMRSD }), + }, + //14、SD NE NE NMR/SD + new CalculationDto(){ + Column1=ReadingCommon.EnumToString(new List() { CTMRIOverallAssessment.SD }), + Column2=ReadingCommon.EnumToString(new List() { FDGPETOverallAssessment.NE }), + Column3=ReadingCommon.EnumToString(new List() { FDGPETOverallAssessment.NE, FDGPETOverallAssessment.NA,}), + Column4=ReadingCommon.EnumToString(new List() { ImagingOverallAssessment_Lugano.NMRSD }), + }, + }; + + var resultdata = data.Where(x => + (x.NotEq.Contains(1) ? !x.Column1.Contains(cTandMRIData) : x.Column1.Contains(cTandMRIData) || x.Column1.Count() == 0) && + (x.NotEq.Contains(2) ? !x.Column2.Contains(fDGPETData) : x.Column2.Contains(fDGPETData) || x.Column2.Count() == 0) && + (x.NotEq.Contains(3) ? !x.Column3.Contains(lastFDGPETData) : x.Column3.Contains(lastFDGPETData) || x.Column3.Count() == 0)) + .Select(x => x.Column4.FirstOrDefault()) + .FirstOrDefault(); + return resultdata ?? string.Empty; + } + + #endregion + + #region 获取基线脾脏长度 + /// + /// 获取基线脾脏长度 + /// + /// + /// + public async Task GetBaseLineSpleenLength(ReadingCalculateDto inDto) + { + var baseLineTaskId = await GetBaseLineTaskId(inDto); + + var baseLineSpleenLength = (await _readingTaskQuestionAnswerRepository.Where(x => x.VisitTaskId == baseLineTaskId && x.ReadingQuestionTrial.QuestionType == QuestionType.SpleenLength).Select(x => x.Answer).FirstOrDefaultAsync()).IsNullOrEmptyReturn0(); + return baseLineSpleenLength; + } + + + #endregion + + #region 与最低点相比脾脏垂直径长度的增加值 + /// + /// 与最低点相比脾脏垂直径长度的增加值 + /// + /// + /// + public async Task GetSplenoncusDiameterChange(ReadingCalculateDto inDto) + { + + if (inDto.IsBaseLine) + { + return "NA"; + } + + var baseLineTaskId = await GetBaseLineTaskId(inDto); + var presentSpleenLength = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.SpleenLength).Select(x => x.Answer).FirstOrDefault().IsNullOrEmptyReturn0(); + var baseLineSpleenLength = (await _readingTaskQuestionAnswerRepository.Where(x => x.VisitTaskId == baseLineTaskId && x.ReadingQuestionTrial.QuestionType == QuestionType.SpleenLength).Select(x => x.Answer).FirstOrDefaultAsync()).IsNullOrEmptyReturn0(); + + return (presentSpleenLength - baseLineSpleenLength).ToString(); + + + } + #endregion + + + #region 获取靶病灶评估 + /// + /// 获取靶病灶评估 + /// + /// + /// + public async Task GetTargetLesionEvaluate(ReadingCalculateDto inDto) + { + + + + var rowInfo = inDto.QuestionInfo.Where(x => x.LesionType == LesionType.TargetLesion).SelectMany(x => x.TableRowInfoList).ToList(); + if (inDto.IsBaseLine) + { + return TargetAssessment.NA.GetEnumInt(); + } + var tableQuestions = rowInfo.SelectMany(x => x.TableQuestionList).ToList(); + + TargetAssessment result = TargetAssessment.SD; + + //或者当前访视非淋巴结靶病灶全部消失; + //并且 2.当前访视淋巴结靶病灶的状态全部变为“消失”。 + + var eqCR = true; + //当前访视中,靶病灶的Σ PPD; + decimal spd = 0; + foreach (var item in rowInfo) + { + if (item.TableQuestionList.Any(x => x.QuestionMark == QuestionMark.IsLymph && x.Answer.EqEnum(YesOrNoOrNa.No))) + { + // 或者当前访视非淋巴结靶病灶全部消失; + eqCR = eqCR && item.TableQuestionList.Any(x => x.QuestionMark == QuestionMark.State && x.Answer.EqEnum(TargetState.Loss)); + } + spd += (item.TableQuestionList.Where(x => x.QuestionMark == QuestionMark.PPD).Select(x => x.Answer).FirstOrDefault()).IsNullOrEmptyReturn0(); + if (item.TableQuestionList.Any(x => x.QuestionMark == QuestionMark.IsLymph && x.Answer.EqEnum(YesOrNoOrNa.Yes))) + { + // 当前访视淋巴结靶病灶的状态全部变为“消失” + eqCR = eqCR && item.TableQuestionList.Any(x => x.QuestionMark == QuestionMark.State && (x.Answer.EqEnum(TargetState.Loss)|| x.Answer.EqEnum(TargetState.TooSmall))); + } + } + // 1、与基线相比SPD变化的百分比 ≥50%,; + var eqPR = false; + + if (inDto.IsBaseLine) + { + eqPR = false; + } + else + { + // 先找到基线的任务 + var baseLineTaskId = await _visitTaskRepository.Where(x => x.SubjectId == inDto.SubjectId && x.ReadingCategory == ReadingCategory.Visit + && x.TrialReadingCriterionId == inDto.TrialReadingCriterionId && + x.SourceSubjectVisit.IsBaseLine && x.TaskState == TaskState.Effect && + x.IsAnalysisCreate == inDto.IsAnalysisCreate + && x.DoctorUserId == inDto.DoctorUserId + && x.IsSelfAnalysis == inDto.IsSelfAnalysis && x.ArmEnum == inDto.ArmEnum) + .Select(x => x.Id).FirstOrDefaultAsync(); + + var baseLineSPD = (await _readingTaskQuestionAnswerRepository.Where(x => x.VisitTaskId == baseLineTaskId && x.ReadingQuestionTrial.QuestionType == QuestionType.SPD).Select(x => x.Answer).FirstOrDefaultAsync()).IsNullOrEmptyReturn0(); + var presentSPD = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.SPD).Select(x => x.Answer).FirstIsNullReturnEmpty().IsNullOrEmptyReturn0(); + + if (baseLineSPD > 0) + { + eqPR = (presentSPD - baseLineSPD) / baseLineSPD <=- 0.5m; + } + } + + + + //基线未选择靶病灶 + if (rowInfo.Count() == 0) + { + result = TargetAssessment.ND; + } + // 任一单个病灶进展即可 + else if (tableQuestions.Any(x => x.QuestionMark == QuestionMark.State && x.Answer.EqEnum(TargetState.DiseaseProgression))) + { + result = TargetAssessment.PD; + } + + //当前访视存在至少一个状态为“不可评估”的靶病灶。 + else if ( + tableQuestions.Any(x => x.QuestionMark == QuestionMark.State && x.Answer.EqEnum(TargetState.UnableEvaluate))) + { + result = TargetAssessment.NE; + } + //当前访视非淋巴结靶病灶全部消失 && (当前访视淋巴结靶病灶的状态全部变为“消失” 或者 "太小" ) + else if (eqCR) + { + result = TargetAssessment.CR; + } + // 与基线相比SPD变化的百分比 <=-50%,; + else if (eqPR) + { + result = TargetAssessment.PR; + } + + + return result.GetEnumInt(); + } + #endregion + + #region 获取非靶病灶评估 + + /// + /// 获取非靶病灶评估 + /// + /// + /// + public async Task GetNoTargetLesionEvaluate(ReadingCalculateDto inDto) + { + + NoTargetAssessment result = NoTargetAssessment.PD; + + if (inDto.IsBaseLine) + { + return NoTargetAssessment.NA.GetEnumInt(); + } + + var tableRows = inDto.QuestionInfo.Where(x => x.LesionType == LesionType.NonTargetLesions).SelectMany(x => x.TableRowInfoList).ToList(); + + var tableQuestions = tableRows.SelectMany(x => x.TableQuestionList).ToList(); + + //基线未选择非靶病灶 + if (tableQuestions.Count() == 0) + { + result = NoTargetAssessment.ND; + } + // 随访至少存在一个状态为“显著增大”的非靶病灶 + else if (tableQuestions.Any(x => x.QuestionMark == QuestionMark.State && x.Answer.EqEnum(NoTargetState.Increase))) + { + result = NoTargetAssessment.PD; + } + + // 随访存在至少一个状态为“不可评估”的非靶病灶 + else if (tableQuestions.Any(x => x.QuestionMark == QuestionMark.State && x.Answer.EqEnum(NoTargetState.UnableEvaluate))) + { + result = NoTargetAssessment.NE; + } + //所有单个病灶/病灶组状态评估状态为“消失” + else if (tableQuestions.Count(x => x.QuestionMark == QuestionMark.State && x.Answer.EqEnum(NoTargetState.Loss))== tableQuestions.Count(x=> x.QuestionMark == QuestionMark.State) && tableQuestions.Count(x => x.QuestionMark == QuestionMark.State)>0) + { + result = NoTargetAssessment.CR; + } + else + { + result = NoTargetAssessment.PRSD; + } + + return result.GetEnumInt(); + + } + + #endregion + + #region 获取新病灶评估 + /// + /// 获取新病灶评估 + /// + /// + /// + public async Task GetNewLesionEvaluate(ReadingCalculateDto inDto) + { + + NewLesionAssessment result = NewLesionAssessment.No; + if (inDto.IsBaseLine) + { + return NewLesionAssessment.NA.GetEnumInt(); + } + + var tableRows = inDto.QuestionInfo.Where(x => x.LesionType == LesionType.NewLesions).SelectMany(x => x.TableRowInfoList).ToList(); + + var tableQuestions = tableRows.SelectMany(x => x.TableQuestionList).ToList(); + + + + // 当前访视存在至少一个明确新病灶 + if (tableQuestions.Any(x => x.QuestionMark == QuestionMark.State && x.Answer.EqEnum(NewLesionState.Exist))) + { + result = NewLesionAssessment.Yes; + } + //只要有任何一个新病灶状态为“无法评估” + else if (tableQuestions.Any(x => x.QuestionMark == QuestionMark.State && x.Answer.EqEnum(NewLesionState.UnableEvaluate))) + { + result = NewLesionAssessment.NE; + } + //当前访视不存在明确新病灶且存在至少一个疑似新病灶 + else if (!tableQuestions.Any(x => x.QuestionMark == QuestionMark.State && x.Answer.EqEnum(NewLesionState.Exist)) && + tableQuestions.Any(x => x.QuestionMark == QuestionMark.State && x.Answer.EqEnum(NewLesionState.Suspected)) + ) + { + result = NewLesionAssessment.Suspected; + } + + + else + { + result = NewLesionAssessment.No; + } + return result.GetEnumInt(); + + } + #endregion + + + #region CTMRI 总体评估 + + /// + /// CTMRI 总体评估 + /// + /// + /// + public async Task CTMRIEvaluation(ReadingCalculateDto inDto) + { + if (inDto.IsBaseLine) + { + return CTMRIOverallAssessment.NA.GetEnumInt(); + } + // 靶病灶评估 + var targetEvaluation = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.TargetLesion).Select(x => x.Answer).FirstOrDefault(); + + // 非靶病灶评估 + var noTargetEvaluation = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.NoTargetLesion).Select(x => x.Answer).FirstOrDefault(); + + // 存在新病灶 + var existsNewTarget = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.NewLesionEvaluation).Select(x => x.Answer).FirstOrDefault(); + + // 肝脏评估 + var liverEvaluation = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.LiverAssessment).Select(x => x.Answer).FirstOrDefault(); + + // 脾脏评估 + var spleenEvaluation = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.SplenicEvaluation).Select(x => x.Answer).FirstOrDefault(); + + return CalculationCTMRIEvaluation(targetEvaluation, noTargetEvaluation, existsNewTarget, liverEvaluation, spleenEvaluation); + } + + /// + /// 计算CTMRI 总体评估 【测试】 + /// + /// 靶病灶评估 + /// 非靶病灶评估 + /// 存在新病灶 + /// 肝脏评估 + /// 脾脏评估 + /// + [HttpPost] + public string CalculationCTMRIEvaluation(string? targetEvaluation,string? noTargetEvaluation,string? existsNewTarget,string? liverEvaluation,string? spleenEvaluation) + { + List data = new List() { + + //ND ND 否/疑似 正常 正常 ND + new CalculationDto(){ + Column1=ReadingCommon.EnumToString(new List() { TargetAssessment.ND }), + Column2=ReadingCommon.EnumToString(new List() { NoTargetAssessment.ND }), + Column3=ReadingCommon.EnumToString(new List() { NewLesionAssessment.No, NewLesionAssessment.Suspected }), + Column4=ReadingCommon.EnumToString(new List() { LiverAssessment.Normal }), + Column5=ReadingCommon.EnumToString(new List() { SpleenAssessment.Normal }), + Column6=ReadingCommon.EnumToString(new List() { CTMRIOverallAssessment.ND }), + }, + + //PD 任一结果 任一结果 任一结果 任一结果 PD + new CalculationDto(){ + Column1=ReadingCommon.EnumToString(new List() { TargetAssessment.PD }), + Column2=ReadingCommon.EnumToString(new List() { }), + Column3=ReadingCommon.EnumToString(new List() { }), + Column4=ReadingCommon.EnumToString(new List() { }), + Column5=ReadingCommon.EnumToString(new List() { }), + Column6=ReadingCommon.EnumToString(new List() { CTMRIOverallAssessment.PD }), + }, + //任一结果 PD 任一结果 任一结果 任一结果 PD + new CalculationDto(){ + Column1=ReadingCommon.EnumToString(new List() { }), + Column2=ReadingCommon.EnumToString(new List() { NoTargetAssessment.PD }), + Column3=ReadingCommon.EnumToString(new List() {}), + Column4=ReadingCommon.EnumToString(new List() { }), + Column5=ReadingCommon.EnumToString(new List() { }), + Column6=ReadingCommon.EnumToString(new List() { CTMRIOverallAssessment.PD }), + }, + //任一结果 任一结果 是 任一结果 任一结果 PD + new CalculationDto(){ + Column1=ReadingCommon.EnumToString(new List() { }), + Column2=ReadingCommon.EnumToString(new List() { }), + Column3=ReadingCommon.EnumToString(new List() { NewLesionAssessment.Yes }), + Column4=ReadingCommon.EnumToString(new List() { }), + Column5=ReadingCommon.EnumToString(new List() { }), + Column6=ReadingCommon.EnumToString(new List() { CTMRIOverallAssessment.PD }), + }, + //任一结果 任一结果 任一结果 显著增大 任一结果 PD + new CalculationDto(){ + Column1=ReadingCommon.EnumToString(new List() { }), + Column2=ReadingCommon.EnumToString(new List() { }), + Column3=ReadingCommon.EnumToString(new List() { }), + Column4=ReadingCommon.EnumToString(new List() { LiverAssessment.Increase }), + Column5=ReadingCommon.EnumToString(new List() { }), + Column6=ReadingCommon.EnumToString(new List() { CTMRIOverallAssessment.PD }), + }, + //任一结果 任一结果 任一结果 任一结果 显著增大 PD + new CalculationDto(){ + Column1=ReadingCommon.EnumToString(new List() { }), + Column2=ReadingCommon.EnumToString(new List() { }), + Column3=ReadingCommon.EnumToString(new List() {}), + Column4=ReadingCommon.EnumToString(new List() { }), + Column5=ReadingCommon.EnumToString(new List() { SpleenAssessment.Increase }), + Column6=ReadingCommon.EnumToString(new List() { CTMRIOverallAssessment.PD }), + }, + //CR CR/ND 否 正常 正常 CR + new CalculationDto(){ + Column1=ReadingCommon.EnumToString(new List() { TargetAssessment.CR }), + Column2=ReadingCommon.EnumToString(new List() { NoTargetAssessment.CR, NoTargetAssessment.ND }), + Column3=ReadingCommon.EnumToString(new List() { NewLesionAssessment.No }), + Column4=ReadingCommon.EnumToString(new List() { LiverAssessment.Normal }), + Column5=ReadingCommon.EnumToString(new List() { SpleenAssessment.Normal }), + Column6=ReadingCommon.EnumToString(new List() { CTMRIOverallAssessment.CR }), + }, + //ND CR 否 正常 正常 CR + new CalculationDto(){ + Column1=ReadingCommon.EnumToString(new List() { TargetAssessment.ND }), + Column2=ReadingCommon.EnumToString(new List() { NoTargetAssessment.CR }), + Column3=ReadingCommon.EnumToString(new List() { NewLesionAssessment.No }), + Column4=ReadingCommon.EnumToString(new List() { LiverAssessment.Normal }), + Column5=ReadingCommon.EnumToString(new List() { SpleenAssessment.Normal }), + Column6=ReadingCommon.EnumToString(new List() { CTMRIOverallAssessment.CR }), + }, + //NE 非PD 否/疑似/无法评估 非显著增大 非显著增大 NE + new CalculationDto(){ + NotEq=new List(){ 2,4,5}, + Column1=ReadingCommon.EnumToString(new List() { TargetAssessment.NE }), + Column2=ReadingCommon.EnumToString(new List() { NoTargetAssessment.PD }), + Column3=ReadingCommon.EnumToString(new List() { NewLesionAssessment.No,NewLesionAssessment.Suspected, NewLesionAssessment.NE}), + Column4=ReadingCommon.EnumToString(new List() { LiverAssessment.Increase }), + Column5=ReadingCommon.EnumToString(new List() { SpleenAssessment.Increase }), + Column6=ReadingCommon.EnumToString(new List() { CTMRIOverallAssessment.NE }), + }, + //ND NE 否/疑似/无法评估(不为是) 正常/稳定/无法评估/部分缓解(非显著增大) 正常/稳定/无法评估/部分缓解(非显著增大) NE + new CalculationDto(){ + NotEq=new List(){ 3,4,5}, + Column1=ReadingCommon.EnumToString(new List() { TargetAssessment.ND }), + Column2=ReadingCommon.EnumToString(new List() { NoTargetAssessment.NE }), + Column3=ReadingCommon.EnumToString(new List() { NewLesionAssessment.Yes }), + Column4=ReadingCommon.EnumToString(new List() { LiverAssessment.Increase }), + Column5=ReadingCommon.EnumToString(new List() { SpleenAssessment.Increase }), + Column6=ReadingCommon.EnumToString(new List() { CTMRIOverallAssessment.NE }), + }, + //ND ND 无法评估 正常/稳定/无法评估/部分缓解(非显著增大) 正常/稳定/无法评估/部分缓解(非显著增大) NE + new CalculationDto(){ + NotEq=new List(){ 4,5}, + Column1=ReadingCommon.EnumToString(new List() { TargetAssessment.ND }), + Column2=ReadingCommon.EnumToString(new List() { NoTargetAssessment.ND }), + Column3=ReadingCommon.EnumToString(new List() { NewLesionAssessment.NE }), + Column4=ReadingCommon.EnumToString(new List() { LiverAssessment.Increase }), + Column5=ReadingCommon.EnumToString(new List() { SpleenAssessment.Increase }), + Column6=ReadingCommon.EnumToString(new List() { CTMRIOverallAssessment.NE }), + }, + //ND ND 否/疑似 无法评估 正常/稳定/无法评估/部分缓解(非显著增大) NE + new CalculationDto(){ + NotEq=new List(){ 5}, + Column1=ReadingCommon.EnumToString(new List() { TargetAssessment.ND }), + Column2=ReadingCommon.EnumToString(new List() { NoTargetAssessment.ND }), + Column3=ReadingCommon.EnumToString(new List() { NewLesionAssessment.No,NewLesionAssessment.Suspected }), + Column4=ReadingCommon.EnumToString(new List() { LiverAssessment.NotEvaluable }), + Column5=ReadingCommon.EnumToString(new List() { SpleenAssessment.Increase }), + Column6=ReadingCommon.EnumToString(new List() { CTMRIOverallAssessment.NE }), + }, + // ND ND 否/疑似 正常/稳定 NE NE + new CalculationDto(){ + Column1=ReadingCommon.EnumToString(new List() { TargetAssessment.ND }), + Column2=ReadingCommon.EnumToString(new List() { NoTargetAssessment.ND }), + Column3=ReadingCommon.EnumToString(new List() { NewLesionAssessment.No,NewLesionAssessment.Suspected }), + Column4=ReadingCommon.EnumToString(new List() { LiverAssessment.Normal,LiverAssessment.Stabilization }), + Column5=ReadingCommon.EnumToString(new List() { SpleenAssessment.NotEvaluable }), + Column6=ReadingCommon.EnumToString(new List() { CTMRIOverallAssessment.NE }), + }, + //1 PR CR或PR/SD或NE或ND 否/疑似/无法评估NE 正常/稳定/NE 正常/部分缓解/稳定/NE PR + new CalculationDto(){ + Column1=ReadingCommon.EnumToString(new List() { TargetAssessment.PR }), + Column2=ReadingCommon.EnumToString(new List() { NoTargetAssessment.CR,NoTargetAssessment.PRSD,NoTargetAssessment.NE,NoTargetAssessment.ND }), + Column3=ReadingCommon.EnumToString(new List() { NewLesionAssessment.No,NewLesionAssessment.Suspected,NewLesionAssessment.NE }), + Column4=ReadingCommon.EnumToString(new List() { LiverAssessment.Normal,LiverAssessment.Stabilization,LiverAssessment.NotEvaluable}), + Column5=ReadingCommon.EnumToString(new List() { SpleenAssessment.Normal,SpleenAssessment.Remission,SpleenAssessment.Stabilization,SpleenAssessment.NotEvaluable }), + Column6=ReadingCommon.EnumToString(new List() { CTMRIOverallAssessment.PR }), + }, + //2 CR (PR/SD)或者NE 否/疑似/无法评估 正常/稳定/NE 正常/部分缓解/稳定/NE PR + new CalculationDto(){ + Column1=ReadingCommon.EnumToString(new List() { TargetAssessment.CR }), + Column2=ReadingCommon.EnumToString(new List() { NoTargetAssessment.PRSD,NoTargetAssessment.NE }), + Column3=ReadingCommon.EnumToString(new List() { NewLesionAssessment.No,NewLesionAssessment.Suspected ,NewLesionAssessment.NE}), + Column4=ReadingCommon.EnumToString(new List() { LiverAssessment.Normal,LiverAssessment.Stabilization,LiverAssessment.NotEvaluable}), + Column5=ReadingCommon.EnumToString(new List() { SpleenAssessment.Normal,SpleenAssessment.Remission ,SpleenAssessment.Stabilization,SpleenAssessment.NotEvaluable}), + Column6=ReadingCommon.EnumToString(new List() { CTMRIOverallAssessment.PR }), + }, + //3 CR CR/ND 疑似/无法评估 正常/稳定/NE 正常/部分缓解/稳定/NE PR + new CalculationDto(){ + Column1=ReadingCommon.EnumToString(new List() { TargetAssessment.CR }), + Column2=ReadingCommon.EnumToString(new List() { NoTargetAssessment.CR,NoTargetAssessment.ND }), + Column3=ReadingCommon.EnumToString(new List() { NewLesionAssessment.Suspected, NewLesionAssessment.NE }), + Column4=ReadingCommon.EnumToString(new List() { LiverAssessment.Normal,LiverAssessment.Stabilization,LiverAssessment.NotEvaluable}), + Column5=ReadingCommon.EnumToString(new List() { SpleenAssessment.Normal,SpleenAssessment.Remission ,SpleenAssessment.Stabilization,SpleenAssessment.NotEvaluable }), + Column6=ReadingCommon.EnumToString(new List() { CTMRIOverallAssessment.PR }), + }, + //4 CR CR/ND 否 稳定/NE 正常/部分缓解/稳定/NE PR + new CalculationDto(){ + Column1=ReadingCommon.EnumToString(new List() { TargetAssessment.CR }), + Column2=ReadingCommon.EnumToString(new List() { NoTargetAssessment.CR,NoTargetAssessment.ND }), + Column3=ReadingCommon.EnumToString(new List() { NewLesionAssessment.No }), + Column4=ReadingCommon.EnumToString(new List() {LiverAssessment.Stabilization,LiverAssessment.NotEvaluable}), + Column5=ReadingCommon.EnumToString(new List() { SpleenAssessment.Normal,SpleenAssessment.Remission ,SpleenAssessment.Stabilization,SpleenAssessment.NotEvaluable }), + Column6=ReadingCommon.EnumToString(new List() { CTMRIOverallAssessment.PR }), + }, + //5 CR CR/ND 否 正常 部分缓解/稳定/NE PR + new CalculationDto(){ + Column1=ReadingCommon.EnumToString(new List() { TargetAssessment.CR }), + Column2=ReadingCommon.EnumToString(new List() { NoTargetAssessment.CR,NoTargetAssessment.ND }), + Column3=ReadingCommon.EnumToString(new List() { NewLesionAssessment.No }), + Column4=ReadingCommon.EnumToString(new List() {LiverAssessment.Normal}), + Column5=ReadingCommon.EnumToString(new List() { SpleenAssessment.Remission ,SpleenAssessment.Stabilization,SpleenAssessment.NotEvaluable }), + Column6=ReadingCommon.EnumToString(new List() { CTMRIOverallAssessment.PR }), + }, + // 6 ND CR 疑似/无法评估 正常/稳定/NE 正常/部分缓解/稳定/NE PR + new CalculationDto(){ + Column1=ReadingCommon.EnumToString(new List() { TargetAssessment.ND }), + Column2=ReadingCommon.EnumToString(new List() { NoTargetAssessment.CR }), + Column3=ReadingCommon.EnumToString(new List() { NewLesionAssessment.Suspected, NewLesionAssessment.NE }), + Column4=ReadingCommon.EnumToString(new List() { LiverAssessment.Normal,LiverAssessment.Stabilization,LiverAssessment.NotEvaluable}), + Column5=ReadingCommon.EnumToString(new List() { SpleenAssessment.Normal,SpleenAssessment.Remission,SpleenAssessment.Stabilization,SpleenAssessment.NotEvaluable }), + Column6=ReadingCommon.EnumToString(new List() { CTMRIOverallAssessment.PR }), + }, + // 7 ND CR 否 稳定/NE 正常/部分缓解/稳定/NE PR + new CalculationDto(){ + Column1=ReadingCommon.EnumToString(new List() { TargetAssessment.ND }), + Column2=ReadingCommon.EnumToString(new List() { NoTargetAssessment.CR }), + Column3=ReadingCommon.EnumToString(new List() { NewLesionAssessment.No }), + Column4=ReadingCommon.EnumToString(new List() {LiverAssessment.Stabilization,LiverAssessment.NotEvaluable}), + Column5=ReadingCommon.EnumToString(new List() { SpleenAssessment.Normal,SpleenAssessment.Remission,SpleenAssessment.Stabilization,SpleenAssessment.NotEvaluable }), + Column6=ReadingCommon.EnumToString(new List() { CTMRIOverallAssessment.PR }), + }, + // 8 ND CR 否 正常 部分缓解/稳定/NE PR + new CalculationDto(){ + Column1=ReadingCommon.EnumToString(new List() { TargetAssessment.ND }), + Column2=ReadingCommon.EnumToString(new List() { NoTargetAssessment.CR }), + Column3=ReadingCommon.EnumToString(new List() { NewLesionAssessment.No }), + Column4=ReadingCommon.EnumToString(new List() {LiverAssessment.Normal}), + Column5=ReadingCommon.EnumToString(new List() { SpleenAssessment.Remission,SpleenAssessment.Stabilization,SpleenAssessment.NotEvaluable }), + Column6=ReadingCommon.EnumToString(new List() { CTMRIOverallAssessment.PR }), + }, + new CalculationDto(){ + Column1=ReadingCommon.EnumToString(new List() { }), + Column2=ReadingCommon.EnumToString(new List() { }), + Column3=ReadingCommon.EnumToString(new List() { }), + Column4=ReadingCommon.EnumToString(new List() { }), + Column5=ReadingCommon.EnumToString(new List() { }), + Column6=ReadingCommon.EnumToString(new List() { CTMRIOverallAssessment.SD }), + }, + }; + + var index = data.FindIndex(x => + (x.NotEq.Contains(1) ? !x.Column1.Contains(targetEvaluation) : x.Column1.Contains(targetEvaluation) || x.Column1.Count() == 0) && + (x.NotEq.Contains(2) ? !x.Column2.Contains(noTargetEvaluation) : x.Column2.Contains(noTargetEvaluation) || x.Column2.Count() == 0) && + (x.NotEq.Contains(3) ? !x.Column3.Contains(existsNewTarget) : x.Column3.Contains(existsNewTarget) || x.Column3.Count() == 0) && + (x.NotEq.Contains(4) ? !x.Column4.Contains(liverEvaluation) : x.Column4.Contains(liverEvaluation) || x.Column4.Count() == 0) && + (x.NotEq.Contains(5) ? !x.Column5.Contains(spleenEvaluation) : x.Column5.Contains(spleenEvaluation) || x.Column5.Count() == 0)) + ; + var result = data.Where(x => + (x.NotEq.Contains(1) ? !x.Column1.Contains(targetEvaluation) : x.Column1.Contains(targetEvaluation) || x.Column1.Count() == 0) && + (x.NotEq.Contains(2) ? !x.Column2.Contains(noTargetEvaluation) : x.Column2.Contains(noTargetEvaluation) || x.Column2.Count() == 0) && + (x.NotEq.Contains(3) ? !x.Column3.Contains(existsNewTarget) : x.Column3.Contains(existsNewTarget) || x.Column3.Count() == 0) && + (x.NotEq.Contains(4) ? !x.Column4.Contains(liverEvaluation) : x.Column4.Contains(liverEvaluation) || x.Column4.Count() == 0) && + (x.NotEq.Contains(5) ? !x.Column5.Contains(spleenEvaluation) : x.Column5.Contains(spleenEvaluation) || x.Column5.Count() == 0)) + .Select(x => x.Column6.FirstOrDefault()) + .FirstOrDefault(); + return result ?? string.Empty; + } + + #endregion + + /// + /// 保留小数 + /// + /// + /// + /// + public string ReserveDecimal (decimal answer, int digitPlaces) + { + return decimal.Round(answer, digitPlaces).ToString(); + } + + #region 脾脏评估 + + ///// + ///// 获取脾脏评估 + ///// + ///// + ///// + //public async Task GetSplenicEvaluation(ReadingCalculateDto inDto) + //{ + + //} + #endregion + + #endregion + + } + +} From f524aa5e5763d28b58c4d9660e5e5b20e81253aa Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Thu, 27 Jun 2024 13:18:41 +0800 Subject: [PATCH 015/251] =?UTF-8?q?=E5=8F=91=E5=B8=83=E6=B5=8B=E8=AF=95?= =?UTF-8?q?=E7=8E=AF=E5=A2=83=E5=AF=B9=E6=8E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.API/appsettings.Test_IRC.json | 2 -- 1 file changed, 2 deletions(-) diff --git a/IRaCIS.Core.API/appsettings.Test_IRC.json b/IRaCIS.Core.API/appsettings.Test_IRC.json index 59668cfce..44e6a76ad 100644 --- a/IRaCIS.Core.API/appsettings.Test_IRC.json +++ b/IRaCIS.Core.API/appsettings.Test_IRC.json @@ -71,9 +71,7 @@ "FromEmail": "test@extimaging.com", "FromName": "Test_IRC", "AuthorizationCode": "SHzyyl2021", - "SiteUrl": "http://irc.test.extimaging.com/login", - "CompanyName": "Extensive Imaging", "CompanyNameCN": "上海展影医疗科技有限公司", "CompanyShortName": "Extensive Imaging", From ba8f22f26090c740f2a130c984e134e84b33795b Mon Sep 17 00:00:00 2001 From: he <109787524@qq.com> Date: Thu, 27 Jun 2024 14:21:32 +0800 Subject: [PATCH 016/251] =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Reading/Dto/ReadingMedicalReviewDto.cs | 22 ++++++++++- .../ReadingMedicalReviewService.cs | 39 +++++++++++++++++-- 2 files changed, 56 insertions(+), 5 deletions(-) diff --git a/IRaCIS.Core.Application/Service/Reading/Dto/ReadingMedicalReviewDto.cs b/IRaCIS.Core.Application/Service/Reading/Dto/ReadingMedicalReviewDto.cs index c63e757d2..0e56ef61a 100644 --- a/IRaCIS.Core.Application/Service/Reading/Dto/ReadingMedicalReviewDto.cs +++ b/IRaCIS.Core.Application/Service/Reading/Dto/ReadingMedicalReviewDto.cs @@ -32,7 +32,19 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto public bool IsApplyHeavyReading { get; set; } = false; } - public class GetIRMedicalFeedbackListInDto:PageInput + public class GetNextIRMedicalFeedbackInDto + { + /// + /// 项目Id + /// + [NotDefault] + public Guid TrialId { get; set; } + + public Guid? TrialReadingCriterionId { get; set; } + } + + + public class GetIRMedicalFeedbackListInDto:PageInput { /// /// 项目Id @@ -78,7 +90,13 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto public bool? IsInvalid { get; set; } public Guid? TrialReadingCriterionId { get; set; } - } + + /// + /// 获取不加急的 + /// + public bool IsNotHaveSigned { get; set; } = false; + + } public class GetIRMedicalFeedbackListOutDto { diff --git a/IRaCIS.Core.Application/Service/Reading/MedicalAudit/ReadingMedicalReviewService.cs b/IRaCIS.Core.Application/Service/Reading/MedicalAudit/ReadingMedicalReviewService.cs index b59c45897..a624d586c 100644 --- a/IRaCIS.Core.Application/Service/Reading/MedicalAudit/ReadingMedicalReviewService.cs +++ b/IRaCIS.Core.Application/Service/Reading/MedicalAudit/ReadingMedicalReviewService.cs @@ -780,13 +780,45 @@ namespace IRaCIS.Core.Application.Service return ResponseOutput.Result(result); } - /// - /// 获取IR医学审核信息 + /// 获取下一个IR医学反馈 /// /// /// + /// [HttpPost] + public async Task GetNextIRMedicalFeedback(GetNextIRMedicalFeedbackInDto inDto) + { + var list = await GetIRMedicalFeedbackList(new GetIRMedicalFeedbackListInDto() + { + TrialId=inDto.TrialId, + IsNotHaveSigned=true, + TrialReadingCriterionId=inDto.TrialReadingCriterionId, + PageIndex=1, + PageSize=1, + }); + + if (list.CurrentPageData.Count() > 0) + { + return list.CurrentPageData[0]; + } + else + { + throw new BusinessValidationFailedException(_localizer["MedicalReview_IRFinish"], ApiResponseCodeEnum.CloseCurrentWindows); + } + + + + + + } + + /// + /// 获取IR医学审核信息 + /// + /// + /// + [HttpPost] public async Task> GetIRMedicalFeedbackList(GetIRMedicalFeedbackListInDto inDto) { var taskMedicalReviewquery = _taskMedicalReviewRepository.Where(x => x.TrialId == inDto.TrialId).Include(x => x.VisitTask) @@ -795,7 +827,8 @@ namespace IRaCIS.Core.Application.Service .WhereIf(!inDto.TaskBlindName.IsNullOrEmpty(), x => x.VisitTask.TaskBlindName == inDto.TaskBlindName) .WhereIf(inDto.IsUrgent != null, x => x.VisitTask.IsUrgent == inDto.IsUrgent!) .WhereIf(inDto.AuditState != null, x => x.AuditState == inDto.AuditState!) - .WhereIf(inDto.ReadingCategory != null, x => x.VisitTask.ReadingCategory == inDto.ReadingCategory!) + .WhereIf(inDto.IsNotHaveSigned, x => x.AuditState != MedicalReviewAuditState.HaveSigned) + .WhereIf(inDto.ReadingCategory != null, x => x.VisitTask.ReadingCategory == inDto.ReadingCategory!) .WhereIf(inDto.AuditAdviceEnum != null, x => x.AuditAdviceEnum == inDto.AuditAdviceEnum!) .WhereIf(inDto.DoctorUserIdeaEnum != null, x => x.DoctorUserIdeaEnum == inDto.DoctorUserIdeaEnum!) .WhereIf(inDto.IsClosedDialog != null, x => x.IsClosedDialog == inDto.IsClosedDialog!) From 27d9104607416fc14b80f2dc391d44319e072e32 Mon Sep 17 00:00:00 2001 From: he <109787524@qq.com> Date: Thu, 27 Jun 2024 14:25:20 +0800 Subject: [PATCH 017/251] =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Reading/Dto/ReadingMedicalReviewDto.cs | 9 ++++++-- .../ReadingMedicalReviewService.cs | 22 ++++++++++++++++--- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/IRaCIS.Core.Application/Service/Reading/Dto/ReadingMedicalReviewDto.cs b/IRaCIS.Core.Application/Service/Reading/Dto/ReadingMedicalReviewDto.cs index 0e56ef61a..b89ece8e1 100644 --- a/IRaCIS.Core.Application/Service/Reading/Dto/ReadingMedicalReviewDto.cs +++ b/IRaCIS.Core.Application/Service/Reading/Dto/ReadingMedicalReviewDto.cs @@ -40,7 +40,9 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto [NotDefault] public Guid TrialId { get; set; } - public Guid? TrialReadingCriterionId { get; set; } + public Guid TrialReadingCriterionId { get; set; } + + public Guid SubjectId { get; set; } } @@ -55,7 +57,10 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto public bool? IsUrgent { get; set; } - public MedicalReviewAuditState? AuditState { get; set; } + public Guid? SubjectId { get; set; } + + + public MedicalReviewAuditState? AuditState { get; set; } public string SubjectCode { get; set; } = string.Empty; diff --git a/IRaCIS.Core.Application/Service/Reading/MedicalAudit/ReadingMedicalReviewService.cs b/IRaCIS.Core.Application/Service/Reading/MedicalAudit/ReadingMedicalReviewService.cs index a624d586c..3a16532c3 100644 --- a/IRaCIS.Core.Application/Service/Reading/MedicalAudit/ReadingMedicalReviewService.cs +++ b/IRaCIS.Core.Application/Service/Reading/MedicalAudit/ReadingMedicalReviewService.cs @@ -792,13 +792,28 @@ namespace IRaCIS.Core.Application.Service var list = await GetIRMedicalFeedbackList(new GetIRMedicalFeedbackListInDto() { TrialId=inDto.TrialId, - IsNotHaveSigned=true, + AuditState= MedicalReviewAuditState.Auditing, TrialReadingCriterionId=inDto.TrialReadingCriterionId, + SubjectId=inDto.SubjectId, PageIndex=1, PageSize=1, }); - if (list.CurrentPageData.Count() > 0) + + if (list.CurrentPageData.Count() == 0) + { + list = await GetIRMedicalFeedbackList(new GetIRMedicalFeedbackListInDto() + { + TrialId = inDto.TrialId, + AuditState = MedicalReviewAuditState.Auditing, + TrialReadingCriterionId = inDto.TrialReadingCriterionId, + PageIndex = 1, + PageSize = 1, + }); + } + + + if (list.CurrentPageData.Count() > 0) { return list.CurrentPageData[0]; } @@ -825,7 +840,8 @@ namespace IRaCIS.Core.Application.Service .Where(x => x.VisitTask.DoctorUserId == _userInfo.Id) .Where(x => x.IsHaveQuestion) .WhereIf(!inDto.TaskBlindName.IsNullOrEmpty(), x => x.VisitTask.TaskBlindName == inDto.TaskBlindName) - .WhereIf(inDto.IsUrgent != null, x => x.VisitTask.IsUrgent == inDto.IsUrgent!) + .WhereIf(inDto.SubjectId != null, x => x.VisitTask.SubjectId == inDto.SubjectId!) + .WhereIf(inDto.IsUrgent != null, x => x.VisitTask.IsUrgent == inDto.IsUrgent!) .WhereIf(inDto.AuditState != null, x => x.AuditState == inDto.AuditState!) .WhereIf(inDto.IsNotHaveSigned, x => x.AuditState != MedicalReviewAuditState.HaveSigned) .WhereIf(inDto.ReadingCategory != null, x => x.VisitTask.ReadingCategory == inDto.ReadingCategory!) From 4a314f207087ab52d3e1776fa7b0e29ea3f770a3 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Thu, 27 Jun 2024 14:34:09 +0800 Subject: [PATCH 018/251] =?UTF-8?q?=E4=BF=AE=E6=94=B9BM=20=E7=BB=9F?= =?UTF-8?q?=E8=AE=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Service/TrialSiteUser/PersonalWorkstation.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/IRaCIS.Core.Application/Service/TrialSiteUser/PersonalWorkstation.cs b/IRaCIS.Core.Application/Service/TrialSiteUser/PersonalWorkstation.cs index 2159ae68e..ae62d3db5 100644 --- a/IRaCIS.Core.Application/Service/TrialSiteUser/PersonalWorkstation.cs +++ b/IRaCIS.Core.Application/Service/TrialSiteUser/PersonalWorkstation.cs @@ -880,7 +880,7 @@ namespace IRaCIS.Core.Application // 前序 不存在 未一致性核查未通过的 .Where(t => !t.Subject.SubjectVisitList.Any(sv => sv.CheckState != CheckStateEnum.CVPassed && t.VisitTaskNum > sv.VisitNum)) //前序 不存在 未生成任务的访视 - .Where(t => c.IsAutoCreate ? !t.Subject.SubjectCriteriaEvaluationVisitFilterList.Where(d => d.TrialReadingCriterionId == t.TrialReadingCriterionId).Any(f => f.IsGeneratedTask == false && t.VisitTaskNum > f.SubjectVisit.VisitNum) : true) + .Where(t => c.IsAutoCreate == false ? !t.Subject.SubjectCriteriaEvaluationVisitFilterList.Where(d => d.TrialReadingCriterionId == t.TrialReadingCriterionId).Any(f => f.IsGeneratedTask == false && t.VisitTaskNum > f.SubjectVisit.VisitNum) : true) .Where(y => y.IsFrontTaskNeedSignButNotSign == false && (y.IsNeedClinicalDataSign == false || y.IsClinicalDataSign == true)) .Count(t => t.IsUrgent), @@ -891,7 +891,7 @@ namespace IRaCIS.Core.Application .Where(t => !t.Subject.SubjectVisitList.Any(sv => sv.CheckState != CheckStateEnum.CVPassed && t.VisitTaskNum > sv.VisitNum)) //前序 不存在 未生成任务的访视 //.WhereIf(g.Key.IsAutoCreate == false, t => !t.Subject.SubjectCriteriaEvaluationVisitFilterList.Where(d => d.TrialReadingCriterionId == t.TrialReadingCriterionId).Any(f => f.IsGeneratedTask == false && t.VisitTaskNum > f.SubjectVisit.VisitNum)) - .Where(t => c.IsAutoCreate ? !t.Subject.SubjectCriteriaEvaluationVisitFilterList.Where(d => d.TrialReadingCriterionId == t.TrialReadingCriterionId).Any(f => f.IsGeneratedTask == false && t.VisitTaskNum > f.SubjectVisit.VisitNum) : true) + .Where(t => c.IsAutoCreate==false ? !t.Subject.SubjectCriteriaEvaluationVisitFilterList.Where(d => d.TrialReadingCriterionId == t.TrialReadingCriterionId).Any(f => f.IsGeneratedTask == false && t.VisitTaskNum > f.SubjectVisit.VisitNum) : true) .Where(y => y.IsFrontTaskNeedSignButNotSign == false && (y.IsNeedClinicalDataSign == false || y.IsClinicalDataSign == true)) .Count(), From a91a706e0bd79eb72f4f9fa1b8a1505282547fb7 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Thu, 27 Jun 2024 15:17:32 +0800 Subject: [PATCH 019/251] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E5=BA=93=E6=A8=A1=E5=9E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.Domain/Common/PublishLog.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/IRaCIS.Core.Domain/Common/PublishLog.cs b/IRaCIS.Core.Domain/Common/PublishLog.cs index 0a58ed3a3..a93c7f9a5 100644 --- a/IRaCIS.Core.Domain/Common/PublishLog.cs +++ b/IRaCIS.Core.Domain/Common/PublishLog.cs @@ -21,8 +21,6 @@ namespace IRaCIS.Core.Domain.Models [Required] public string Version { get; set; } - - [Required] public DateTime? PublishTime { get; set; } From c7935ee90f72b124b077855fb961694b07cda025 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Thu, 27 Jun 2024 15:25:48 +0800 Subject: [PATCH 020/251] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E9=99=90=E5=88=B6?= =?UTF-8?q?=E5=BD=93=E5=89=8D=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../IRaCIS.Core.Application.xml | 546 ++++++++++++++++++ .../Service/Common/PublishLogService.cs | 9 +- 2 files changed, 554 insertions(+), 1 deletion(-) diff --git a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml index fda29c5ae..21496c38d 100644 --- a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml +++ b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml @@ -2316,6 +2316,534 @@ + + + 获取阅片的计算数据 + + + + + + + 获取Sod的值 + + + + + 基线任务Id + + + + + 影像是否无法融合 + + + + + 删除病灶获取起始病灶序号(RECIST1Point1 固定是1) + + + + + + 获取阅片报告 + + + + + + + 获取是否是最大suvmax 病灶 + + + + + + + 获取是否可选择不能融合影像 + + + + + + + 测试计算 + + + + + + + + 获取最低PDD信息 + + + + + + + 计算任务 + + + + + + + 获取报告验证的信息(这里每个标准可能不一样 返回用object) + + + + + + + 自动计算 + + + + + + + + 获取影像是否无法融合 + + + + + + + 获取报告整体整体评估 + + + + + + + 获取报告是否存在疾病 + + + + + + + 验证访视提交 + + + + + + + 计算融合靶病灶的状态 + + + + + + + 计算分裂靶病灶状态 + + + + + + + 获取分裂病灶的PPd之和 不包括当前的主病灶 + + + + + + 将上一次的访视病灶添加到这一次 + + + + + + + 获取SOD + + + 靶病灶径线之和(SOD) + 非淋巴结的长径 和淋巴结的短径 + + + + + + 非淋巴结靶病灶长径之和 + + + + + + + 与基线SOD相比变化量(mm) + + + + + + + 与基线访视相比SOD变化百分比 + + + + + + + 与整个访视期间SOD最低点相比增加的值(mm) + + + + 要更新之前的 + + + + + + 与整个访视期间SOD最低点相比增加的百分比 + + + + 要更新之前的 + + + + + + 整个访视期间SOD最低点访视名称 + + + + 要更新之前的 + + + + + + 是否存在非淋巴结靶病灶 + + + + + + + 是否存在淋巴结靶病灶且该病灶比上一访视短径增加5MM以上 + + + + + + + 获取存在淋巴结靶病灶且该病灶比上一访视短径增加5MM以上的病灶 + + + + + + + 被评估为NE的单个靶病灶 + + + + + + + 整体肿瘤评估 + + + + + + + 是否存在疾病 + + + + + + + 修改最低方式点名称 + + + + + + + 修改所有访视任务的答案 + + + + + + + + + 获取基线任务的Id + + + + + + + 获取基线SOD + + + + + + + 获取最低方式 + + + + + + + 获取访视任务信息 + + + + + + + 获取上一个访视任务Id + + + + + + 获取SPD + + + + + + + 获取脾脏垂直径 + + + + + + + 与基线相比SPD变化的百分比 + + + + + + + 与基线相比脾肿大增加的百分比 + [(当前垂直径-130)-(基线垂直径-130)]/(基线垂直径-130) + + + + + + + 与最低点相比脾脏垂直径长度的增加值 + + + + + + + 脾肿垂直径最低点访视 + + + + + + + 获取脾脏状态 + + + + + + + + 获取最低垂直径 + + + + + + 获取脾脏验证 + + + + + + + 获取脾脏状态 + + + + + + + 获取脾脏评估 + + + + + + + 获取PET5PS评分 + + + + + + + 获取PET5PS评分备注 + + + + + + + 与基线相比摄取值变化 + + + + + + + 获取上一次FDGPET 评估 + + + + + + + FDG-PET总体评估结果 + + + + + + + 计算FDG-PET总体评估结果【测试】 + + PET5PS评分 + 与基线相比摄取值变化 + 骨髓中是否存在局灶性 FDG亲和病灶的证据 + + + + + 骨髓中是否存在局灶性 FDG亲和病灶的证据 + + + + + + + 获取肝脏评估 + + + + + + + SuvMax所在病灶 + + + + + + + 最大sum + + + + + + + 是否存在PET + + + + + + + 影像学整体肿瘤评估 + + + + + + + 计算整体肿瘤评估 【测试】 + + CT/MRI总体评估 + FDG-PET总体评估 + 上一次 FDG-PET总体评估 + + + + + 获取基线脾脏长度 + + + + + + + 与最低点相比脾脏垂直径长度的增加值 + + + + + + + 获取靶病灶评估 + + + + + + + 获取非靶病灶评估 + + + + + + + 获取新病灶评估 + + + + + + + CTMRI 总体评估 + + + + + + + 计算CTMRI 总体评估 【测试】 + + 靶病灶评估 + 非靶病灶评估 + 存在新病灶 + 肝脏评估 + 脾脏评估 + + + + + 保留小数 + + + + + 获取阅片的计算数据 @@ -6384,6 +6912,11 @@ 是否申请重阅 + + + 项目Id + + 项目Id @@ -6419,6 +6952,11 @@ 无效的 为True无效 + + + 获取不加急的 + + 医学审核对话关闭原因 @@ -8699,6 +9237,14 @@ + + + 获取下一个IR医学反馈 + + + + + 获取IR医学审核信息 diff --git a/IRaCIS.Core.Application/Service/Common/PublishLogService.cs b/IRaCIS.Core.Application/Service/Common/PublishLogService.cs index 213c0b90a..da799e220 100644 --- a/IRaCIS.Core.Application/Service/Common/PublishLogService.cs +++ b/IRaCIS.Core.Application/Service/Common/PublishLogService.cs @@ -60,9 +60,16 @@ namespace IRaCIS.Core.Application.Service VerifyMsg = "发布编号不能重复" }; + var verifyExp2 = new EntityVerifyExp() + { + VerifyExp = u => u.IsCurrentVersion == addOrEditPublishLog.IsCurrentVersion, + VerifyMsg = "当前发布版本只允许有一个", - var entity = await _publishLogRepository.InsertOrUpdateAsync(addOrEditPublishLog, true, verifyExp1); + IsVerify=addOrEditPublishLog.IsCurrentVersion==true + }; + + var entity = await _publishLogRepository.InsertOrUpdateAsync(addOrEditPublishLog, true, verifyExp1, verifyExp2); return ResponseOutput.Ok(entity.Id.ToString()); From 4922ffa5c32b78eb73a35527aad87993d04f0fe9 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Thu, 27 Jun 2024 15:31:03 +0800 Subject: [PATCH 021/251] =?UTF-8?q?=E5=9B=BD=E9=99=85=E5=8C=96=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=20=E7=89=88=E6=9C=AC=E5=AD=97=E6=AE=B5=E5=B1=95?= =?UTF-8?q?=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Service/Common/DTO/InternationalizationViewModel.cs | 3 +++ IRaCIS.Core.Application/Service/Common/_MapConfig.cs | 3 ++- IRaCIS.Core.Domain/Common/Internationalization.cs | 3 +++ 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/IRaCIS.Core.Application/Service/Common/DTO/InternationalizationViewModel.cs b/IRaCIS.Core.Application/Service/Common/DTO/InternationalizationViewModel.cs index 8aa5e7e0c..2ad2de83c 100644 --- a/IRaCIS.Core.Application/Service/Common/DTO/InternationalizationViewModel.cs +++ b/IRaCIS.Core.Application/Service/Common/DTO/InternationalizationViewModel.cs @@ -17,6 +17,9 @@ namespace IRaCIS.Core.Application.ViewModel public DateTime UpdateTime { get; set; } public Guid UpdateUserId { get; set; } + + public string Version { get; set; } + } ///InternationalizationQuery 列表查询参数模型 diff --git a/IRaCIS.Core.Application/Service/Common/_MapConfig.cs b/IRaCIS.Core.Application/Service/Common/_MapConfig.cs index 743955f1a..7312de9f9 100644 --- a/IRaCIS.Core.Application/Service/Common/_MapConfig.cs +++ b/IRaCIS.Core.Application/Service/Common/_MapConfig.cs @@ -66,7 +66,8 @@ namespace IRaCIS.Core.Application.Service CreateMap().ReverseMap(); - CreateMap(); + CreateMap() + .ForMember(o => o.Version, t => t.MapFrom(u => u.PublishLog.Version)); CreateMap().ReverseMap(); CreateMap().ReverseMap(); diff --git a/IRaCIS.Core.Domain/Common/Internationalization.cs b/IRaCIS.Core.Domain/Common/Internationalization.cs index 6d7a9e864..0da0a2f35 100644 --- a/IRaCIS.Core.Domain/Common/Internationalization.cs +++ b/IRaCIS.Core.Domain/Common/Internationalization.cs @@ -50,6 +50,9 @@ namespace IRaCIS.Core.Domain.Models //关联版本历史记录表Id public Guid? PublishLogId { get; set; } + [JsonIgnore] + public PublishLog PublishLog { get; set; } + } From 3efc40e9aeb394c521104ac0cae4b1936d08be31 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Thu, 27 Jun 2024 15:33:18 +0800 Subject: [PATCH 022/251] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=8F=91=E5=B8=83?= =?UTF-8?q?=E7=89=88=E6=9C=AC=E9=99=8D=E5=BA=8F=E6=8E=92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.Application/Service/Common/PublishLogService.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/IRaCIS.Core.Application/Service/Common/PublishLogService.cs b/IRaCIS.Core.Application/Service/Common/PublishLogService.cs index da799e220..ca2eb25a0 100644 --- a/IRaCIS.Core.Application/Service/Common/PublishLogService.cs +++ b/IRaCIS.Core.Application/Service/Common/PublishLogService.cs @@ -100,7 +100,7 @@ namespace IRaCIS.Core.Application.Service public async Task> GetPublishVersionSelect() { - return await _publishLogRepository.ProjectTo(_mapper.ConfigurationProvider).OrderByDescending(t => t.State).ToListAsync(); + return await _publishLogRepository.ProjectTo(_mapper.ConfigurationProvider).OrderByDescending(t => t.Version).ToListAsync(); } } From 49993edb37aebf3105e4fd9c6f5b571fe4789a1d Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Thu, 27 Jun 2024 15:38:00 +0800 Subject: [PATCH 023/251] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=9B=BD=E9=99=85?= =?UTF-8?q?=E5=8C=96=E6=9F=A5=E8=AF=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Service/Common/DTO/InternationalizationViewModel.cs | 4 ++++ .../Service/Common/InternationalizationService.cs | 2 ++ 2 files changed, 6 insertions(+) diff --git a/IRaCIS.Core.Application/Service/Common/DTO/InternationalizationViewModel.cs b/IRaCIS.Core.Application/Service/Common/DTO/InternationalizationViewModel.cs index 2ad2de83c..eb64a391e 100644 --- a/IRaCIS.Core.Application/Service/Common/DTO/InternationalizationViewModel.cs +++ b/IRaCIS.Core.Application/Service/Common/DTO/InternationalizationViewModel.cs @@ -33,6 +33,10 @@ namespace IRaCIS.Core.Application.ViewModel public string? ValueCN { get; set; } + public string? Module { get; set; } + //关联版本历史记录表Id + public Guid? PublishLogId { get; set; } + } /// InternationalizationAddOrEdit 列表查询参数模型 diff --git a/IRaCIS.Core.Application/Service/Common/InternationalizationService.cs b/IRaCIS.Core.Application/Service/Common/InternationalizationService.cs index f3c18f9d3..5f0743d27 100644 --- a/IRaCIS.Core.Application/Service/Common/InternationalizationService.cs +++ b/IRaCIS.Core.Application/Service/Common/InternationalizationService.cs @@ -100,6 +100,8 @@ namespace IRaCIS.Core.Application.Service var internationalizationQueryable = _internationalizationRepository .WhereIf(inQuery.Description != null, t => t.Description.Contains(inQuery.Description)) + .WhereIf(inQuery.Module != null, t => t.Description.Contains(inQuery.Module)) + .WhereIf(inQuery.PublishLogId != null, t => t.PublishLogId==inQuery.PublishLogId) .WhereIf(inQuery.Code != null, t => t.Code.Contains(inQuery.Code)) .WhereIf(inQuery.State != null, t => t.State == inQuery.State) .WhereIf(inQuery.InternationalizationType != null, t => t.InternationalizationType == inQuery.InternationalizationType) From 10380994a4df99a995b40d03604979bc8368363e Mon Sep 17 00:00:00 2001 From: he <109787524@qq.com> Date: Thu, 27 Jun 2024 16:02:29 +0800 Subject: [PATCH 024/251] =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Allocation/TaskMedicalReviewService.cs | 2 +- .../Reading/Dto/ReadingMedicalReviewDto.cs | 2 +- .../ReadingMedicalReviewService.cs | 43 ++++++++----------- 3 files changed, 20 insertions(+), 27 deletions(-) diff --git a/IRaCIS.Core.Application/Service/Allocation/TaskMedicalReviewService.cs b/IRaCIS.Core.Application/Service/Allocation/TaskMedicalReviewService.cs index 8e349d3af..d272aef84 100644 --- a/IRaCIS.Core.Application/Service/Allocation/TaskMedicalReviewService.cs +++ b/IRaCIS.Core.Application/Service/Allocation/TaskMedicalReviewService.cs @@ -259,7 +259,7 @@ namespace IRaCIS.Core.Application.Service .ProjectTo(_mapper.ConfigurationProvider); - var defalutSortArray = new string[] { nameof(TaskMedicalReviewView.AuditState), nameof(TaskMedicalReviewView.SubjectId), nameof(TaskMedicalReviewView.ArmEnum), nameof(TaskMedicalReviewView.VisitTaskNum) }; + var defalutSortArray = new string[] { nameof(TaskMedicalReviewView.SubjectId), nameof(TaskMedicalReviewView.ArmEnum), nameof(TaskMedicalReviewView.VisitTaskNum) }; var pageList = await taskMedicalReviewQueryable.ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, inQuery.SortField, inQuery.Asc, string.IsNullOrWhiteSpace(inQuery.SortField), defalutSortArray); return ResponseOutput.Ok(pageList, new diff --git a/IRaCIS.Core.Application/Service/Reading/Dto/ReadingMedicalReviewDto.cs b/IRaCIS.Core.Application/Service/Reading/Dto/ReadingMedicalReviewDto.cs index b89ece8e1..feebe486e 100644 --- a/IRaCIS.Core.Application/Service/Reading/Dto/ReadingMedicalReviewDto.cs +++ b/IRaCIS.Core.Application/Service/Reading/Dto/ReadingMedicalReviewDto.cs @@ -42,7 +42,7 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto public Guid TrialReadingCriterionId { get; set; } - public Guid SubjectId { get; set; } + public Guid TaskMedicalReviewId { get; set; } } diff --git a/IRaCIS.Core.Application/Service/Reading/MedicalAudit/ReadingMedicalReviewService.cs b/IRaCIS.Core.Application/Service/Reading/MedicalAudit/ReadingMedicalReviewService.cs index 3a16532c3..c0dcd1578 100644 --- a/IRaCIS.Core.Application/Service/Reading/MedicalAudit/ReadingMedicalReviewService.cs +++ b/IRaCIS.Core.Application/Service/Reading/MedicalAudit/ReadingMedicalReviewService.cs @@ -792,40 +792,33 @@ namespace IRaCIS.Core.Application.Service var list = await GetIRMedicalFeedbackList(new GetIRMedicalFeedbackListInDto() { TrialId=inDto.TrialId, - AuditState= MedicalReviewAuditState.Auditing, TrialReadingCriterionId=inDto.TrialReadingCriterionId, - SubjectId=inDto.SubjectId, PageIndex=1, - PageSize=1, + PageSize=99999, }); + var index = list.CurrentPageData.ToList().FindIndex(x => x.Id == inDto.TaskMedicalReviewId); - if (list.CurrentPageData.Count() == 0) + var result = new GetIRMedicalFeedbackListOutDto() { }; + + if (index + 1 == list.CurrentPageData.Count()) // 最后一个 { - list = await GetIRMedicalFeedbackList(new GetIRMedicalFeedbackListInDto() - { - TrialId = inDto.TrialId, - AuditState = MedicalReviewAuditState.Auditing, - TrialReadingCriterionId = inDto.TrialReadingCriterionId, - PageIndex = 1, - PageSize = 1, - }); - } - - - if (list.CurrentPageData.Count() > 0) - { - return list.CurrentPageData[0]; - } - else - { throw new BusinessValidationFailedException(_localizer["MedicalReview_IRFinish"], ApiResponseCodeEnum.CloseCurrentWindows); } + else if (index == -1 || list.CurrentPageData.Count == 1) // 第一个或者只有一个 + { + if (list.CurrentPageData[0].Id == inDto.TaskMedicalReviewId) + { + throw new BusinessValidationFailedException(_localizer["MedicalReview_IRFinish"], ApiResponseCodeEnum.CloseCurrentWindows); + } + result = list.CurrentPageData[0]; + } + else + { + result = list.CurrentPageData.Skip(index + 1).Take(1).First(); - - - - + } + return result; } /// From 1a3ad4f602a5a9f86ef882e4e57d989049e9fa40 Mon Sep 17 00:00:00 2001 From: he <109787524@qq.com> Date: Fri, 28 Jun 2024 09:35:54 +0800 Subject: [PATCH 025/251] =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Service/QC/DTO/QCListViewModel.cs | 13 +++- .../Service/QC/QCListService.cs | 64 +++++++++++++++++-- 2 files changed, 71 insertions(+), 6 deletions(-) diff --git a/IRaCIS.Core.Application/Service/QC/DTO/QCListViewModel.cs b/IRaCIS.Core.Application/Service/QC/DTO/QCListViewModel.cs index dd47abc68..82c491a75 100644 --- a/IRaCIS.Core.Application/Service/QC/DTO/QCListViewModel.cs +++ b/IRaCIS.Core.Application/Service/QC/DTO/QCListViewModel.cs @@ -1107,8 +1107,19 @@ namespace IRaCIS.Core.Application.Contracts } + public class GetNextCRCChallengeInDto + { + [NotDefault] + public Guid TrialId { get; set; } - public class ChallengeQuery : PageInput + /// + /// QCChallengeId + /// + public Guid QCChallengeId { get; set; } + } + + + public class ChallengeQuery : PageInput { [NotDefault] public Guid TrialId { get; set; } diff --git a/IRaCIS.Core.Application/Service/QC/QCListService.cs b/IRaCIS.Core.Application/Service/QC/QCListService.cs index 11c4b7e90..4bcae96ac 100644 --- a/IRaCIS.Core.Application/Service/QC/QCListService.cs +++ b/IRaCIS.Core.Application/Service/QC/QCListService.cs @@ -9,6 +9,7 @@ using IRaCIS.Application.Contracts; using IRaCIS.Core.Application.ViewModel; using IRaCIS.Core.Application.Service.Reading.Dto; using static Org.BouncyCastle.Math.EC.ECCurve; +using IRaCIS.Core.Infrastructure; namespace IRaCIS.Core.Application.Image.QA { @@ -87,14 +88,67 @@ namespace IRaCIS.Core.Application.Image.QA } - - /// - /// CRC 质疑列表 + /// 获取下一个crc的未关闭的质疑 /// - /// + /// /// + /// [HttpPost] + public async Task GetNextCRCChallenge(GetNextCRCChallengeInDto inDto) + { + var list =await GetCRCChallengeList(new ChallengeQuery() + { + TrialId = inDto.TrialId, + PageIndex = 1, + PageSize = 9999 + }); + + + var data = list.Item1.CurrentPageData.Where(x=>x.Id==inDto.QCChallengeId||x.IsClosed==false).ToList(); + + if (data.Count > 0) + { + + var index = data.ToList().FindIndex(x => x.Id == inDto.QCChallengeId); + + var result = new QCCRCChallengeViewModel() { }; + + if (index + 1 == data.Count()) // 最后一个 + { + throw new BusinessValidationFailedException(_localizer["QCList_CRCFinishChallenge"]); + } + else if (index == -1 || data.Count == 1) // 第一个或者只有一个 + { + if (data[0].Id == inDto.QCChallengeId) + { + throw new BusinessValidationFailedException(_localizer["QCList_CRCFinishChallenge"]); + } + result = data[0]; + } + else + { + result = data.Skip(index + 1).Take(1).First(); + + } + return result; + + } + else + { + throw new BusinessValidationFailedException(_localizer["QCList_CRCFinishChallenge"]); + } + + } + + + + /// + /// CRC 质疑列表 + /// + /// + /// + [HttpPost] public async Task<(PageOutput, TrialSubjectAndSVConfig)> GetCRCChallengeList(ChallengeQuery challengeQuery) { @@ -117,7 +171,7 @@ namespace IRaCIS.Core.Application.Image.QA .WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.CRA, t => t.SubjectVisit.TrialSite.CRCUserList.Any(t => t.UserId == _userInfo.Id)) .ProjectTo(_mapper.ConfigurationProvider); - var pageList = await query2.ToPagedListAsync(challengeQuery.PageIndex, challengeQuery.PageSize, challengeQuery.SortField, challengeQuery.Asc, string.IsNullOrWhiteSpace(challengeQuery.SortField), new string[] { "IsUrgent desc", "IsClosed asc" }); + var pageList = await query2.ToPagedListAsync(challengeQuery.PageIndex, challengeQuery.PageSize, challengeQuery.SortField, challengeQuery.Asc, string.IsNullOrWhiteSpace(challengeQuery.SortField), new string[] { "IsUrgent desc", "CreateTime asc" }); var config = await _repository.Where(t => t.Id == challengeQuery.TrialId).ProjectTo(_mapper.ConfigurationProvider).FirstOrDefaultAsync().IfNullThrowException(); return (pageList, config); From ae2907ad5ded7a2a97446ffa5db73425461237cc Mon Sep 17 00:00:00 2001 From: he <109787524@qq.com> Date: Fri, 28 Jun 2024 10:19:34 +0800 Subject: [PATCH 026/251] =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.Application/Service/QC/QCListService.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/IRaCIS.Core.Application/Service/QC/QCListService.cs b/IRaCIS.Core.Application/Service/QC/QCListService.cs index 4bcae96ac..4ec4e93bf 100644 --- a/IRaCIS.Core.Application/Service/QC/QCListService.cs +++ b/IRaCIS.Core.Application/Service/QC/QCListService.cs @@ -104,8 +104,10 @@ namespace IRaCIS.Core.Application.Image.QA PageSize = 9999 }); + var pageList = list.Item1.CurrentPageData.ToList(); - var data = list.Item1.CurrentPageData.Where(x=>x.Id==inDto.QCChallengeId||x.IsClosed==false).ToList(); + + var data = pageList.Where(x=>x.Id==inDto.QCChallengeId||x.IsClosed==false).ToList(); if (data.Count > 0) { From 4585b7b7320a28e28420b97817576b9851e435db Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Fri, 28 Jun 2024 11:30:20 +0800 Subject: [PATCH 027/251] =?UTF-8?q?=E4=B8=80=E8=87=B4=E6=80=A7=E5=88=86?= =?UTF-8?q?=E6=9E=90=E7=AD=9B=E9=80=89+=20=E9=80=80=E5=9B=9E=E5=92=8C?= =?UTF-8?q?=E9=87=8D=E9=98=85=E5=A2=9E=E5=8A=A0APM=E8=A7=92=E8=89=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../DTO/TaskConsistentRuleViewModel.cs | 3 +- .../Allocation/TaskConsistentRuleService.cs | 55 ++++++++++--------- .../Service/Allocation/VisitTaskService.cs | 35 ++++++++---- 3 files changed, 55 insertions(+), 38 deletions(-) diff --git a/IRaCIS.Core.Application/Service/Allocation/DTO/TaskConsistentRuleViewModel.cs b/IRaCIS.Core.Application/Service/Allocation/DTO/TaskConsistentRuleViewModel.cs index a77887387..e45e9c2bb 100644 --- a/IRaCIS.Core.Application/Service/Allocation/DTO/TaskConsistentRuleViewModel.cs +++ b/IRaCIS.Core.Application/Service/Allocation/DTO/TaskConsistentRuleViewModel.cs @@ -183,7 +183,8 @@ namespace IRaCIS.Core.Application.ViewModel public string TaskCode { get; set; } - + + [JsonIgnore] //可以不查询 public List GlobalVisitTaskList { get; set; } diff --git a/IRaCIS.Core.Application/Service/Allocation/TaskConsistentRuleService.cs b/IRaCIS.Core.Application/Service/Allocation/TaskConsistentRuleService.cs index dbb8aa148..1a1a2bdbf 100644 --- a/IRaCIS.Core.Application/Service/Allocation/TaskConsistentRuleService.cs +++ b/IRaCIS.Core.Application/Service/Allocation/TaskConsistentRuleService.cs @@ -19,6 +19,7 @@ using Medallion.Threading; using IRaCIS.Core.Infrastructure.Extention; using System; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using NPOI.SS.Formula.Functions; namespace IRaCIS.Core.Application.Service { @@ -178,9 +179,7 @@ namespace IRaCIS.Core.Application.Service var list = await GetIQueryableDoctorSelfConsistentSubjectView(filterObj, doctorUserId, inCommand.SubejctIdList).ToListAsync(); - //var (group, query) = GetIQueryableDoctorSelfConsistentRuleSubjectView(filterObj, inCommand.SubejctIdList); - //var list = query.OrderByDescending(t => t.IsHaveGeneratedTask).ToList(); var @lock = _distributedLockProvider.CreateLock($"VisitTaskCode"); @@ -552,7 +551,8 @@ namespace IRaCIS.Core.Application.Service var subjectQuery = _subjectRepository.Where(t => t.TrialId == trialId && t.SubjectVisitTaskList.AsQueryable().Where(visitTaskFilter).Count() >= filterObj.PlanVisitCount) - .WhereIf(filterObj.IsHaveReadingPeriod == true, u => u.SubjectVisitTaskList.AsQueryable().Where(comonTaskFilter).Where(t => t.ReadingCategory == ReadingCategory.Visit || t.ReadingCategory == ReadingCategory.Global).OrderBy(t => t.VisitTaskNum).Take(filterObj.PlanVisitCount + 1).Any(t => t.ReadingCategory == ReadingCategory.Global)) + .WhereIf(filterObj.IsHaveReadingPeriod == true, u => u.SubjectVisitTaskList.AsQueryable().Where(comonTaskFilter) + .Where(t => t.ReadingCategory == ReadingCategory.Visit || t.ReadingCategory == ReadingCategory.Global).Any(t => t.ReadingCategory == ReadingCategory.Global)) ; @@ -596,29 +596,27 @@ namespace IRaCIS.Core.Application.Service IsClinicalDataSign = c.IsClinicalDataSign, IsNeedClinicalDataSign = c.IsNeedClinicalDataSign, - //自身一致性才有意义 - //IsHaveGeneratedTask = c.Subject.SubjectVisitTaskList.Any(t => t.ConsistentAnalysisOriginalTaskId == c.Id), - GlobalVisitTaskList = c.Subject.SubjectVisitTaskList.AsQueryable().Where(comonTaskFilter).Where(t => t.VisitTaskNum == c.VisitTaskNum + ReadingCommon.TaskNumDic[ReadingCategory.Global]).Select(c => new VisitTaskSimpleDTO() - { - Id = c.Id, - ReadingCategory = c.ReadingCategory, - ReadingTaskState = c.ReadingTaskState, - TaskBlindName = c.TaskBlindName, - TaskCode = c.TaskCode, - TaskName = c.TaskName, - TaskState = c.TaskState, - ArmEnum = c.ArmEnum, - SubjectId = c.SubjectId, - VisitTaskNum = c.VisitTaskNum, - TrialId = c.TrialId, - SourceSubjectVisitId = c.SourceSubjectVisitId, - SouceReadModuleId = c.SouceReadModuleId, + //GlobalVisitTaskList = c.Subject.SubjectVisitTaskList.AsQueryable().Where(comonTaskFilter).Where(t => t.VisitTaskNum == c.VisitTaskNum + ReadingCommon.TaskNumDic[ReadingCategory.Global]).Select(c => new VisitTaskSimpleDTO() + //{ + // Id = c.Id, + // ReadingCategory = c.ReadingCategory, + // ReadingTaskState = c.ReadingTaskState, + // TaskBlindName = c.TaskBlindName, + // TaskCode = c.TaskCode, + // TaskName = c.TaskName, + // TaskState = c.TaskState, + // ArmEnum = c.ArmEnum, + // SubjectId = c.SubjectId, + // VisitTaskNum = c.VisitTaskNum, + // TrialId = c.TrialId, + // SourceSubjectVisitId = c.SourceSubjectVisitId, + // SouceReadModuleId = c.SouceReadModuleId, - TrialReadingCriterionId = c.TrialReadingCriterionId, - IsClinicalDataSign = c.IsClinicalDataSign, - IsNeedClinicalDataSign = c.IsNeedClinicalDataSign, - }).ToList(), + // TrialReadingCriterionId = c.TrialReadingCriterionId, + // IsClinicalDataSign = c.IsClinicalDataSign, + // IsNeedClinicalDataSign = c.IsNeedClinicalDataSign, + //}).ToList(), }).ToList() }); @@ -795,7 +793,14 @@ namespace IRaCIS.Core.Application.Service t.SubjectVisitTaskList.AsQueryable().Where(comonTaskFilter) .Where(t => t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId && t.SignTime!.Value.AddDays(taskConsistentRule.IntervalWeeks * 7) < DateTime.Now && t.DoctorUserId == user.Id) - .Where(t => t.ReadingCategory == ReadingCategory.Visit || t.ReadingCategory == ReadingCategory.Global).OrderBy(t => t.VisitTaskNum).Take(taskConsistentRule.PlanVisitCount + 1).Any(t => t.ReadingCategory == ReadingCategory.Global)) + .Where(t => t.ReadingCategory == ReadingCategory.Visit || t.ReadingCategory == ReadingCategory.Global).Any(t => t.ReadingCategory == ReadingCategory.Global) + && + t.SubjectVisitTaskList.AsQueryable().Where(visitTaskFilter) + .Where(t => t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId && t.SignTime!.Value.AddDays(taskConsistentRule.IntervalWeeks * 7) < DateTime.Now && t.DoctorUserId == user.Id) + .Count()>= taskConsistentRule.PlanVisitCount + + ) + .Count(), diff --git a/IRaCIS.Core.Application/Service/Allocation/VisitTaskService.cs b/IRaCIS.Core.Application/Service/Allocation/VisitTaskService.cs index c67402eea..b7eff45b0 100644 --- a/IRaCIS.Core.Application/Service/Allocation/VisitTaskService.cs +++ b/IRaCIS.Core.Application/Service/Allocation/VisitTaskService.cs @@ -1374,7 +1374,7 @@ namespace IRaCIS.Core.Application.Service.Allocation - if (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ProjectManager) + if (IsPMOrAPm()) { if (criterionConfig.IsAutoCreate == false) { @@ -1634,7 +1634,7 @@ namespace IRaCIS.Core.Application.Service.Allocation if (criterionConfig.CriterionType == CriterionType.RECIST1Point1 && criterionConfig.IsAdditionalAssessment) { // PM申请 SPM / CPM审批 - if (visitTaskReReadingAppply.RequestReReadingType == RequestReReadingType.TrialGroupApply && (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.SPM || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.CPM)) + if (visitTaskReReadingAppply.RequestReReadingType == RequestReReadingType.TrialGroupApply && (IsSpmOrCPM())) { filterExpression = filterExpression.And(t => t.TrialReadingCriterionId == origenalTask.TrialReadingCriterionId || t.TrialReadingCriterion.CriterionType == CriterionType.RECIST1Pointt1_MB); } @@ -1643,7 +1643,7 @@ namespace IRaCIS.Core.Application.Service.Allocation { // 1.1 基线任务影响BM任务 - if (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ProjectManager && _subjectVisitRepository.Any(t => t.Id == origenalTask.SourceSubjectVisitId && t.IsBaseLine == true)) + if ((IsPMOrAPm()) && _subjectVisitRepository.Any(t => t.Id == origenalTask.SourceSubjectVisitId && t.IsBaseLine == true)) { isIR1Point1AdditionalAssessmentBaseline = true; @@ -1666,7 +1666,7 @@ namespace IRaCIS.Core.Application.Service.Allocation if (agreeReReadingCommand.RequestReReadingResultEnum == RequestReReadingResult.Agree) { //PM申请 SPM / CPM审批 回退访视,因此这里不生成访视任务 影响多个标准的任务 - if (visitTaskReReadingAppply.RequestReReadingType == RequestReReadingType.TrialGroupApply && (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.SPM || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.CPM)) + if (visitTaskReReadingAppply.RequestReReadingType == RequestReReadingType.TrialGroupApply && (IsSpmOrCPM())) { // 不管有序 无序 都会 回退访视 @@ -1786,7 +1786,7 @@ namespace IRaCIS.Core.Application.Service.Allocation } //IR申请 PM 审批 注意这里有一致性分析的申请同意 不会回退访视,在此要生成影响的访视任务 - else if (visitTaskReReadingAppply.RequestReReadingType == RequestReReadingType.DocotorApply && (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ProjectManager || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.AIR)) + else if (visitTaskReReadingAppply.RequestReReadingType == RequestReReadingType.DocotorApply && (IsPMOrAPm() || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.AIR)) { @@ -2291,7 +2291,7 @@ namespace IRaCIS.Core.Application.Service.Allocation //PM 才允许操作 - if (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ProjectManager) + if (IsPMOrAPm()) { #region 有序 无序公用流程 @@ -2556,6 +2556,16 @@ namespace IRaCIS.Core.Application.Service.Allocation } + private bool IsPMOrAPm() + { + return _userInfo.UserTypeEnumInt == (int)UserTypeEnum.ProjectManager || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.APM; + } + + private bool IsSpmOrCPM() + { + return _userInfo.UserTypeEnumInt == (int)UserTypeEnum.SPM || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.CPM; + } + /// /// 影响提示列表 重阅仅仅针对已完成的任务申请 退回针对的是未完成的(退回仅仅针对是访视类型的) /// @@ -2587,12 +2597,12 @@ namespace IRaCIS.Core.Application.Service.Allocation { // IR 申请 PM 同意 - if (((_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ProjectManager && applyId != null && await _visitTaskReReadingRepository.AnyAsync(t => t.Id == applyId && t.CreateUser.UserTypeEnum == UserTypeEnum.IndependentReviewer)) + if ((( IsPMOrAPm() && applyId != null && await _visitTaskReReadingRepository.AnyAsync(t => t.Id == applyId && t.CreateUser.UserTypeEnum == UserTypeEnum.IndependentReviewer)) || (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.IndependentReviewer && applyId == null))) { // 1.1 基线任务影响BM任务 - if (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ProjectManager && _subjectVisitRepository.Any(t => t.Id == filterObj.SourceSubjectVisitId && t.IsBaseLine == true)) + if (IsPMOrAPm() && _subjectVisitRepository.Any(t => t.Id == filterObj.SourceSubjectVisitId && t.IsBaseLine == true)) { isIR1Point1AdditionalAssessmentBaseline = true; @@ -2630,7 +2640,7 @@ namespace IRaCIS.Core.Application.Service.Allocation //IR 申请 PM 同意 仅仅影响自己 - if ((_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ProjectManager && applyId != null && await _visitTaskReReadingRepository.AnyAsync(t => t.Id == applyId && t.CreateUser.UserTypeEnum == UserTypeEnum.IndependentReviewer)) + if ((IsPMOrAPm() && applyId != null && await _visitTaskReReadingRepository.AnyAsync(t => t.Id == applyId && t.CreateUser.UserTypeEnum == UserTypeEnum.IndependentReviewer)) || (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.IndependentReviewer && applyId == null)) { @@ -2748,8 +2758,9 @@ namespace IRaCIS.Core.Application.Service.Allocation } //PM 影响所有阅片人 仅仅针对访视 SPM CPM 调用 - else if (((_userInfo.UserTypeEnumInt == (int)UserTypeEnum.SPM || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.CPM) && applyId != null && await _visitTaskReReadingRepository.AnyAsync(t => t.Id == applyId && t.CreateUser.UserTypeEnum == UserTypeEnum.ProjectManager) && filterObj.IsAnalysisCreate == false && filterObj.ReadingCategory == ReadingCategory.Visit) - || (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ProjectManager && applyId == null)) + else if (((IsSpmOrCPM()) && applyId != null && + await _visitTaskReReadingRepository.AnyAsync(t => t.Id == applyId && (t.CreateUser.UserTypeEnum == UserTypeEnum.ProjectManager || t.CreateUser.UserTypeEnum == UserTypeEnum.APM)) && filterObj.IsAnalysisCreate == false && filterObj.ReadingCategory == ReadingCategory.Visit) + || (IsPMOrAPm() && applyId == null)) { @@ -2812,7 +2823,7 @@ namespace IRaCIS.Core.Application.Service.Allocation throw new BusinessValidationFailedException(_localizer["VisitTask_NoConsistencyReturn"]); } - if (filterObj.ReadingCategory == ReadingCategory.Visit && _userInfo.UserTypeEnumInt == (int)UserTypeEnum.ProjectManager) + if (filterObj.ReadingCategory == ReadingCategory.Visit && IsPMOrAPm()) { //有序 if (criterionConfig.IsReadingTaskViewInOrder == ReadingOrder.InOrder) From 76c6e8442ae3cf4c5aa6943149458bbcf1cee871 Mon Sep 17 00:00:00 2001 From: he <109787524@qq.com> Date: Mon, 1 Jul 2024 11:50:23 +0800 Subject: [PATCH 028/251] =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ReadingClinicalDataService.cs | 11 ++++--- .../Reading/Dto/ReadingClinicalDataDto.cs | 31 ++++++++++++++++--- .../ClinicalData/ReadingClinicalDataPDF.cs | 10 +++++- 3 files changed, 42 insertions(+), 10 deletions(-) diff --git a/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs b/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs index 6256d045a..3b71babca 100644 --- a/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs +++ b/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs @@ -103,10 +103,10 @@ namespace IRaCIS.Application.Services var entity = _mapper.Map(indto); entity.ReadingClinicalDataPDFList = indto.AddFileList.Select(x => new ReadingClinicalDataPDF() { - FileName = x.FileName, Path = x.Path, - + Size = x.Size, + Type = x.Type, }).ToList(); entity.ReadingClinicalDataState = ReadingClinicalDataStatus.HaveUploaded; @@ -127,7 +127,8 @@ namespace IRaCIS.Application.Services FileName = x.FileName, Path = x.Path, - + Size = x.Size, + Type = x.Type, ReadingClinicalDataId = entity.Id, }).ToList(); @@ -209,7 +210,9 @@ namespace IRaCIS.Application.Services PDFFileList = x.ReadingClinicalDataPDFList.Select(y => new GetFileDto() { Id = y.Id, - FileName = y.FileName, + Size = y.Size, + Type = y.Type, + FileName = y.FileName, Path = y.Path, CreateTime = y.CreateTime, }).ToList(), diff --git a/IRaCIS.Core.Application/Service/Reading/Dto/ReadingClinicalDataDto.cs b/IRaCIS.Core.Application/Service/Reading/Dto/ReadingClinicalDataDto.cs index fbe40bf2a..b4cca0cfa 100644 --- a/IRaCIS.Core.Application/Service/Reading/Dto/ReadingClinicalDataDto.cs +++ b/IRaCIS.Core.Application/Service/Reading/Dto/ReadingClinicalDataDto.cs @@ -184,7 +184,17 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto /// 路径 /// public string Path { get; set; } - } + + /// + /// 大小 + /// + public int Size { get; set; } = 0; + + /// + /// 文件类型 + /// + public string Type { get; set; } + } public class GetReadingOrTaskClinicalDataListInDto @@ -489,10 +499,21 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto public string FileName { get; set; } - /// - /// 上传时间 - /// - public DateTime CreateTime { get; set; } + + /// + /// 大小 + /// + public int Size { get; set; } = 0; + + /// + /// 文件类型 + /// + public string Type { get; set; } + + /// + /// 上传时间 + /// + public DateTime CreateTime { get; set; } } diff --git a/IRaCIS.Core.Domain/Reading/ClinicalData/ReadingClinicalDataPDF.cs b/IRaCIS.Core.Domain/Reading/ClinicalData/ReadingClinicalDataPDF.cs index a42e9c86a..b8213b6d9 100644 --- a/IRaCIS.Core.Domain/Reading/ClinicalData/ReadingClinicalDataPDF.cs +++ b/IRaCIS.Core.Domain/Reading/ClinicalData/ReadingClinicalDataPDF.cs @@ -44,8 +44,16 @@ namespace IRaCIS.Core.Domain.Models /// public Guid CreateUserId { get; set; } + /// + /// 大小 + /// + public int Size { get; set; } = 0; - } + /// + /// 文件类型 + /// + public string Type { get; set; } + } From 5b0026f30fbcfd169456fae2ab6790816e333803 Mon Sep 17 00:00:00 2001 From: he <109787524@qq.com> Date: Mon, 1 Jul 2024 13:41:55 +0800 Subject: [PATCH 029/251] =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Service/Reading/ClinicalData/ReadingClinicalDataService.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs b/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs index 3b71babca..21aa436b2 100644 --- a/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs +++ b/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs @@ -45,6 +45,7 @@ namespace IRaCIS.Application.Services IRepository clinicalFormRepository, IRepository previousOtherRepository, IRepository previousSurgeryRepository, + IRepository readingQuestionCriterionTrialRepository, IServiceProvider IServiceProvider, IRepository subjectRepository, From f446d400a100ebb700f9525ec05a8fa2c0a4f8ed Mon Sep 17 00:00:00 2001 From: he <109787524@qq.com> Date: Mon, 1 Jul 2024 13:46:54 +0800 Subject: [PATCH 030/251] =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Service/Reading/ClinicalData/ReadingClinicalDataService.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs b/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs index 21aa436b2..be62b141e 100644 --- a/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs +++ b/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs @@ -284,6 +284,8 @@ namespace IRaCIS.Application.Services Id = y.Id, FileName = y.FileName, Path = y.Path, + Size = y.Size, + Type = y.Type, CreateTime = y.CreateTime, }).ToList(), From f158f092ce38914de5701fb84280f0b28a25b1db Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Mon, 1 Jul 2024 14:54:15 +0800 Subject: [PATCH 031/251] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=B8=80=E8=87=B4?= =?UTF-8?q?=E6=80=A7=E5=88=86=E6=9E=90=20=E4=BB=A5=E5=8F=8A=E9=A1=B9?= =?UTF-8?q?=E7=9B=AE=E9=83=A8=E4=BD=8D=E7=BC=96=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../IRaCIS.Core.Application.xml | 33 +++++ .../Allocation/TaskConsistentRuleService.cs | 31 ++++- .../Allocation/VisitTaskHelpeService.cs | 14 +- .../TrialSiteUser/DTO/TrialConfigDTO.cs | 7 + .../TrialSiteUser/TrialConfigService.cs | 2 +- .../Allocation/AllocationRelation.cs | 2 +- .../ReadingConsistentClinicalData.cs | 120 ++++++++++++++++++ .../ReadingConsistentClinicalDataPDF.cs | 65 ++++++++++ IRaCIS.Core.Domain/Trial/TrialBodyPart.cs | 3 + .../Context/IRaCISDBContext.cs | 2 + .../Extention/RandomExtensions.cs | 37 ++++++ 11 files changed, 308 insertions(+), 8 deletions(-) create mode 100644 IRaCIS.Core.Domain/Reading/ClinicalData/ReadingConsistentClinicalData.cs create mode 100644 IRaCIS.Core.Domain/Reading/ClinicalData/ReadingConsistentClinicalDataPDF.cs create mode 100644 IRaCIS.Core.Infrastructure/Extention/RandomExtensions.cs diff --git a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml index 21496c38d..ed3163fab 100644 --- a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml +++ b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml @@ -5262,6 +5262,16 @@ 路径 + + + 大小 + + + + + 文件类型 + + 临床数据类型Id @@ -5462,6 +5472,16 @@ FileName + + + 大小 + + + + + 文件类型 + + 上传时间 @@ -11340,6 +11360,11 @@ 组件一致性和原Arm2是否有差异 + + + QCChallengeId + + @@ -12336,6 +12361,14 @@ + + + 获取下一个crc的未关闭的质疑 + + + + + CRC 质疑列表 diff --git a/IRaCIS.Core.Application/Service/Allocation/TaskConsistentRuleService.cs b/IRaCIS.Core.Application/Service/Allocation/TaskConsistentRuleService.cs index 1a1a2bdbf..9242506ef 100644 --- a/IRaCIS.Core.Application/Service/Allocation/TaskConsistentRuleService.cs +++ b/IRaCIS.Core.Application/Service/Allocation/TaskConsistentRuleService.cs @@ -154,7 +154,7 @@ namespace IRaCIS.Core.Application.Service { - var filterObj = await _taskConsistentRuleRepository.FirstOrDefaultAsync(t => t.Id == inCommand.TaskConsistentRuleId); + var filterObj = await _taskConsistentRuleRepository.Where(t => t.Id == inCommand.TaskConsistentRuleId).Include(t=>t.TrialReadingCriterion).FirstOrDefaultAsync(); var doctorUserId = inCommand.DoctorUserId; var trialReadingCriterionId = filterObj.TrialReadingCriterionId; @@ -174,7 +174,7 @@ namespace IRaCIS.Core.Application.Service throw new BusinessValidationFailedException(_localizer["TaskConsistent_NotAllowedGenerate1"]); } - inCommand.SubejctIdList = GetRandomSubjectIdList(subjectList.Select(t => t.SubjectId).ToList(), filterObj.PlanSubjectCount); + inCommand.SubejctIdList = subjectList.Select(t => t.SubjectId).ToList().GetRandomCountList(filterObj.PlanSubjectCount); } var list = await GetIQueryableDoctorSelfConsistentSubjectView(filterObj, doctorUserId, inCommand.SubejctIdList).ToListAsync(); @@ -212,7 +212,18 @@ namespace IRaCIS.Core.Application.Service blindSubjectCode = filterObj.BlindTrialSiteCode + (maxCodeInt + 1).ToString($"D{filterObj.BlindSubjectNumberOfPlaces}"); } - subject.VisitTaskList = subject.VisitTaskList.Take(filterObj.PlanVisitCount).ToList(); + //有序阅片 + if (filterObj.TrialReadingCriterion.IsReadingTaskViewInOrder == ReadingOrder.InOrder) + { + subject.VisitTaskList = subject.VisitTaskList.Take(filterObj.PlanVisitCount).ToList(); + + } + else + { + //完全随机 和受试者随机,都是随机挑选访视 + subject.VisitTaskList = subject.VisitTaskList.GetRandomCountList(filterObj.PlanVisitCount); + } + subject.VisitTaskList.ForEach(t => { @@ -325,10 +336,12 @@ namespace IRaCIS.Core.Application.Service { var trialId = inCommand.TrialId; - var filterObj = await _taskConsistentRuleRepository.FirstOrDefaultAsync(t => t.TrialId == trialId && t.TrialReadingCriterionId == inCommand.TrialReadingCriterionId && t.IsSelfAnalysis == false); + var filterObj = await _taskConsistentRuleRepository.Where(t => t.TrialId == trialId && t.TrialReadingCriterionId == inCommand.TrialReadingCriterionId && t.IsSelfAnalysis == false).Include(t=>t.TrialReadingCriterion).FirstNotNullAsync(); var trialReadingCriterionId = filterObj.TrialReadingCriterionId; + + //随机分配 if (inCommand.IsAutoAllocateGenerateTask) { @@ -345,7 +358,7 @@ namespace IRaCIS.Core.Application.Service throw new BusinessValidationFailedException(_localizer["TaskConsistent_NotAllowedGenerate1"]); } - inCommand.SubejctIdList = GetRandomSubjectIdList(subjectSelectList.Select(t => t.SubjectId).ToList(), filterObj.PlanSubjectCount); + inCommand.SubejctIdList = subjectSelectList.Select(t => t.SubjectId).ToList().GetRandomCountList(filterObj.PlanSubjectCount) ; } @@ -415,6 +428,11 @@ namespace IRaCIS.Core.Application.Service foreach (var needAddDoctorUserId in needAddDoctorUserIdList) { + //if(filterObj.TrialReadingCriterion.IsReadingTaskViewInOrder== ReadingOrder.InOrder) + //{ + + //} + //每个医生 都生成处理的任务 foreach (var task in subject.SubjectTaskVisitList.Take(filterObj.PlanVisitCount)) { @@ -995,5 +1013,8 @@ namespace IRaCIS.Core.Application.Service //return matchSubjectIdList.OrderBy(g => random.Next()).Take(countToSelect).ToList(); } + + + } } diff --git a/IRaCIS.Core.Application/Service/Allocation/VisitTaskHelpeService.cs b/IRaCIS.Core.Application/Service/Allocation/VisitTaskHelpeService.cs index cdb8a02e2..c861c348d 100644 --- a/IRaCIS.Core.Application/Service/Allocation/VisitTaskHelpeService.cs +++ b/IRaCIS.Core.Application/Service/Allocation/VisitTaskHelpeService.cs @@ -1411,6 +1411,18 @@ namespace IRaCIS.Core.Application.Service break; case GenerateTaskCategory.SelfConsistent: + var readingCriterionId = generateTaskCommand.GenerataConsistentTaskList.First().TrialReadingCriterionId; + //var trialReadingCriterion=_trialReadingCriterionRepository.Where(t=>t.Id== trialReadingCriterionId).FirstOrDefault(); + + //判断是否存在传输方式为Pdf得临床数据 + + var exsitPDF = await _trialClinicalDataSetRepository.AnyAsync(t => t.TrialId == trialId && + t.TrialClinicalDataSetCriteriaList.Any(c => c.TrialReadingCriterionId == readingCriterionId) + && t.ClinicalUploadType == ClinicalUploadType.PDF); + + var taskState = exsitPDF ? TaskState.NotEffect : TaskState.Effect; + + foreach (var task in generateTaskCommand.GenerataConsistentTaskList) { var consistentTask = new VisitTask() @@ -1424,7 +1436,7 @@ namespace IRaCIS.Core.Application.Service VisitTaskNum = task.VisitTaskNum, ReadingCategory = task.ReadingCategory, - TaskState = TaskState.Effect, + TaskState = taskState, Code = currentMaxCodeInt + 1, TaskCode = AppSettings.GetCodeStr(currentMaxCodeInt + 1, nameof(VisitTask)), diff --git a/IRaCIS.Core.Application/Service/TrialSiteUser/DTO/TrialConfigDTO.cs b/IRaCIS.Core.Application/Service/TrialSiteUser/DTO/TrialConfigDTO.cs index f88b288dc..dc0d0ded9 100644 --- a/IRaCIS.Core.Application/Service/TrialSiteUser/DTO/TrialConfigDTO.cs +++ b/IRaCIS.Core.Application/Service/TrialSiteUser/DTO/TrialConfigDTO.cs @@ -1106,6 +1106,9 @@ namespace IRaCIS.Core.Application.Contracts [NotDefault] public Guid TrialId { get; set; } + + + public bool IsHandAdd { get; set; } = true; } public class TrialBodyPartView @@ -1114,5 +1117,9 @@ namespace IRaCIS.Core.Application.Contracts public string Name { get; set; } + + public Guid Id { get; set; } + + public bool IsHandAdd { get; set; } } } diff --git a/IRaCIS.Core.Application/Service/TrialSiteUser/TrialConfigService.cs b/IRaCIS.Core.Application/Service/TrialSiteUser/TrialConfigService.cs index ef9c33a6d..573b0b300 100644 --- a/IRaCIS.Core.Application/Service/TrialSiteUser/TrialConfigService.cs +++ b/IRaCIS.Core.Application/Service/TrialSiteUser/TrialConfigService.cs @@ -1318,7 +1318,7 @@ namespace IRaCIS.Core.Application public async Task>> GetTrialBodyPartList(Guid trialId) { - var list = await _trialRepository.Where(t => t.Id == trialId).SelectMany(t => t.TrialBodyPartList).Select(t => new TrialBodyPartView() { Code = t.Code, Name = _userInfo.IsEn_Us ? t.Name : t.NameCN }).ToListAsync(); + var list = await _trialRepository.Where(t => t.Id == trialId).SelectMany(t => t.TrialBodyPartList).Select(t => new TrialBodyPartView() { Code = t.Code, Name = _userInfo.IsEn_Us ? t.Name : t.NameCN ,Id=t.Id,IsHandAdd=t.IsHandAdd}).ToListAsync(); return ResponseOutput.Ok(list); } diff --git a/IRaCIS.Core.Domain.Share/Allocation/AllocationRelation.cs b/IRaCIS.Core.Domain.Share/Allocation/AllocationRelation.cs index 9948da85c..d5c6dec54 100644 --- a/IRaCIS.Core.Domain.Share/Allocation/AllocationRelation.cs +++ b/IRaCIS.Core.Domain.Share/Allocation/AllocationRelation.cs @@ -279,7 +279,7 @@ namespace IRaCIS.Core.Domain.Share Effect = 0, //未生效 - //NotEffect = 1, + NotEffect = 1, // 失效 Adbandon = 3, diff --git a/IRaCIS.Core.Domain/Reading/ClinicalData/ReadingConsistentClinicalData.cs b/IRaCIS.Core.Domain/Reading/ClinicalData/ReadingConsistentClinicalData.cs new file mode 100644 index 000000000..59d28bd54 --- /dev/null +++ b/IRaCIS.Core.Domain/Reading/ClinicalData/ReadingConsistentClinicalData.cs @@ -0,0 +1,120 @@ + + +using System; +using IRaCIS.Core.Domain.Share; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; +using System.Collections.Generic; + +namespace IRaCIS.Core.Domain.Models +{ + /// + /// 项目的临床数据 + /// + [Table("ReadingConsistentClinicalData")] + public class ReadingConsistentClinicalData : Entity, IAuditAdd + { + /// + /// 项目ID + /// + public Guid TrialId { get; set; } + + /// + /// 访视Id 或者模块Id + /// + public Guid ReadingId { get; set; } + + public Guid? StudyId { get; set; } + + /// + /// 受试者ID + /// + public Guid SubjectId { get; set; } + + /// + /// 临床数据类型Id + /// + public Guid ClinicalDataTrialSetId { get; set; } + + /// + /// 是否为访视 + /// xiu + public bool IsVisit { get; set; } + + /// + /// 创建时间 + /// + public DateTime CreateTime { get; set; } + + /// + /// 是否签名 + /// + public bool IsSign { get; set; } + + /// + /// 是否盲化 + /// + public bool? IsBlind { get; set; } + + /// + /// 是否完整 + /// + public bool? IsComplete { get; set; } + + /// + /// 创建人 + /// + public Guid CreateUserId { get; set; } + + public int FileCount { get; set; } + + + //临床数据状态 + public ReadingClinicalDataStatus ReadingClinicalDataState { get; set; } + + [JsonIgnore] + [ForeignKey("ClinicalDataTrialSetId")] + + public ClinicalDataTrialSet ClinicalDataTrialSet { get; set; } + + [JsonIgnore] + + public DicomStudy? DicomStudy { get; set; } + + [JsonIgnore] + [ForeignKey("TrialId")] + + public Trial Trial { get; set; } + + [JsonIgnore] + [ForeignKey("ReadingId")] + + public SubjectVisit SubjectVisit { get; set; } + + [JsonIgnore] + [ForeignKey("SubjectId")] + + public Subject Subject { get; set; } + + [JsonIgnore] + [ForeignKey("ReadingId")] + + public ReadModule ReadModule { get; set; } + + /// + /// PDF文件 + /// + [JsonIgnore] + public List ReadingClinicalDataPDFList { get; set; } + + + + + } + + + + + + +} diff --git a/IRaCIS.Core.Domain/Reading/ClinicalData/ReadingConsistentClinicalDataPDF.cs b/IRaCIS.Core.Domain/Reading/ClinicalData/ReadingConsistentClinicalDataPDF.cs new file mode 100644 index 000000000..ce3183971 --- /dev/null +++ b/IRaCIS.Core.Domain/Reading/ClinicalData/ReadingConsistentClinicalDataPDF.cs @@ -0,0 +1,65 @@ + + +using System; +using IRaCIS.Core.Domain.Share; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace IRaCIS.Core.Domain.Models +{ + /// + /// 项目的临床数据 + /// + [Table("ReadingConsistentClinicalDataPDF")] + public class ReadingConsistentClinicalDataPDF : Entity, IAuditAdd + { + [JsonIgnore] + [ForeignKey("ReadingConsistentClinicalDataId")] + public ReadingConsistentClinicalData ReadingConsistentClinicalData { get; set; } + /// + /// 阅片临床数据ID + /// + public Guid ReadingConsistentClinicalDataId { get; set; } + + /// + /// Path + /// + [Required] + public string Path { get; set; } + + /// + /// FileName + /// + [Required] + public string FileName { get; set; } + + + /// + /// 创建时间 + /// + public DateTime CreateTime { get; set; } + + /// + /// 创建人 + /// + public Guid CreateUserId { get; set; } + + /// + /// 大小 + /// + public int Size { get; set; } = 0; + + /// + /// 文件类型 + /// + public string Type { get; set; } + + + } + + + + + + +} diff --git a/IRaCIS.Core.Domain/Trial/TrialBodyPart.cs b/IRaCIS.Core.Domain/Trial/TrialBodyPart.cs index b69845dca..7dc64d2ab 100644 --- a/IRaCIS.Core.Domain/Trial/TrialBodyPart.cs +++ b/IRaCIS.Core.Domain/Trial/TrialBodyPart.cs @@ -35,5 +35,8 @@ namespace IRaCIS.Core.Domain.Models [JsonIgnore] public Trial Trial { get; set; } + + public bool IsHandAdd { get; set; } + } } diff --git a/IRaCIS.Core.Infra.EFCore/Context/IRaCISDBContext.cs b/IRaCIS.Core.Infra.EFCore/Context/IRaCISDBContext.cs index c5dd471f2..913ae7a94 100644 --- a/IRaCIS.Core.Infra.EFCore/Context/IRaCISDBContext.cs +++ b/IRaCIS.Core.Infra.EFCore/Context/IRaCISDBContext.cs @@ -208,6 +208,8 @@ namespace IRaCIS.Core.Infra.EFCore //public virtual DbSet ReadingClinicalDataView { get; set; } public virtual DbSet ReadingClinicalDataPDF { get; set; } + public virtual DbSet ReadingConsistentClinicalData { get; set; } + public virtual DbSet ReadingConsistentClinicalDataPDF { get; set; } public virtual DbSet ReadingJudgeInfo { get; set; } diff --git a/IRaCIS.Core.Infrastructure/Extention/RandomExtensions.cs b/IRaCIS.Core.Infrastructure/Extention/RandomExtensions.cs new file mode 100644 index 000000000..db395d9b4 --- /dev/null +++ b/IRaCIS.Core.Infrastructure/Extention/RandomExtensions.cs @@ -0,0 +1,37 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace IRaCIS.Core.Infrastructure.Extention +{ + public static class RandomExtensions + { + private static Random _random = new Random(); + + public static List GetRandomCountList(this List list, int count) + { + if (count > list.Count) + { + throw new ArgumentException("Sample size cannot be greater than list size."); + } + + // 使用 Fisher-Yates 洗牌算法来随机选择元素 + List result = list.ToList(); // 复制原始列表,以避免修改原始列表 + int n = result.Count; + + while (n > 1) + { + n--; + int k = _random.Next(n + 1); + T value = result[k]; + result[k] = result[n]; + result[n] = value; + } + + // 返回所需数量的元素 + return result.Take(count).ToList(); + } + } +} From 2354ee91743d46bdf436170d6fd5e8b8313af50c Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Mon, 1 Jul 2024 15:40:13 +0800 Subject: [PATCH 032/251] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=B8=80=E8=87=B4?= =?UTF-8?q?=E6=80=A7=E5=88=86=E6=9E=90=E5=92=8C=E4=B8=B4=E5=BA=8A=E6=95=B0?= =?UTF-8?q?=E6=8D=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Allocation/VisitTaskHelpeService.cs | 34 ++++++++++++++++--- .../Service/Allocation/VisitTaskService.cs | 6 ++-- .../Service/Allocation/_MapConfig.cs | 3 ++ .../ReadingConsistentClinicalData.cs | 2 +- 4 files changed, 38 insertions(+), 7 deletions(-) diff --git a/IRaCIS.Core.Application/Service/Allocation/VisitTaskHelpeService.cs b/IRaCIS.Core.Application/Service/Allocation/VisitTaskHelpeService.cs index c861c348d..8c7eec7c7 100644 --- a/IRaCIS.Core.Application/Service/Allocation/VisitTaskHelpeService.cs +++ b/IRaCIS.Core.Application/Service/Allocation/VisitTaskHelpeService.cs @@ -51,6 +51,7 @@ namespace IRaCIS.Core.Application.Service private readonly IRepository _trialClinicalDataSetRepository; private readonly IRepository _readingClinicalDataRepository; + private readonly IRepository _readingConsistentClinicalDataRepository; private readonly IRepository _subjectCriteriaEvaluationRepository; @@ -67,8 +68,9 @@ namespace IRaCIS.Core.Application.Service IRepository readingJudgeInfoRepository, IRepository taskAllocationRuleRepository, IMapper mapper, IUserInfo userInfo, IRepository visitTaskReReadingRepository, IRepository trialReadingCriterionRepository, IRepository trialClinicalDataSetRepository, IRepository readingClinicalDataRepository, - IRepository subjectCriteriaEvaluationRepository) + IRepository subjectCriteriaEvaluationRepository, IRepository readingConsistentClinicalDataRepository) { + _readingConsistentClinicalDataRepository = readingConsistentClinicalDataRepository; _readingClinicalDataRepository = readingClinicalDataRepository; _trialClinicalDataSetRepository = trialClinicalDataSetRepository; @@ -207,7 +209,7 @@ namespace IRaCIS.Core.Application.Service if (trialReadingCriterionConfig.IsReadingTaskViewInOrder == ReadingOrder.InOrder) { - if (visitNumList.IndexOf(subjectVisit.VisitNum) == 0 && subjectVisit.VisitNum==0) + if (visitNumList.IndexOf(subjectVisit.VisitNum) == 0 && subjectVisit.VisitNum == 0) { blindTaskName = visitBlindConfig.BlindBaseLineName; } @@ -217,9 +219,9 @@ namespace IRaCIS.Core.Application.Service } } - else + else { - blindTaskName ="Timepoint"; + blindTaskName = "Timepoint"; } @@ -1412,6 +1414,7 @@ namespace IRaCIS.Core.Application.Service case GenerateTaskCategory.SelfConsistent: var readingCriterionId = generateTaskCommand.GenerataConsistentTaskList.First().TrialReadingCriterionId; + var subjectId = generateTaskCommand.GenerataConsistentTaskList.First().SubjectId; //var trialReadingCriterion=_trialReadingCriterionRepository.Where(t=>t.Id== trialReadingCriterionId).FirstOrDefault(); //判断是否存在传输方式为Pdf得临床数据 @@ -1422,6 +1425,29 @@ namespace IRaCIS.Core.Application.Service var taskState = exsitPDF ? TaskState.NotEffect : TaskState.Effect; + var clinicalDataList = _readingClinicalDataRepository.Where(t => t.SubjectId == subjectId).Include(t => t.ReadingClinicalDataPDFList).Include(t=>t.ClinicalDataTrialSet).ToList(); + + foreach (var clinicalData in clinicalDataList) + { + var consistnentClinicalData = _mapper.Map(clinicalData); + var id = NewId.NextSequentialGuid(); + consistnentClinicalData.Id = id; + + if(consistnentClinicalData.ClinicalDataTrialSet.ClinicalUploadType == ClinicalUploadType.PDF) + { + consistnentClinicalData.IsSign = false; + consistnentClinicalData.IsBlind = false; + consistnentClinicalData.ReadingClinicalDataState = ReadingClinicalDataStatus.HaveUploaded; + } + + var consistanClinicalDataPdfList = _mapper.Map>(clinicalData.ReadingClinicalDataPDFList); + + consistanClinicalDataPdfList.ForEach(t => { t.ReadingConsistentClinicalDataId = id; t.Id = Guid.Empty; }); + + consistnentClinicalData.ReadingClinicalDataPDFList = consistanClinicalDataPdfList; + + await _readingConsistentClinicalDataRepository.AddAsync(consistnentClinicalData); + } foreach (var task in generateTaskCommand.GenerataConsistentTaskList) { diff --git a/IRaCIS.Core.Application/Service/Allocation/VisitTaskService.cs b/IRaCIS.Core.Application/Service/Allocation/VisitTaskService.cs index b7eff45b0..e9aeb5a17 100644 --- a/IRaCIS.Core.Application/Service/Allocation/VisitTaskService.cs +++ b/IRaCIS.Core.Application/Service/Allocation/VisitTaskService.cs @@ -1476,9 +1476,11 @@ namespace IRaCIS.Core.Application.Service.Allocation } else { - if (task.ReadingCategory != ReadingCategory.Visit && task.ReadingCategory != ReadingCategory.Global) + //也要支持裁判重阅240701 + + if (task.ReadingCategory != ReadingCategory.Visit && task.ReadingCategory != ReadingCategory.Judge) { - //---无序阅片,仅仅允许IR 申请 全局和访视类型类别的任务进行重阅 + //---无序阅片,仅仅允许IR 申请 访视、裁判类型类别的任务进行重阅 throw new BusinessValidationFailedException(_localizer["VisitTask_IRGlobalRecheck"]); } } diff --git a/IRaCIS.Core.Application/Service/Allocation/_MapConfig.cs b/IRaCIS.Core.Application/Service/Allocation/_MapConfig.cs index d6fc8810b..35612f29d 100644 --- a/IRaCIS.Core.Application/Service/Allocation/_MapConfig.cs +++ b/IRaCIS.Core.Application/Service/Allocation/_MapConfig.cs @@ -318,6 +318,9 @@ namespace IRaCIS.Core.Application.Service + CreateMap().ReverseMap(); + CreateMap().ReverseMap(); + } } diff --git a/IRaCIS.Core.Domain/Reading/ClinicalData/ReadingConsistentClinicalData.cs b/IRaCIS.Core.Domain/Reading/ClinicalData/ReadingConsistentClinicalData.cs index 59d28bd54..66c216fc9 100644 --- a/IRaCIS.Core.Domain/Reading/ClinicalData/ReadingConsistentClinicalData.cs +++ b/IRaCIS.Core.Domain/Reading/ClinicalData/ReadingConsistentClinicalData.cs @@ -105,7 +105,7 @@ namespace IRaCIS.Core.Domain.Models /// PDF文件 /// [JsonIgnore] - public List ReadingClinicalDataPDFList { get; set; } + public List ReadingClinicalDataPDFList { get; set; } From 709529da87b5f666c8b3158096459cf51c368d60 Mon Sep 17 00:00:00 2001 From: he <109787524@qq.com> Date: Tue, 2 Jul 2024 09:33:42 +0800 Subject: [PATCH 033/251] =?UTF-8?q?=E5=85=B3=E9=94=AE=E5=BA=8F=E5=88=97?= =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ImageAndDoc/DTO/DicomSeriesModel.cs | 13 ++++++++ .../Service/Visit/SubjectVisitService.cs | 30 ++++++++++++++----- 2 files changed, 36 insertions(+), 7 deletions(-) diff --git a/IRaCIS.Core.Application/Service/ImageAndDoc/DTO/DicomSeriesModel.cs b/IRaCIS.Core.Application/Service/ImageAndDoc/DTO/DicomSeriesModel.cs index e6f2443cb..ceca4a370 100644 --- a/IRaCIS.Core.Application/Service/ImageAndDoc/DTO/DicomSeriesModel.cs +++ b/IRaCIS.Core.Application/Service/ImageAndDoc/DTO/DicomSeriesModel.cs @@ -52,6 +52,19 @@ namespace IRaCIS.Core.Application.Contracts.Dicom.DTO public string ImageResizePath { get; set; } } + public class StudyInstanceInfo + { + + public int ShowOrder { get; set; } + + + public decimal RowIndex { get; set; } + + public Guid? SeriesId { get; set; } + + public Guid? StudyId { get; set; } + public Guid? InstanceId { get; set; } + } public class InstanceBasicInfo { public Guid Id { get; set; } diff --git a/IRaCIS.Core.Application/Service/Visit/SubjectVisitService.cs b/IRaCIS.Core.Application/Service/Visit/SubjectVisitService.cs index 221bd30a9..5d435d1e2 100644 --- a/IRaCIS.Core.Application/Service/Visit/SubjectVisitService.cs +++ b/IRaCIS.Core.Application/Service/Visit/SubjectVisitService.cs @@ -32,6 +32,7 @@ namespace IRaCIS.Core.Application.Services private readonly IRepository _dicomInstanceRepository; private readonly IRepository _visitTaskRepository; private readonly IRepository _readingTableAnswerRowInfoRepository; + private readonly IRepository _readingCustomTagRepository; private readonly IRepository _noneDicomStudyFileRepository; private readonly IRepository _readingPeriodPlanRepository; private readonly IRepository _subjectRepository; @@ -50,6 +51,7 @@ namespace IRaCIS.Core.Application.Services IRepository dicomInstanceRepository, IRepository visitTaskRepository, IRepository readingTableAnswerRowInfoRepository, + IRepository readingCustomTagRepository, IRepository noneDicomStudyFileRepository, IRepository readingPeriodPlanRepository, IRepository subjectRepository, @@ -70,6 +72,7 @@ namespace IRaCIS.Core.Application.Services this._dicomInstanceRepository = dicomInstanceRepository; this._visitTaskRepository = visitTaskRepository; this._readingTableAnswerRowInfoRepository = readingTableAnswerRowInfoRepository; + this._readingCustomTagRepository = readingCustomTagRepository; this._noneDicomStudyFileRepository = noneDicomStudyFileRepository; this._readingPeriodPlanRepository = readingPeriodPlanRepository; _subjectRepository = subjectRepository; @@ -574,15 +577,28 @@ namespace IRaCIS.Core.Application.Services //已经签名的任务,加关键序列 if (taskInfo.ReadingTaskState == ReadingTaskState.HaveSigned) { - var rowInfoList = await _readingTableAnswerRowInfoRepository.Where(x => x.VisitTaskId == indto.VisitTaskId && x.StudyId != null).OrderBy(x => x.ReadingQuestionTrial.ShowOrder).ThenBy(x => x.RowIndex).Select(x => new + var rowInfoList = await _readingTableAnswerRowInfoRepository.Where(x => x.VisitTaskId == indto.VisitTaskId && x.StudyId != null).OrderBy(x => x.ReadingQuestionTrial.ShowOrder).ThenBy(x => x.RowIndex).Select(x => new StudyInstanceInfo() { - x.ReadingQuestionTrial.ShowOrder, - x.RowIndex, - x.SeriesId, - x.StudyId, - x.InstanceId, + ShowOrder = x.ReadingQuestionTrial.ShowOrder, + RowIndex = x.RowIndex, + SeriesId = x.SeriesId, + StudyId = x.StudyId, + InstanceId = x.InstanceId, }).ToListAsync(); + + + var customoList = await _readingCustomTagRepository.Where(x => x.VisitTaskId == indto.VisitTaskId && x.StudyId != null).Select(x => new StudyInstanceInfo() + { + ShowOrder = 0, + RowIndex = 0m, + SeriesId = x.SeriesId, + StudyId = x.StudyId, + InstanceId = x.InstanceId, + }).ToListAsync(); + + rowInfoList.AddRange(customoList); + var thisStudyIds = rowInfoList.OrderBy(x => x.ShowOrder).ThenBy(x => x.RowIndex).Select(x => x.StudyId).Distinct().ToList(); var thisSeriesIdIds = rowInfoList.Where(x => x.SeriesId != null).OrderBy(x => x.ShowOrder).ThenBy(x => x.RowIndex).Select(x => x.SeriesId).Distinct().ToList(); if (rowInfoList.Count > 0) @@ -649,7 +665,7 @@ namespace IRaCIS.Core.Application.Services - studyList.Add(thisVisitTaskStudy); + studyList.Insert(0,thisVisitTaskStudy); } From 7c3b0e9e72f33f51832953441962f691a109456f Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Tue, 2 Jul 2024 09:45:18 +0800 Subject: [PATCH 034/251] =?UTF-8?q?=E6=B5=8F=E8=A7=88=E5=99=A8=E7=89=88?= =?UTF-8?q?=E6=9C=AC=E6=8E=A8=E8=8D=90=20--=E8=BF=81=E7=A7=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Common/DTO/ExploreRecommendViewModel.cs | 67 ++++++++++++++ .../Service/Common/ExploreRecommendService.cs | 92 +++++++++++++++++++ .../Interface/IExploreRecommendService.cs | 24 +++++ .../Service/Common/_MapConfig.cs | 3 +- IRaCIS.Core.Domain/Common/ExploreRecommend.cs | 53 +++++++++++ .../Context/IRaCISDBContext.cs | 3 + IRaCIS.Core.Test/DbHelper.ttinclude | 2 +- .../TT_Template/IRaCIS .Core.ServiceAsync.tt | 5 +- 8 files changed, 245 insertions(+), 4 deletions(-) create mode 100644 IRaCIS.Core.Application/Service/Common/DTO/ExploreRecommendViewModel.cs create mode 100644 IRaCIS.Core.Application/Service/Common/ExploreRecommendService.cs create mode 100644 IRaCIS.Core.Application/Service/Common/Interface/IExploreRecommendService.cs create mode 100644 IRaCIS.Core.Domain/Common/ExploreRecommend.cs diff --git a/IRaCIS.Core.Application/Service/Common/DTO/ExploreRecommendViewModel.cs b/IRaCIS.Core.Application/Service/Common/DTO/ExploreRecommendViewModel.cs new file mode 100644 index 000000000..b87cfc9e7 --- /dev/null +++ b/IRaCIS.Core.Application/Service/Common/DTO/ExploreRecommendViewModel.cs @@ -0,0 +1,67 @@ +//-------------------------------------------------------------------- +// 此代码由T4模板自动生成 byzhouhang 20210918 +// 生成时间 2024-07-02 09:29:36 +// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。 +//-------------------------------------------------------------------- +using System; +using IRaCIS.Core.Domain.Share; +using System.Collections.Generic; +namespace IRaCIS.Core.Application.ViewModel +{ + /// ExploreRecommendView 列表视图模型 + public class ExploreRecommendView + { + public Guid Id { get; set; } + public string Version { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + public Guid CreateUserId { get; set; } + public Guid UpdateUserId { get; set; } + public DateTime UpdateTime { get; set; } + public bool IsDeleted { get; set; } + public string DownloadUrl { get; set; } + public string Path { get; set; } + public string FileName { get; set; } + public DateTime? DeleteTime { get; set; } + public Guid? DeleteUserId { get; set; } + } + + ///ExploreRecommendQuery 列表查询参数模型 + public class ExploreRecommendQuery:PageInput + { + + public string? Version { get; set; } + + + public string? Title { get; set; } + + + public string? DownloadUrl { get; set; } + + + public string? FileName { get; set; } + + public bool? IsDeleted { get; set; } + + } + + /// ExploreRecommendAddOrEdit 列表查询参数模型 + public class ExploreRecommendAddOrEdit + { + public Guid Id { get; set; } + public string Version { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + public Guid CreateUserId { get; set; } + public Guid UpdateUserId { get; set; } + public DateTime UpdateTime { get; set; } + public bool IsDeleted { get; set; } + public string DownloadUrl { get; set; } + public string Path { get; set; } + public string FileName { get; set; } + } + + +} + + diff --git a/IRaCIS.Core.Application/Service/Common/ExploreRecommendService.cs b/IRaCIS.Core.Application/Service/Common/ExploreRecommendService.cs new file mode 100644 index 000000000..76d181268 --- /dev/null +++ b/IRaCIS.Core.Application/Service/Common/ExploreRecommendService.cs @@ -0,0 +1,92 @@ +//-------------------------------------------------------------------- +// 此代码由T4模板自动生成 byzhouhang 20210918 +// 生成时间 2024-07-02 09:26:59 +// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。 +//-------------------------------------------------------------------- + +using IRaCIS.Core.Domain.Models; +using Microsoft.AspNetCore.Mvc; +using IRaCIS.Core.Application.Interfaces; +using IRaCIS.Core.Application.ViewModel; +using Microsoft.AspNetCore.Authorization; +namespace IRaCIS.Core.Application.Service +{ + /// + /// ExploreRecommendService + /// + [ApiExplorerSettings(GroupName = "Common")] + public class ExploreRecommendService : BaseService, IExploreRecommendService + { + + private readonly IRepository _exploreRecommendRepository; + + public ExploreRecommendService(IRepository exploreRecommendRepository) + { + _exploreRecommendRepository = exploreRecommendRepository; + } + + [HttpPost] + public async Task> GetExploreRecommendList(ExploreRecommendQuery inQuery) + { + + var exploreRecommendQueryable = + + _exploreRecommendRepository + .WhereIf(string.IsNullOrEmpty(inQuery.Title), t => t.Title.Contains(inQuery.Title)) + .WhereIf(string.IsNullOrEmpty(inQuery.FileName), t => t.Title.Contains(inQuery.FileName)) + .WhereIf(string.IsNullOrEmpty(inQuery.DownloadUrl), t => t.Title.Contains(inQuery.DownloadUrl)) + .WhereIf(string.IsNullOrEmpty(inQuery.Version), t => t.Title.Contains(inQuery.Version)) + .WhereIf(inQuery.IsDeleted != null, t => t.IsDeleted == t.IsDeleted) + .ProjectTo(_mapper.ConfigurationProvider); + + var pageList = await exploreRecommendQueryable + .ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, string.IsNullOrWhiteSpace(inQuery.SortField) ? nameof(ExploreRecommendView.Id) : inQuery.SortField, + inQuery.Asc); + + return pageList; + } + + + public async Task AddOrUpdateExploreRecommend(ExploreRecommendAddOrEdit addOrEditExploreRecommend) + { + var verifyExp2 = new EntityVerifyExp() + { + VerifyExp = u => u.IsDeleted == addOrEditExploreRecommend.IsDeleted, + + VerifyMsg = "当前启用版本只允许有一个", + + IsVerify = addOrEditExploreRecommend.IsDeleted == false + }; + + var entity = await _exploreRecommendRepository.InsertOrUpdateAsync(addOrEditExploreRecommend, true, verifyExp2); + + return ResponseOutput.Ok(entity.Id.ToString()); + + } + + + [HttpDelete("{exploreRecommendId:guid}")] + public async Task DeleteExploreRecommend(Guid exploreRecommendId) + { + var success = await _exploreRecommendRepository.DeleteFromQueryAsync(t => t.Id == exploreRecommendId, true); + return ResponseOutput.Ok(); + } + + [AllowAnonymous] + public async Task GetExploreRecommentInfo() + { + + + var result = await _exploreRecommendRepository.Where(t => t.IsDeleted == false).ProjectTo(_mapper.ConfigurationProvider).FirstOrDefaultAsync(); + + if (result == null) + { + throw new QueryBusinessObjectNotExistException("系统浏览器版本推荐未维护,请联系维护人员"); + } + + return result; + } + + + } +} diff --git a/IRaCIS.Core.Application/Service/Common/Interface/IExploreRecommendService.cs b/IRaCIS.Core.Application/Service/Common/Interface/IExploreRecommendService.cs new file mode 100644 index 000000000..2dc5556b2 --- /dev/null +++ b/IRaCIS.Core.Application/Service/Common/Interface/IExploreRecommendService.cs @@ -0,0 +1,24 @@ +//-------------------------------------------------------------------- +// 此代码由T4模板自动生成 byzhouhang 20210918 +// 生成时间 2024-07-02 09:27:36 +// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。 +//-------------------------------------------------------------------- + +using IRaCIS.Core.Application.ViewModel; +namespace IRaCIS.Core.Application.Interfaces +{ + /// + /// IExploreRecommendService + /// + public interface IExploreRecommendService + { + + Task> GetExploreRecommendList(ExploreRecommendQuery inQuery); + + Task AddOrUpdateExploreRecommend(ExploreRecommendAddOrEdit addOrEditExploreRecommend); + + Task DeleteExploreRecommend(Guid exploreRecommendId); + + + } +} diff --git a/IRaCIS.Core.Application/Service/Common/_MapConfig.cs b/IRaCIS.Core.Application/Service/Common/_MapConfig.cs index 7312de9f9..916cabf1f 100644 --- a/IRaCIS.Core.Application/Service/Common/_MapConfig.cs +++ b/IRaCIS.Core.Application/Service/Common/_MapConfig.cs @@ -80,8 +80,9 @@ namespace IRaCIS.Core.Application.Service CreateMap().ReverseMap(); CreateMap(); - + CreateMap(); + CreateMap().ReverseMap(); } } diff --git a/IRaCIS.Core.Domain/Common/ExploreRecommend.cs b/IRaCIS.Core.Domain/Common/ExploreRecommend.cs new file mode 100644 index 000000000..db000e174 --- /dev/null +++ b/IRaCIS.Core.Domain/Common/ExploreRecommend.cs @@ -0,0 +1,53 @@ + +//-------------------------------------------------------------------- +// 此代码由T4模板自动生成 byzhouhang 20210918 +// 生成时间 2024-07-02 09:26:43 +// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。 +using System; +using IRaCIS.Core.Domain.Share; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; +namespace IRaCIS.Core.Domain.Models +{ + /// + ///ExploreRecommend + /// + [Table("ExploreRecommend")] + public class ExploreRecommend : Entity, IAuditUpdate, IAuditAdd,ISoftDelete + { + + public string Version { get; set; }=string.Empty; + + + public string Title { get; set; } = string.Empty; + + + public DateTime CreateTime { get; set; } + + + public Guid CreateUserId { get; set; } + + + public Guid UpdateUserId { get; set; } + + + public DateTime UpdateTime { get; set; } + + + public bool IsDeleted { get; set; } + + + public string DownloadUrl { get; set; } = string.Empty; + + + public string Path { get; set; } = string.Empty; + + public string FileName { get; set; } = string.Empty; + + public DateTime? DeletedTime { get; set; } + + public Guid? DeleteUserId { get; set; } + + } + +} diff --git a/IRaCIS.Core.Infra.EFCore/Context/IRaCISDBContext.cs b/IRaCIS.Core.Infra.EFCore/Context/IRaCISDBContext.cs index 913ae7a94..c5e8715c7 100644 --- a/IRaCIS.Core.Infra.EFCore/Context/IRaCISDBContext.cs +++ b/IRaCIS.Core.Infra.EFCore/Context/IRaCISDBContext.cs @@ -481,6 +481,9 @@ namespace IRaCIS.Core.Infra.EFCore public virtual DbSet TrialBodyPart { get; set; } + public virtual DbSet ExploreRecommend { get; set; } + + public override async Task SaveChangesAsync(CancellationToken cancellationToken = new CancellationToken()) { // 采用触发器的方式 设置 CreateUserId CreateTime UpdateTime UpdateUserId 稽查实体里面没有这四个字段的值 因为先后顺序的原因 diff --git a/IRaCIS.Core.Test/DbHelper.ttinclude b/IRaCIS.Core.Test/DbHelper.ttinclude index 93d6bd2d6..649ef03e0 100644 --- a/IRaCIS.Core.Test/DbHelper.ttinclude +++ b/IRaCIS.Core.Test/DbHelper.ttinclude @@ -4,7 +4,7 @@ public static readonly string ConnectionString = "Server=106.14.89.110,1435;Database=Test_IRC;User ID=sa;Password=xc@123456;TrustServerCertificate=true"; public static readonly string DbDatabase = "Test_IRC"; //表名称用字符串,拼接 - public static readonly string TableName = "TrialBodyPart"; + public static readonly string TableName = "ExploreRecommend"; //具体文件里面 例如service 可以配置是否分页 } #> diff --git a/IRaCIS.Core.Test/TT_Template/IRaCIS .Core.ServiceAsync.tt b/IRaCIS.Core.Test/TT_Template/IRaCIS .Core.ServiceAsync.tt index fa5c367b7..5a1998a61 100644 --- a/IRaCIS.Core.Test/TT_Template/IRaCIS .Core.ServiceAsync.tt +++ b/IRaCIS.Core.Test/TT_Template/IRaCIS .Core.ServiceAsync.tt @@ -65,6 +65,7 @@ namespace IRaCIS.Core.Application.Service } <# if(isPage){#> + [HttpPost] public async TaskView>> Get<#=tableName#>List(<#=tableName#>Query inQuery) { @@ -74,13 +75,13 @@ namespace IRaCIS.Core.Application.Service .ProjectTo<<#=tableName#>View>(_mapper.ConfigurationProvider); var pageList= await <#=char.ToLower(tableName[0]) + tableName.Substring(1)#>Queryable - .ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, string.IsNullOrWhiteSpace(inQuery.SortField) ? "Id" : inQuery.SortField, + .ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, string.IsNullOrWhiteSpace(inQuery.SortField) ? nameof(<#=tableName#>View.Id) : inQuery.SortField, inQuery.Asc); return pageList; } <# } else {#> - + [HttpPost] public async TaskView>> Get<#=tableName#>List(<#=tableName#>Query inQuery) { From 27b99eb3be2eaac262f2945ec0744ea961c08338 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Tue, 2 Jul 2024 11:08:11 +0800 Subject: [PATCH 035/251] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=8E=A5=E5=8F=A3?= =?UTF-8?q?=E8=BF=94=E5=9B=9E=E8=B7=AF=E5=BE=84=E4=BF=A1=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../IRaCIS.Core.Application.xml | 19 +++++++++++ .../ImageAndDoc/DownloadAndUploadService.cs | 33 +++++++++++++++++++ 2 files changed, 52 insertions(+) diff --git a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml index ed3163fab..dc0ac3d68 100644 --- a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml +++ b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml @@ -707,6 +707,11 @@ + + + ExploreRecommendService + + InternationalizationService @@ -9960,6 +9965,15 @@ CommonDocumentAddOrEdit 列表查询参数模型 + + ExploreRecommendView 列表视图模型 + + + ExploreRecommendQuery 列表查询参数模型 + + + ExploreRecommendAddOrEdit 列表查询参数模型 + FrontAuditConfigView 列表视图模型 @@ -11002,6 +11016,11 @@ ICommonDocumentService + + + IExploreRecommendService + + IFrontAuditConfigService diff --git a/IRaCIS.Core.Application/Service/ImageAndDoc/DownloadAndUploadService.cs b/IRaCIS.Core.Application/Service/ImageAndDoc/DownloadAndUploadService.cs index b733298cb..f8e3c2606 100644 --- a/IRaCIS.Core.Application/Service/ImageAndDoc/DownloadAndUploadService.cs +++ b/IRaCIS.Core.Application/Service/ImageAndDoc/DownloadAndUploadService.cs @@ -506,6 +506,39 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc } + + public async Task GetSubejectVisitPathInfo(Guid subjectVisitId) + { + var query = from sv in _subjectVisitRepository.Where(t => t.Id == subjectVisitId) + + select new + { + SubjectCode = sv.Subject.Code, + VisitName = sv.VisitName, + StudyList = sv.StudyList.Select(u => new + { + u.PatientId, + u.StudyTime, + u.StudyCode, + + SeriesList = u.SeriesList.Select(z => new + { + z.Modality, + + InstancePathList = z.DicomInstanceList.Select(k => new + { + k.Path + }) + }) + + }) + }; + + var info = query.FirstOrDefault(); + + return ResponseOutput.Ok(info); + } + /// /// 后台任务调用,前端忽略该接口 /// From 5cc41b3b0f86599bfb8fa73fb3764ed8714e51cd Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Tue, 2 Jul 2024 17:16:46 +0800 Subject: [PATCH 036/251] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=B8=80=E8=87=B4?= =?UTF-8?q?=E6=80=A7=E6=A0=B8=E6=9F=A5=E9=A2=9C=E8=89=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../_MediatR/Handlers/ConsistencyVerificationHandler.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/IRaCIS.Core.Application/_MediatR/Handlers/ConsistencyVerificationHandler.cs b/IRaCIS.Core.Application/_MediatR/Handlers/ConsistencyVerificationHandler.cs index b2cb55016..975656660 100644 --- a/IRaCIS.Core.Application/_MediatR/Handlers/ConsistencyVerificationHandler.cs +++ b/IRaCIS.Core.Application/_MediatR/Handlers/ConsistencyVerificationHandler.cs @@ -213,7 +213,7 @@ namespace IRaCIS.Core.Application.MediatR.Handlers else { //"Problems are as follows: - dialogMsg.AppendLine($"
{_localizer["ConsistencyVerification_Prob"]}
"); + dialogMsg.AppendLine($"
{_localizer["ConsistencyVerification_Prob"]}
"); num = 0; foreach (var item in dbExceptExcel) From d094f22ab21a51d262fb5d7bfaad2a0471afaede Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Tue, 2 Jul 2024 17:20:32 +0800 Subject: [PATCH 037/251] =?UTF-8?q?pacs=20=E7=9B=B4=E8=BF=9E=E4=BF=AE?= =?UTF-8?q?=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Controllers/InspectionController.cs | 13 ++ .../IRaCIS.Core.Application.xml | 58 +++++++ .../Common/DTO/ExploreRecommendViewModel.cs | 16 +- .../TrialSiteUser/DTO/DicomAEViewModel.cs | 66 ++++++++ .../TrialSiteUser/DTO/TrialConfigDTO.cs | 10 ++ .../DTO/TrialSiteDicomAEViewModel.cs | 55 +++++++ .../Interface/IDicomAEService.cs | 24 +++ .../Interface/ITrialConfigService.cs | 2 +- .../Interface/ITrialSiteDicomAEService.cs | 24 +++ .../TrialSiteUser/TrialConfigService.cs | 25 ++- .../TrialSiteUser/TrialDicomAEService.cs | 149 ++++++++++++++++++ .../TrialSiteUser/TrialSiteDicomAEService.cs | 74 +++++++++ .../Service/TrialSiteUser/_MapConfig2.cs | 6 +- IRaCIS.Core.Domain/Image/SCPImageUpload.cs | 61 +++++++ IRaCIS.Core.Domain/Image/SCPInstance.cs | 53 +++++++ IRaCIS.Core.Domain/Image/SCPPatient.cs | 37 +++++ IRaCIS.Core.Domain/Image/SCPSeries.cs | 57 +++++++ IRaCIS.Core.Domain/Image/SCPStudy.cs | 95 +++++++++++ IRaCIS.Core.Domain/Image/TrialDicomAE.cs | 52 ++++++ IRaCIS.Core.Domain/Trial/Trial.cs | 2 + .../TrialSiteUser/TrialSiteDicomAE.cs | 59 +++++++ .../Context/IRaCISDBContext.cs | 12 ++ IRaCIS.Core.Test/DbHelper.ttinclude | 2 +- 23 files changed, 934 insertions(+), 18 deletions(-) create mode 100644 IRaCIS.Core.Application/Service/TrialSiteUser/DTO/DicomAEViewModel.cs create mode 100644 IRaCIS.Core.Application/Service/TrialSiteUser/DTO/TrialSiteDicomAEViewModel.cs create mode 100644 IRaCIS.Core.Application/Service/TrialSiteUser/Interface/IDicomAEService.cs create mode 100644 IRaCIS.Core.Application/Service/TrialSiteUser/Interface/ITrialSiteDicomAEService.cs create mode 100644 IRaCIS.Core.Application/Service/TrialSiteUser/TrialDicomAEService.cs create mode 100644 IRaCIS.Core.Application/Service/TrialSiteUser/TrialSiteDicomAEService.cs create mode 100644 IRaCIS.Core.Domain/Image/SCPImageUpload.cs create mode 100644 IRaCIS.Core.Domain/Image/SCPInstance.cs create mode 100644 IRaCIS.Core.Domain/Image/SCPPatient.cs create mode 100644 IRaCIS.Core.Domain/Image/SCPSeries.cs create mode 100644 IRaCIS.Core.Domain/Image/SCPStudy.cs create mode 100644 IRaCIS.Core.Domain/Image/TrialDicomAE.cs create mode 100644 IRaCIS.Core.Domain/TrialSiteUser/TrialSiteDicomAE.cs diff --git a/IRaCIS.Core.API/Controllers/InspectionController.cs b/IRaCIS.Core.API/Controllers/InspectionController.cs index 7de33aaae..e9deab588 100644 --- a/IRaCIS.Core.API/Controllers/InspectionController.cs +++ b/IRaCIS.Core.API/Controllers/InspectionController.cs @@ -402,6 +402,19 @@ namespace IRaCIS.Core.API.Controllers return result; } + + [HttpPost, Route("Inspection/configTrialBasicInfo/ConfigTrialPACSInfoConfirm")] + [UnitOfWork] + [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "BeforeOngoingCantOpt" })] + public async Task ConfigTrialPACSInfoConfirm(DataInspectionDto opt) + { + opt.Data.IsTrialPACSConfirmed = true; + var singid = await _inspectionService.RecordSing(opt.SignInfo); + var result = await _trialConfigService.ConfigTrialPACSInfo(opt.Data); + await _inspectionService.CompletedSign(singid, result); + return result; + } + /// /// 签名确认 /// diff --git a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml index dc0ac3d68..8232128a0 100644 --- a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml +++ b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml @@ -9813,6 +9813,24 @@ + + + DicomAEService + + + + + 获取项目dicom AE 配置信息,otherinfo里面有IsPACSConnect IsTrialPACSConfirmed + + + + + + + 测试scp server 是否可以连接 + + + 项目外部人员 录入流程相关 @@ -9825,6 +9843,11 @@ + + + TrialSiteDicomAEService + + TaskAllocationRuleView 列表视图模型 @@ -10973,6 +10996,15 @@ UserWLTemplateAddOrEdit 列表查询参数模型 + + DicomAEView 列表视图模型 + + + DicomAEQuery 列表查询参数模型 + + + DicomAEAddOrEdit 列表查询参数模型 + TrialExternalUserView 列表视图模型 @@ -10982,6 +11014,15 @@ TrialExternalUserAddOrEdit 列表查询参数模型 + + TrialSiteDicomAEView 列表视图模型 + + + TrialSiteDicomAEQuery 列表查询参数模型 + + + TrialSiteDicomAEAddOrEdit 列表查询参数模型 + TrialUserPreparation View 列表视图模型 @@ -11071,11 +11112,21 @@ IOrganInfoService + + + IDicomAEService + + ITrialExternalUserService + + + ITrialSiteDicomAEService + + EmailNoticeConfigView 列表视图模型 @@ -13059,6 +13110,13 @@ + + + 配置pacs信息 + + + + 更新项目状态 diff --git a/IRaCIS.Core.Application/Service/Common/DTO/ExploreRecommendViewModel.cs b/IRaCIS.Core.Application/Service/Common/DTO/ExploreRecommendViewModel.cs index b87cfc9e7..382271cf1 100644 --- a/IRaCIS.Core.Application/Service/Common/DTO/ExploreRecommendViewModel.cs +++ b/IRaCIS.Core.Application/Service/Common/DTO/ExploreRecommendViewModel.cs @@ -9,19 +9,14 @@ using System.Collections.Generic; namespace IRaCIS.Core.Application.ViewModel { /// ExploreRecommendView 列表视图模型 - public class ExploreRecommendView + public class ExploreRecommendView: ExploreRecommendAddOrEdit { - public Guid Id { get; set; } - public string Version { get; set; } - public string Title { get; set; } + public DateTime CreateTime { get; set; } public Guid CreateUserId { get; set; } public Guid UpdateUserId { get; set; } public DateTime UpdateTime { get; set; } - public bool IsDeleted { get; set; } - public string DownloadUrl { get; set; } - public string Path { get; set; } - public string FileName { get; set; } + public DateTime? DeleteTime { get; set; } public Guid? DeleteUserId { get; set; } } @@ -51,10 +46,7 @@ namespace IRaCIS.Core.Application.ViewModel public Guid Id { get; set; } public string Version { get; set; } public string Title { get; set; } - public DateTime CreateTime { get; set; } - public Guid CreateUserId { get; set; } - public Guid UpdateUserId { get; set; } - public DateTime UpdateTime { get; set; } + public bool IsDeleted { get; set; } public string DownloadUrl { get; set; } public string Path { get; set; } diff --git a/IRaCIS.Core.Application/Service/TrialSiteUser/DTO/DicomAEViewModel.cs b/IRaCIS.Core.Application/Service/TrialSiteUser/DTO/DicomAEViewModel.cs new file mode 100644 index 000000000..6e335b36d --- /dev/null +++ b/IRaCIS.Core.Application/Service/TrialSiteUser/DTO/DicomAEViewModel.cs @@ -0,0 +1,66 @@ +//-------------------------------------------------------------------- +// 此代码由T4模板自动生成 byzhouhang 20210918 +// 生成时间 2024-03-22 15:44:37 +// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。 +//-------------------------------------------------------------------- +using System; +using IRaCIS.Core.Domain.Share; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +namespace IRaCIS.Core.Application.ViewModel +{ + /// DicomAEView 列表视图模型 + public class DicomAEView : DicomAEAddOrEdit + { + public DateTime CreateTime { get; set; } + public Guid CreateUserId { get; set; } + public Guid UpdateUserId { get; set; } + public DateTime UpdateTime { get; set; } + + public DateTime? LatestTestTime { get; set; } + + public bool IsTestOK { get; set; } + + public bool IsPACSConnect { get; set; } + + public bool IsTrialPACSConfirmed { get; set; } + + } + + ///DicomAEQuery 列表查询参数模型 + public class DicomAEQuery : PageInput + { + public Guid? TrialId { get; set; } + + public string? CalledAE { get; set; } + + public string? IP { get; set; } + + + public int? Port { get; set; } + + + public string? Modality { get; set; } + + public string? Description { get; set; } + } + + /// DicomAEAddOrEdit 列表查询参数模型 + public class DicomAEAddOrEdit + { + public Guid? Id { get; set; } + + [NotDefault] + public Guid TrialId { get; set; } + + public string CalledAE { get; set; } + public string IP { get; set; } + public int Port { get; set; } + public string Modality { get; set; } = string.Empty; + public string Description { get; set; } = string.Empty; + } + + +} + + diff --git a/IRaCIS.Core.Application/Service/TrialSiteUser/DTO/TrialConfigDTO.cs b/IRaCIS.Core.Application/Service/TrialSiteUser/DTO/TrialConfigDTO.cs index dc0d0ded9..2508214e5 100644 --- a/IRaCIS.Core.Application/Service/TrialSiteUser/DTO/TrialConfigDTO.cs +++ b/IRaCIS.Core.Application/Service/TrialSiteUser/DTO/TrialConfigDTO.cs @@ -313,6 +313,16 @@ namespace IRaCIS.Core.Application.Contracts } + public class TrialPACSConfig + { + [NotDefault] + public Guid TrialId { get; set; } + + public bool IsPACSConnect { get; set; } + + public bool IsTrialPACSConfirmed { get; set; } = true; + } + public class TrialStateChangeDTO { public Guid Id { get; set; } diff --git a/IRaCIS.Core.Application/Service/TrialSiteUser/DTO/TrialSiteDicomAEViewModel.cs b/IRaCIS.Core.Application/Service/TrialSiteUser/DTO/TrialSiteDicomAEViewModel.cs new file mode 100644 index 000000000..94ac1e703 --- /dev/null +++ b/IRaCIS.Core.Application/Service/TrialSiteUser/DTO/TrialSiteDicomAEViewModel.cs @@ -0,0 +1,55 @@ +//-------------------------------------------------------------------- +// 此代码由T4模板自动生成 byzhouhang 20210918 +// 生成时间 2024-07-02 16:53:52 +// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。 +//-------------------------------------------------------------------- +using System; +using IRaCIS.Core.Domain.Share; +using System.Collections.Generic; +namespace IRaCIS.Core.Application.ViewModel +{ + /// TrialSiteDicomAEView 列表视图模型 + public class TrialSiteDicomAEView : TrialSiteDicomAEAddOrEdit + { + + public Guid UpdateUserId { get; set; } + public Guid? DeleteUserId { get; set; } + public DateTime CreateTime { get; set; } + public Guid CreateUserId { get; set; } + public DateTime UpdateTime { get; set; } + + } + + ///TrialSiteDicomAEQuery 列表查询参数模型 + public class TrialSiteDicomAEQuery : PageInput + { + public string? CallingAE { get; set; } + + public string? IP { get; set; } + + public string? Port { get; set; } + + public string? Description { get; set; } + + } + + /// TrialSiteDicomAEAddOrEdit 列表查询参数模型 + public class TrialSiteDicomAEAddOrEdit + { + public Guid? Id { get; set; } + public Guid TrialId { get; set; } + + + public Guid TrialSiteId { get; set; } + public string CallingAE { get; set; } + public string IP { get; set; } + public string Port { get; set; } + public string Description { get; set; } + + //public bool IsDeleted { get; set; } + } + + +} + + diff --git a/IRaCIS.Core.Application/Service/TrialSiteUser/Interface/IDicomAEService.cs b/IRaCIS.Core.Application/Service/TrialSiteUser/Interface/IDicomAEService.cs new file mode 100644 index 000000000..71f56aeb4 --- /dev/null +++ b/IRaCIS.Core.Application/Service/TrialSiteUser/Interface/IDicomAEService.cs @@ -0,0 +1,24 @@ +//-------------------------------------------------------------------- +// 此代码由T4模板自动生成 byzhouhang 20210918 +// 生成时间 2024-03-22 15:44:27 +// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。 +//-------------------------------------------------------------------- + +using IRaCIS.Core.Application.ViewModel; +namespace IRaCIS.Core.Application.Interfaces +{ + /// + /// IDicomAEService + /// + public interface IDicomAEService + { + + Task>> GetDicomAEList(DicomAEQuery inQuery); + + Task AddOrUpdateDicomAE(DicomAEAddOrEdit addOrEditDicomAE); + + Task DeleteDicomAE(Guid dicomAEId); + + + } +} diff --git a/IRaCIS.Core.Application/Service/TrialSiteUser/Interface/ITrialConfigService.cs b/IRaCIS.Core.Application/Service/TrialSiteUser/Interface/ITrialConfigService.cs index 7a06d0fb5..1de70d035 100644 --- a/IRaCIS.Core.Application/Service/TrialSiteUser/Interface/ITrialConfigService.cs +++ b/IRaCIS.Core.Application/Service/TrialSiteUser/Interface/ITrialConfigService.cs @@ -18,7 +18,7 @@ namespace IRaCIS.Application.Interfaces Task ConfigTrialUrgentInfo(TrialUrgentConfig trialConfig); - + Task ConfigTrialPACSInfo(TrialPACSConfig trialConfig); Task TrialConfigSignatureConfirm(SignConfirmDTO signConfirmDTO); Task AsyncTrialCriterionDictionary(AsyncTrialCriterionDictionaryInDto inDto); diff --git a/IRaCIS.Core.Application/Service/TrialSiteUser/Interface/ITrialSiteDicomAEService.cs b/IRaCIS.Core.Application/Service/TrialSiteUser/Interface/ITrialSiteDicomAEService.cs new file mode 100644 index 000000000..a6c2323a6 --- /dev/null +++ b/IRaCIS.Core.Application/Service/TrialSiteUser/Interface/ITrialSiteDicomAEService.cs @@ -0,0 +1,24 @@ +//-------------------------------------------------------------------- +// 此代码由T4模板自动生成 byzhouhang 20210918 +// 生成时间 2024-07-02 16:53:55 +// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。 +//-------------------------------------------------------------------- + +using IRaCIS.Core.Application.ViewModel; +namespace IRaCIS.Core.Application.Interfaces +{ + /// + /// ITrialSiteDicomAEService + /// + public interface ITrialSiteDicomAEService + { + + Task> GetTrialSiteDicomAEList(TrialSiteDicomAEQuery inQuery); + + Task AddOrUpdateTrialSiteDicomAE(TrialSiteDicomAEAddOrEdit addOrEditTrialSiteDicomAE); + + Task DeleteTrialSiteDicomAE(Guid trialSiteDicomAEId); + + + } +} diff --git a/IRaCIS.Core.Application/Service/TrialSiteUser/TrialConfigService.cs b/IRaCIS.Core.Application/Service/TrialSiteUser/TrialConfigService.cs index 573b0b300..4be695071 100644 --- a/IRaCIS.Core.Application/Service/TrialSiteUser/TrialConfigService.cs +++ b/IRaCIS.Core.Application/Service/TrialSiteUser/TrialConfigService.cs @@ -604,7 +604,7 @@ namespace IRaCIS.Core.Application await _readingQuestionCriterionTrialRepository.UpdatePartialFromQueryAsync(inDto.TrialReadingCriterionId, x => new ReadingQuestionCriterionTrial() { - IsImageFilter=inDto.IsImageFilter, + IsImageFilter = inDto.IsImageFilter, ImageDownloadEnum = inDto.ImageDownloadEnum, ImageUploadEnum = inDto.ImageUploadEnum, CriterionModalitys = inDto.CriterionModalitys, @@ -954,7 +954,7 @@ namespace IRaCIS.Core.Application trialInfo.UpdateTime = DateTime.Now; - //await _readingQuestionCriterionTrialRepository.BatchUpdateNoTrackingAsync(t => t.TrialId == trialConfig.TrialId && t.IsSigned == false, u => new ReadingQuestionCriterionTrial() { CriterionModalitys = trialConfig.Modalitys }); + //await _readingQuestionCriterionTrialRepository.BatchUpdateNoTrackingAsync(t => t.TrialId == trialConfig.TrialId && t.IsSigned == false, u => new ReadingQuestionCriterionTrial() { CriterionModalitys = trialConfig.Modalitys }); return ResponseOutput.Ok(await _repository.SaveChangesAsync()); } @@ -1151,6 +1151,25 @@ namespace IRaCIS.Core.Application return ResponseOutput.Ok(await _repository.SaveChangesAsync()); } + /// + /// 配置pacs信息 + /// + /// + /// + [HttpPut] + [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "BeforeOngoingCantOpt", "AfterStopCannNotOpt" })] + public async Task ConfigTrialPACSInfo(TrialPACSConfig trialConfig) + { + var trialInfo = (await _trialRepository.FirstOrDefaultAsync(t => t.Id == trialConfig.TrialId)).IfNullThrowException(); + trialInfo.IsPACSConnect = trialConfig.IsPACSConnect; + trialConfig.IsTrialPACSConfirmed = trialConfig.IsTrialPACSConfirmed; + trialInfo.UpdateTime = DateTime.Now; + await _trialRepository.SaveChangesAsync(); + + return ResponseOutput.Ok(await _repository.SaveChangesAsync()); + } + + [HttpGet("{trialId:guid}")] public async Task IfTrialCanOngoing(Guid trialId) { @@ -1318,7 +1337,7 @@ namespace IRaCIS.Core.Application public async Task>> GetTrialBodyPartList(Guid trialId) { - var list = await _trialRepository.Where(t => t.Id == trialId).SelectMany(t => t.TrialBodyPartList).Select(t => new TrialBodyPartView() { Code = t.Code, Name = _userInfo.IsEn_Us ? t.Name : t.NameCN ,Id=t.Id,IsHandAdd=t.IsHandAdd}).ToListAsync(); + var list = await _trialRepository.Where(t => t.Id == trialId).SelectMany(t => t.TrialBodyPartList).Select(t => new TrialBodyPartView() { Code = t.Code, Name = _userInfo.IsEn_Us ? t.Name : t.NameCN, Id = t.Id, IsHandAdd = t.IsHandAdd }).ToListAsync(); return ResponseOutput.Ok(list); } diff --git a/IRaCIS.Core.Application/Service/TrialSiteUser/TrialDicomAEService.cs b/IRaCIS.Core.Application/Service/TrialSiteUser/TrialDicomAEService.cs new file mode 100644 index 000000000..035be1e3e --- /dev/null +++ b/IRaCIS.Core.Application/Service/TrialSiteUser/TrialDicomAEService.cs @@ -0,0 +1,149 @@ +//-------------------------------------------------------------------- +// 此代码由T4模板自动生成 byzhouhang 20210918 +// 生成时间 2024-03-22 15:44:31 +// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。 +//-------------------------------------------------------------------- + +using IRaCIS.Core.Domain.Models; +using Microsoft.AspNetCore.Mvc; +using IRaCIS.Core.Application.Interfaces; +using IRaCIS.Core.Application.ViewModel; +using FellowOakDicom.Network.Client; +using FellowOakDicom.Network; +using IRaCIS.Application.Contracts; +using IRaCIS.Core.Domain.Share; +namespace IRaCIS.Core.Application.Service +{ + /// + /// DicomAEService + /// + [ApiExplorerSettings(GroupName = "Trial")] + public class TrialDicomAEService : BaseService, IDicomAEService + { + + private readonly IRepository _dicomAERepository; + private readonly IRepository _trialRepository; + + public TrialDicomAEService(IRepository dicomAERepository, IRepository trialRepository) + { + _trialRepository = trialRepository; + _dicomAERepository = dicomAERepository; + } + + [HttpPost] + public async Task>> GetDicomAEList(DicomAEQuery inQuery) + { + + var dicomAEQueryable = _dicomAERepository + .WhereIf(!string.IsNullOrWhiteSpace(inQuery.IP), t => t.IP.Contains(inQuery.IP)) + .WhereIf(inQuery.Port != null, t => t.Port == inQuery.Port) + .WhereIf(!string.IsNullOrWhiteSpace(inQuery.CalledAE), t => t.CalledAE.Contains(inQuery.CalledAE)) + .WhereIf(!string.IsNullOrWhiteSpace(inQuery.Description), t => t.Description.Contains(inQuery.Description)) + .WhereIf(!string.IsNullOrWhiteSpace(inQuery.Modality), t => t.Modality.Contains(inQuery.Modality)) + .ProjectTo(_mapper.ConfigurationProvider); + + + + + var pageList = await dicomAEQueryable.ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, inQuery.SortField == string.Empty ? nameof(DicomAEView.CalledAE) : inQuery.SortField, inQuery.Asc); + + + return ResponseOutput.Ok(pageList); + } + + + /// + /// 获取项目dicom AE 配置信息,otherinfo里面有IsPACSConnect IsTrialPACSConfirmed + /// + /// + /// + public async Task> GetTrialDicomAEList(Guid trialId) + { + var dicomAE = _dicomAERepository.Where(t => t.TrialId == trialId).ProjectTo(_mapper.ConfigurationProvider).FirstOrDefault(); + var trialConfig = _trialRepository.Where(t => t.Id == trialId).Select(t => new { t.IsPACSConnect, t.IsTrialPACSConfirmed }); + return ResponseOutput.Ok(dicomAE, trialConfig); + + } + + + public async Task AddOrUpdateDicomAE(DicomAEAddOrEdit addOrEditDicomAE) + { + var verifyExp1 = new EntityVerifyExp() + { + VerifyExp = u => u.IP == addOrEditDicomAE.IP && u.Port == addOrEditDicomAE.Port && u.TrialId == addOrEditDicomAE.TrialId, + + VerifyMsg = "不允许添加相同的IP和端口的记录" + }; + + //var verifyExp2 = new EntityVerifyExp() + //{ + // VerifyExp = u => u.TrialId == addOrEditDicomAE.TrialId, + + // VerifyMsg = "只允许配置一条记录", + // IsVerify=addOrEditDicomAE.Id==null + //}; + + // 在此处拷贝automapper 映射 + var entity = await _dicomAERepository.InsertOrUpdateAsync(addOrEditDicomAE, true, verifyExp1); + + return ResponseOutput.Ok(entity.Id.ToString()); + + } + + + [HttpDelete("{dicomAEId:guid}")] + public async Task DeleteDicomAE(Guid dicomAEId) + { + var success = await _dicomAERepository.DeleteFromQueryAsync(t => t.Id == dicomAEId, true); + return ResponseOutput.Ok(); + } + + + /// + /// 测试scp server 是否可以连接 + /// + /// + [HttpGet("{dicomAEId:guid}")] + public async Task TestSCPServerConnect(Guid dicomAEId) + { + var find = await _dicomAERepository.FirstOrDefaultAsync(t => t.Id == dicomAEId); + + if (find == null) + { + + return false; + } + else + { + find.LatestTestTime = DateTime.Now; + + try + { + var client = DicomClientFactory.Create(find.IP, find.Port, false, "test-callingAE", find.CalledAE); + + client.NegotiateAsyncOps(); + + await client.AddRequestAsync(new DicomCEchoRequest()); + + await client.SendAsync(); + + find.IsTestOK = true; + await _dicomAERepository.SaveChangesAsync(); + + return true; + } + catch (Exception ex) + { + find.IsTestOK = false; + await _dicomAERepository.SaveChangesAsync(); + + return false; + } + } + + + } + + + } +} diff --git a/IRaCIS.Core.Application/Service/TrialSiteUser/TrialSiteDicomAEService.cs b/IRaCIS.Core.Application/Service/TrialSiteUser/TrialSiteDicomAEService.cs new file mode 100644 index 000000000..2cfec8f8f --- /dev/null +++ b/IRaCIS.Core.Application/Service/TrialSiteUser/TrialSiteDicomAEService.cs @@ -0,0 +1,74 @@ +//-------------------------------------------------------------------- +// 此代码由T4模板自动生成 byzhouhang 20210918 +// 生成时间 2024-07-02 16:53:58 +// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。 +//-------------------------------------------------------------------- + +using IRaCIS.Core.Domain.Models; +using Microsoft.AspNetCore.Mvc; +using IRaCIS.Core.Application.Interfaces; +using IRaCIS.Core.Application.ViewModel; +namespace IRaCIS.Core.Application.Service +{ + /// + /// TrialSiteDicomAEService + /// + [ApiExplorerSettings(GroupName = "Trial")] + public class TrialSiteDicomAEService : BaseService, ITrialSiteDicomAEService + { + + private readonly IRepository _trialSiteDicomAERepository; + + public TrialSiteDicomAEService(IRepository trialSiteDicomAERepository) + { + _trialSiteDicomAERepository = trialSiteDicomAERepository; + } + + [HttpPost] + public async Task> GetTrialSiteDicomAEList(TrialSiteDicomAEQuery inQuery) + { + + var trialSiteDicomAEQueryable = + + _trialSiteDicomAERepository + .WhereIf(!string.IsNullOrWhiteSpace(inQuery.IP), t => t.IP.Contains(inQuery.IP)) + .WhereIf(!string.IsNullOrWhiteSpace(inQuery.Port), t => t.Port.Contains(inQuery.Port)) + .WhereIf(!string.IsNullOrWhiteSpace(inQuery.Description), t => t.Description.Contains(inQuery.Description)) + .WhereIf(!string.IsNullOrWhiteSpace(inQuery.CallingAE), t => t.CallingAE.Contains(inQuery.CallingAE)) + .ProjectTo(_mapper.ConfigurationProvider); + + var pageList = await trialSiteDicomAEQueryable + .ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, string.IsNullOrWhiteSpace(inQuery.SortField) ? nameof(TrialSiteDicomAEView.Id) : inQuery.SortField, + inQuery.Asc); + + return pageList; + } + + + public async Task AddOrUpdateTrialSiteDicomAE(TrialSiteDicomAEAddOrEdit addOrEditTrialSiteDicomAE) + { + var verifyExp1 = new EntityVerifyExp() + { + VerifyExp = u => u.IP == addOrEditTrialSiteDicomAE.IP && u.Port == addOrEditTrialSiteDicomAE.Port &&u.CallingAE==addOrEditTrialSiteDicomAE.CallingAE && u.TrialId == addOrEditTrialSiteDicomAE.TrialId, + + VerifyMsg = "不允许添加相同的IP和端口的记录" + }; + + + var entity = await _trialSiteDicomAERepository.InsertOrUpdateAsync(addOrEditTrialSiteDicomAE, true, verifyExp1); + + return ResponseOutput.Ok(entity.Id.ToString()); + + } + + + [HttpDelete("{trialSiteDicomAEId:guid}")] + public async Task DeleteTrialSiteDicomAE(Guid trialSiteDicomAEId) + { + var success = await _trialSiteDicomAERepository.DeleteFromQueryAsync(t => t.Id == trialSiteDicomAEId, true); + return ResponseOutput.Ok(); + } + + + } +} diff --git a/IRaCIS.Core.Application/Service/TrialSiteUser/_MapConfig2.cs b/IRaCIS.Core.Application/Service/TrialSiteUser/_MapConfig2.cs index b608fb229..96041148e 100644 --- a/IRaCIS.Core.Application/Service/TrialSiteUser/_MapConfig2.cs +++ b/IRaCIS.Core.Application/Service/TrialSiteUser/_MapConfig2.cs @@ -45,7 +45,11 @@ namespace IRaCIS.Core.Application.Service CreateMap(); - + + CreateMap(); + CreateMap().ReverseMap(); + + } } diff --git a/IRaCIS.Core.Domain/Image/SCPImageUpload.cs b/IRaCIS.Core.Domain/Image/SCPImageUpload.cs new file mode 100644 index 000000000..a2982fba0 --- /dev/null +++ b/IRaCIS.Core.Domain/Image/SCPImageUpload.cs @@ -0,0 +1,61 @@ + +//-------------------------------------------------------------------- +// 此代码由T4模板自动生成 byzhouhang 20210918 +// 生成时间 2024-05-24 14:31:45 +// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。 +using System; +using IRaCIS.Core.Domain.Share; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; +using System.Collections.Generic; +namespace IRaCIS.Core.Domain.Models +{ + /// + ///SCPImageUpload + /// + [Table("SCPImageUpload")] + public class SCPImageUpload : Entity, IAuditAdd + { + + + + [Required] + public DateTime CreateTime { get; set; } + + + [Required] + public Guid CreateUserId { get; set; } + + + [Required] + public string CallingAE { get; set; }=string.Empty; + + [Required] + public string CalledAE { get; set; } = string.Empty; + + + [Required] + public string CallingAEIP { get; set; } = string.Empty; + + + [Required] + public DateTime StartTime { get; set; } + + [Required] + public DateTime EndTime { get; set; } + + + [Required] + public int FileCount { get; set; } + + + [Required] + public long FileSize { get; set; } + + + public int StudyCount { get; set; } + + } + + +} diff --git a/IRaCIS.Core.Domain/Image/SCPInstance.cs b/IRaCIS.Core.Domain/Image/SCPInstance.cs new file mode 100644 index 000000000..f0eb643f6 --- /dev/null +++ b/IRaCIS.Core.Domain/Image/SCPInstance.cs @@ -0,0 +1,53 @@ +using System; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace IRaCIS.Core.Domain.Models +{ + [Table("SCPInstance")] + public class SCPInstance : Entity, IAuditAdd, IAuditUpdate + { + [JsonIgnore] + [ForeignKey("SeriesId")] + public SCPSeries SCPSeries { get; set; } + + [JsonIgnore] + [ForeignKey("StudyId")] + public SCPStudy SCPStudy { get; set; } + + [DatabaseGenerated(DatabaseGeneratedOption.Identity)] + + public Guid SeqId { get; set; } + public Guid StudyId { get; set; } + public Guid SeriesId { get; set; } + public string StudyInstanceUid { get; set; } + public string SeriesInstanceUid { get; set; } + public string SopInstanceUid { get; set; } + public int InstanceNumber { get; set; } + public DateTime? InstanceTime { get; set; } + public bool CPIStatus { get; set; } + public int ImageRows { get; set; } + public int ImageColumns { get; set; } + public int SliceLocation { get; set; } + + + public string SliceThickness { get; set; } + public int NumberOfFrames { get; set; } + public string PixelSpacing { get; set; } + + public string ImagerPixelSpacing { get; set; } + public string FrameOfReferenceUID { get; set; } + public string WindowCenter { get; set; } + public string WindowWidth { get; set; } + + public bool Anonymize { get; set; } + public string Path { get; set; } = string.Empty; + + public Guid CreateUserId { get; set; } + public DateTime CreateTime { get; set; } = DateTime.Now; + public Guid UpdateUserId { get; set; } + public DateTime UpdateTime { get; set; } = DateTime.Now; + + + } +} diff --git a/IRaCIS.Core.Domain/Image/SCPPatient.cs b/IRaCIS.Core.Domain/Image/SCPPatient.cs new file mode 100644 index 000000000..21eda7f87 --- /dev/null +++ b/IRaCIS.Core.Domain/Image/SCPPatient.cs @@ -0,0 +1,37 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace IRaCIS.Core.Domain.Models +{ + [Table("SCPPatient")] + public class SCPPatient : Entity, IAuditUpdate, IAuditAdd + { + public List SCPStudyList { get; set; } + + public string PatientIdStr { get; set; } = string.Empty; + public string PatientName { get; set; } = string.Empty; + public string PatientAge { get; set; } = string.Empty; + public string PatientSex { get; set; } = string.Empty; + public string PatientBirthDate { get; set; } = string.Empty; + + public Guid UpdateUserId { get; set; } + public DateTime UpdateTime { get; set; } = DateTime.Now; + public Guid CreateUserId { get; set; } + public DateTime CreateTime { get; set; } = DateTime.Now; + + + public DateTime? EarliestStudyTime { get; set; } + + public DateTime? LatestStudyTime { get; set; } + + public DateTime LatestPushTime { get; set; } + + + [JsonIgnore] + public Subject Subject { get; set; } + public Guid? SubjectId { get; set; } + + } +} diff --git a/IRaCIS.Core.Domain/Image/SCPSeries.cs b/IRaCIS.Core.Domain/Image/SCPSeries.cs new file mode 100644 index 000000000..5c2213c20 --- /dev/null +++ b/IRaCIS.Core.Domain/Image/SCPSeries.cs @@ -0,0 +1,57 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace IRaCIS.Core.Domain.Models +{ + [Table("SCPSeries")] + public class SCPSeries : Entity, IAuditAdd, IAuditUpdate, ISoftDelete + { + [JsonIgnore] + [ForeignKey("StudyId")] + public SCPStudy SCPStudy { get; set; } + + [JsonIgnore] + public List SCPInstanceList { get; set; } + + [DatabaseGenerated(DatabaseGeneratedOption.Identity)] + public Guid SeqId { get; set; } + public Guid StudyId { get; set; } + public string StudyInstanceUid { get; set; } + public string SeriesInstanceUid { get; set; } + public int SeriesNumber { get; set; } + public DateTime? SeriesTime { get; set; } + public string Modality { get; set; } + public string Description { get; set; } + public int InstanceCount { get; set; } + public string SliceThickness { get; set; } + + public string ImagePositionPatient { get; set; } + public string ImageOrientationPatient { get; set; } + public string BodyPartExamined { get; set; } + public string SequenceName { get; set; } + public string ProtocolName { get; set; } + public string ImagerPixelSpacing { get; set; } + + public string AcquisitionTime { get; set; } = string.Empty; + public string AcquisitionNumber { get; set; } = string.Empty; + public string TriggerTime { get; set; } = string.Empty; + + public string BodyPartForEdit { get; set; } = string.Empty; + + public Guid CreateUserId { get; set; } + public DateTime CreateTime { get; set; } = DateTime.Now; + public Guid UpdateUserId { get; set; } + public DateTime UpdateTime { get; set; } = DateTime.Now; + + public DateTime? DeletedTime { get; set; } + + public Guid? DeleteUserId { get; set; } + public bool IsDeleted {get;set;} + public bool IsReading { get; set; } = true; + + public string ImageResizePath { get; set; }=string.Empty; + + } +} diff --git a/IRaCIS.Core.Domain/Image/SCPStudy.cs b/IRaCIS.Core.Domain/Image/SCPStudy.cs new file mode 100644 index 000000000..c78222617 --- /dev/null +++ b/IRaCIS.Core.Domain/Image/SCPStudy.cs @@ -0,0 +1,95 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace IRaCIS.Core.Domain.Models +{ + [Table("SCPStudy")] + public class SCPStudy : Entity, IAuditUpdate, IAuditAdd, ISoftDelete + { + + + + + + //0 未知 1 单重 2 双重 + public bool IsDoubleReview { get; set; } + + [JsonIgnore] + public List InstanceList { get; set; } + + [JsonIgnore] + public List SeriesList { get; set; } + + + [DatabaseGenerated(DatabaseGeneratedOption.Identity)] + public Guid SeqId { get; set; } + + [ForeignKey("PatientId")] + [JsonIgnore] + public SCPPatient Patient { get; set; } + public Guid PatientId { get; set; } + + + + + public string StudyInstanceUid { get; set; } = string.Empty; + public DateTime? StudyTime { get; set; } + public string Modalities { get; set; } = string.Empty; + + public string Description { get; set; } = string.Empty; + public int SeriesCount { get; set; } = 0; + public int InstanceCount { get; set; } = 0; + + + public string InstitutionName { get; set; } = string.Empty; + public string PatientIdStr { get; set; } = string.Empty; + public string PatientName { get; set; } = string.Empty; + public string PatientAge { get; set; } = string.Empty; + public string PatientSex { get; set; } = string.Empty; + + public string StudyId { get; set; } = string.Empty; + public string AccessionNumber { get; set; } = string.Empty; + public string PatientBirthDate { get; set; } = string.Empty; + public string AcquisitionTime { get; set; } = string.Empty; + public string AcquisitionNumber { get; set; } = string.Empty; + public string TriggerTime { get; set; } = string.Empty; + + public string BodyPartExamined { get; set; } = string.Empty; + + public string BodyPartForEdit { get; set; } = string.Empty; + + public string ModalityForEdit { get; set; } = string.Empty; + + + + public Guid UpdateUserId { get; set; } + public DateTime UpdateTime { get; set; } = DateTime.Now; + public Guid CreateUserId { get; set; } + public DateTime CreateTime { get; set; } = DateTime.Now; + + + //软删除 + public bool IsDeleted { get; set; } + + public DateTime? DeletedTime { get; set; } + + public Guid? DeleteUserId { get; set; } + + public string CallingAE { get; set; } = string.Empty; + + public string CalledAE { get; set; } = string.Empty; + + public bool IsUploadFinished { get; set; } + + + + + public Guid? SubjectVisitId { get; set; } + + [JsonIgnore] + public SubjectVisit SubjectVisit { get; set; } + + } +} diff --git a/IRaCIS.Core.Domain/Image/TrialDicomAE.cs b/IRaCIS.Core.Domain/Image/TrialDicomAE.cs new file mode 100644 index 000000000..0d91a9c77 --- /dev/null +++ b/IRaCIS.Core.Domain/Image/TrialDicomAE.cs @@ -0,0 +1,52 @@ + +//-------------------------------------------------------------------- +// 此代码由T4模板自动生成 byzhouhang 20210918 +// 生成时间 2024-03-22 15:44:11 +// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。 +using System; +using IRaCIS.Core.Domain.Share; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; +namespace IRaCIS.Core.Domain.Models +{ + /// + ///DicomAE + /// + [Table("TrialDicomAE")] + public class TrialDicomAE : Entity, IAuditUpdate, IAuditAdd + { + + public Guid TrialId { get; set; } + + public DateTime CreateTime { get; set; } + + + public Guid CreateUserId { get; set; } + + + public Guid UpdateUserId { get; set; } + + + public DateTime UpdateTime { get; set; } + + public string CalledAE { get; set; } = string.Empty; + + public string IP { get; set; } + + + public int Port { get; set; } + + + public string Modality { get; set; } = string.Empty; + + + public string Description { get; set; }=string.Empty; + + + public DateTime? LatestTestTime { get; set; } + + public bool IsTestOK { get; set; } + + } + +} diff --git a/IRaCIS.Core.Domain/Trial/Trial.cs b/IRaCIS.Core.Domain/Trial/Trial.cs index e63ca4315..d00d43d55 100644 --- a/IRaCIS.Core.Domain/Trial/Trial.cs +++ b/IRaCIS.Core.Domain/Trial/Trial.cs @@ -401,7 +401,9 @@ namespace IRaCIS.Core.Domain.Models #endregion + public bool IsPACSConnect { get; set; } + public bool IsTrialPACSConfirmed { get; set; } ///// ///// 图像是否有标注 diff --git a/IRaCIS.Core.Domain/TrialSiteUser/TrialSiteDicomAE.cs b/IRaCIS.Core.Domain/TrialSiteUser/TrialSiteDicomAE.cs new file mode 100644 index 000000000..a23e4d5b6 --- /dev/null +++ b/IRaCIS.Core.Domain/TrialSiteUser/TrialSiteDicomAE.cs @@ -0,0 +1,59 @@ + +//-------------------------------------------------------------------- +// 此代码由T4模板自动生成 byzhouhang 20210918 +// 生成时间 2024-07-02 16:53:49 +// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。 +using System; +using IRaCIS.Core.Domain.Share; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; +namespace IRaCIS.Core.Domain.Models +{ + /// + ///TrialSiteDicomAE + /// + [Table("TrialSiteDicomAE")] + public class TrialSiteDicomAE : Entity, IAuditUpdate, IAuditAdd + { + + + + public DateTime? DeletedTime { get; set; } + + + public Guid TrialId { get; set; } + + + public Guid UpdateUserId { get; set; } + + + public Guid? DeleteUserId { get; set; } + + + public DateTime CreateTime { get; set; } + + + public Guid CreateUserId { get; set; } + + public bool IsDeleted { get; set; } + + public DateTime UpdateTime { get; set; } + + + public Guid TrialSiteId { get; set; } + + + public string CallingAE { get; set; } + + + public string IP { get; set; } + + + public string Port { get; set; } + + + public string Description { get; set; } + + } + +} diff --git a/IRaCIS.Core.Infra.EFCore/Context/IRaCISDBContext.cs b/IRaCIS.Core.Infra.EFCore/Context/IRaCISDBContext.cs index c5e8715c7..f4dcffdd9 100644 --- a/IRaCIS.Core.Infra.EFCore/Context/IRaCISDBContext.cs +++ b/IRaCIS.Core.Infra.EFCore/Context/IRaCISDBContext.cs @@ -483,6 +483,18 @@ namespace IRaCIS.Core.Infra.EFCore public virtual DbSet ExploreRecommend { get; set; } + public virtual DbSet SCPPatient { get; set; } + public virtual DbSet SCPStudy { get; set; } + public virtual DbSet SCPSeries { get; set; } + public virtual DbSet SCPInstance { get; set; } + public virtual DbSet TrialDicomAE { get; set; } + + + public virtual DbSet TrialSiteDicomAE { get; set; } + + + public virtual DbSet SCPImageUpload { get; set; } + public override async Task SaveChangesAsync(CancellationToken cancellationToken = new CancellationToken()) { diff --git a/IRaCIS.Core.Test/DbHelper.ttinclude b/IRaCIS.Core.Test/DbHelper.ttinclude index 649ef03e0..8790fcb50 100644 --- a/IRaCIS.Core.Test/DbHelper.ttinclude +++ b/IRaCIS.Core.Test/DbHelper.ttinclude @@ -4,7 +4,7 @@ public static readonly string ConnectionString = "Server=106.14.89.110,1435;Database=Test_IRC;User ID=sa;Password=xc@123456;TrustServerCertificate=true"; public static readonly string DbDatabase = "Test_IRC"; //表名称用字符串,拼接 - public static readonly string TableName = "ExploreRecommend"; + public static readonly string TableName = "TrialSiteDicomAE"; //具体文件里面 例如service 可以配置是否分页 } #> From 9f66a932fcdde4d6fd8cded40988b3c4335bbd00 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Wed, 3 Jul 2024 14:00:29 +0800 Subject: [PATCH 038/251] =?UTF-8?q?=E5=A2=9E=E5=8A=A0pacs=20=E7=9B=B4?= =?UTF-8?q?=E8=BF=9E=20=20scp=E9=A1=B9=E7=9B=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../BusinessFilter/ModelActionFilter .cs | 37 + IRC.Core.SCP/BusinessFilter/ModelBinding.cs | 28 + .../BusinessFilter/ProjectExceptionFilter.cs | 61 + .../BusinessFilter/UnifiedApiResultFilter.cs | 120 ++ IRC.Core.SCP/Helper/ImageHelper.cs | 62 + IRC.Core.SCP/HostConfig/AutofacModuleSetup.cs | 57 + IRC.Core.SCP/HostConfig/EFSetup.cs | 44 + .../HostConfig/NewtonsoftJsonSetup.cs | 59 + .../HostConfig/NullToEmptyStringResolver.cs | 36 + .../NullToEmptyStringValueProvider.cs | 42 + IRC.Core.SCP/IRC.Core.SCP.csproj | 38 + IRC.Core.SCP/Program.cs | 208 +++ IRC.Core.SCP/Properties/launchSettings.json | 31 + IRC.Core.SCP/Service/BaseService.cs | 118 ++ IRC.Core.SCP/Service/CStoreSCPService.cs | 368 +++++ IRC.Core.SCP/Service/DicomArchiveService.cs | 333 +++++ .../Service/Interface/IDicomArchiveService.cs | 11 + IRC.Core.SCP/Service/OSSService.cs | 427 ++++++ IRC.Core.SCP/appsettings.IRC_Prod_SCP.json | 63 + IRC.Core.SCP/appsettings.IRC_Test_SCP.json | 79 + IRC.Core.SCP/appsettings.IRC_US_SCP.json | 76 + IRC.Core.SCP/appsettings.IRC_Uat_SCP.json | 76 + IRC.Core.SCP/appsettings.json | 9 + IRaCIS.Core.API.sln | 6 + IRaCIS.Core.API/IRaCIS.Core.API.csproj | 9 +- .../Service/Common/ExploreRecommendService.cs | 2 +- .../Service/Visit/DTO/PatientViewModel.cs | 1083 ++++++++++++++ .../Service/Visit/PatientService.cs | 1323 +++++++++++++++++ .../IRaCIS.Core.Infrastructure.csproj | 10 +- 29 files changed, 4805 insertions(+), 11 deletions(-) create mode 100644 IRC.Core.SCP/BusinessFilter/ModelActionFilter .cs create mode 100644 IRC.Core.SCP/BusinessFilter/ModelBinding.cs create mode 100644 IRC.Core.SCP/BusinessFilter/ProjectExceptionFilter.cs create mode 100644 IRC.Core.SCP/BusinessFilter/UnifiedApiResultFilter.cs create mode 100644 IRC.Core.SCP/Helper/ImageHelper.cs create mode 100644 IRC.Core.SCP/HostConfig/AutofacModuleSetup.cs create mode 100644 IRC.Core.SCP/HostConfig/EFSetup.cs create mode 100644 IRC.Core.SCP/HostConfig/NewtonsoftJsonSetup.cs create mode 100644 IRC.Core.SCP/HostConfig/NullToEmptyStringResolver.cs create mode 100644 IRC.Core.SCP/HostConfig/NullToEmptyStringValueProvider.cs create mode 100644 IRC.Core.SCP/IRC.Core.SCP.csproj create mode 100644 IRC.Core.SCP/Program.cs create mode 100644 IRC.Core.SCP/Properties/launchSettings.json create mode 100644 IRC.Core.SCP/Service/BaseService.cs create mode 100644 IRC.Core.SCP/Service/CStoreSCPService.cs create mode 100644 IRC.Core.SCP/Service/DicomArchiveService.cs create mode 100644 IRC.Core.SCP/Service/Interface/IDicomArchiveService.cs create mode 100644 IRC.Core.SCP/Service/OSSService.cs create mode 100644 IRC.Core.SCP/appsettings.IRC_Prod_SCP.json create mode 100644 IRC.Core.SCP/appsettings.IRC_Test_SCP.json create mode 100644 IRC.Core.SCP/appsettings.IRC_US_SCP.json create mode 100644 IRC.Core.SCP/appsettings.IRC_Uat_SCP.json create mode 100644 IRC.Core.SCP/appsettings.json create mode 100644 IRaCIS.Core.Application/Service/Visit/DTO/PatientViewModel.cs create mode 100644 IRaCIS.Core.Application/Service/Visit/PatientService.cs diff --git a/IRC.Core.SCP/BusinessFilter/ModelActionFilter .cs b/IRC.Core.SCP/BusinessFilter/ModelActionFilter .cs new file mode 100644 index 000000000..2f0ec4873 --- /dev/null +++ b/IRC.Core.SCP/BusinessFilter/ModelActionFilter .cs @@ -0,0 +1,37 @@ +using IRaCIS.Core.Infrastructure.Extention; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.Filters; +using Microsoft.Extensions.Localization; +using Newtonsoft.Json; + + +namespace IRaCIS.Core.SCP.Filter +{ + + + public class ModelActionFilter : ActionFilterAttribute, IActionFilter + { + public IStringLocalizer _localizer; + public ModelActionFilter(IStringLocalizer localizer) + { + _localizer = localizer; + } + + public override void OnActionExecuting(ActionExecutingContext context) + { + if (!context.ModelState.IsValid) + { + + var validationErrors = context.ModelState + .Keys + .SelectMany(k => context.ModelState[k]!.Errors) + .Select(e => e.ErrorMessage) + .ToArray(); + + //---提供给接口的参数无效。 + context.Result = new JsonResult(ResponseOutput.NotOk(_localizer["ModelAction_InvalidAPIParameter"] + JsonConvert.SerializeObject( validationErrors))); + } + } + } + +} diff --git a/IRC.Core.SCP/BusinessFilter/ModelBinding.cs b/IRC.Core.SCP/BusinessFilter/ModelBinding.cs new file mode 100644 index 000000000..56e18b418 --- /dev/null +++ b/IRC.Core.SCP/BusinessFilter/ModelBinding.cs @@ -0,0 +1,28 @@ +using System; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc.Filters; +using Microsoft.AspNetCore.Mvc.ModelBinding; + +namespace IRaCIS.Core.SCP.Filter +{ + #region snippet_DisableFormValueModelBindingAttribute + [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)] + public class DisableFormValueModelBindingAttribute : Attribute, IResourceFilter + { + public void OnResourceExecuting(ResourceExecutingContext context) + { + + + var factories = context.ValueProviderFactories; + //factories.RemoveType(); + factories.RemoveType(); + factories.RemoveType(); + context.HttpContext.Request.EnableBuffering(); + } + + public void OnResourceExecuted(ResourceExecutedContext context) + { + } + } + #endregion +} diff --git a/IRC.Core.SCP/BusinessFilter/ProjectExceptionFilter.cs b/IRC.Core.SCP/BusinessFilter/ProjectExceptionFilter.cs new file mode 100644 index 000000000..0952bc457 --- /dev/null +++ b/IRC.Core.SCP/BusinessFilter/ProjectExceptionFilter.cs @@ -0,0 +1,61 @@ +using IRaCIS.Core.Infrastructure; +using IRaCIS.Core.Infrastructure.Extention; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.Filters; +using Microsoft.Extensions.Localization; +using Microsoft.Extensions.Logging; + +namespace IRaCIS.Core.SCP.Filter +{ + public class ProjectExceptionFilter : Attribute, IExceptionFilter + { + private readonly ILogger _logger; + + public IStringLocalizer _localizer; + + public ProjectExceptionFilter(IStringLocalizer localizer, ILogger logger) + { + _logger = logger; + _localizer = localizer; + } + public void OnException(ExceptionContext context) + { + //context.ExceptionHandled;//记录当前这个异常是否已经被处理过了 + + if (!context.ExceptionHandled) + { + if (context.Exception.GetType().Name == "DbUpdateConcurrencyException") + { + //---并发更新,当前不允许该操作 + context.Result = new JsonResult(ResponseOutput.NotOk(_localizer["ProjectException_ConcurrentUpdateNotAllowed"] + context.Exception.Message)); + } + + if (context.Exception.GetType() == typeof(BusinessValidationFailedException)) + { + var error = context.Exception as BusinessValidationFailedException; + + context.Result = new JsonResult(ResponseOutput.NotOk(context.Exception.Message, error!.Code)); + } + else if(context.Exception.GetType() == typeof(QueryBusinessObjectNotExistException)) + { + context.Result = new JsonResult(ResponseOutput.NotOk( context.Exception.Message, ApiResponseCodeEnum.DataNotExist)); + } + else + { + context.Result = new JsonResult(ResponseOutput.NotOk(_localizer["Project_ExceptionContactDeveloper"] + (context.Exception.InnerException is null ? (context.Exception.Message /*+ context.Exception.StackTrace*/) + : (context.Exception.InnerException?.Message /*+ context.Exception.InnerException?.StackTrace*/)), ApiResponseCodeEnum.ProgramException)); + } + + + _logger.LogError(context.Exception.InnerException is null ? (context.Exception.Message + context.Exception.StackTrace) : (context.Exception.InnerException?.Message + context.Exception.InnerException?.StackTrace)); + + + } + else + { + //继续 + } + context.ExceptionHandled = true;//标记当前异常已经被处理过了 + } + } +} diff --git a/IRC.Core.SCP/BusinessFilter/UnifiedApiResultFilter.cs b/IRC.Core.SCP/BusinessFilter/UnifiedApiResultFilter.cs new file mode 100644 index 000000000..7609ae4bc --- /dev/null +++ b/IRC.Core.SCP/BusinessFilter/UnifiedApiResultFilter.cs @@ -0,0 +1,120 @@ +using Microsoft.AspNetCore.Mvc.Filters; +using Microsoft.AspNetCore.Mvc; +using IRaCIS.Core.Domain.Share; +using IRaCIS.Core.Infrastructure.Extention; + +namespace IRaCIS.Application.Services.BusinessFilter +{ + /// + /// 统一返回前端数据包装,之前在控制器包装,现在修改为动态Api 在ResultFilter这里包装,减少重复冗余代码 + /// by zhouhang 2021.09.12 周末 + /// + public class UnifiedApiResultFilter : Attribute, IAsyncResultFilter + { + /// + /// 异步版本 + /// + /// + /// + /// + public async Task OnResultExecutionAsync(ResultExecutingContext context, ResultExecutionDelegate next) + { + + if (context.Result is ObjectResult objectResult) + { + var statusCode = objectResult.StatusCode ?? context.HttpContext.Response.StatusCode; + + //是200 并且没有包装 那么包装结果 + if (statusCode == 200 && !(objectResult.Value is IResponseOutput)) + { + //if (objectResult.Value == null) + //{ + // var apiResponse = ResponseOutput.DBNotExist(); + + // objectResult.Value = apiResponse; + // objectResult.DeclaredType = apiResponse.GetType(); + //} + //else + //{ + + var type = objectResult.Value?.GetType(); + + + if ( type!=null&& type.IsGenericType&&(type.GetGenericTypeDefinition()==typeof(ValueTuple<,>)|| type.GetGenericTypeDefinition()==typeof(Tuple<,>))) + { + + //报错 + //var tuple = (object, object))objectResult.Value; + + //var (val1, val2) = ((dynamic, dynamic))objectResult.Value; + //var apiResponse = ResponseOutput.Ok(val1, val2); + + //OK + var tuple = (dynamic)objectResult.Value; + var apiResponse = ResponseOutput.Ok(tuple.Item1, tuple.Item2); + + + objectResult.Value = apiResponse; + objectResult.DeclaredType = apiResponse.GetType(); + } + else + { + var apiResponse = ResponseOutput.Ok(objectResult.Value); + + objectResult.Value = apiResponse; + objectResult.DeclaredType = apiResponse.GetType(); + } + + + //} + + } + //如果不是200 是IResponseOutput 不处理 + else if (statusCode != 200 && (objectResult.Value is IResponseOutput)) + { + } + + else if(statusCode != 200&&!(objectResult.Value is IResponseOutput)) + { + //---程序错误,请联系开发人员。 + var apiResponse = ResponseOutput.NotOk(StaticData.International("UnifiedAPI_ProgramError")); + + objectResult.Value = apiResponse; + objectResult.DeclaredType = apiResponse.GetType(); + } + + } + + await next.Invoke(); + + } + + public static bool IsTupleType(Type type, bool checkBaseTypes = false) + { + if (type == null) + throw new ArgumentNullException(nameof(type)); + + if (type == typeof(Tuple)) + return true; + + while (type != null) + { + if (type.IsGenericType) + { + var genType = type.GetGenericTypeDefinition(); + if (genType == typeof(Tuple<>) + || genType == typeof(Tuple<,>) + || genType == typeof(Tuple<,>)) + return true; + } + + if (!checkBaseTypes) + break; + + type = type.BaseType; + } + + return false; + } + } +} diff --git a/IRC.Core.SCP/Helper/ImageHelper.cs b/IRC.Core.SCP/Helper/ImageHelper.cs new file mode 100644 index 000000000..50f0ab4f6 --- /dev/null +++ b/IRC.Core.SCP/Helper/ImageHelper.cs @@ -0,0 +1,62 @@ + +using FellowOakDicom.Imaging; +using SixLabors.ImageSharp.Formats.Jpeg; +using SixLabors.ImageSharp; +using SixLabors.ImageSharp.Processing; +using System.Security.Cryptography; +using System.Text; + +namespace IRaCIS.Core.Application.Helper; + +public static class ImageHelper +{ + + // 采用ImageSharp组件 跨平台,不依赖windows 平台图像处理组件,这里大坑(net 6 下,之前由于Dicom处理最新组件 依赖了这个库的一个旧版本,导致缩略图bug,单独升级依赖组件才解决) + public static void ResizeSave(string filePath, string? fileStorePath) + { + + fileStorePath = fileStorePath ?? filePath + ".preview.jpeg"; + + using (var image = SixLabors.ImageSharp.Image.Load(filePath)) + { + + image.Mutate(x => x.Resize(500, 500)); + + image.Save(fileStorePath); + + } + } + + + + public static Stream RenderPreviewJpeg(string filePath) + { + string jpegPath = filePath + ".preview.jpg"; + + if (!File.Exists(jpegPath)) + { + using (Stream stream = new FileStream(jpegPath, FileMode.Create)) + { + DicomImage image = new DicomImage(filePath); + + var sharpimage = image.RenderImage().AsSharpImage(); + + sharpimage.Save(stream, new JpegEncoder()); + + } + } + + return new FileStream(jpegPath, FileMode.Open); + } + + public static void RemovePreviewJpeg(string filePath) + { + string jpegPath = filePath + ".preview.jpg"; + if (File.Exists(jpegPath)) File.Delete(jpegPath); + } + + +} + + + diff --git a/IRC.Core.SCP/HostConfig/AutofacModuleSetup.cs b/IRC.Core.SCP/HostConfig/AutofacModuleSetup.cs new file mode 100644 index 000000000..183eb235b --- /dev/null +++ b/IRC.Core.SCP/HostConfig/AutofacModuleSetup.cs @@ -0,0 +1,57 @@ +using Autofac; +using IRaCIS.Core.Infra.EFCore; +using Microsoft.AspNetCore.Http; +using Panda.DynamicWebApi; +using System; +using System.Linq; +using System.Reflection; +using IRaCIS.Core.Domain.Models; +using IRaCIS.Core.Domain.Share; +using IRaCIS.Application.Services; +using AutoMapper; +using IRaCIS.Core.SCP.Service; + +namespace IRaCIS.Core.SCP +{ + // ReSharper disable once IdentifierTypo + public class AutofacModuleSetup : Autofac.Module + { + protected override void Load(ContainerBuilder containerBuilder) + { + + #region byzhouhang 20210917 此处注册泛型仓储 可以减少Domain层 和Infra.EFcore 两层 空的仓储接口定义和 仓储文件定义 + + containerBuilder.RegisterGeneric(typeof(Repository<>)) + .As(typeof(IRepository<>)).InstancePerLifetimeScope();//注册泛型仓储 + + containerBuilder.RegisterType().As().InstancePerLifetimeScope(); + + + #endregion + + #region 指定控制器也由autofac 来进行实例获取 https://www.cnblogs.com/xwhqwer/p/15320838.html + + //获取所有控制器类型并使用属性注入 + containerBuilder.RegisterAssemblyTypes(typeof(BaseService).Assembly) + .Where(type => typeof(IDynamicWebApi).IsAssignableFrom(type)) + .PropertiesAutowired(); + + #endregion + + + + Assembly application = Assembly.LoadFrom(AppDomain.CurrentDomain.BaseDirectory + "IRaCIS.Core.SCP.dll"); + containerBuilder.RegisterAssemblyTypes(application).Where(t => t.FullName.Contains("Service")) + .PropertiesAutowired().AsImplementedInterfaces(); + + + containerBuilder.RegisterType().As().SingleInstance(); + containerBuilder.RegisterType().As().InstancePerLifetimeScope(); + + + + + + } + } +} \ No newline at end of file diff --git a/IRC.Core.SCP/HostConfig/EFSetup.cs b/IRC.Core.SCP/HostConfig/EFSetup.cs new file mode 100644 index 000000000..b53095cbd --- /dev/null +++ b/IRC.Core.SCP/HostConfig/EFSetup.cs @@ -0,0 +1,44 @@ +using IRaCIS.Core.Infra.EFCore; +using Medallion.Threading; +using Medallion.Threading.SqlServer; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; + +namespace IRaCIS.Core.SCP +{ + public static class EFSetup + { + public static void AddEFSetup( this IServiceCollection services, IConfiguration configuration) + { + //services.AddScoped(); + + //这个注入没有成功--注入是没问题的,构造函数也只是支持参数就好,错在注入的地方不能写DbContext + //Web程序中通过重用池中DbContext实例可提高高并发场景下的吞吐量, 这在概念上类似于ADO.NET Provider原生的连接池操作方式,具有节省DbContext实例化成本的优点 + services.AddDbContext(options => + { + options.UseSqlServer(configuration.GetSection("ConnectionStrings:RemoteNew").Value, + contextOptionsBuilder => contextOptionsBuilder.EnableRetryOnFailure()); + + options.EnableSensitiveDataLogging(); + + options.AddInterceptors(new QueryWithNoLockDbCommandInterceptor()); + + options.UseProjectables(); + + + + }); + + //注意区分 easy caching 也有 IDistributedLockProvider + services.AddSingleton(sp => + { + //var connection = ConnectionMultiplexer.Connect(configuration["Redis:Configuration"]!); + + return new SqlDistributedSynchronizationProvider(configuration.GetSection("ConnectionStrings:RemoteNew").Value); + }); + + //services.AddAssemblyTriggers(typeof(SubjectVisitImageDateTrigger).Assembly); + } + } +} diff --git a/IRC.Core.SCP/HostConfig/NewtonsoftJsonSetup.cs b/IRC.Core.SCP/HostConfig/NewtonsoftJsonSetup.cs new file mode 100644 index 000000000..00d5ae329 --- /dev/null +++ b/IRC.Core.SCP/HostConfig/NewtonsoftJsonSetup.cs @@ -0,0 +1,59 @@ + + +using Microsoft.Extensions.DependencyInjection; +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; +using System; + +namespace IRaCIS.Core.SCP +{ + public static class NewtonsoftJsonSetup + { + public static void AddNewtonsoftJsonSetup(this IMvcBuilder builder, IServiceCollection services) + { + services.AddHttpContextAccessor(); + services.AddScoped(); + + builder.AddNewtonsoftJson(options => + { + //options.SerializerSettings.PreserveReferencesHandling = PreserveReferencesHandling.Objects; + // 忽略循环引用 + options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore; + //options.SerializerSettings.TypeNameHandling = TypeNameHandling.All; + + //处理返回给前端 可空类型 给出默认值 比如in? 为null 设置 默认值0 + options.SerializerSettings.ContractResolver = new NullToEmptyStringResolver(); //new DefaultContractResolver();// new NullToEmptyStringResolver(); + // 设置时间格式 + options.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss"; + + options.SerializerSettings.DateTimeZoneHandling = DateTimeZoneHandling.RoundtripKind; + + //options.SerializerSettings.Converters.Add(new JSONCustomDateConverter()) ; + + //options.SerializerSettings.Converters.Add(services.BuildServiceProvider().GetService()); + + + + }) + .AddControllersAsServices()//动态webApi属性注入需要 + .ConfigureApiBehaviorOptions(o => + { + o.SuppressModelStateInvalidFilter = true; //自己写验证 + + }); + + + Newtonsoft.Json.JsonSerializerSettings setting = new Newtonsoft.Json.JsonSerializerSettings(); + JsonConvert.DefaultSettings = new Func(() => + { + //日期类型默认格式化处理 + setting.DateFormatString = "yyyy-MM-dd HH:mm:ss"; + setting.ReferenceLoopHandling = ReferenceLoopHandling.Ignore; + + return setting; + }); + + + } + } +} diff --git a/IRC.Core.SCP/HostConfig/NullToEmptyStringResolver.cs b/IRC.Core.SCP/HostConfig/NullToEmptyStringResolver.cs new file mode 100644 index 000000000..f4bd469a6 --- /dev/null +++ b/IRC.Core.SCP/HostConfig/NullToEmptyStringResolver.cs @@ -0,0 +1,36 @@ +using Newtonsoft.Json; +using Newtonsoft.Json.Serialization; +using System; +using System.Collections.Generic; +using System.Linq; + +namespace IRaCIS.Core.SCP +{ + public class NullToEmptyStringResolver : DefaultContractResolver + { + + + protected override IList CreateProperties(Type type, MemberSerialization memberSerialization) + { + IList properties = base.CreateProperties(type, memberSerialization); + + var list= type.GetProperties() + .Select(p => + { + var jp = base.CreateProperty(p, memberSerialization); + jp.ValueProvider = new NullToEmptyStringValueProvider(p); + return jp; + }).ToList(); + + var uu = list.Select(t => t.PropertyName).ToList(); + + //获取复杂对象属性 + properties = properties.TakeWhile(t => !uu.Contains(t.PropertyName)).ToList(); + + list.AddRange(properties); + return list; + } + + + } +} diff --git a/IRC.Core.SCP/HostConfig/NullToEmptyStringValueProvider.cs b/IRC.Core.SCP/HostConfig/NullToEmptyStringValueProvider.cs new file mode 100644 index 000000000..10e7e613d --- /dev/null +++ b/IRC.Core.SCP/HostConfig/NullToEmptyStringValueProvider.cs @@ -0,0 +1,42 @@ +using System; +using System.Reflection; +using Newtonsoft.Json.Serialization; + +namespace IRaCIS.Core.SCP +{ + + public class NullToEmptyStringValueProvider : IValueProvider + { + PropertyInfo _MemberInfo; + public NullToEmptyStringValueProvider(PropertyInfo memberInfo) + { + _MemberInfo = memberInfo; + } + public object GetValue(object target) + { + object result = _MemberInfo.GetValue(target); + if (_MemberInfo.PropertyType == typeof(string) && result == null) result = ""; + else if (_MemberInfo.PropertyType == typeof(String[]) && result == null) result = new string[] { }; + //else if (_MemberInfo.PropertyType == typeof(Nullable) && result == null) result = 0; + else if (_MemberInfo.PropertyType == typeof(Nullable) && result == null) result = 0.00M; + + return result; + } + public void SetValue(object target, object value) + { + + if(_MemberInfo.PropertyType == typeof(string)) + { + //去掉前后空格 + _MemberInfo.SetValue(target, value==null?string.Empty: value.ToString()==string.Empty? value:value.ToString().Trim()); + + } + else + { + _MemberInfo.SetValue(target, value); + } + + } + } + +} diff --git a/IRC.Core.SCP/IRC.Core.SCP.csproj b/IRC.Core.SCP/IRC.Core.SCP.csproj new file mode 100644 index 000000000..9407aa2ba --- /dev/null +++ b/IRC.Core.SCP/IRC.Core.SCP.csproj @@ -0,0 +1,38 @@ + + + + net8.0 + enable + enable + + + + + + + + + + + + + + + + true + + + + + + + + + + + + + + + + diff --git a/IRC.Core.SCP/Program.cs b/IRC.Core.SCP/Program.cs new file mode 100644 index 000000000..5ad53894d --- /dev/null +++ b/IRC.Core.SCP/Program.cs @@ -0,0 +1,208 @@ + +using Autofac; +using Autofac.Extensions.DependencyInjection; +using AutoMapper.EquivalencyExpression; +using FellowOakDicom; +using FellowOakDicom.Imaging; +using FellowOakDicom.Imaging.NativeCodec; +using FellowOakDicom.Network; +using IRaCIS.Core.Infra.EFCore; +using IRaCIS.Core.SCP; +using IRaCIS.Core.SCP.Filter; +using IRaCIS.Core.SCP.Service; +using MassTransit; +using MassTransit.NewIdProviders; +using Microsoft.AspNetCore.HttpOverrides; +using Microsoft.Extensions.DependencyInjection; +using Panda.DynamicWebApi; +using Serilog; +using Serilog.Events; +using System.Runtime.InteropServices; + + +//以配置文件为准,否则 从url中取环境值(服务以命令行传递参数启动,配置文件配置了就不需要传递环境参数) +var config = new ConfigurationBuilder() + .AddEnvironmentVariables() + .Build(); + +var enviromentName = config["ASPNETCORE_ENVIRONMENT"]; + +var builder = WebApplication.CreateBuilder(new WebApplicationOptions +{ + EnvironmentName = enviromentName +}); + +#region 兼容windows 服务命令行的方式 + +int urlsIndex = Array.FindIndex(args, arg => arg != null && arg.StartsWith("--port")); + +if (urlsIndex > -1) +{ + var port = args[urlsIndex].Substring("--port=".Length); + Console.WriteLine(port); + builder.WebHost.UseUrls($"http://0.0.0.0:{port}"); +} + +#endregion + +#region 主机配置 + +NewId.SetProcessIdProvider(new CurrentProcessIdProvider()); + +builder.Configuration.AddJsonFile("appsettings.json", false, true) + .AddJsonFile($"appsettings.{enviromentName}.json", false, true); +builder.Host + .UseServiceProviderFactory(new AutofacServiceProviderFactory()) + .ConfigureContainer(containerBuilder => + { + containerBuilder.RegisterModule(); + }) + .UseSerilog(); +#endregion + +#region 配置服务 +var _configuration = builder.Configuration; + +//健康检查 +builder.Services.AddHealthChecks(); + +//本地化 +builder.Services.AddJsonLocalization(options => options.ResourcesPath = "Resources"); + + +// 异常、参数统一验证过滤器、Json序列化配置、字符串参数绑型统一Trim() +builder.Services.AddControllers(options => +{ + //options.Filters.Add(); + options.Filters.Add(); + options.Filters.Add(); + options.Filters.Add(); + + +}) + .AddNewtonsoftJsonSetup(builder.Services); // NewtonsoftJson 序列化 处理 + + +builder.Services.AddOptions().Configure(_configuration.GetSection("AliyunOSS")); +builder.Services.AddOptions().Configure(_configuration.GetSection("ObjectStoreService")); +builder.Services.AddOptions().Configure(_configuration.GetSection("DicomSCPServiceConfig")); + + +//动态WebApi + UnifiedApiResultFilter 省掉控制器代码 +//动态webApi 目前存在的唯一小坑是生成api上服务上的动态代理AOP失效 间接掉用不影响 +builder.Services + .AddDynamicWebApi(dynamicWebApiOption => + { + //默认是 api + dynamicWebApiOption.DefaultApiPrefix = ""; + //首字母小写 + dynamicWebApiOption.GetRestFulActionName = (actionName) => char.ToLower(actionName[0]) + actionName.Substring(1); + //删除 Service后缀 + dynamicWebApiOption.RemoveControllerPostfixes.Add("Service"); + + }); + +//AutoMapper +builder.Services.AddAutoMapper(automapper => +{ + + automapper.AddCollectionMappers(); + + +}, typeof(BaseService).Assembly); + +//EF ORM QueryWithNoLock +builder.Services.AddEFSetup(_configuration); + + +//转发头设置 获取真实IP +builder.Services.Configure(options => +{ + options.ForwardedHeaders = + ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto; +}); + +//Dicom影像渲染图片 跨平台 +//builder.Services.AddDicomSetup(); +new DicomSetupBuilder() + .RegisterServices(s => + s.AddFellowOakDicom() + .AddTranscoderManager() + //.AddTranscoderManager() + .AddImageManager()) + .SkipValidation() + .Build(); + + + +#endregion + +// Add services to the container. + +builder.Services.AddControllers(); +// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle +builder.Services.AddEndpointsApiExplorer(); +builder.Services.AddSwaggerGen(); + +var app = builder.Build(); + +// Configure the HTTP request pipeline. +//if (app.Environment.IsDevelopment()) +//{ +app.UseSwagger(); +app.UseSwaggerUI(); +//} + +app.UseAuthorization(); + +app.MapControllers(); + +#region 日志 + +Log.Logger = new LoggerConfiguration() + .MinimumLevel.Information() + .MinimumLevel.Override("Microsoft", LogEventLevel.Information) + // Filter out ASP.NET Core infrastructre logs that are Information and below 日志太多了 一个请求 记录好几条 + .MinimumLevel.Override("Microsoft.AspNetCore", LogEventLevel.Warning) + .MinimumLevel.Override("Hangfire", LogEventLevel.Warning) + .MinimumLevel.Override("System.Net.Http.HttpClient.HttpReports", LogEventLevel.Warning) + .Enrich.WithClientIp() + + .Enrich.FromLogContext() + + //控制台 方便调试 问题 我们显示记录日志 时 获取上下文的ip 和用户名 用户类型 + .WriteTo.Console(restrictedToMinimumLevel: LogEventLevel.Warning, + outputTemplate: "[{Timestamp:HH:mm:ss} {Level:u3}] {SourceContext:l} || {Message} || {Exception} ||end {NewLine}") + + .WriteTo.File($"{AppContext.BaseDirectory}Serilogs/.log", rollingInterval: RollingInterval.Day, + outputTemplate: "[{Timestamp:HH:mm:ss} {Level:u3}] {SourceContext:l} || {Message} || {Exception} ||end {NewLine}") + .CreateLogger(); + + +#endregion + + +#region 运行环境 部署平台 + +Log.Logger.Warning($"当前环境:{enviromentName}"); + +if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) +{ + Log.Logger.Warning($"当前部署平台环境:windows"); +} +else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) +{ + Log.Logger.Warning($"当前部署平台环境:linux"); +} +else +{ + Log.Logger.Warning($"当前部署平台环境:OSX or FreeBSD"); +} + +#endregion + + +var server = DicomServerFactory.Create(_configuration.GetSection("DicomSCPServiceConfig").GetValue("ServerPort"), userState: app.Services); + + +app.Run(); diff --git a/IRC.Core.SCP/Properties/launchSettings.json b/IRC.Core.SCP/Properties/launchSettings.json new file mode 100644 index 000000000..ec782f999 --- /dev/null +++ b/IRC.Core.SCP/Properties/launchSettings.json @@ -0,0 +1,31 @@ +{ + "$schema": "http://json.schemastore.org/launchsettings.json", + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:36358", + "sslPort": 0 + } + }, + "profiles": { + "http": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "launchUrl": "swagger", + "applicationUrl": "http://localhost:5243", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "launchUrl": "swagger", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} diff --git a/IRC.Core.SCP/Service/BaseService.cs b/IRC.Core.SCP/Service/BaseService.cs new file mode 100644 index 000000000..a10e9bf9c --- /dev/null +++ b/IRC.Core.SCP/Service/BaseService.cs @@ -0,0 +1,118 @@ +using AutoMapper; +using IRaCIS.Application.Services.BusinessFilter; +using IRaCIS.Core.Infra.EFCore; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.Localization; +using Panda.DynamicWebApi; +using Panda.DynamicWebApi.Attributes; +using System.Diagnostics.CodeAnalysis; +using IRaCIS.Core.Domain.Share; +using IRaCIS.Core.Infrastructure.Extention; +using IRaCIS.Core.Domain.Models; + +namespace IRaCIS.Core.SCP.Service +{ + +#pragma warning disable CS8618 + + + #region 非泛型版本 + + [Authorize, DynamicWebApi, UnifiedApiResultFilter] + public class BaseService : IBaseService, IDynamicWebApi + { + public IMapper _mapper { get; set; } + + public IUserInfo _userInfo { get; set; } + + public IRepository _repository { get; set; } + + public IStringLocalizer _localizer { get; set; } + + public IWebHostEnvironment _hostEnvironment { get; set; } + + + + + public static IResponseOutput Null404NotFound(TEntity? businessObject) where TEntity : class + { + return new ResponseOutput() + .NotOk($"The query object {typeof(TEntity).Name} does not exist , or was deleted by someone else, or an incorrect parameter query caused", code: ApiResponseCodeEnum.DataNotExist); + } + } + + + public interface IBaseService + { + [MemberNotNull(nameof(_mapper))] + public IMapper _mapper { get; set; } + + [MemberNotNull(nameof(_userInfo))] + public IUserInfo _userInfo { get; set; } + + [MemberNotNull(nameof(_repository))] + public IRepository _repository { get; set; } + + [MemberNotNull(nameof(_localizer))] + public IStringLocalizer _localizer { get; set; } + + [MemberNotNull(nameof(_hostEnvironment))] + public IWebHostEnvironment _hostEnvironment { get; set; } + + } + #endregion + + + #region 泛型版本测试 + + + public interface IBaseServiceTest where T : Entity + { + [MemberNotNull(nameof(_mapper))] + public IMapper _mapper { get; set; } + + [MemberNotNull(nameof(_userInfo))] + public IUserInfo _userInfo { get; set; } + + [MemberNotNull(nameof(_repository))] + public IRepository _repository { get; set; } + + [MemberNotNull(nameof(_localizer))] + public IStringLocalizer _localizer { get; set; } + + + + } + + + [Authorize, DynamicWebApi, UnifiedApiResultFilter] + public class BaseServiceTest : IBaseServiceTest, IDynamicWebApi where T : Entity + { + public IMapper _mapper { get; set; } + + public IUserInfo _userInfo { get; set; } + + public IRepository _repository { get; set; } + + public IStringLocalizer _localizer { get; set; } + + public static IResponseOutput Null404NotFound(TEntity? businessObject) where TEntity : class + { + return new ResponseOutput() + .NotOk($"The query object {typeof(TEntity).Name} does not exist , or was deleted by someone else, or an incorrect parameter query caused", code: ApiResponseCodeEnum.DataNotExist); + } + + + } + + + #endregion + + + + + + + +} diff --git a/IRC.Core.SCP/Service/CStoreSCPService.cs b/IRC.Core.SCP/Service/CStoreSCPService.cs new file mode 100644 index 000000000..a81e11ec1 --- /dev/null +++ b/IRC.Core.SCP/Service/CStoreSCPService.cs @@ -0,0 +1,368 @@ +using FellowOakDicom.Network; +using FellowOakDicom; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using IRaCIS.Core.SCP.Service; +using IRaCIS.Core.Domain.Models; +using IRaCIS.Core.Infra.EFCore; +using Medallion.Threading; +using IRaCIS.Core.Domain.Share; +using Serilog; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion.Internal; +using Microsoft.Extensions.Options; +using System.Data; +using FellowOakDicom.Imaging; +using SharpCompress.Common; +using SixLabors.ImageSharp.Formats.Jpeg; +using IRaCIS.Core.Infrastructure; + +namespace IRaCIS.Core.SCP.Service +{ + /// + /// 后台托管服务的方式运行 + /// + //public class CStoreSCPHostedService : IHostedService + //{ + // private readonly ILogger _logger; + // private readonly IDicomServerFactory _dicomServerFactory; + // private IDicomServer? _server; + + // public CStoreSCPHostedService(ILogger logger, IDicomServerFactory dicomServerFactory) + // { + // _logger = logger ?? throw new ArgumentNullException(nameof(logger)); + // _dicomServerFactory = dicomServerFactory ?? throw new ArgumentNullException(nameof(dicomServerFactory)); + // } + + // public async Task StartAsync(CancellationToken cancellationToken) + // { + // _logger.LogInformation("Starting DICOM server"); + // _server = _dicomServerFactory.Create(104); + // _logger.LogInformation("DICOM server is running"); + // } + + // public Task StopAsync(CancellationToken cancellationToken) + // { + // if (_server != null) + // { + // _server.Stop(); + // _server.Dispose(); + // _server = null; + // } + // return Task.CompletedTask; + // } + //} + public class DicomSCPServiceOption + { + public List CalledAEList { get; set; } + + public string ServerPort { get; set; } + } + + + + + public class CStoreSCPService : DicomService, IDicomServiceProvider, IDicomCStoreProvider, IDicomCEchoProvider + { + private IServiceProvider _serviceProvider { get; set; } + + private List _SCPStudyIdList { get; set; } = new List(); + + private SCPImageUpload _upload { get; set; } + + + private static readonly DicomTransferSyntax[] _acceptedTransferSyntaxes = new DicomTransferSyntax[] + { + DicomTransferSyntax.ExplicitVRLittleEndian, + DicomTransferSyntax.ExplicitVRBigEndian, + DicomTransferSyntax.ImplicitVRLittleEndian + }; + + private static readonly DicomTransferSyntax[] _acceptedImageTransferSyntaxes = new DicomTransferSyntax[] + { + // Lossless + DicomTransferSyntax.JPEGLSLossless, + DicomTransferSyntax.JPEG2000Lossless, + DicomTransferSyntax.JPEGProcess14SV1, + DicomTransferSyntax.JPEGProcess14, + DicomTransferSyntax.RLELossless, + // Lossy + DicomTransferSyntax.JPEGLSNearLossless, + DicomTransferSyntax.JPEG2000Lossy, + DicomTransferSyntax.JPEGProcess1, + DicomTransferSyntax.JPEGProcess2_4, + // Uncompressed + DicomTransferSyntax.ExplicitVRLittleEndian, + DicomTransferSyntax.ExplicitVRBigEndian, + DicomTransferSyntax.ImplicitVRLittleEndian + }; + + + public CStoreSCPService(INetworkStream stream, Encoding fallbackEncoding, Microsoft.Extensions.Logging.ILogger log, DicomServiceDependencies dependencies) + : base(stream, fallbackEncoding, log, dependencies) + { + } + + + + + public Task OnReceiveAssociationRequestAsync(DicomAssociation association) + { + + _upload = new SCPImageUpload() { StartTime = DateTime.Now, CallingAE = association.CallingAE, CalledAE = association.CalledAE, CallingAEIP = association.RemoteHost }; + + + Log.Logger.Warning($"接收到来自{association.CallingAE}的连接"); + + _serviceProvider = (IServiceProvider)this.UserState; + + var option = _serviceProvider.GetService>().CurrentValue; + + + + var calledAEList = option.CalledAEList; + + if (!calledAEList.Contains(association.CalledAE)) + + //if (association.CalledAE != "STORESCP") + { + + Log.Logger.Warning($"拒绝CalledAE:{association.CalledAE}的连接"); + + return SendAssociationRejectAsync( + DicomRejectResult.Permanent, + DicomRejectSource.ServiceUser, + DicomRejectReason.CalledAENotRecognized); + } + + foreach (var pc in association.PresentationContexts) + { + if (pc.AbstractSyntax == DicomUID.Verification) + { + pc.AcceptTransferSyntaxes(_acceptedTransferSyntaxes); + } + else if (pc.AbstractSyntax.StorageCategory != DicomStorageCategory.None) + { + pc.AcceptTransferSyntaxes(_acceptedImageTransferSyntaxes); + } + } + + return SendAssociationAcceptAsync(association); + } + + + public async Task OnReceiveAssociationReleaseRequestAsync() + { + await DataMaintenanceAsaync(); + + //记录监控 + + var _SCPImageUploadRepository = _serviceProvider.GetService>(); + + _upload.EndTime = DateTime.Now; + _upload.StudyCount = _SCPStudyIdList.Count; + + await _SCPImageUploadRepository.AddAsync(_upload,true); + + await SendAssociationReleaseResponseAsync(); + } + + + private async Task DataMaintenanceAsaync() + { + Log.Logger.Warning($"CallingAE:{Association.CallingAE} CalledAE:{Association.CalledAE}传输结束:开始维护数据,处理检查Modality 以及自动创建访视,绑定检查"); + + //var patientStudyService = _serviceProvider.GetService(); + + //await patientStudyService.AutoBindingPatientStudyVisitAsync(_SCPStudyIdList); + + //处理检查Modality + var _dictionaryRepository = _serviceProvider.GetService>(); + var _seriesRepository = _serviceProvider.GetService>(); + var _studyRepository = _serviceProvider.GetService>(); + + var dicModalityList = _dictionaryRepository.Where(t => t.Code == "Modality").SelectMany(t => t.ChildList.Select(c => c.Value)).ToList(); + var seriesModalityList = _seriesRepository.Where(t => _SCPStudyIdList.Contains(t.StudyId)).Select(t => new { SCPStudyId = t.StudyId, t.Modality }).ToList(); + + foreach (var g in seriesModalityList.GroupBy(t => t.SCPStudyId)) + { + var modality = string.Join('、', g.Select(t => t.Modality).Distinct().ToList()); + + //特殊逻辑 + var modalityForEdit = dicModalityList.Contains(modality) ? modality : String.Empty; + + if (modality == "MR") + { + modalityForEdit = "MRI"; + } + + if (modality == "PT") + { + modalityForEdit = "PET"; + } + if (modality == "PT、CT" || modality == "CT、PT") + { + modalityForEdit = "PET-CT"; + } + + await _studyRepository.BatchUpdateNoTrackingAsync(t => t.Id == g.Key, u => new SCPStudy() { Modalities = modality, ModalityForEdit = modalityForEdit }); + + } + + Log.Logger.Warning($"CallingAE:{Association.CallingAE} CalledAE:{Association.CalledAE}维护数据结束"); + } + + public void OnReceiveAbort(DicomAbortSource source, DicomAbortReason reason) + { + Log.Logger.Warning($"CallingAE:{Association.CallingAE} CalledAE:{Association.CalledAE}接收中断,中断原因:{source.ToString() + reason.ToString()}"); + /* nothing to do here */ + } + + + public async void OnConnectionClosed(Exception exception) + { + /* nothing to do here */ + + //奇怪的bug 上传的时候,用王捷修改的影像,会关闭,重新连接,导致检查id 丢失,然后状态不一致 + if (exception == null) + { + var _studyRepository = _serviceProvider.GetService>(); + //将检查设置为传输结束 + await _studyRepository.BatchUpdateNoTrackingAsync(t => _SCPStudyIdList.Contains(t.Id), u => new SCPStudy() { IsUploadFinished = true }); + + await _studyRepository.SaveChangesAndClearAllTrackingAsync(); + } + + Log.Logger.Warning($"连接关闭 {exception?.Message} {exception?.InnerException?.Message}"); + } + + + + + public async Task OnCStoreRequestAsync(DicomCStoreRequest request) + { + + string studyInstanceUid = request.Dataset.GetString(DicomTag.StudyInstanceUID); + string seriesInstanceUid = request.Dataset.GetString(DicomTag.SeriesInstanceUID); + string sopInstanceUid = request.Dataset.GetString(DicomTag.SOPInstanceUID); + + Guid seriesId = IdentifierHelper.CreateGuid(studyInstanceUid, seriesInstanceUid); + Guid instanceId = IdentifierHelper.CreateGuid(studyInstanceUid, seriesInstanceUid, sopInstanceUid); + + + var ossService = _serviceProvider.GetService(); + var dicomArchiveService = _serviceProvider.GetService(); + var _seriesRepository = _serviceProvider.GetService>(); + + var _distributedLockProvider = _serviceProvider.GetService(); + + var storeRelativePath = string.Empty; + var ossFolderPath = $"Dicom/{studyInstanceUid}"; + + + long fileSize = 0; + try + { + + using (MemoryStream ms = new MemoryStream()) + { + await request.File.SaveAsync(ms); + + //irc 从路径最后一截取Guid + storeRelativePath = await ossService.UploadToOSSAsync(ms, ossFolderPath, instanceId.ToString(), false); + + fileSize = ms.Length; + } + + Log.Logger.Information($"CallingAE:{Association.CallingAE} CalledAE:{Association.CalledAE} {request.SOPInstanceUID} 上传完成 "); + + } + catch (Exception ec) + { + Log.Logger.Warning($"CallingAE:{Association.CallingAE} CalledAE:{Association.CalledAE} 上传异常 {ec.Message}"); + } + + + + var @lock = _distributedLockProvider.CreateLock($"{studyInstanceUid}"); + + using (await @lock.AcquireAsync()) + { + try + { + var scpStudyId = await dicomArchiveService.ArchiveDicomFileAsync(request.Dataset, storeRelativePath, Association.CallingAE, Association.CalledAE); + + if (!_SCPStudyIdList.Contains(scpStudyId)) + { + _SCPStudyIdList.Add(scpStudyId); + } + + var series = await _seriesRepository.FindAsync(seriesId); + + //没有缩略图 + if (series != null && string.IsNullOrEmpty(series.ImageResizePath)) + { + + // 生成缩略图 + using (var memoryStream = new MemoryStream()) + { + DicomImage image = new DicomImage(request.Dataset); + + var sharpimage = image.RenderImage().AsSharpImage(); + sharpimage.Save(memoryStream, new JpegEncoder()); + + // 上传缩略图到 OSS + + var seriesPath = await ossService.UploadToOSSAsync(memoryStream, ossFolderPath, seriesId.ToString() + ".preview.jpg", false); + + Console.WriteLine(seriesPath + " Id: " + seriesId); + + series.ImageResizePath = seriesPath; + + + + //await _seriesRepository.BatchUpdateNoTrackingAsync(t => t.Id == seriesId, u => new SCPSeries() { ImageResizePath = seriesPath }); + + + } + } + + await _seriesRepository.SaveChangesAsync(); + } + catch (Exception ex) + { + + Log.Logger.Warning($"CallingAE:{Association.CallingAE} CalledAE:{Association.CalledAE} 传输处理异常:{ex.ToString()}"); + + } + + } + + + + //监控信息设置 + _upload.FileCount++; + _upload.FileSize= _upload.FileSize+ fileSize; + return new DicomCStoreResponse(request, DicomStatus.Success); + } + + + public Task OnCStoreRequestExceptionAsync(string tempFileName, Exception e) + { + // let library handle logging and error response + return Task.CompletedTask; + } + + + public Task OnCEchoRequestAsync(DicomCEchoRequest request) + { + return Task.FromResult(new DicomCEchoResponse(request, DicomStatus.Success)); + } + + } +} diff --git a/IRC.Core.SCP/Service/DicomArchiveService.cs b/IRC.Core.SCP/Service/DicomArchiveService.cs new file mode 100644 index 000000000..439741952 --- /dev/null +++ b/IRC.Core.SCP/Service/DicomArchiveService.cs @@ -0,0 +1,333 @@ +using IRaCIS.Core.Domain.Share; +using System.Text; +using Microsoft.AspNetCore.Hosting; +using IRaCIS.Core.Infrastructure; +using Medallion.Threading; +using FellowOakDicom; +using FellowOakDicom.Imaging.Codec; +using System.Data; +using IRaCIS.Core.Domain.Models; +using FellowOakDicom.Network; +using IRaCIS.Core.SCP.Service; +using IRaCIS.Core.Infra.EFCore; +using MassTransit; + +namespace IRaCIS.Core.SCP.Service +{ + public class DicomArchiveService : BaseService, IDicomArchiveService + { + private readonly IRepository _patientRepository; + private readonly IRepository _studyRepository; + private readonly IRepository _seriesRepository; + private readonly IRepository _instanceRepository; + private readonly IRepository _dictionaryRepository; + private readonly IDistributedLockProvider _distributedLockProvider; + + + private List _instanceIdList = new List(); + + public DicomArchiveService(IRepository patientRepository, IRepository studyRepository, + IRepository seriesRepository, + IRepository instanceRepository, + IRepository dictionaryRepository, + IDistributedLockProvider distributedLockProvider) + { + _distributedLockProvider = distributedLockProvider; + _studyRepository = studyRepository; + _patientRepository = patientRepository; + _seriesRepository = seriesRepository; + _instanceRepository = instanceRepository; + _dictionaryRepository = dictionaryRepository; + + } + + + + + /// + /// 单个文件接收 归档 + /// + /// + /// + /// + public async Task ArchiveDicomFileAsync(DicomDataset dataset, string fileRelativePath, string callingAE, string calledAE) + { + string studyInstanceUid = dataset.GetString(DicomTag.StudyInstanceUID); + string seriesInstanceUid = dataset.GetString(DicomTag.SeriesInstanceUID); + string sopInstanceUid = dataset.GetString(DicomTag.SOPInstanceUID); + + string patientIdStr = dataset.GetString(DicomTag.PatientID); + + //Guid patientId= IdentifierHelper.CreateGuid(patientIdStr); + Guid studyId = IdentifierHelper.CreateGuid(studyInstanceUid); + Guid seriesId = IdentifierHelper.CreateGuid(studyInstanceUid, seriesInstanceUid); + Guid instanceId = IdentifierHelper.CreateGuid(studyInstanceUid, seriesInstanceUid, sopInstanceUid); + + var isStudyNeedAdd = false; + var isSeriesNeedAdd = false; + var isInstanceNeedAdd = false; + var isPatientNeedAdd = false; + + //var @lock = _distributedLockProvider.CreateLock($"{studyInstanceUid}"); + + //using (@lock.Acquire()) + { + var findPatient = await _patientRepository.FirstOrDefaultAsync(t => t.PatientIdStr == patientIdStr); + var findStudy = await _studyRepository.FindAsync(studyId); + var findSerice = await _seriesRepository.FindAsync(seriesId); + var findInstance = await _instanceRepository.FindAsync(instanceId); + + DateTime? studyTime = dataset.GetSingleValueOrDefault(DicomTag.StudyDate, string.Empty) == string.Empty ? null : dataset.GetSingleValue(DicomTag.StudyDate).Add(dataset.GetSingleValueOrDefault(DicomTag.StudyTime, string.Empty) == string.Empty ? TimeSpan.Zero : dataset.GetSingleValue(DicomTag.StudyTime).TimeOfDay); + + //先传输了修改了患者编号的,又传输了没有修改患者编号的,导致后传输的没有修改患者编号的下面的检查为0 + if (findPatient == null && findStudy==null) + { + isPatientNeedAdd = true; + + + findPatient = new SCPPatient() + { + Id = NewId.NextSequentialGuid(), + PatientIdStr = dataset.GetSingleValueOrDefault(DicomTag.PatientID, string.Empty), + PatientName = dataset.GetSingleValueOrDefault(DicomTag.PatientName, string.Empty), + PatientAge = dataset.GetSingleValueOrDefault(DicomTag.PatientAge, string.Empty), + PatientSex = dataset.GetSingleValueOrDefault(DicomTag.PatientSex, string.Empty), + PatientBirthDate = dataset.GetSingleValueOrDefault(DicomTag.PatientBirthDate, string.Empty), + + EarliestStudyTime = studyTime, + LatestStudyTime = studyTime, + LatestPushTime = DateTime.Now, + }; + + if (findPatient.PatientBirthDate.Length == 8) + { + var birthDateStr = $"{findPatient.PatientBirthDate[0]}{findPatient.PatientBirthDate[1]}{findPatient.PatientBirthDate[2]}{findPatient.PatientBirthDate[3]}-{findPatient.PatientBirthDate[4]}{findPatient.PatientBirthDate[5]}-{findPatient.PatientBirthDate[6]}{findPatient.PatientBirthDate[7]}"; + + var yearStr = $"{findPatient.PatientBirthDate[0]}{findPatient.PatientBirthDate[1]}{findPatient.PatientBirthDate[2]}{findPatient.PatientBirthDate[3]}"; + + int year = 0; + + var canParse = int.TryParse(yearStr, out year); + + if (canParse && year > 1900) + { + findPatient.PatientBirthDate = birthDateStr; + + } + else + { + findPatient.PatientBirthDate = string.Empty; + } + + } + } + else + { + if (studyTime < findPatient.EarliestStudyTime) + { + findPatient.EarliestStudyTime = studyTime; + } + if (studyTime > findPatient.LatestStudyTime) + { + findPatient.LatestStudyTime = studyTime; + } + + findPatient.LatestPushTime = DateTime.Now; + } + + if (findStudy == null) + { + isStudyNeedAdd = true; + findStudy = new SCPStudy + { + CalledAE = calledAE, + CallingAE = callingAE, + + PatientId = findPatient.Id, + Id = studyId, + StudyInstanceUid = studyInstanceUid, + StudyTime = studyTime, + Modalities = dataset.GetSingleValueOrDefault(DicomTag.Modality, string.Empty), + //ModalityForEdit = modalityForEdit, + Description = dataset.GetSingleValueOrDefault(DicomTag.StudyDescription, string.Empty), + InstitutionName = dataset.GetSingleValueOrDefault(DicomTag.InstitutionName, string.Empty), + PatientIdStr = dataset.GetSingleValueOrDefault(DicomTag.PatientID, string.Empty), + PatientName = dataset.GetSingleValueOrDefault(DicomTag.PatientName, string.Empty), + PatientAge = dataset.GetSingleValueOrDefault(DicomTag.PatientAge, string.Empty), + PatientSex = dataset.GetSingleValueOrDefault(DicomTag.PatientSex, string.Empty), + BodyPartExamined = dataset.GetSingleValueOrDefault(DicomTag.BodyPartExamined, string.Empty), + + StudyId = dataset.GetSingleValueOrDefault(DicomTag.StudyID, string.Empty), + AccessionNumber = dataset.GetSingleValueOrDefault(DicomTag.AccessionNumber, string.Empty), + + //需要特殊处理 + PatientBirthDate = dataset.GetSingleValueOrDefault(DicomTag.PatientBirthDate, string.Empty), + + + AcquisitionTime = dataset.GetSingleValueOrDefault(DicomTag.AcquisitionTime, string.Empty), + AcquisitionNumber = dataset.GetSingleValueOrDefault(DicomTag.AcquisitionNumber, string.Empty), + TriggerTime = dataset.GetSingleValueOrDefault(DicomTag.TriggerTime, string.Empty), + + + + //IsDoubleReview = addtionalInfo.IsDoubleReview, + SeriesCount = 0, + InstanceCount = 0 + }; + + + if (findStudy.PatientBirthDate.Length == 8) + { + findStudy.PatientBirthDate = $"{findStudy.PatientBirthDate[0]}{findStudy.PatientBirthDate[1]}{findStudy.PatientBirthDate[2]}{findStudy.PatientBirthDate[3]}-{findStudy.PatientBirthDate[4]}{findStudy.PatientBirthDate[5]}-{findStudy.PatientBirthDate[6]}{findStudy.PatientBirthDate[7]}"; + } + } + + + if (findSerice == null) + { + isSeriesNeedAdd = true; + + findSerice = new SCPSeries + { + Id = seriesId, + StudyId = findStudy.Id, + + StudyInstanceUid = findStudy.StudyInstanceUid, + SeriesInstanceUid = seriesInstanceUid, + SeriesNumber = dataset.GetSingleValueOrDefault(DicomTag.SeriesNumber, 1), + //SeriesTime = dataset.GetSingleValueOrDefault(DicomTag.SeriesDate, DateTime.Now).Add(dataset.GetSingleValueOrDefault(DicomTag.SeriesTime, DateTime.Now).TimeOfDay), + //SeriesTime = DateTime.TryParse(dataset.GetSingleValue(DicomTag.SeriesDate) + dataset.GetSingleValue(DicomTag.SeriesTime), out DateTime dt) ? dt : null, + SeriesTime = dataset.GetSingleValueOrDefault(DicomTag.SeriesDate, string.Empty) == string.Empty ? null : dataset.GetSingleValue(DicomTag.SeriesDate).Add(dataset.GetSingleValueOrDefault(DicomTag.SeriesTime, string.Empty) == string.Empty ? TimeSpan.Zero : dataset.GetSingleValue(DicomTag.SeriesTime).TimeOfDay), + Modality = dataset.GetSingleValueOrDefault(DicomTag.Modality, string.Empty), + Description = dataset.GetSingleValueOrDefault(DicomTag.SeriesDescription, string.Empty), + SliceThickness = dataset.GetSingleValueOrDefault(DicomTag.SliceThickness, string.Empty), + + ImagePositionPatient = dataset.GetSingleValueOrDefault(DicomTag.ImagePositionPatient, string.Empty), + ImageOrientationPatient = dataset.GetSingleValueOrDefault(DicomTag.ImageOrientationPatient, string.Empty), + BodyPartExamined = dataset.GetSingleValueOrDefault(DicomTag.BodyPartExamined, string.Empty), + SequenceName = dataset.GetSingleValueOrDefault(DicomTag.SequenceName, string.Empty), + ProtocolName = dataset.GetSingleValueOrDefault(DicomTag.ProtocolName, string.Empty), + ImagerPixelSpacing = dataset.GetSingleValueOrDefault(DicomTag.ImagerPixelSpacing, string.Empty), + + AcquisitionTime = dataset.GetSingleValueOrDefault(DicomTag.AcquisitionTime, string.Empty), + AcquisitionNumber = dataset.GetSingleValueOrDefault(DicomTag.AcquisitionNumber, string.Empty), + TriggerTime = dataset.GetSingleValueOrDefault(DicomTag.TriggerTime, string.Empty), + + + InstanceCount = 0 + }; + + ++findStudy.SeriesCount; + } + + + if (findInstance == null) + { + isInstanceNeedAdd = true; + findInstance = new SCPInstance + { + Id = instanceId, + StudyId = findStudy.Id, + SeriesId = findSerice.Id, + StudyInstanceUid = findStudy.StudyInstanceUid, + SeriesInstanceUid = findSerice.SeriesInstanceUid, + + SopInstanceUid = sopInstanceUid, + InstanceNumber = dataset.GetSingleValueOrDefault(DicomTag.InstanceNumber, 1), + InstanceTime = dataset.GetSingleValueOrDefault(DicomTag.ContentDate, string.Empty) == string.Empty ? null : dataset.GetSingleValue(DicomTag.ContentDate).Add(dataset.GetSingleValueOrDefault(DicomTag.ContentTime, string.Empty) == string.Empty ? TimeSpan.Zero : dataset.GetSingleValue(DicomTag.ContentTime).TimeOfDay), + //InstanceTime = DateTime.TryParse(dataset.GetSingleValue(DicomTag.ContentDate) + dataset.GetSingleValue(DicomTag.ContentTime), out DateTime dt) ? dt : null, + //InstanceTime = dataset.GetSingleValueOrDefault(DicomTag.ContentDate,(DateTime?)null)?.Add(dataset.GetSingleValueOrDefault(DicomTag.ContentTime, TimeSpan.Zero)), + //dataset.GetSingleValueOrDefault(DicomTag.ContentDate,DateTime.Now);//, DicomTag.ContentTime) + CPIStatus = false, + ImageRows = dataset.GetSingleValueOrDefault(DicomTag.Rows, 0), + ImageColumns = dataset.GetSingleValueOrDefault(DicomTag.Columns, 0), + SliceLocation = dataset.GetSingleValueOrDefault(DicomTag.SliceLocation, 0), + + SliceThickness = dataset.GetSingleValueOrDefault(DicomTag.SliceThickness, string.Empty), + NumberOfFrames = dataset.GetSingleValueOrDefault(DicomTag.NumberOfFrames, 0), + PixelSpacing = dataset.GetSingleValueOrDefault(DicomTag.PixelSpacing, string.Empty), + ImagerPixelSpacing = dataset.GetSingleValueOrDefault(DicomTag.ImagerPixelSpacing, string.Empty), + FrameOfReferenceUID = dataset.GetSingleValueOrDefault(DicomTag.FrameOfReferenceUID, string.Empty), + WindowCenter = dataset.GetSingleValueOrDefault(DicomTag.WindowCenter, string.Empty), + WindowWidth = dataset.GetSingleValueOrDefault(DicomTag.WindowWidth, string.Empty), + + Path = fileRelativePath + }; + + ++findStudy.InstanceCount; + ++findSerice.InstanceCount; + } + + if (isPatientNeedAdd) + { + var ss = await _patientRepository.AddAsync(findPatient); + } + if (isStudyNeedAdd) + { + var dd = await _studyRepository.AddAsync(findStudy); + } + else + { + await _studyRepository.BatchUpdateNoTrackingAsync(t => t.Id == findStudy.Id, t => new SCPStudy() { IsUploadFinished = false }); + } + + if (isSeriesNeedAdd) + { + await _seriesRepository.AddAsync(findSerice); + } + if (isInstanceNeedAdd) + { + await _instanceRepository.AddAsync(findInstance); + } + else + { + await _instanceRepository.BatchUpdateNoTrackingAsync(t => t.Id == instanceId, u => new SCPInstance() { Path = fileRelativePath }); + } + + //await _studyRepository.SaveChangesAsync(); + + return findStudy.Id; + } + + } + + + // 从DICOM文件中获取使用的字符集 + private string GetEncodingVaulueFromDicomFile(DicomDataset dataset, DicomTag dicomTag) + { + + // 获取DICOM文件的特定元素,通常用于指示使用的字符集 + var charset = dataset.GetSingleValueOrDefault(DicomTag.SpecificCharacterSet, string.Empty); + + var dicomEncoding = DicomEncoding.GetEncoding(charset); + + + var dicomStringElement = dataset.GetDicomItem(dicomTag); + + var bytes = dicomStringElement.Buffer.Data; + + + return dicomEncoding.GetString(bytes); + + + //// 从DICOM文件中获取使用的字符集 + //string filePath = "C:\\Users\\hang\\Documents\\WeChat Files\\wxid_r2imdzb7j3q922\\FileStorage\\File\\2024-05\\1.2.840.113619.2.80.169103990.5390.1271401378.4.dcm"; + //DicomFile dicomFile = DicomFile.Open(filePath); + + //// 获取DICOM文件的特定元素,通常用于指示使用的字符集 + //var charset = dicomFile.Dataset.GetSingleValueOrDefault(DicomTag.SpecificCharacterSet, string.Empty); + + //var dicomEncoding = DicomEncoding.GetEncoding(charset); + + //var value = dicomFile.Dataset.GetSingleValueOrDefault(DicomTag.PatientName, string.Empty); + + //var dicomStringElement = dicomFile.Dataset.GetDicomItem(DicomTag.PatientName); + + //var bytes = dicomStringElement.Buffer.Data; + + //var aa= dicomEncoding.GetString(bytes); + + + } + } +} diff --git a/IRC.Core.SCP/Service/Interface/IDicomArchiveService.cs b/IRC.Core.SCP/Service/Interface/IDicomArchiveService.cs new file mode 100644 index 000000000..970b3e146 --- /dev/null +++ b/IRC.Core.SCP/Service/Interface/IDicomArchiveService.cs @@ -0,0 +1,11 @@ +using FellowOakDicom; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion.Internal; + +namespace IRaCIS.Core.SCP.Service +{ + public interface IDicomArchiveService + { + Task ArchiveDicomFileAsync(DicomDataset dicomDataset,string fileRelativePath,string callingAE,string calledAE); + + } +} diff --git a/IRC.Core.SCP/Service/OSSService.cs b/IRC.Core.SCP/Service/OSSService.cs new file mode 100644 index 000000000..cfbe4b3f8 --- /dev/null +++ b/IRC.Core.SCP/Service/OSSService.cs @@ -0,0 +1,427 @@ +using Aliyun.OSS; +using IRaCIS.Core.Infrastructure; +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Options; +using Minio.DataModel.Args; +using Minio; +using SharpCompress.Common; +using System; +using System.Collections.Generic; +using System.Drawing; +using System.IO; +using System.Linq; +using System.Security.AccessControl; +using System.Text; +using System.Threading.Tasks; + +namespace IRaCIS.Core.SCP +{ + public class MinIOOptions : AWSOptions + { + public int port { get; set; } + + } + + public class AWSOptions + { + public string endPoint { get; set; } + public bool useSSL { get; set; } + public string accessKey { get; set; } + public string secretKey { get; set; } + public string bucketName { get; set; } + public string viewEndpoint { get; set; } + } + + public class AliyunOSSOptions + { + public string regionId { get; set; } + public string accessKeyId { get; set; } + public string accessKeySecret { get; set; } + public string endPoint { get; set; } + public string bucketName { get; set; } + + public string roleArn { get; set; } + + public string region { get; set; } + + public string viewEndpoint { get; set; } + + } + + public class ObjectStoreServiceOptions + { + public string ObjectStoreUse { get; set; } + public AliyunOSSOptions AliyunOSS { get; set; } + public MinIOOptions MinIO { get; set; } + + public AWSOptions AWS { get; set; } + + } + + public class ObjectStoreDTO + { + public string ObjectStoreUse { get; set; } + + public AliyunOSSOptions AliyunOSS { get; set; } + + public MinIOOptions MinIO { get; set; } + + public AWSOptions AWS { get; set; } + + } + + public class AliyunOSSTempToken + { + public string AccessKeyId { get; set; } + public string AccessKeySecret { get; set; } + public string SecurityToken { get; set; } + public string Expiration { get; set; } + + public string Region { get; set; } + public string BucketName { get; set; } + public string ViewEndpoint { get; set; } + } + + + + public enum ObjectStoreUse + { + AliyunOSS = 0, + MinIO = 1, + AWS = 2, + } + + public interface IOSSService + { + public Task UploadToOSSAsync(Stream fileStream, string oosFolderPath, string fileRealName,bool isFileNameAddGuid=true); + public Task UploadToOSSAsync(string localFilePath, string oosFolderPath, bool isFileNameAddGuid = true); + + public Task DownLoadFromOSSAsync(string ossRelativePath, string localFilePath); + + public ObjectStoreServiceOptions ObjectStoreServiceOptions { get; set; } + + public Task GetSignedUrl(string ossRelativePath); + + } + + + public class OSSService : IOSSService + { + public ObjectStoreServiceOptions ObjectStoreServiceOptions { get; set; } + + + public OSSService(IOptionsMonitor options) + { + ObjectStoreServiceOptions = options.CurrentValue; + } + + /// + /// oosFolderPath 不要 "/ "开头 应该: TempFolder/ChildFolder + /// + /// + /// + /// + /// + public async Task UploadToOSSAsync(Stream fileStream, string oosFolderPath, string fileRealName, bool isFileNameAddGuid = true) + { + + + var ossRelativePath = isFileNameAddGuid? $"{oosFolderPath}/{Guid.NewGuid()}_{fileRealName}": $"{oosFolderPath}/{fileRealName}"; + //var ossRelativePath = oosFolderPath + "/" + fileRealName; + + try + { + using (var memoryStream = new MemoryStream()) + { + fileStream.Seek(0, SeekOrigin.Begin); + + fileStream.CopyTo(memoryStream); + + memoryStream.Seek(0, SeekOrigin.Begin); + + + if (ObjectStoreServiceOptions.ObjectStoreUse == "AliyunOSS") + { + var aliConfig = ObjectStoreServiceOptions.AliyunOSS; + + var _ossClient = new OssClient(aliConfig.endPoint, aliConfig.accessKeyId, aliConfig.accessKeySecret); + + + + // 上传文件 + var result = _ossClient.PutObject(aliConfig.bucketName, ossRelativePath, memoryStream); + + } + else if (ObjectStoreServiceOptions.ObjectStoreUse == "MinIO") + { + var minIOConfig = ObjectStoreServiceOptions.MinIO; + + + var minioClient = new MinioClient().WithEndpoint($"{minIOConfig.endPoint}:{minIOConfig.port}") + .WithCredentials(minIOConfig.accessKey, minIOConfig.secretKey).WithSSL(minIOConfig.useSSL) + .Build(); + + var putObjectArgs = new PutObjectArgs() + .WithBucket(minIOConfig.bucketName) + .WithObject(ossRelativePath) + .WithStreamData(memoryStream) + .WithObjectSize(memoryStream.Length); + + await minioClient.PutObjectAsync(putObjectArgs); + } + else if (ObjectStoreServiceOptions.ObjectStoreUse == "AWS") + { + var minIOConfig = ObjectStoreServiceOptions.AWS; + + + var minioClient = new MinioClient().WithEndpoint($"{minIOConfig.endPoint}") + .WithCredentials(minIOConfig.accessKey, minIOConfig.secretKey).WithSSL(minIOConfig.useSSL) + .Build(); + + var putObjectArgs = new PutObjectArgs() + .WithBucket(minIOConfig.bucketName) + .WithObject(ossRelativePath) + .WithStreamData(memoryStream) + .WithObjectSize(memoryStream.Length); + + await minioClient.PutObjectAsync(putObjectArgs); + } + else + { + throw new BusinessValidationFailedException("未定义的存储介质类型"); + } + } + } + catch (Exception ex) + { + + throw new BusinessValidationFailedException($"上传发生异常:{ex.Message}"); ; + } + + + + + return "/" + ossRelativePath; + + } + + + + /// + /// oosFolderPath 不要 "/ "开头 应该: TempFolder/ChildFolder + /// + /// + /// + /// + /// + public async Task UploadToOSSAsync(string localFilePath, string oosFolderPath, bool isFileNameAddGuid = true) + { + var localFileName = Path.GetFileName(localFilePath); + + var ossRelativePath = isFileNameAddGuid? $"{oosFolderPath}/{Guid.NewGuid()}_{localFileName}" : $"{oosFolderPath}/{localFileName}"; + + //var ossRelativePath = oosFolderPath + "/" + localFileName; + + + if (ObjectStoreServiceOptions.ObjectStoreUse == "AliyunOSS") + { + var aliConfig = ObjectStoreServiceOptions.AliyunOSS; + + var _ossClient = new OssClient(aliConfig.endPoint, aliConfig.accessKeyId, aliConfig.accessKeySecret); + + // 上传文件 + var result = _ossClient.PutObject(aliConfig.bucketName, ossRelativePath, localFilePath); + + } + else if (ObjectStoreServiceOptions.ObjectStoreUse == "MinIO") + { + var minIOConfig = ObjectStoreServiceOptions.MinIO; + + + var minioClient = new MinioClient().WithEndpoint($"{minIOConfig.endPoint}:{minIOConfig.port}") + .WithCredentials(minIOConfig.accessKey, minIOConfig.secretKey).WithSSL(minIOConfig.useSSL) + .Build(); + + var putObjectArgs = new PutObjectArgs() + .WithBucket(minIOConfig.bucketName) + .WithObject(ossRelativePath) + .WithFileName(localFilePath); + + await minioClient.PutObjectAsync(putObjectArgs); + } + else if (ObjectStoreServiceOptions.ObjectStoreUse == "AWS") + { + var minIOConfig = ObjectStoreServiceOptions.AWS; + + + var minioClient = new MinioClient().WithEndpoint($"{minIOConfig.endPoint}") + .WithCredentials(minIOConfig.accessKey, minIOConfig.secretKey).WithSSL(minIOConfig.useSSL) + .Build(); + + var putObjectArgs = new PutObjectArgs() + .WithBucket(minIOConfig.bucketName) + .WithObject(ossRelativePath) + .WithFileName(localFilePath); + + await minioClient.PutObjectAsync(putObjectArgs); + } + else + { + throw new BusinessValidationFailedException("未定义的存储介质类型"); + } + return "/" + ossRelativePath; + + } + + public async Task DownLoadFromOSSAsync(string ossRelativePath, string localFilePath) + { + + ossRelativePath = ossRelativePath.TrimStart('/'); + try + { + + + if (ObjectStoreServiceOptions.ObjectStoreUse == "AliyunOSS") + { + var aliConfig = ObjectStoreServiceOptions.AliyunOSS; + + var _ossClient = new OssClient(aliConfig.endPoint, aliConfig.accessKeyId, aliConfig.accessKeySecret); + + // 上传文件 + var result = _ossClient.GetObject(aliConfig.bucketName, ossRelativePath); + + // 将下载的文件流保存到本地文件 + using (var fs = File.OpenWrite(localFilePath)) + { + result.Content.CopyTo(fs); + fs.Close(); + } + + } + else if (ObjectStoreServiceOptions.ObjectStoreUse == "MinIO") + { + var minIOConfig = ObjectStoreServiceOptions.MinIO; + + var minioClient = new MinioClient().WithEndpoint($"{minIOConfig.endPoint}:{minIOConfig.port}") + .WithCredentials(minIOConfig.accessKey, minIOConfig.secretKey).WithSSL(minIOConfig.useSSL) + .Build(); + + var getObjectArgs = new GetObjectArgs() + .WithBucket(minIOConfig.bucketName) + .WithObject(ossRelativePath) + .WithFile(localFilePath); + + await minioClient.GetObjectAsync(getObjectArgs); + + } + else if (ObjectStoreServiceOptions.ObjectStoreUse == "AWS") + { + var minIOConfig = ObjectStoreServiceOptions.AWS; + + var minioClient = new MinioClient().WithEndpoint($"{minIOConfig.endPoint}") + .WithCredentials(minIOConfig.accessKey, minIOConfig.secretKey).WithSSL(minIOConfig.useSSL) + .Build(); + + var getObjectArgs = new GetObjectArgs() + .WithBucket(minIOConfig.bucketName) + .WithObject(ossRelativePath) + .WithFile(localFilePath); + + await minioClient.GetObjectAsync(getObjectArgs); + } + else + { + throw new BusinessValidationFailedException("未定义的存储介质类型"); + } + } + catch (Exception ex) + { + + throw new BusinessValidationFailedException("oss下载失败!" + ex.Message); + } + + + + + + } + + public async Task GetSignedUrl(string ossRelativePath) + { + ossRelativePath = ossRelativePath.TrimStart('/'); + try + { + + + if (ObjectStoreServiceOptions.ObjectStoreUse == "AliyunOSS") + { + var aliConfig = ObjectStoreServiceOptions.AliyunOSS; + + var _ossClient = new OssClient(aliConfig.endPoint, aliConfig.accessKeyId, aliConfig.accessKeySecret); + + // 生成签名URL。 + var req = new GeneratePresignedUriRequest(aliConfig.bucketName, ossRelativePath, SignHttpMethod.Get) + { + // 设置签名URL过期时间,默认值为3600秒。 + Expiration = DateTime.Now.AddHours(1), + }; + var uri = _ossClient.GeneratePresignedUri(req); + + return uri.PathAndQuery; + + } + else if (ObjectStoreServiceOptions.ObjectStoreUse == "MinIO") + { + var minIOConfig = ObjectStoreServiceOptions.MinIO; + + var minioClient = new MinioClient().WithEndpoint($"{minIOConfig.endPoint}:{minIOConfig.port}") + .WithCredentials(minIOConfig.accessKey, minIOConfig.secretKey).WithSSL(minIOConfig.useSSL) + .Build(); + + //var reqParams = new Dictionary(StringComparer.Ordinal) + // { + // { "response-content-type", "application/json" } + // }; + + var args = new PresignedGetObjectArgs() + .WithBucket(minIOConfig.bucketName) + .WithObject(ossRelativePath) + .WithExpiry(3600) + /*.WithHeaders(reqParams)*/; + + var presignedUrl = await minioClient.PresignedGetObjectAsync(args); + + Uri uri = new Uri(presignedUrl); + + string relativePath = uri.PathAndQuery; + + + return relativePath; + + } + else if (ObjectStoreServiceOptions.ObjectStoreUse == "AWS") + { + var minIOConfig = ObjectStoreServiceOptions.AWS; + + var minioClient = new MinioClient().WithEndpoint($"{minIOConfig.endPoint}") + .WithCredentials(minIOConfig.accessKey, minIOConfig.secretKey).WithSSL(minIOConfig.useSSL) + .Build(); + + return string.Empty; + } + else + { + throw new BusinessValidationFailedException("未定义的存储介质类型"); + } + } + catch (Exception ex) + { + + throw new BusinessValidationFailedException("oss授权url失败!" + ex.Message); + } + + } + } + + +} diff --git a/IRC.Core.SCP/appsettings.IRC_Prod_SCP.json b/IRC.Core.SCP/appsettings.IRC_Prod_SCP.json new file mode 100644 index 000000000..32ee00af6 --- /dev/null +++ b/IRC.Core.SCP/appsettings.IRC_Prod_SCP.json @@ -0,0 +1,63 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft": "Warning", + "Microsoft.Hosting.Lifetime": "Information" + } + }, + "ObjectStoreService": { + "ObjectStoreUse": "AliyunOSS", + "AliyunOSS": { + "regionId": "cn-shanghai", + "endpoint": "https://oss-cn-shanghai.aliyuncs.com", + "accessKeyId": "LTAI5tKvzs7ed3UfSpNk3xwQ", + "accessKeySecret": "zTIceGEShlZDGnLrCFfIGFE7TXVRio", + "bucketName": "zy-irc-store", + "roleArn": "acs:ram::1899121822495495:role/oss-upload", + "viewEndpoint": "https://zy-irc-cache.oss-cn-shanghai.aliyuncs.com", + "region": "oss-cn-shanghai" + }, + + "MinIO": { + "endpoint": "http://192.168.3.68", + "port": "8001", + "useSSL": false, + "accessKey": "IDFkwEpWej0b4DtiuThL", + "secretKey": "Lhuu83yMhVwu7c1SnjvGY6lq74jzpYqifK6Qtj4h", + "bucketName": "test" + } + }, + + "ConnectionStrings": { + //"RemoteNew": "Server=47.117.165.18,1434;Database=Prod_Study;User ID=sa;Password=zhanying@2021;TrustServerCertificate=true", + //"Hangfire": "Server=47.117.165.18,1434;Database=Prod_Study_Hangfire;User ID=sa;Password=zhanying@2021;TrustServerCertificate=true", + "RemoteNew": "Server=prod_mssql_standard,1433;Database=Prod_Study;User ID=sa;Password=zhanying@2021;TrustServerCertificate=true", + "Hangfire": "Server=prod_mssql_standard,1433;Database=Prod_Study_Hangfire;User ID=sa;Password=zhanying@2021;TrustServerCertificate=true" + }, + + "BasicSystemConfig": { + + "OpenUserComplexPassword": true, + + "OpenSignDocumentBeforeWork": true, + + "OpenTrialRelationDelete": true, + + "OpenLoginLimit": true, + "LoginMaxFailCount": 5, + + "LoginFailLockMinutes": 30 + + }, + + "SystemEmailSendConfig": { + "Port": 465, + "Host": "smtp.qiye.aliyun.com", + "FromEmail": "study@extimaging.com", + "FromName": "研究单位阅片系统", + "AuthorizationCode": "zhanying123", + "SiteUrl": "https://study.extimaging.com/login" + } + +} diff --git a/IRC.Core.SCP/appsettings.IRC_Test_SCP.json b/IRC.Core.SCP/appsettings.IRC_Test_SCP.json new file mode 100644 index 000000000..5e93530c7 --- /dev/null +++ b/IRC.Core.SCP/appsettings.IRC_Test_SCP.json @@ -0,0 +1,79 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft": "Warning", + "Microsoft.Hosting.Lifetime": "Information" + } + }, + "ObjectStoreService": { + "ObjectStoreUse": "AliyunOSS", + "AliyunOSS": { + "regionId": "cn-shanghai", + "endPoint": "https://oss-cn-shanghai.aliyuncs.com", + "accessKeyId": "LTAI5tKvzs7ed3UfSpNk3xwQ", + "accessKeySecret": "zTIceGEShlZDGnLrCFfIGFE7TXVRio", + "bucketName": "zy-irc-test-store", + "roleArn": "acs:ram::1899121822495495:role/oss-upload", + "viewEndpoint": "https://zy-irc-test-store.oss-cn-shanghai.aliyuncs.com", + "region": "oss-cn-shanghai" + }, + + "MinIO": { + "endPoint": "106.14.89.110", + "port": "9001", + "useSSL": false, + "accessKey": "fbStsVYCIPKHQneeqMwD", + "secretKey": "TzgvyA3zGXMUnpilJNUlyMYHfosl1hBMl6lxPmjy", + "bucketName": "hir-test", + "viewEndpoint": "http://106.14.89.110:9001/hir-test/" + }, + + "AWS": { + "endPoint": "s3.us-east-1.amazonaws.com", + "useSSL": false, + "accessKey": "AKIAZQ3DRSOHFPJJ6FEU", + "secretKey": "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", + "bucketName": "ei-irc-test-store", + "viewEndpoint": "https://ei-irc-test-store.s3.amazonaws.com/" + } + }, + + "ConnectionStrings": { + "RemoteNew": "Server=106.14.89.110,1435;Database=Test_HIR;User ID=sa;Password=xc@123456;TrustServerCertificate=true", + "Hangfire": "Server=106.14.89.110,1435;Database=Test_HIR_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true" + }, + "BasicSystemConfig": { + + "OpenUserComplexPassword": false, + + "OpenSignDocumentBeforeWork": false, + + "OpenTrialRelationDelete": true, + + "OpenLoginLimit": false, + "LoginMaxFailCount": 5, + + "LoginFailLockMinutes": 30 + + }, + + "SystemEmailSendConfig": { + "Port": 465, + "Host": "smtp.qiye.aliyun.com", + "FromEmail": "test-study@extimaging.com", + "FromName": "Test_Study", + "AuthorizationCode": "zhanying123", + + "SiteUrl": "http://study.test.extimaging.com/login" + }, + "DicomSCPServiceConfig": { + "CalledAEList": [ + "STORESCP", + "Value1", + "Value2", + "Value3" + ], + "ServerPort": 11112 + } +} diff --git a/IRC.Core.SCP/appsettings.IRC_US_SCP.json b/IRC.Core.SCP/appsettings.IRC_US_SCP.json new file mode 100644 index 000000000..7821a16b8 --- /dev/null +++ b/IRC.Core.SCP/appsettings.IRC_US_SCP.json @@ -0,0 +1,76 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft": "Warning", + "Microsoft.Hosting.Lifetime": "Information" + } + }, + "ObjectStoreService": { + "ObjectStoreUse": "MinIO", + "AliyunOSS": { + "regionId": "cn-shanghai", + "endpoint": "https://oss-cn-shanghai.aliyuncs.com", + "accessKeyId": "LTAI5tKvzs7ed3UfSpNk3xwQ", + "accessKeySecret": "zTIceGEShlZDGnLrCFfIGFE7TXVRio", + "bucketName": "zy-sir-test-store", + "roleArn": "acs:ram::1899121822495495:role/oss-upload", + "viewEndpoint": "https://zy-sir-test-store.oss-cn-shanghai.aliyuncs.com", + "region": "oss-cn-shanghai" + }, + + "MinIO": { + "endPoint": "44.218.11.19", + "port": "9001", + "useSSL": false, + "accessKey": "lH8DkKskLuDqPaiubuSQ", + "secretKey": "pdPdicvvLeH7xAC5yFUrI7odMyBfOXxvVWMvKYV4", + "bucketName": "hir-us", + "viewEndpoint": "http://hir.us.extimaging.com/oss/hir-us" + }, + + "AWS": { + "endPoint": "s3.us-east-1.amazonaws.com", + "useSSL": false, + "accessKey": "AKIAZQ3DRSOHFPJJ6FEU", + "secretKey": "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", + "bucketName": "ei-irc-test-store", + "viewEndpoint": "https://ei-irc-test-store.s3.amazonaws.com/" + } + }, + "ConnectionStrings": { + "RemoteNew": "Server=44.218.11.19,1435;Database=US_HIR;User ID=sa;Password=xc@123456;TrustServerCertificate=true", + "Hangfire": "Server=44.218.11.19,1435;Database=US_HIR_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true" + }, + "BasicSystemConfig": { + + "OpenUserComplexPassword": false, + + "OpenSignDocumentBeforeWork": false, + + "OpenTrialRelationDelete": true, + + "OpenLoginLimit": false, + "LoginMaxFailCount": 5, + + "LoginFailLockMinutes": 30 + }, + + "SystemEmailSendConfig": { + "Port": 465, + "Host": "smtp.qiye.aliyun.com", + "FromEmail": "uat-study@extimaging.com", + "FromName": "Uat_Study", + "AuthorizationCode": "zhanying123", + "SiteUrl": "http://study.uat.extimaging.com/login" + }, + "DicomSCPServiceConfig": { + "CalledAEList": [ + "STORESCP", + "Value1", + "Value2", + "Value3" + ], + "ServerPort": 11112 + } +} diff --git a/IRC.Core.SCP/appsettings.IRC_Uat_SCP.json b/IRC.Core.SCP/appsettings.IRC_Uat_SCP.json new file mode 100644 index 000000000..f50eedf66 --- /dev/null +++ b/IRC.Core.SCP/appsettings.IRC_Uat_SCP.json @@ -0,0 +1,76 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft": "Warning", + "Microsoft.Hosting.Lifetime": "Information" + } + }, + "ObjectStoreService": { + "ObjectStoreUse": "MinIO", + "AliyunOSS": { + "regionId": "cn-shanghai", + "endpoint": "https://oss-cn-shanghai.aliyuncs.com", + "accessKeyId": "LTAI5tKvzs7ed3UfSpNk3xwQ", + "accessKeySecret": "zTIceGEShlZDGnLrCFfIGFE7TXVRio", + "bucketName": "zy-irc-uat-store", + "roleArn": "acs:ram::1899121822495495:role/oss-upload", + "viewEndpoint": "https://zy-irc-uat-store.oss-cn-shanghai.aliyuncs.com", + "region": "oss-cn-shanghai" + }, + + "MinIO": { + "endPoint": "47.117.164.182", + "port": "9001", + "useSSL": false, + "accessKey": "b9Ul0e98xPzt6PwRXA1Q", + "secretKey": "DzMaU2L4OXl90uytwOmDXF2encN0Jf4Nxu2XkYqQ", + "bucketName": "hir-uat", + "viewEndpoint": "http://hir.uat.extimaging.com/oss/hir-uat" + }, + + "AWS": { + "endPoint": "s3.us-east-1.amazonaws.com", + "useSSL": false, + "accessKey": "AKIAZQ3DRSOHFPJJ6FEU", + "secretKey": "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", + "bucketName": "ei-irc-test-store", + "viewEndpoint": "https://ei-irc-test-store.s3.amazonaws.com/" + } + }, + "ConnectionStrings": { + "RemoteNew": "Server=47.117.164.182,1434;Database=Uat_HIR;User ID=sa;Password=xc@123456;TrustServerCertificate=true", + "Hangfire": "Server=47.117.164.182,1434;Database=Uat_HIR_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true" + }, + "BasicSystemConfig": { + + "OpenUserComplexPassword": false, + + "OpenSignDocumentBeforeWork": false, + + "OpenTrialRelationDelete": true, + + "OpenLoginLimit": false, + "LoginMaxFailCount": 5, + + "LoginFailLockMinutes": 30 + }, + + "SystemEmailSendConfig": { + "Port": 465, + "Host": "smtp.qiye.aliyun.com", + "FromEmail": "uat-study@extimaging.com", + "FromName": "Uat_Study", + "AuthorizationCode": "zhanying123", + "SiteUrl": "http://study.uat.extimaging.com/login" + }, + "DicomSCPServiceConfig": { + "CalledAEList": [ + "STORESCP", + "Value1", + "Value2", + "Value3" + ], + "ServerPort": 11112 + } +} diff --git a/IRC.Core.SCP/appsettings.json b/IRC.Core.SCP/appsettings.json new file mode 100644 index 000000000..10f68b8c8 --- /dev/null +++ b/IRC.Core.SCP/appsettings.json @@ -0,0 +1,9 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "AllowedHosts": "*" +} diff --git a/IRaCIS.Core.API.sln b/IRaCIS.Core.API.sln index d5afa55fa..9511e66e3 100644 --- a/IRaCIS.Core.API.sln +++ b/IRaCIS.Core.API.sln @@ -17,6 +17,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IRaCIS.Core.Infra.EFCore", EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IRaCIS.Core.Infrastructure", "IRaCIS.Core.Infrastructure\IRaCIS.Core.Infrastructure.csproj", "{07EED0F8-08E6-46F3-ACBE-17BC1391BD4C}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IRC.Core.SCP", "IRC.Core.SCP\IRC.Core.SCP.csproj", "{ECD08F47-DC1A-484E-BB91-6CDDC8823CC5}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -51,6 +53,10 @@ Global {07EED0F8-08E6-46F3-ACBE-17BC1391BD4C}.Debug|Any CPU.Build.0 = Debug|Any CPU {07EED0F8-08E6-46F3-ACBE-17BC1391BD4C}.Release|Any CPU.ActiveCfg = Release|Any CPU {07EED0F8-08E6-46F3-ACBE-17BC1391BD4C}.Release|Any CPU.Build.0 = Release|Any CPU + {ECD08F47-DC1A-484E-BB91-6CDDC8823CC5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {ECD08F47-DC1A-484E-BB91-6CDDC8823CC5}.Debug|Any CPU.Build.0 = Debug|Any CPU + {ECD08F47-DC1A-484E-BB91-6CDDC8823CC5}.Release|Any CPU.ActiveCfg = Release|Any CPU + {ECD08F47-DC1A-484E-BB91-6CDDC8823CC5}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/IRaCIS.Core.API/IRaCIS.Core.API.csproj b/IRaCIS.Core.API/IRaCIS.Core.API.csproj index f6e1614ef..a434c6d2b 100644 --- a/IRaCIS.Core.API/IRaCIS.Core.API.csproj +++ b/IRaCIS.Core.API/IRaCIS.Core.API.csproj @@ -64,22 +64,21 @@ - true - + - + - + - + diff --git a/IRaCIS.Core.Application/Service/Common/ExploreRecommendService.cs b/IRaCIS.Core.Application/Service/Common/ExploreRecommendService.cs index 76d181268..b67c4f25f 100644 --- a/IRaCIS.Core.Application/Service/Common/ExploreRecommendService.cs +++ b/IRaCIS.Core.Application/Service/Common/ExploreRecommendService.cs @@ -31,7 +31,7 @@ namespace IRaCIS.Core.Application.Service var exploreRecommendQueryable = - _exploreRecommendRepository + _exploreRecommendRepository.Where().IgnoreQueryFilters() .WhereIf(string.IsNullOrEmpty(inQuery.Title), t => t.Title.Contains(inQuery.Title)) .WhereIf(string.IsNullOrEmpty(inQuery.FileName), t => t.Title.Contains(inQuery.FileName)) .WhereIf(string.IsNullOrEmpty(inQuery.DownloadUrl), t => t.Title.Contains(inQuery.DownloadUrl)) diff --git a/IRaCIS.Core.Application/Service/Visit/DTO/PatientViewModel.cs b/IRaCIS.Core.Application/Service/Visit/DTO/PatientViewModel.cs new file mode 100644 index 000000000..72b1ee836 --- /dev/null +++ b/IRaCIS.Core.Application/Service/Visit/DTO/PatientViewModel.cs @@ -0,0 +1,1083 @@ +using IRaCIS.Core.Application.ViewModel; +using IRaCIS.Core.Domain.Share; +using IRaCIS.Core.Infrastructure.Extention; +using Newtonsoft.Json; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; +using System.Web; + +namespace IRaCIS.Application.Contracts +{ + public class SystemHospitalOption + { + public string HospitalName { get; set; } + public string HospitalAliasName { get; set; } + public string Country { get; set; } + public string City { get; set; } + public string Province { get; set; } + public string Address { get; set; } + public string Phone { get; set; } + + public bool IsCanConnectInternet { get; set; } + + public string HospitalCode { get; set; } + public string HospitalLogoPath { get; set; } + public int TrialKeepCount { get; set; } + + } + + + public class NewTrialView : PatientJoinTrialInitView + { + public Guid Id { get; set; } + //授权年限 + public int AuthorizationDuration { get; set; } + + public DateTime? AuthorizationDate { get; set; } + + public string AuthorizationEncrypt { get; set; } + + public string CriterionTypes { get; set; } + public List CriterionTypeList => CriterionTypes.Split('|', StringSplitOptions.RemoveEmptyEntries) + .Select(s => Enum.Parse(typeof(CriterionType), s)).Cast().ToList(); + + public int? UnSubmitCount { get; set; } + + public int? UnReadCount { get; set; } + } + + public class NewTrialQuery : PageInput + { + public string? ExperimentName { get; set; } + public string? ResearchProgramNo { get; set; } + public TrialType? TrialType { get; set; } + + public string? SponsorName { get; set; } + + public string? TrialCode { get; set; } + } + + public class TrialInfoDTO : AddOrUpdateTrialCommand + { + [JsonIgnore] + public List DictionaryList { get; set; } = new List(); + + public new List ModalityIds => DictionaryList.Where(t => t.ParentCode == StaticData.Modality).OrderBy(t => t.ShowOrder).Select(t => t.Id).ToList(); + + public string CriterionTypes { get; set; } = string.Empty; + + + public new List CriterionTypeList => CriterionTypes.Split('|', StringSplitOptions.RemoveEmptyEntries) + .Select(s => Enum.Parse(typeof(CriterionType), s)).Cast().ToList(); + + public string AuthorizationEncrypt { get; set; } + + public TrialAuthorizationInfo AuthorizationInfo { get; set; } + + public string TrialStatusStr { get; set; } + + public DateTime CreateTime { get; set; } + } + + public class AddOrUpdateTrialCommand + { + + public Guid? Id { get; set; } + public string TrialCode { get; set; } = string.Empty; + + public TrialType TrialType { get; set; } + + + //研究方案号 + public string ResearchProgramNo { get; set; } = string.Empty; + + //实验名称 + public string ExperimentName { get; set; } = string.Empty; + + // 负责人PI + public string HeadPI { get; set; } = string.Empty; + + public string CRO { get; set; } = string.Empty; + + public string Sponsor { get; set; } = string.Empty; + + //药物名称 + public string MedicineName { get; set; } = string.Empty; + + + //临床分期 + public Guid? PhaseId { get; set; } + + //适应症 + public string Indication { get; set; } = string.Empty; + + //检查技术 + public List ModalityIds { get; set; } = new List(); + + //阅片标准 + public List CriterionTypeList { get; set; } + + //联系人 + public string ContactUser { get; set; } = string.Empty; + //联系电话 + public string ContactPhone { get; set; } = string.Empty; + + //授权年限 + public int AuthorizationDuration { get; set; } + + public DateTime? AuthorizationDate { get; set; } + + } + + public class PatientJoinTrialInitQuery : PageInput + { + [NotDefault] + public Guid PatientId { get; set; } + + public string? Filter { get; set; } + + } + + public class PatientJoinedTrialQuery + { + [NotDefault] + public Guid PatientId { get; set; } + } + + public class PatientJoinedTrialView : PatientJoinTrialInitView + { + public Guid SubjectId { get; set; } + public string Code { get; set; } + + public string ShortName { get; set; } + + public string Sex { get; set; } + + public int? Age { get; set; } + } + + public class PatientJoinTrialSelectView + { + public Guid TrialId { get; set; } + public string ExperimentName { get; set; } + public string ResearchProgramNo { get; set; } + public string Sponsor { get; set; } + } + + + public class TrialCacheInfo + { + public Guid TrialId { get; set; } + public Guid CreateUserId { get; set; } + public string TrialCode { get; set; } + + public DateTime? AuthorizationDate { get; set; } + public string TrialStatusStr { get; set; } + + public string AuthorizationEncrypt { get; set; } + + public string CriterionTypes { get; set; } + public List CriterionTypeList => CriterionTypes.Split('|', StringSplitOptions.RemoveEmptyEntries) + .Select(s => Enum.Parse(typeof(CriterionType), s)).Cast().ToList(); + } + public class TrialAuthorizationInfo + { + public Guid TrialId { get; set; } + public Guid CreateUserId { get; set; } + public string TrialCode { get; set; } + + public string HospitalName { get; set; } + + public string HospitalCode { get; set; } + + public int PurchaseDuration { get; set; } + + + + public List CriterionTypeList { get; set; } + + public DateTime? AuthorizationDeadLineDate { get; set; } + + public DateTime? ActiveDeadLineDate { get; set; } + + public DateTime? ActiveTime { get; set; } + + } + public class PatientJoinTrialInitView + { + public Guid TrialId { get; set; } + + public string TrialCode { get; set; } + public string ExperimentName { get; set; } + public string ResearchProgramNo { get; set; } + public TrialType TrialType { get; set; } + + public string Sponsor { get; set; } + + public string TrialStatusStr { get; set; } + + public DateTime CreateTime { get; set; } + } + + + public class PatientTrialQuery : PageInput + { + public string? PatientIdStr { get; set; } + public string? PatientName { get; set; } + public List CalledAEList { get; set; } = new List(); + + public string? CallingAE { get; set; } + + public string? ExperimentName { get; set; } = string.Empty; + + public DateTime? BeginPushTime { get; set; } + public DateTime? EndPushTime { get; set; } + + } + + public class PatientTrialView : PatientQueryView + { + + public int? StudyCount { get; set; } + + public List TrialList { get; set; } + } + + public class PatientTrialStatInfo + { + public int? VisitCount { get; set; } + + public string ExperimentName { get; set; } + } + + public class PatientQuery : PageInput + { + [NotDefault] + public Guid TrialId { get; set; } + public Guid? SubjectId { get; set; } + public string? PatientIdStr { get; set; } + public string? PatientName { get; set; } + public List CalledAEList { get; set; } = new List(); + + public string? CallingAE { get; set; } + + public DateTime? EarliestStudyTime { get; set; } + + public DateTime? LatestStudyTime { get; set; } + + } + + public class PatientQueryView + { + public Guid PatientId { get; set; } + public string PatientIdStr { get; set; } = string.Empty; + public string PatientName { get; set; } = string.Empty; + public string PatientAge { get; set; } = string.Empty; + public string PatientSex { get; set; } = string.Empty; + public string PatientBirthDate { get; set; } = string.Empty; + + public DateTime? EarliestStudyTime { get; set; } + + public DateTime? LatestStudyTime { get; set; } + + public DateTime LatestPushTime { get; set; } + + public List CallingAEList { get; set; } = new List(); + + public List CalledAEList { get; set; } = new List(); + + public Guid UpdateUserId { get; set; } + public DateTime UpdateTime { get; set; } = DateTime.Now; + public Guid CreateUserId { get; set; } + public DateTime CreateTime { get; set; } = DateTime.Now; + } + + public class UpdateSubjectVisitStudyBindingCommand + { + [NotDefault] + public Guid TrialId { get; set; } + + [NotDefault] + public Guid SubjectId { get; set; } + [NotDefault] + public Guid SCPStudyId { get; set; } + + [NotDefault] + public Guid SubjectVisitId { get; set; } + + public bool IsAdd { get; set; } + + + } + + public class DeleteSubejctPatientCommand + { + [NotDefault] + public Guid SubjectId { get; set; } + [NotDefault] + public Guid PatientId { get; set; } + + [NotDefault] + public Guid TrialId { get; set; } + } + + + public class VisitStudyVerifyTimeQuery + { + public Guid SCPStudyId { get; set; } + + public Guid SubjectId { get; set; } + public Guid TrialId { get; set; } + } + + public class VerifyTrialSubjectCommand + { + [NotDefault] + public Guid TrialId { get; set; } + public string SubjectCode { get; set; } = string.Empty; + } + public class AddSubjectPatientCommand + { + [NotDefault] + public Guid TrialId { get; set; } + public string SubjectCode { get; set; } = string.Empty; + + public Guid? SubjectId { get; set; } + + public List PatientIdList { get; set; } + } + + public class VerifyVisitStudyDTO + { + public Guid SubjectVisitId { get; set; } + public decimal VisitNum { get; set; } + public DateTime? StudyTime { get; set; } + public Guid SCPStudyId { get; set; } + } + public class AddSubjectPatientStudyVisitCommand + { + [NotDefault] + public Guid TrialId { get; set; } + [NotDefault] + public Guid SubjectId { get; set; } + [NotDefault] + public Guid SubjectVisitId { get; set; } + [NotDefault] + public Guid SCPStudyId { get; set; } + + //public string VisitName { get; set; } + + } + + public class SubmitVisitStudyBindingCommand + { + [NotDefault] + public Guid TrialId { get; set; } + + [NotDefault] + public Guid SubjectId { get; set; } + + public List SubjectVisitIdList { get; set; } + } + + public class SubjectVisitSelectQuery + { + [NotDefault] + public Guid TrialId { get; set; } + [NotDefault] + public Guid SubjectId { get; set; } + + public Guid? SCPStudyId { get; set; } + } + + public class SubjectVisitSelectDto + { + public Guid Id { get; set; } + + public Guid TrialId { get; set; } + public Guid SubjectId { get; set; } + + public string VisitNum { get; set; } + + public string VisitName { get; set; } + + public SubmitStateEnum SubmitState { get; set; } + + public DateTime? VisitMaxStudyTime { get; set; } + + public DateTime? VisitMinStudyTime { get; set; } + } + public class AddOrUpdateSubjectVisitCommand + { + public Guid? Id { get; set; } + public Guid TrialId { get; set; } + public Guid SubjectId { get; set; } + + public decimal VisitNum { get; set; } + + public string VisitName { get; set; } + } + public class SubjectSelectQuery + { + public string? SubjectCode { get; set; } + + + public Guid? SubjectId { get; set; } + + [NotDefault] + public Guid TrialId { get; set; } + } + + public class SubjectPatientSelectQuery + { + public string? SubjectCode { get; set; } + public string? PatientIdStr { get; set; } + + public Guid? SubjectId { get; set; } + + public Guid? PatientId { get; set; } + [NotDefault] + public Guid TrialId { get; set; } + } + public class SubjectSelectDto + { + public Guid SubejctId { get; set; } + + public string SubjectCode { get; set; } + + public string ShortName { get; set; } + + public string Sex { get; set; } + + public int? Age { get; set; } + + public DateTime? BirthDate { get; set; } + + public SubjectStatus Status { get; set; } + + public List PatientList { get; set; } + } + + public class PatienBasicInfo + { + public Guid PatientId { get; set; } + public string PatientIdStr { get; set; } + } + + public class SubjectPatientSelectDto + { + public Guid Id { get; set; } + public Guid PatientId { get; set; } + public Guid TrialId { get; set; } + public Guid SubejctId { get; set; } + public string? PatientIdStr { get; set; } + public string SubjectCode { get; set; } + } + + public class PatientStudyInfoQuery : PageInput + { + [NotDefault] + public Guid PatientId { get; set; } + + public DateTime? EarliestStudyTime { get; set; } + + public DateTime? LatestStudyTime { get; set; } + public string? Modalities { get; set; } + } + + public class PatientStudyQuery : PageInput + { + [NotDefault] + public Guid TrialId { get; set; } + + public List PatientIdList { get; set; } + + + + public DateTime? EarliestStudyTime { get; set; } + + public DateTime? LatestStudyTime { get; set; } + } + + + public class PatientVisitTaskQuery : PageInput + { + [NotDefault] + public Guid TrialId { get; set; } + + + public Guid? SubjectId { get; set; } + + public string SubjectCode { get; set; } = String.Empty; + + public string? SubjectShortName { get; set; } + + public string TaskName { get; set; } = String.Empty; + + public Guid? DoctorUserId { get; set; } + + public ReadingCategory? ReadingCategory { get; set; } + + public ReadingTaskState? ReadingTaskState { get; set; } + + public TaskState? TaskState { get; set; } + + + public string? TaskCode { get; set; } + + public Arm? ArmEnum { get; set; } + + public Guid? TrialReadingCriterionId { get; set; } + + + public DateTime? BeginSignTime { get; set; } + public DateTime? EndSignTime { get; set; } + + public DateTime? BeginTaskCreateTime { get; set; } + public DateTime? EndTaskCreateTime { get; set; } + + + public string? PatientName { get; set; } + public string? PatientIdStr { get; set; } + + public string? PatientSex { get; set; } + + } + + public class PatientVisitTaskDTO + { + public List PatientList { get; set; } + + public Guid Id { get; set; } + public Guid TrialId { get; set; } + + public string TaskCode { get; set; } + + public string TaskName { get; set; } + public string TaskBlindName { get; set; } + + public decimal VisitTaskNum { get; set; } + + public Guid? SourceSubjectVisitId { get; set; } + + public ReadingCategory ReadingCategory { get; set; } + + + public TaskState TaskState { get; set; } + + public DateTime? SignTime { get; set; } + + public DateTime? AllocateTime { get; set; } + public Guid SubjectId { get; set; } + + public string SubjectCode { get; set; } = String.Empty; + + public string SubjectShortName { get; set; } + + public string VisitImageZipPath { get; set; } + + public PackState PackState { get; set; } + + public Arm ArmEnum { get; set; } + public Guid? DoctorUserId { get; set; } + + + public Guid TrialReadingCriterionId { get; set; } + + public string TrialReadingCriterionName { get; set; } + + public CriterionType CriterionType { get; set; } + + public DateTime CreateTime { get; set; } + + public UserSimpleInfo DoctorUser { get; set; } + + //任务阅片状态 + public ReadingTaskState ReadingTaskState { get; set; } + + //public bool IsUrgent { get; set; } + + ///// + ///// 加急类型 + ///// + //public TaskUrgentType? TaskUrgentType { get; set; } + + + //public string TaskUrgentRemake { get; set; } = string.Empty; + + + //public TaskAllocationState TaskAllocationState { get; set; } + //public bool IsNeedClinicalDataSign { get; set; } + + //public bool IsClinicalDataSign { get; set; } + + } + + public class AutoBindingPatientStudyVisitCommand + { + [NotDefault] + public Guid TrialId { get; set; } + + + } + public class TrialPatientStudyQuery : PageInput + { + [NotDefault] + public Guid TrialId { get; set; } + + public string? SubjectCode { get; set; } + + + public Guid? PatientId { get; set; } + + public string? PatientIdStr { get; set; } + + public string? PatientSex { get; set; } + + public string? SubjectShortName { get; set; } + + public int? SubjectAge { get; set; } + public string? SubjectSex { get; set; } + + public DateTime? BeginStudyTime { get; set; } + + public DateTime? EndStudyTime { get; set; } + + public string? VisitName { get; set; } + + public bool? IsBindedVisit { get; set; } + } + + public class AddOrUpdateSubjectCommand + { + + public Guid? Id { get; set; } + + [NotDefault] + public Guid TrialId { get; set; } + public string Code { get; set; } = String.Empty; + + public int? Age { get; set; } + public string Sex { get; set; } = string.Empty; + + public string ShortName { get; set; } = string.Empty; + + + public DateTime? BirthDate { get; set; } + + + } + public class PatientSubjectQuery : PageInput + { + [NotDefault] + public Guid TrialId { get; set; } + + public string? Code { get; set; } + + public string? ShortName { get; set; } + + public string? Sex { get; set; } + + public SubjectStatus? Status { get; set; } + + public string? PatientName { get; set; } + public string? PatientIdStr { get; set; } + + public string? PatientSex { get; set; } + + } + + public class PatienSubejctView + { + public List PatientList { get; set; } + + public Guid TrialId { get; set; } + public Guid Id { get; set; } + public string Code { get; set; } + + + public string ShortName { get; set; } + + public string Sex { get; set; } + + public int? Age { get; set; } + + public SubjectStatus Status { get; set; } + + public DateTime? BirthDate { get; set; } + + public int? VisitCount { get; set; } + + public DateTime CreateTime { get; set; } + + public string LatestVisitName { get; set; } + + public DateTime? VisitOverTime { get; set; } + + public Guid? FinalSubjectVisitId { get; set; } + + public string Reason { get; set; } + } + + public class PatientSubejctVisitQuery : PageInput + { + [NotDefault] + public Guid TrialId { get; set; } + public string? SubjectCode { get; set; } + + + public string? SubjectShortName { get; set; } + + public string? SubjectSex { get; set; } + + public string? PatientName { get; set; } + public string? PatientIdStr { get; set; } + + public string? PatientSex { get; set; } + + public string? VisitName { get; set; } + + public SubmitStateEnum? SubmitState { get; set; } + + public DateTime? BeginStudyTime { get; set; } + + public DateTime? EndStudyTime { get; set; } + } + + public class PatientStudyBeforeConfirmView : PatientStudyView + { + public Guid PatientId { get; set; } + public string CalledAE { get; set; } = string.Empty; + + public string CallingAE { get; set; } = string.Empty; + } + + public class PatientStudyView + { + + public string PatientName { get; set; } + public string PatientIdStr { get; set; } + + public string PatientSex { get; set; } + + public string PatientAge { get; set; } = string.Empty; + public string PatientBirthDate { get; set; } = string.Empty; + + + public Guid StudyId { get; set; } + public string Modalities { get; set; } + + public string ModalityForEdit { get; set; } + + public DateTime? StudyTime { get; set; } + + public string Description { get; set; } = string.Empty; + public int SeriesCount { get; set; } = 0; + public int InstanceCount { get; set; } = 0; + + + + public Guid SubjectId { get; set; } + + public string SubjectCode { get; set; } + + + public string SubjectShortName { get; set; } = String.Empty; + + public int? SubjectAge { get; set; } + public string SubjectSex { get; set; } = string.Empty; + + public Guid? SubjectVisitId { get; set; } + public string? VisitName { get; set; } + + public decimal? VisitNum { get; set; } + + public DateTime? VisitEarliestStudyTime { get; set; } + + public DateTime? VisitLatestStudyTime { get; set; } + + public DateTime? SubmitTime { get; set; } + + public SubmitStateEnum? SubmitState { get; set; } + + } + + public class PatientBasicInfo + { + public Guid PatientId { get; set; } + + public string PatientIdStr { get; set; } + + public string PatientSex { get; set; } + + public string PatientName { get; set; } + + public string PatientAge { get; set; } = string.Empty; + public string PatientBirthDate { get; set; } = string.Empty; + } + + + public class PatientSubjectVisitView + { + public Guid TrialId { get; set; } + public Guid SubjectId { get; set; } + + public string SubjectCode { get; set; } + + public List PatientList { get; set; } + + public string SubjectShortName { get; set; } = String.Empty; + + public int? SubjectAge { get; set; } + public string SubjectSex { get; set; } = string.Empty; + + public Guid SubjectVisitId { get; set; } + public string VisitName { get; set; } + + public decimal VisitNum { get; set; } + + public DateTime? VisitEarliestStudyTime { get; set; } + + public DateTime? VisitLatestStudyTime { get; set; } + + public DateTime? SubmitTime { get; set; } + + public SubmitStateEnum SubmitState { get; set; } + + public string VisitImageZipPath { get; set; } + public PackState PackState { get; set; } + } + + public class SubjectPatientStudyView : PatientStudySimpleView + { + public Guid SubjectId { get; set; } + + public string SubjectCode { get; set; } + + public List PatientList { get; set; } + + public string SubjectShortName { get; set; } = String.Empty; + + public int? SubjectAge { get; set; } + public string SubjectSex { get; set; } = string.Empty; + + } + + public class SubjectVisitStudyQuery : PageInput + { + [NotDefault] + public Guid SujectVisitId { get; set; } + + public SubmitStateEnum? SubmitState { get; set; } + } + + public class PatientStudyOtherQuery : PageInput + { + [NotDefault] + public Guid TrialId { get; set; } + public List PatientIdList { get; set; } + + [NotDefault] + public Guid SujectVisitId { get; set; } + + public DateTime? EarliestStudyTime { get; set; } + + public DateTime? LatestStudyTime { get; set; } + + public string? PatientIdStr { get; set; } + + } + + public class VisitImageDownloadQuery : PageInput + { + [NotDefault] + public Guid TrialId { get; set; } + + public string? IP { get; set; } + + public string? SubjectCode { get; set; } + + public string? VisitName { get; set; } + + public string? Name { get; set; } + + public DateTime? BeginDownloadTime { get; set; } + + public DateTime? EndDownloadTime { get; set; } + + public UserTypeEnum? UserTypeEnum { get; set; } + } + + public class VisitImageDownloadView + { + public string SubjectCode { get; set; } + + public string VisitName { get; set; } + + public DateTime DownloadTime { get; set; } + + public string DownloadUserName { get; set; } + + public string DownLoadUserFullName { get; set; } + + public string IP { get; set; } + + public long VisitImageZipSize { get; set; } + + //文件大小 + public int VisitImageFileCount { get; set; } + + public string VisitImageZipPath { get; set; } = string.Empty; + + public int? StudyCount { get; set; } + + public UserTypeEnum UserTypeEnum { get; set; } + + } + + + public class SCPImageUploadQuery : PageInput + { + public string? CallingAE { get; set; } + + public string? CalledAE { get; set; } + + public string? CallingAEIP { get; set; } + + public DateTime? StartTime { get; set; } + + public DateTime? EndTime { get; set; } + } + + public class SCPImageUploadView + { + public string CallingAE { get; set; } = string.Empty; + + public string CalledAE { get; set; } = string.Empty; + + public string CallingAEIP { get; set; } = string.Empty; + + public DateTime StartTime { get; set; } + + public DateTime EndTime { get; set; } + + public int FileCount { get; set; } + + public long FileSize { get; set; } + + public int StudyCount { get; set; } + + } + public class VisitPatientStudyView : PatientStudySelectDto + { + + public string VisitName { get; set; } + } + + public class UnbindStudyView : VisitPatientStudyView + { + public Guid TrialId { get; set; } + + public Guid SubjectId { get; set; } + public string SubjectCode { get; set; } + + public string SubjectShortName { get; set; } = String.Empty; + + public int? SubjectAge { get; set; } + public string SubjectSex { get; set; } = string.Empty; + + public DateTime? SubjectBirthDate { get; set; } + + } + + public class PatientStudySimpleView + { + public Guid SCPStudyId { get; set; } + + public Guid PatientId { get; set; } + + public DateTime? StudyTime { get; set; } + public string Modalities { get; set; } = string.Empty; + + public string Description { get; set; } = string.Empty; + public int SeriesCount { get; set; } = 0; + public int InstanceCount { get; set; } = 0; + + public string CalledAE { get; set; } = string.Empty; + + public string CallingAE { get; set; } = string.Empty; + + } + + + + public class PatientSeriesDTO + { + + public bool IsDicom { get; set; } = true; + + + public Guid Id { get; set; } + public Guid StudyId { get; set; } + public string StudyInstanceUid { get; set; } = String.Empty; + public string SeriesInstanceUid { get; set; } = String.Empty; + public int SeriesNumber { get; set; } + public DateTime? SeriesTime { get; set; } + public string Modality { get; set; } = String.Empty; + public string Description { get; set; } = String.Empty; + public int InstanceCount { get; set; } + public string SliceThickness { get; set; } = String.Empty; + + public DateTime CreateTime { get; set; } + public DateTime UpdateTime { get; set; } + + public bool IsDeleted { get; set; } + public bool IsReading { get; set; } = true; + + public List InstanceList { get; set; } = new List(); + + public List InstancePathList { get; set; } = new List(); + + public string ImageResizePath { get; set; } + } + + public class PatientStudySelectDto + { + public Guid SCPStudyId { get; set; } + + public Guid PatientId { get; set; } + public string PatientIdStr { get; set; } = string.Empty; + public string PatientName { get; set; } = string.Empty; + public string PatientAge { get; set; } = string.Empty; + public string PatientSex { get; set; } = string.Empty; + public string PatientBirthDate { get; set; } = string.Empty; + + public DateTime? StudyTime { get; set; } + public string Modalities { get; set; } = string.Empty; + + public string Description { get; set; } = string.Empty; + public int SeriesCount { get; set; } = 0; + public int InstanceCount { get; set; } = 0; + + public string CalledAE { get; set; } = string.Empty; + + public string CallingAE { get; set; } + public Guid? SubjectVisitId { get; set; } + + public SubmitStateEnum? SubmitState { get; set; } + + //public Guid? SubjectVisitId { get; set; } + + //public string CallingAE { get; set; } = string.Empty; + + //public string BodyPartExamined { get; set; } = string.Empty; + + //public string BodyPartForEdit { get; set; } = string.Empty; + + //public string ModalityForEdit { get; set; } = string.Empty; + + + + } + +} diff --git a/IRaCIS.Core.Application/Service/Visit/PatientService.cs b/IRaCIS.Core.Application/Service/Visit/PatientService.cs new file mode 100644 index 000000000..c4bef2800 --- /dev/null +++ b/IRaCIS.Core.Application/Service/Visit/PatientService.cs @@ -0,0 +1,1323 @@ +//using IRaCIS.Application.Interfaces; +//using IRaCIS.Application.Contracts; +//using IRaCIS.Core.Application.Filter; +//using IRaCIS.Core.Domain.Share; +//using Microsoft.AspNetCore.Mvc; +//using Microsoft.AspNetCore.Authorization; +//using IRaCIS.Core.Application.Auth; +//using MassTransit; +//using Panda.DynamicWebApi.Attributes; +//using DocumentFormat.OpenXml.Spreadsheet; +//using AutoMapper.EntityFrameworkCore; +//using IRaCIS.Core.Domain.Models; +//using IRaCIS.Core.Application.Service.Reading.Dto; +//using Microsoft.Extensions.Options; +//using Microsoft.Extensions.Configuration; +//using Microsoft.Extensions.Configuration.Json; +//using Newtonsoft.Json; +//using Newtonsoft.Json.Linq; +//using SharpCompress.Common; +//using System.Reactive.Subjects; +//using Subject = IRaCIS.Core.Domain.Models.Subject; +//using IRaCIS.Core.Application.ViewModel; +//using Medallion.Threading; +//using IRaCIS.Core.Infrastructure; +//using EasyCaching.Core; +//using Pipelines.Sockets.Unofficial.Arenas; +//using IRaCIS.Core.Application.Contracts; +//using MailKit.Search; +//using DocumentFormat.OpenXml.Office2010.Excel; +//using IRaCIS.Core.Application.Contracts.Dicom.DTO; +//using IRaCIS.Core.Application.Helper; +//using NPOI.SS.Formula.Functions; +//using System.Linq; +//using System.Linq.Dynamic.Core; +//using System.Text; +//using DocumentFormat.OpenXml.EMMA; +//using Azure; +//using System.IO.Compression; +//using static IRaCIS.Core.Domain.Share.StaticData; +//using FellowOakDicom; +//using DocumentFormat.OpenXml.Office2010.Drawing; +//using EasyCaching.Core.DistributedLock; +//using IDistributedLockProvider = Medallion.Threading.IDistributedLockProvider; +//using DocumentFormat.OpenXml.InkML; + +//namespace IRaCIS.Application.Services +//{ +// [ApiExplorerSettings(GroupName = "Trial")] +// public class PatientService : BaseService +// { + +// private readonly IRepository _trialRepository; +// private readonly IRepository _patientRepository; +// private readonly IRepository _studyRepository; +// private readonly IRepository _subjectRepository; +// private readonly IRepository _subjectVisitRepository; +// private readonly IDistributedLockProvider _distributedLockProvider; + +// public PatientService(IRepository studyRepository, IRepository trialRepository, IRepository patientRepository, IRepository subjectRepository, IRepository subjectVisitRepository, IDistributedLockProvider distributedLockProvider) +// { +// _studyRepository = studyRepository; +// _trialRepository = trialRepository; +// _patientRepository = patientRepository; +// _subjectRepository = subjectRepository; +// _subjectVisitRepository = subjectVisitRepository; +// _distributedLockProvider = distributedLockProvider; +// } + + + + + +// #region 患者检查管理 + +// /// +// ///检查管理-> 检查Tab 患者列表 (带加入的项目信息 以及检查统计) 原型标注错误,不是检查列表 +// /// +// /// +// /// +// [HttpPost] +// public async Task>> GetPatientList(PatientTrialQuery inQuery) +// { + +// var isAdminOrOA = _userInfo.UserTypeEnumInt == (int)UserTypeEnum.Admin || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.OA || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.SuperAdmin; + +// #region new ok +// var query = _patientRepository +// .WhereIf(!string.IsNullOrWhiteSpace(inQuery.PatientIdStr), t => t.PatientIdStr.Contains(inQuery.PatientIdStr)) +// .WhereIf(!string.IsNullOrWhiteSpace(inQuery.PatientName), t => t.PatientName.Contains(inQuery.PatientName)) +// //.WhereIf(!string.IsNullOrWhiteSpace(inQuery.ExperimentName), t => t.SubjectPatientList.Any(t => t.Subject.Trial.ExperimentName.Contains(inQuery.ExperimentName))) +// .WhereIf(!string.IsNullOrWhiteSpace(inQuery.CallingAE), t => t.SCPStudyList.Any(t => t.CallingAE == inQuery.CallingAE)) +// .WhereIf(inQuery.BeginPushTime != null, t => t.LatestPushTime >= inQuery.BeginPushTime) +// .WhereIf(inQuery.EndPushTime != null, t => t.LatestPushTime <= inQuery.EndPushTime); + +// foreach (var calledAE in inQuery.CalledAEList) +// { +// query = query.Where(t => t.SCPStudyList.Select(c => c.CalledAE).Contains(calledAE)); +// } + + +// var resultQuery = from patient in query + +// select new PatientTrialView() +// { +// PatientId = patient.Id, +// PatientBirthDate = patient.PatientBirthDate, +// CreateTime = patient.CreateTime, +// CalledAEList = patient.SCPStudyList.Select(t => t.CalledAE).Distinct().ToList(), +// CallingAEList = patient.SCPStudyList.Select(t => t.CallingAE).Distinct().ToList(), +// CreateUserId = patient.CreateUserId, +// UpdateTime = patient.UpdateTime, +// UpdateUserId = patient.UpdateUserId, + +// EarliestStudyTime = patient.EarliestStudyTime, +// LatestStudyTime = patient.LatestStudyTime, +// LatestPushTime = patient.LatestPushTime, +// PatientAge = patient.PatientAge, +// PatientName = patient.PatientName, +// PatientIdStr = patient.PatientIdStr, +// PatientSex = patient.PatientSex, + +// StudyCount = patient.SCPStudyList.Count(), + +// TrialList = patient.SubjectPatientList.Where(t => isAdminOrOA ? true : t.Subject.Trial.TrialUserList.Any(t => t.UserId == _userInfo.Id)).Select(c => new PatientTrialStatInfo() +// { +// ExperimentName = c.Subject.Trial.ExperimentName, +// VisitCount = c.Subject.SubjectVisitList.Count() +// }).ToList(), + +// }; + + + + +// var pageList = await resultQuery.ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, inQuery.SortField == string.Empty ? nameof(PatientQueryView.PatientIdStr) : inQuery.SortField, inQuery.Asc); +// #endregion + + +// return ResponseOutput.Ok(pageList); +// } + + + + + +// /// +// /// 检查管理-> 获取患者检查列表(同步影像数据之前的) +// /// +// /// +// /// +// [HttpPost] +// public async Task> GetPatientStudyList(PatientStudyInfoQuery inQuery) +// { +// var query = from scpStudy in _studyRepository.Where(t => t.PatientId == inQuery.PatientId) +// .WhereIf(inQuery.EarliestStudyTime != null, t => t.StudyTime >= inQuery.EarliestStudyTime) +// .WhereIf(inQuery.LatestStudyTime != null, t => t.StudyTime <= inQuery.LatestStudyTime) +// .WhereIf(!string.IsNullOrWhiteSpace(inQuery.Modalities), t => t.Modalities.Contains(inQuery.Modalities)) +// select new PatientStudySimpleView() +// { +// Description = scpStudy.Description, +// CalledAE = scpStudy.CalledAE, +// CallingAE = scpStudy.CallingAE, +// InstanceCount = scpStudy.InstanceCount, +// Modalities = scpStudy.Modalities, +// PatientId = scpStudy.PatientId, +// SCPStudyId = scpStudy.Id, +// SeriesCount = scpStudy.SeriesCount, +// StudyTime = scpStudy.StudyTime, +// }; + + +// var sortField = string.IsNullOrWhiteSpace(inQuery.SortField) ? nameof(PatientStudySimpleView.StudyTime) : inQuery.SortField; +// var orderQuery = inQuery.Asc ? query.OrderBy(sortField) : query.OrderBy(sortField + " desc"); + +// var list = await orderQuery.ToListAsync(); + +// return list; +// } + + + +// public async Task>> GetPatientSeriesList(Guid scpStudyId, +// [FromServices] IRepository _seriesRepository, +// [FromServices] IRepository _instanceRepository +// ) +// { + +// var seriesList = await _seriesRepository.Where(s => s.StudyId == scpStudyId).OrderBy(s => s.SeriesNumber). +// ThenBy(s => s.SeriesTime).ThenBy(s => s.CreateTime) +// .ProjectTo(_mapper.ConfigurationProvider).ToListAsync(); + +// var idList = await _instanceRepository.Where(s => s.StudyId == scpStudyId).OrderBy(t => t.SeriesId).ThenBy(t => t.InstanceNumber) +// .ThenBy(s => s.InstanceTime).ThenBy(s => s.CreateTime) +// .Select(t => new { t.SeriesId, t.Id, t.Path, t.NumberOfFrames, t.InstanceNumber }).ToListAsync();//.GroupBy(u => u.SeriesId); + +// foreach (var item in seriesList) +// { +// item.InstanceList = idList.Where(s => s.SeriesId == item.Id).Select(u => u.Id).ToList(); + +// //处理多帧 +// item.InstancePathList = idList.Where(s => s.SeriesId == item.Id).OrderBy(t => t.InstanceNumber) +// .SelectMany(u => +// { + +// if (u.NumberOfFrames > 1) +// { +// var pathList = new List(); + +// for (int i = 1; i <= u.NumberOfFrames; i++) +// { +// pathList.Add(u.Path + "?frame=" + (i - 1)); +// } +// return pathList; +// } +// else +// { +// return new List { u.Path }; + +// } +// }) +// .ToList(); +// } + + +// var study = await _studyRepository.FindAsync(scpStudyId); + +// return ResponseOutput.Ok(seriesList, study); +// } + + + + + +// /// +// /// 清除该患者绑定的受试者的所有的数据、(subject subjectVisit visitTask dicom) +// /// +// /// +// /// +// [UnitOfWork] +// public async Task DeletePatientStudyAllData(Guid patientId, +// [FromServices] IRepository _visitTaskRepository, +// [FromServices] IRepository _SeriesRepository, +// [FromServices] IRepository _instanceRepository, +// [FromServices] IRepository _dicomStudyRepository, +// [FromServices] IRepository _dicomSeriesRepository, +// [FromServices] IRepository _dicomInstanceRepository, +// [FromServices] IOSSService oSSService) +// { +// //清理自己管理的项目的数据 +// var subjectPatientList = await _subjectPatientRepository.Where(t => t.PatientId == patientId && t.Subject.Trial.TrialUserList.Any(t => t.UserId == _userInfo.Id)) +// .Select(t => new { t.SubjectId, StudyInstanceUidList = t.Patient.SCPStudyList.Select(t => t.StudyInstanceUid).ToList() }).ToListAsync(); + +// if (_studyRepository.Any(t => t.IsUploadFinished == false && t.PatientId == patientId)) +// { +// return ResponseOutput.NotOk("当前患者有检查正在上传,不允许清理数据"); +// } + +// foreach (var item in subjectPatientList) +// { +// var subjectId = item.SubjectId; + +// await _subjectRepository.BatchDeleteNoTrackingAsync(t => t.Id == subjectId); +// await _subjectVisitRepository.BatchDeleteNoTrackingAsync(t => t.SubjectId == subjectId); +// await _visitTaskRepository.BatchDeleteNoTrackingAsync(t => t.SubjectId == subjectId); +// await _dicomStudyRepository.BatchDeleteNoTrackingAsync(t => t.SubjectId == subjectId); +// await _dicomSeriesRepository.BatchDeleteNoTrackingAsync(t => t.SubjectId == subjectId); +// await _dicomInstanceRepository.BatchDeleteNoTrackingAsync(t => t.SubjectId == subjectId); +// } + +// var instanceUidList = subjectPatientList.SelectMany(t => t.StudyInstanceUidList).Distinct().ToList(); +// foreach (var studyInstanceUid in instanceUidList) +// { +// { +// var ossFolderPath = $"Dicom/{studyInstanceUid}"; + +// await oSSService.DeleteFromPrefix(ossFolderPath); + +// } +// } + + +// var sCPStudyIdList = _studyRepository.Where(t => t.PatientId == patientId).Select(t => t.Id).ToList(); + +// await _patientRepository.BatchDeleteNoTrackingAsync(t => t.Id == patientId); + +// foreach (var item in sCPStudyIdList) +// { +// await _studyRepository.BatchDeleteNoTrackingAsync(t => t.Id == item); +// await _SeriesRepository.BatchDeleteNoTrackingAsync(t => t.StudyId == item); +// await _instanceRepository.BatchDeleteNoTrackingAsync(t => t.StudyId == item); +// } + + + +// return ResponseOutput.Ok(); +// } +// #endregion + + +// #region 受试者管理 + + +// [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })] +// [HttpPost] +// public async Task> AddOrUpdateSubject([FromBody] AddOrUpdateSubjectCommand subjectCommand) +// { +// var svlist = new List(); + +// var verifyExp1 = new EntityVerifyExp() +// { +// VerifyExp = u => u.Code == subjectCommand.Code && u.TrialId == subjectCommand.TrialId, +// //---已存在具有相关受试者编号的受试者。 +// VerifyMsg = _localizer["Subject_DuplicateSubjectNum"] +// }; + + +// Subject? mapedSubject = null; + +// if (subjectCommand.Id == null) //insert +// { + + +// mapedSubject = await _subjectRepository.InsertFromDTOAsync(subjectCommand, false, verifyExp1); + + +// } +// else //update +// { + +// mapedSubject = await _subjectRepository.UpdateFromDTOAsync(subjectCommand, false, false, verifyExp1/*, verifyExp2*/); + +// } + + + +// await _subjectRepository.SaveChangesAsync(); + +// return ResponseOutput.Ok(mapedSubject.Id.ToString()); + +// } + +// /// +// /// 受试者管理-> 受试者列表 (带患者信息,患者信息是数组) +// /// +// /// +// /// +// [HttpPost] +// public async Task>> GetPatientSubejctList(PatientSubjectQuery inQuery) +// { +// var subjectQuery = _subjectRepository.Where(u => u.TrialId == inQuery.TrialId) +// .WhereIf(!string.IsNullOrWhiteSpace(inQuery.Code), t => t.Code.Contains(inQuery.Code)) +// .WhereIf(!string.IsNullOrWhiteSpace(inQuery.ShortName), t => t.ShortName.Contains(inQuery.ShortName)) +// .WhereIf(!string.IsNullOrWhiteSpace(inQuery.Sex), t => t.Sex.Contains(inQuery.Sex)) + +// //.WhereIf(!string.IsNullOrWhiteSpace(inQuery.PatientIdStr), t => t.SubjectPatientList.Any(t => t.Patient.PatientIdStr.Contains(inQuery.PatientIdStr))) +// .WhereIf(!string.IsNullOrWhiteSpace(inQuery.PatientName), t => t.SubjectPatientList.Any(t => t.Patient.PatientName.Contains(inQuery.PatientName))) +// .WhereIf(!string.IsNullOrWhiteSpace(inQuery.PatientSex), t => t.SubjectPatientList.Any(t => t.Patient.PatientSex.Contains(inQuery.PatientSex))) + +// .WhereIf(inQuery.Status != null, t => t.Status == inQuery.Status) +// .ProjectTo(_mapper.ConfigurationProvider); + +// var pageList = await subjectQuery.ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, inQuery.SortField == string.Empty ? nameof(PatienSubejctView.Code) : inQuery.SortField, inQuery.Asc); + + +// return ResponseOutput.Ok(pageList); +// } + +// /// +// /// 受试者管理-> 患者列表 (subject 列表进入,进行关系绑定初始化列表,排除已绑定的患者和已绑定给其他subject的患者) +// /// +// /// +// /// +// [HttpPost] +// public async Task>> GetPatientInitList(PatientQuery inQuery) +// { +// var query = _patientRepository +// .WhereIf(!string.IsNullOrWhiteSpace(inQuery.PatientIdStr), t => t.PatientIdStr.Contains(inQuery.PatientIdStr)) +// .WhereIf(!string.IsNullOrWhiteSpace(inQuery.PatientName), t => t.PatientName.Contains(inQuery.PatientName)) +// .WhereIf(!string.IsNullOrWhiteSpace(inQuery.CallingAE), t => t.SCPStudyList.Any(t => t.CallingAE == inQuery.CallingAE)) +// .WhereIf(inQuery.EarliestStudyTime != null, t => t.EarliestStudyTime >= inQuery.EarliestStudyTime) +// .WhereIf(inQuery.LatestStudyTime != null, t => t.LatestStudyTime <= inQuery.LatestStudyTime) + +// //排除该受试者已绑定的患者 +// //.WhereIf(inQuery.SubjectId != null, t => !t.SubjectPatientList.Any(u => u.SubjectId == inQuery.SubjectId)) + +// //排除该项目已绑定的其他患者 +// .Where(t => !t.SubjectPatientList.Any(c => c.Subject.TrialId == inQuery.TrialId)); + +// foreach (var calledAE in inQuery.CalledAEList) +// { +// query = query.Where(t => t.SCPStudyList.Select(c => c.CalledAE).Contains(calledAE)); +// } + + +// var patientQuery = query.ProjectTo(_mapper.ConfigurationProvider); + + +// var pageList = await patientQuery.ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, inQuery.SortField == string.Empty ? nameof(PatientQueryView.PatientIdStr) : inQuery.SortField, inQuery.Asc); + + +// return ResponseOutput.Ok(pageList); +// } + +// /// +// /// 受试者管理->患者列表 Dicom AE 下拉框数据获取 +// /// +// /// +// public async Task> GetDicomCalledAEList() +// { +// var list = await _studyRepository.Select(t => t.CalledAE).Distinct().ToListAsync(); + +// return list; +// } + +// public async Task> GetDicomCallingAEList() +// { +// var list = await _studyRepository.Select(t => t.CallingAE).Distinct().ToListAsync(); + +// return list; +// } + +// /// +// ///受试者管理-> 患者列表 模糊搜索下拉 选择subject 排除已绑定并提交的 +// /// +// /// +// /// +// [HttpPost] +// public async Task> GetTrialSubejctSelectList(SubjectSelectQuery inQuery) +// { +// var list = await _subjectRepository.Where(t => t.TrialId == inQuery.TrialId && t.Status == SubjectStatus.OnVisit) +// .WhereIf(!string.IsNullOrWhiteSpace(inQuery.SubjectCode), u => u.Code.Contains(inQuery.SubjectCode)) +// .WhereIf(inQuery.SubjectId != null, t => t.Id == inQuery.SubjectId) +// //.Where(t => !t.SubjectVisitList.SelectMany(t => t.SCPStudySubjectVisitList).Any(c => c.StudyId != null)) +// .Select(t => new SubjectSelectDto() +// { +// SubejctId = t.Id, +// SubjectCode = t.Code, +// Status = t.Status, +// Sex = t.Sex, +// ShortName = t.ShortName, +// Age = t.Age, +// BirthDate = t.BirthDate, +// //PatientList = t.SubjectPatientList.Select(c => new PatienBasicInfo() { PatientId = c.PatientId, PatientIdStr = c.Patient.PatientIdStr }).ToList() +// }) +// .ToListAsync(); + +// return list; +// } + +// #endregion + + + +// #region 患者和受试者绑定,生成访视,预先绑定检查和访视 + + + + + + + +// /// +// /// 提交 患者检查和访视的绑定 +// /// +// /// +// /// +// [HttpPost] +// [UnitOfWork] +// [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })] +// public async Task SubmitVisitStudyBinding(SubmitVisitStudyBindingCommand inCommand, [FromServices] IOptionsMonitor _basicSystemConfigConfig) +// { + +// //防止访视重复 +// inCommand.SubjectVisitIdList = inCommand.SubjectVisitIdList.Distinct().ToList(); + +// //确认当前提交的最大的访视之前所有的访视都已提交,并且没有漏的 + +// var curentMaxNum = await _subjectVisitRepository.Where(t => inCommand.SubjectVisitIdList.Contains(t.Id)).Select(t => t.VisitNum).MaxAsync(); + +// var allVisitList = _subjectVisitRepository.Where(t => t.TrialId == inCommand.TrialId && t.SubjectId == inCommand.SubjectId && t.VisitNum <= curentMaxNum).Select(t => new { SubjectVisitId = t.Id, t.Subject.Status, t.VisitNum, t.SubmitState }).OrderBy(t => t.VisitNum).ToList(); + +// //批量提交 +// if (inCommand.SubjectVisitIdList.Count > 1) +// { +// if (allVisitList.Where(t => t.SubmitState != SubmitStateEnum.Submitted).Count() != inCommand.SubjectVisitIdList.Count()) +// { +// return ResponseOutput.NotOk(_localizer["当前批量提交的访视中间有遗漏的访视或者前序有访视未提交"]); +// } +// } + +// else +// { +// if (allVisitList.Any(t => t.VisitNum < curentMaxNum && t.SubmitState != SubmitStateEnum.Submitted)) +// { +// return ResponseOutput.NotOk(_localizer["前序有访视未提交,请先提交前序访视"]); +// } +// } + +// if (allVisitList.Any(t => t.Status == SubjectStatus.EndOfVisit)) +// { +// return ResponseOutput.NotOk(_localizer["受试者状态为访视结束,不允许提交访视生成任务"]); +// } + +// //var list = await _studySubjectVisitRepository.Where(t => inCommand.SubjectVisitIdList.Contains(t.SubjectVisitId)).Select(t => new { t.SCPStudyId, t.SCPStudy.PatientId, t.SubjectVisitId, t.SubjectVisit.VisitNum, t.SubjectVisit.SubjectId, SubjectCode = t.SubjectVisit.Subject.Code, t.SubjectVisit.TrialId, t.SCPStudy.StudyTime, t.StudyId, t.SCPStudy.IsUploadFinished }).OrderBy(t => t.StudyTime).ToListAsync(); + +// //if (list.Any(t => t.StudyId != null)) +// //{ +// // return ResponseOutput.NotOk(_localizer["有访视和检查处于已绑定关系,不允许再次提交绑定"]); +// //} + +// //if (list.Any(t => t.IsUploadFinished == false)) +// //{ +// // return ResponseOutput.NotOk(_localizer["有访视检查正在传输中,不允许提交"]); +// //} + + +// ////判断每个subject 批量提交的是否符合时间要求 +// //foreach (var g in list.GroupBy(t => new { t.SubjectId, t.SubjectCode })) +// //{ +// // var visitOrderStudyList = g.OrderBy(t => t.VisitNum).ThenBy(t => t.StudyTime).ToList(); + +// // var studyTimeOrderList = visitOrderStudyList.OrderBy(t => t.StudyTime).ToList(); + +// // bool arraysEqual = visitOrderStudyList.SequenceEqual(studyTimeOrderList); + +// // if (!arraysEqual) +// // { +// // return ResponseOutput.NotOk(_localizer[$"{g.Key.SubjectCode}所提交的访视中的检查时间,不符合后续访视的检查时间比前序检查的时间大的要求"]); +// // } + +// // if (DateTime.Now < studyTimeOrderList.Max(t => t.StudyTime)) +// // { +// // return ResponseOutput.NotOk(_localizer[$"您当前修改了服务器时间,试图绕过软件授权,请恢复服务器时间,并联系授权方授权才可进行操作"]); +// // } +// //} + +// var trialConfig = await _trialRepository.Where(t => t.Id == inCommand.TrialId).Select(t => new { t.IsEnrollementQualificationConfirm, t.IsPDProgressView, t.AuthorizationEncrypt }).FirstOrDefaultAsync(); + + + +// //var decodedText = Cryptography.DecryptString(trialConfig.AuthorizationEncrypt, _basicSystemConfigConfig.CurrentValue.AESKey, "Trial_AuthorizationEncrypt"); + +// //var authInfo = JsonConvert.DeserializeObject(decodedText); + + + + +// var @lock = _distributedLockProvider.CreateLock($"StudyCode"); + +// using (await @lock.AcquireAsync()) +// { +// var dbStudyCodeIntMax = _repository.Where(s => s.TrialId == inCommand.TrialId).Select(t => t.Code).DefaultIfEmpty().Max(); + +// int currentNextCodeInt = dbStudyCodeIntMax + 1; + +// foreach (var item in list) +// { + + +// var dbSubjectVisit = await _subjectVisitRepository.FirstOrDefaultAsync(t => t.Id == item.SubjectVisitId); + +// //处理脏数据,可能之前的绑定的数据状态是待上传,但是已经绑定了检查 +// if (dbSubjectVisit.SubmitState == SubmitStateEnum.ToSubmit || dbSubjectVisit.SubmitState == SubmitStateEnum.None) +// { +// dbSubjectVisit.SubmitState = SubmitStateEnum.Submitted; +// dbSubjectVisit.SubmitTime = DateTime.Now; +// dbSubjectVisit.SubmitUserId = _userInfo.Id; + +// //维护统一状态 +// //dbSubjectVisit.ReadingStatus = ReadingStatusEnum.TaskAllocate; + +// dbSubjectVisit.AuditState = AuditStateEnum.QCPassed; +// dbSubjectVisit.CheckState = CheckStateEnum.CVPassed; + +// dbSubjectVisit.IsEnrollmentConfirm = dbSubjectVisit.IsBaseLine ? trialConfig.IsEnrollementQualificationConfirm : false; + +// dbSubjectVisit.PDState = trialConfig.IsPDProgressView ? PDStateEnum.PDProgress : PDStateEnum.None; +// } + + + + +// var find = _studyRepository.Where(t => t.Id == item.SCPStudyId).Include(t => t.SeriesList).Include(t => t.InstanceList).FirstOrDefault(); + +// if (find != null) +// { +// //重新算Id +// Guid studyId = IdentifierHelper.CreateGuid(item.TrialId.ToString(), find.StudyInstanceUid); +// find.Id = studyId; +// var newStuty = _mapper.Map(find); + +// await _repository.AddAsync(newStuty); +// //newStuty.Id = NewId.NextSequentialGuid(); + +// newStuty.SeqId = Guid.Empty; +// newStuty.Code = currentNextCodeInt; +// newStuty.StudyCode = AppSettings.GetCodeStr(currentNextCodeInt, nameof(DicomStudy)); +// newStuty.TrialId = item.TrialId; +// newStuty.SubjectId = item.SubjectId; +// newStuty.SubjectVisitId = item.SubjectVisitId; + +// var newSeriesList = _mapper.Map>(find.SeriesList); + +// foreach (var series in newSeriesList) +// { +// Guid seriesId = IdentifierHelper.CreateGuid(item.TrialId.ToString(), find.StudyInstanceUid, series.SeriesInstanceUid); + +// //重新算Id +// series.Id = seriesId; +// series.StudyId = newStuty.Id; + +// series.SeqId = Guid.Empty; +// series.TrialId = item.TrialId; +// series.SubjectId = item.SubjectId; +// series.SubjectVisitId = item.SubjectVisitId; +// } + +// await _repository.AddRangeAsync(newSeriesList); + +// var newInstanceList = _mapper.Map>(find.InstanceList); + +// foreach (var instance in newInstanceList) +// { +// Guid seriesId = IdentifierHelper.CreateGuid(item.TrialId.ToString(), find.StudyInstanceUid, instance.SeriesInstanceUid); +// Guid instanceId = IdentifierHelper.CreateGuid(item.TrialId.ToString(), find.StudyInstanceUid, instance.SeriesInstanceUid, instance.SopInstanceUid); +// //重新算Id +// instance.Id = instanceId; +// instance.SeriesId = seriesId; +// instance.StudyId = newStuty.Id; + +// instance.SeqId = Guid.Empty; +// instance.TrialId = item.TrialId; +// instance.SubjectId = item.SubjectId; +// instance.SubjectVisitId = item.SubjectVisitId; +// } +// await _repository.AddRangeAsync(newInstanceList); +// } + +// currentNextCodeInt++; + +// //await _studySubjectVisitRepository.BatchUpdateNoTrackingAsync(t => t.SubjectVisitId == item.SubjectVisitId && t.SCPStudyId == item.SCPStudyId, u => new SCPStudySubjectVisit() { StudyId = find.Id }); + +// //await _subjectPatientRepository.BatchUpdateNoTrackingAsync(t => t.SubjectId == item.SubjectId && t.PatientId == item.PatientId, u => new SubjectPatient() { IsBinded = true }); + +// } + + +// } + + + +// //await _studySubjectVisitRepository.SaveChangesAsync(); + +// return ResponseOutput.Ok(); +// } + +// #endregion + +// #region 访视基本管理 + + +// /// +// /// 绑定访视 初始化患者检查列表 +// /// +// /// +// /// +// [HttpPost] +// public async Task> GetVisitPatientStudyList(PatientStudyQuery inQuery) +// { +// var patientQuery = from scpStudy in _studyRepository +// .Where(t => inQuery.PatientIdList.Contains(t.PatientId)) +// .WhereIf(inQuery.EarliestStudyTime != null, t => t.StudyTime >= inQuery.EarliestStudyTime) +// .WhereIf(inQuery.LatestStudyTime != null, t => t.StudyTime <= inQuery.LatestStudyTime) + +// join scpStudySubjectVisit in _studySubjectVisitRepository.Where(t => t.SubjectVisit.TrialId == inQuery.TrialId) on scpStudy.Id equals scpStudySubjectVisit.SCPStudyId into cc +// from scpStudySubjectVisit in cc.DefaultIfEmpty() +// select new PatientStudySelectDto() +// { +// Description = scpStudy.Description, +// CalledAE = scpStudy.CalledAE, +// InstanceCount = scpStudy.InstanceCount, +// Modalities = scpStudy.Modalities, +// PatientId = scpStudy.Patient.Id, + +// PatientIdStr = scpStudy.PatientIdStr, +// PatientAge = scpStudy.PatientAge, +// PatientBirthDate = scpStudy.PatientBirthDate, +// PatientSex = scpStudy.PatientSex, +// PatientName = scpStudy.PatientName, + +// SCPStudyId = scpStudy.Id, +// SeriesCount = scpStudy.SeriesCount, +// StudyTime = scpStudy.StudyTime, + +// CallingAE = scpStudy.CallingAE, + +// SubmitState = scpStudySubjectVisit.SubjectVisit.SubmitState, +// SubjectVisitId = scpStudySubjectVisit.SubjectVisitId +// } +// ; + +// var sortField = string.IsNullOrWhiteSpace(inQuery.SortField) ? nameof(VisitPatientStudyView.StudyTime) : inQuery.SortField; +// var orderQuery = inQuery.Asc ? patientQuery.OrderBy(sortField) : patientQuery.OrderBy(sortField + " desc"); + +// var list = await orderQuery.ToListAsync(); + + +// return list; +// } + + + +// /// +// /// 访视管理- 获取subject 已存在的访视列表 ,同时获取项目访视的配置 在otherData里 +// /// +// /// +// /// +// /// +// [HttpPost] +// public async Task GetSubjectVisitSelectList(SubjectVisitSelectQuery inQuery, [FromServices] IRepository _subjectVisitReposiotry) +// { + +// var scpStudyList = await _studySubjectVisitRepository.Where(t => t.TrialId == inQuery.TrialId && t.SubjectId == inQuery.SubjectId && t.SCPStudyId != inQuery.SCPStudyId) +// .Select(t => new { t.SubjectVisitId, StudyTime = t.SCPStudy.StudyTime }) +// .ToListAsync(); + +// var result = scpStudyList.GroupBy(t => t.SubjectVisitId) +// .Select(g => new +// { + +// SubejctVisitId = g.Key, +// VisitMaxStudyTime = g.Max(c => c.StudyTime), +// VisitMinStudyTime = g.Min(c => c.StudyTime) +// }).ToList(); + +// var list = _subjectVisitReposiotry.Where(t => t.SubjectId == inQuery.SubjectId).ProjectTo(_mapper.ConfigurationProvider).ToList(); + +// foreach (var item in list) +// { +// item.VisitMaxStudyTime = result.Where(t => t.SubejctVisitId == item.Id).FirstOrDefault()?.VisitMaxStudyTime; +// item.VisitMinStudyTime = result.Where(t => t.SubejctVisitId == item.Id).FirstOrDefault()?.VisitMinStudyTime; +// } + +// var trialconfig = _trialRepository.Where(t => t.Id == inQuery.TrialId).Select(t => new { t.BlindBaseLineName, t.BlindFollowUpPrefix }).FirstOrDefault(); + +// return ResponseOutput.Ok(list, trialconfig); +// } + + + + +// /// +// ///访视管理-> 访视列表 (带患者信息,患者信息是数组) +// /// +// /// +// /// +// [HttpPost] +// public async Task>> GetPatientSubejctVisitList(PatientSubejctVisitQuery inQuery) +// { +// var query = _subjectVisitRepository.Where(t => t.TrialId == inQuery.TrialId) +// .WhereIf(!string.IsNullOrWhiteSpace(inQuery.SubjectCode), u => u.Subject.Code.Contains(inQuery.SubjectCode)) +// .WhereIf(!string.IsNullOrWhiteSpace(inQuery.SubjectSex), u => u.Subject.Sex.Contains(inQuery.SubjectSex)) +// .WhereIf(!string.IsNullOrWhiteSpace(inQuery.SubjectShortName), u => u.Subject.ShortName.Contains(inQuery.SubjectShortName)) +// .WhereIf(!string.IsNullOrWhiteSpace(inQuery.VisitName), u => u.VisitName.Contains(inQuery.VisitName)) +// .WhereIf(inQuery.SubmitState != null, u => u.SubmitState == inQuery.SubmitState) +// .WhereIf(inQuery.BeginStudyTime != null, t => t.SCPStudySubjectVisitList.Min(t => t.SCPStudy.StudyTime) >= inQuery.BeginStudyTime) +// .WhereIf(inQuery.EndStudyTime != null, t => t.SCPStudySubjectVisitList.Max(t => t.SCPStudy.StudyTime) <= inQuery.EndStudyTime) + +// .WhereIf(!string.IsNullOrWhiteSpace(inQuery.PatientIdStr), t => t.Subject.SubjectPatientList.Any(t => t.Patient.PatientIdStr.Contains(inQuery.PatientIdStr))) +// .WhereIf(!string.IsNullOrWhiteSpace(inQuery.PatientName), t => t.Subject.SubjectPatientList.Any(t => t.Patient.PatientName.Contains(inQuery.PatientName))) +// .WhereIf(!string.IsNullOrWhiteSpace(inQuery.PatientSex), t => t.Subject.SubjectPatientList.Any(t => t.Patient.PatientSex.Contains(inQuery.PatientSex))) +// .Select(t => new PatientSubjectVisitView() +// { +// PatientList = t.Subject.SubjectPatientList.Select(c => new PatientBasicInfo() +// { +// PatientId = c.PatientId, +// PatientAge = c.Patient.PatientAge, +// PatientBirthDate = c.Patient.PatientBirthDate, +// PatientIdStr = c.Patient.PatientIdStr, +// PatientSex = c.Patient.PatientSex, +// PatientName = c.Patient.PatientName, +// }).ToList(), + +// TrialId = t.TrialId, +// SubjectId = t.SubjectId, +// SubjectVisitId = t.Id, +// SubjectAge = t.Subject.Age, +// SubjectSex = t.Subject.Sex, +// SubjectShortName = t.Subject.ShortName, +// SubjectCode = t.Subject.Code, +// SubmitState = t.SubmitState, +// SubmitTime = t.SubmitTime, +// VisitNum = t.VisitNum, +// VisitName = t.VisitName, +// VisitEarliestStudyTime = t.SCPStudySubjectVisitList.Min(t => t.SCPStudy.StudyTime), +// VisitLatestStudyTime = t.SCPStudySubjectVisitList.Max(t => t.SCPStudy.StudyTime), +// VisitImageZipPath = t.VisitImageZipPath, +// PackState = t.PackState, +// }); + +// var defalutSortArray = new string[] { nameof(PatientSubjectVisitView.SubjectId), nameof(PatientSubjectVisitView.VisitNum) }; +// var pageList = await query.ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, inQuery.SortField, inQuery.Asc, string.IsNullOrWhiteSpace(inQuery.SortField), defalutSortArray); + + + +// return ResponseOutput.Ok(pageList); +// } + + +// /// +// ///访视管理-> 获取当前访视 已绑定的患者检查 (从访视列表 进入修改绑定) +// /// +// /// +// /// +// [HttpPost] +// public async Task> GetCurrentVisitPatientStudyList(SubjectVisitStudyQuery inQuery) +// { +// var patientQuery = _studySubjectVisitRepository.Where(t => t.SubjectVisitId == inQuery.SujectVisitId && t.SubjectVisit.SubmitState != SubmitStateEnum.Submitted) +// //.WhereIf(inQuery.SubmitState != null, u => u.SubjectVisit.SubmitState == inQuery.SubmitState) +// .ProjectTo(_mapper.ConfigurationProvider); + +// var sortField = string.IsNullOrWhiteSpace(inQuery.SortField) ? nameof(VisitPatientStudyView.StudyTime) : inQuery.SortField; +// var orderQuery = inQuery.Asc ? patientQuery.OrderBy(sortField) : patientQuery.OrderBy(sortField + " desc"); + +// var list = await orderQuery.ToListAsync(); + +// return list; +// } + + +// /// +// /// 访视管理-> 获取可选访视列表 (从访视列表 进入修改绑定) +// /// +// /// +// /// +// [HttpPost] +// public async Task> GetPatientOtherStudyList(PatientStudyOtherQuery inQuery) +// { +// var query = from scpStudy in _studyRepository.Where(t => inQuery.PatientIdList.Contains(t.PatientId) && !t.SCPStudySubjectVisitList.Any(t => (t.SubjectVisitId == inQuery.SujectVisitId || t.SubjectVisit.SubmitState == SubmitStateEnum.Submitted) && t.TrialId == inQuery.TrialId)) +// .WhereIf(inQuery.EarliestStudyTime != null, t => t.StudyTime >= inQuery.EarliestStudyTime) +// .WhereIf(inQuery.LatestStudyTime != null, t => t.StudyTime <= inQuery.LatestStudyTime) +// .WhereIf(!string.IsNullOrEmpty(inQuery.PatientIdStr), t => t.PatientIdStr.Contains(inQuery.PatientIdStr)) +// //不属于该访视的检查 或者未绑定的检查 +// join scpStudySubjectVisit in _studySubjectVisitRepository.Where(c => c.TrialId == inQuery.TrialId) on scpStudy.Id equals scpStudySubjectVisit.SCPStudyId +// into dd +// from scpStudySV in dd.DefaultIfEmpty() +// select new VisitPatientStudyView() +// { +// PatientIdStr = scpStudy.PatientIdStr, +// PatientBirthDate = scpStudy.PatientBirthDate, +// PatientAge = scpStudy.PatientAge, +// PatientName = scpStudy.PatientName, +// PatientSex = scpStudy.PatientSex, +// Description = scpStudy.Description, +// CalledAE = scpStudy.CalledAE, +// CallingAE = scpStudy.CallingAE, +// InstanceCount = scpStudy.InstanceCount, +// Modalities = scpStudy.Modalities, +// PatientId = scpStudy.PatientId, +// SCPStudyId = scpStudy.Id, +// SeriesCount = scpStudy.SeriesCount, +// StudyTime = scpStudy.StudyTime, + +// SubmitState = scpStudySV.SubjectVisit.SubmitState, +// SubjectVisitId = scpStudySV.SubjectVisitId, +// VisitName = scpStudySV.SubjectVisit.VisitName, +// }; + +// #region 废弃 +// //var notCurrentVisitQuey = _studySubjectVisitRepository.Where(t => t.SubjectVisitId != inQuery.SujectVisitId && t.SCPStudy.Patient.Id == inQuery.PatientId) +// // .Select(t => new VisitPatientStudyView() +// // { +// // Description = t.SCPStudy.Description, +// // CalledAE = t.SCPStudy.CalledAE, +// // InstanceCount = t.SCPStudy.InstanceCount, +// // Modalities = t.SCPStudy.Modalities, +// // PatientId = t.SCPStudy.PatientId, +// // SCPStudyId = t.SCPStudy.PatientId, +// // SeriesCount = t.SCPStudy.SeriesCount, +// // StudyTime = t.SCPStudy.StudyTime, +// // SubjectVisitId = t.SubjectVisitId, +// // VisitName = t.SubjectVisit.VisitName, +// // }); + +// //var notBindQuery= _studyRepository.Where(t => t.PatientId == inQuery.PatientId && t.pa) + +// //var patientQuery = query + +// // .ProjectTo(_mapper.ConfigurationProvider); +// #endregion +// var sortField = string.IsNullOrWhiteSpace(inQuery.SortField) ? nameof(VisitPatientStudyView.StudyTime) : inQuery.SortField; +// var orderQuery = inQuery.Asc ? query.OrderBy(sortField) : query.OrderBy(sortField + " desc"); + +// var list = await orderQuery.ToListAsync(); + +// return list; +// } + +// #endregion + +// #region 检查管理 + + + +// /// +// ///检查管理-> 检查列表 (同步影像数据之前的) +// /// +// /// +// /// +// [HttpPost] +// public async Task>> GetPatientStudyBeforeConfirmList(TrialPatientStudyQuery inQuery) +// { +// #region 只查询已绑定的 +// //var query = _studySubjectVisitRepository.Where(t => t.SubjectVisit.TrialId == inQuery.TrialId) +// // .WhereIf(inQuery.PatientId != null, t => t.SCPStudy.PatientId == inQuery.PatientId) +// // .WhereIf(!string.IsNullOrWhiteSpace(inQuery.SubjectCode), u => u.SubjectVisit.Subject.Code.Contains(inQuery.SubjectCode)) +// // .WhereIf(!string.IsNullOrWhiteSpace(inQuery.PatientIdStr), u => u.SCPStudy.Patient.PatientIdStr.Contains(inQuery.PatientIdStr)) +// // .WhereIf(!string.IsNullOrWhiteSpace(inQuery.PatientSex), t => t.SCPStudy.Patient.PatientSex.Contains(inQuery.PatientSex)) +// // .WhereIf(inQuery.SubjectAge != null, t => t.SubjectVisit.Subject.Age == inQuery.SubjectAge) +// // .WhereIf(!string.IsNullOrWhiteSpace(inQuery.SubjectCode), u => u.SubjectVisit.Subject.Code.Contains(inQuery.SubjectCode)) +// // .WhereIf(!string.IsNullOrWhiteSpace(inQuery.SubjectSex), u => u.SubjectVisit.Subject.Sex.Contains(inQuery.SubjectSex)) +// // .WhereIf(!string.IsNullOrWhiteSpace(inQuery.SubjectShortName), t => t.SubjectVisit.Subject.ShortName.Contains(inQuery.SubjectShortName)) +// // .WhereIf(inQuery.BeginStudyTime != null, t => t.SCPStudy.StudyTime >= inQuery.BeginStudyTime) +// // .WhereIf(inQuery.EndStudyTime != null, t => t.SCPStudy.StudyTime <= inQuery.EndStudyTime) +// // .Select(t => new PatientStudyBeforeConfirmView() +// // { +// // SubjectId = t.SubjectVisit.SubjectId, +// // SubjectAge = t.SubjectVisit.Subject.Age, +// // SubjectSex = t.SubjectVisit.Subject.Sex, +// // SubjectShortName = t.SubjectVisit.Subject.ShortName, + + +// // PatientId = t.SCPStudy.PatientId, +// // PatientAge = t.SCPStudy.PatientAge, +// // PatientBirthDate = t.SCPStudy.PatientBirthDate, +// // PatientIdStr = t.SCPStudy.PatientIdStr, +// // PatientSex = t.SCPStudy.PatientSex, + +// // //PatientList = t.SubjectVisit.Subject.SubjectPatientList.Select(t => new PatientBasicInfo() +// // //{ +// // // PatientId = t.PatientId, +// // // PatientAge = t.Patient.PatientAge, +// // // PatientBirthDate = t.Patient.PatientBirthDate, +// // // PatientIdStr = t.Patient.PatientIdStr, +// // // PatientSex = t.Patient.PatientSex, +// // //}).ToList(), + +// // SubjectCode = t.SubjectVisit.Subject.Code, +// // SubmitState = t.SubjectVisit.SubmitState, +// // SubmitTime = t.SubjectVisit.SubmitTime, +// // VisitName = t.SubjectVisit.VisitName, +// // SubjectVisitId = t.SubjectVisitId, +// // VisitEarliestStudyTime = t.SubjectVisit.SCPStudySubjectVisitList.Min(t => t.SCPStudy.StudyTime), +// // VisitLatestStudyTime = t.SubjectVisit.SCPStudySubjectVisitList.Max(t => t.SCPStudy.StudyTime), + +// // StudyId = t.SCPStudyId, +// // StudyTime = t.SCPStudy.StudyTime, +// // CallingAE = t.SCPStudy.CallingAE, +// // CalledAE = t.SCPStudy.CalledAE + +// // }); +// #endregion + +// var query = from scpStudy in _studyRepository.Where(t => !t.SCPStudySubjectVisitList.Any(t => t.SubjectVisit.SubmitState == SubmitStateEnum.Submitted && t.TrialId == inQuery.TrialId)) +// .WhereIf(inQuery.IsBindedVisit == false, t => !t.SCPStudySubjectVisitList.Any(t => t.TrialId == inQuery.TrialId)) +// .WhereIf(inQuery.IsBindedVisit == true, t => t.SCPStudySubjectVisitList.Any(t => t.TrialId == inQuery.TrialId)) +// .WhereIf(!string.IsNullOrWhiteSpace(inQuery.VisitName), t => t.SCPStudySubjectVisitList.Any(t => t.TrialId == inQuery.TrialId && t.SubjectVisit.VisitName.Contains(inQuery.VisitName))) +// .WhereIf(!string.IsNullOrWhiteSpace(inQuery.PatientSex), t => t.Patient.PatientSex.Contains(inQuery.PatientSex)) +// .WhereIf(!string.IsNullOrWhiteSpace(inQuery.PatientIdStr), u => u.Patient.PatientIdStr.Contains(inQuery.PatientIdStr)) +// .WhereIf(inQuery.BeginStudyTime != null, t => t.StudyTime >= inQuery.BeginStudyTime) +// .WhereIf(inQuery.EndStudyTime != null, t => t.StudyTime <= inQuery.EndStudyTime) +// join subjectPatient in _subjectPatientRepository.Where(t => t.Subject.TrialId == inQuery.TrialId) +// .WhereIf(!string.IsNullOrWhiteSpace(inQuery.SubjectCode), u => u.Subject.Code.Contains(inQuery.SubjectCode)) +// .WhereIf(!string.IsNullOrWhiteSpace(inQuery.SubjectSex), u => u.Subject.Sex.Contains(inQuery.SubjectSex)) +// .WhereIf(!string.IsNullOrWhiteSpace(inQuery.SubjectShortName), t => t.Subject.ShortName.Contains(inQuery.SubjectShortName)) +// on scpStudy.PatientId equals subjectPatient.PatientId +// join scpStudySubjectVisit in _studySubjectVisitRepository.Where(t => t.TrialId == inQuery.TrialId) +// on scpStudy.Id equals scpStudySubjectVisit.SCPStudyId into dd +// from scpStudySV in dd.DefaultIfEmpty() +// select new PatientStudyBeforeConfirmView() +// { +// SubjectId = subjectPatient.Subject.Id, +// SubjectAge = subjectPatient.Subject.Age, +// SubjectSex = subjectPatient.Subject.Sex, +// SubjectShortName = subjectPatient.Subject.ShortName, +// SubjectCode = subjectPatient.Subject.Code, + +// PatientId = scpStudy.PatientId, +// PatientName = scpStudy.PatientName, +// PatientAge = scpStudy.PatientAge, +// PatientBirthDate = scpStudy.PatientBirthDate, +// PatientIdStr = scpStudy.PatientIdStr, +// PatientSex = scpStudy.PatientSex, + +// //PatientList = t.SubjectVisit.Subject.SubjectPatientList.Select(t => new PatientBasicInfo() +// //{ +// // PatientId = t.PatientId, +// // PatientAge = t.Patient.PatientAge, +// // PatientBirthDate = t.Patient.PatientBirthDate, +// // PatientIdStr = t.Patient.PatientIdStr, +// // PatientSex = t.Patient.PatientSex, +// //}).ToList(), + + +// SubmitState = scpStudySV.SubjectVisit.SubmitState, +// SubmitTime = scpStudySV.SubjectVisit.SubmitTime, +// VisitName = scpStudySV.SubjectVisit.VisitName, +// VisitNum = scpStudySV.SubjectVisit.VisitNum, +// SubjectVisitId = scpStudySV.SubjectVisit.Id, +// VisitEarliestStudyTime = scpStudySV.SubjectVisit.SCPStudySubjectVisitList.Min(t => t.SCPStudy.StudyTime), +// VisitLatestStudyTime = scpStudySV.SubjectVisit.SCPStudySubjectVisitList.Max(t => t.SCPStudy.StudyTime), + +// StudyId = scpStudy.Id, +// StudyTime = scpStudy.StudyTime, +// CallingAE = scpStudy.CallingAE, +// CalledAE = scpStudy.CalledAE, +// Description = scpStudy.Description, +// InstanceCount = scpStudy.InstanceCount, +// Modalities = scpStudy.Modalities, +// ModalityForEdit = scpStudy.ModalityForEdit, +// SeriesCount = scpStudy.SeriesCount + +// }; + +// var defalutSortArray = new string[] { nameof(PatientStudyBeforeConfirmView.SubjectCode), nameof(PatientStudyBeforeConfirmView.VisitNum), nameof(PatientStudyBeforeConfirmView.StudyTime) }; +// var pageList = await query.ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, inQuery.SortField, inQuery.Asc, string.IsNullOrWhiteSpace(inQuery.SortField), defalutSortArray); + + + +// return ResponseOutput.Ok(pageList); +// } + + +// /// +// ///检查管理-> 检查列表 (同步影像数据之后的 带患者信息 患者信息是数组) +// /// +// /// +// /// +// [HttpPost] +// public async Task>> GetTrialPatientStudyList(TrialPatientStudyQuery inQuery) +// { +// var query = _repository.Where(t => t.SubjectVisit.TrialId == inQuery.TrialId) +// .WhereIf(!string.IsNullOrWhiteSpace(inQuery.SubjectCode), u => u.SubjectVisit.Subject.Code.Contains(inQuery.SubjectCode)) +// .WhereIf(!string.IsNullOrWhiteSpace(inQuery.PatientIdStr), u => u.PatientIdStr.Contains(inQuery.PatientIdStr)) +// .WhereIf(!string.IsNullOrWhiteSpace(inQuery.PatientSex), t => t.PatientSex.Contains(inQuery.PatientSex)) +// .WhereIf(inQuery.SubjectAge != null, t => t.SubjectVisit.Subject.Age == inQuery.SubjectAge) +// .WhereIf(!string.IsNullOrWhiteSpace(inQuery.SubjectCode), u => u.SubjectVisit.Subject.Code.Contains(inQuery.SubjectCode)) +// .WhereIf(!string.IsNullOrWhiteSpace(inQuery.SubjectSex), u => u.SubjectVisit.Subject.Sex.Contains(inQuery.SubjectSex)) +// .WhereIf(!string.IsNullOrWhiteSpace(inQuery.SubjectShortName), t => t.SubjectVisit.Subject.ShortName.Contains(inQuery.SubjectShortName)) +// .WhereIf(inQuery.BeginStudyTime != null, t => t.StudyTime >= inQuery.BeginStudyTime) +// .WhereIf(inQuery.EndStudyTime != null, t => t.StudyTime <= inQuery.EndStudyTime) +// .Select(t => new PatientStudyView() +// { +// SubjectId = t.SubjectVisit.SubjectId, +// SubjectAge = t.Subject.Age, +// SubjectSex = t.Subject.Sex, +// SubjectShortName = t.Subject.ShortName, + + +// //PatientId = Guid.Empty, +// PatientAge = t.PatientAge, +// PatientName = t.PatientName, +// PatientBirthDate = t.PatientBirthDate, +// PatientIdStr = t.PatientIdStr, +// PatientSex = t.PatientSex, + +// //PatientList = t.Subject.SubjectPatientList.Select(t => new PatientBasicInfo() +// //{ +// // PatientId = t.PatientId, +// // PatientAge = t.Patient.PatientAge, +// // PatientBirthDate = t.Patient.PatientBirthDate, +// // PatientIdStr = t.Patient.PatientIdStr, +// // PatientSex = t.Patient.PatientSex, +// //}).ToList(), + +// Modalities = t.Modalities, +// ModalityForEdit = t.ModalityForEdit, +// SubjectCode = t.SubjectVisit.Subject.Code, +// SubmitState = t.SubjectVisit.SubmitState, +// SubmitTime = t.SubjectVisit.SubmitTime, +// VisitName = t.SubjectVisit.VisitName, +// VisitNum = t.SubjectVisit.VisitNum, +// SubjectVisitId = t.SubjectVisitId, +// VisitEarliestStudyTime = t.SubjectVisit.StudyList.Min(t => t.StudyTime), +// VisitLatestStudyTime = t.SubjectVisit.StudyList.Max(t => t.StudyTime), + +// StudyId = t.Id, +// StudyTime = t.StudyTime, +// Description = t.Description, +// SeriesCount = t.SeriesCount, +// InstanceCount = t.InstanceCount, +// }); + +// var defalutSortArray = new string[] { nameof(PatientStudyView.SubjectCode), nameof(PatientStudyView.VisitNum), nameof(PatientStudyView.StudyTime) }; + +// var pageList = await query.ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, inQuery.SortField, inQuery.Asc, string.IsNullOrWhiteSpace(inQuery.SortField), defalutSortArray); + + +// return ResponseOutput.Ok(pageList); +// } + + + +// /// +// /// 获取该项目 患者已绑定subject ,新来了的检查 可能需要新建访视 但是新增的检查未绑定访视的检查列表 +// /// +// /// +// /// +// [HttpPost] +// public async Task>> GetTrialUnbindSubjectVisitStudyList(TrialPatientStudyQuery inQuery) +// { +// //属于该项目的已绑定患者的检查,同时没有绑定任何访视 +// var query = from scpStudy in _studyRepository.Where(t => !t.SCPStudySubjectVisitList.Any(t => t.TrialId == inQuery.TrialId)) +// .WhereIf(!string.IsNullOrWhiteSpace(inQuery.PatientSex), t => t.Patient.PatientSex.Contains(inQuery.PatientSex)) +// .WhereIf(!string.IsNullOrWhiteSpace(inQuery.PatientIdStr), u => u.Patient.PatientIdStr.Contains(inQuery.PatientIdStr)) +// .WhereIf(inQuery.BeginStudyTime != null, t => t.StudyTime >= inQuery.BeginStudyTime) +// .WhereIf(inQuery.EndStudyTime != null, t => t.StudyTime <= inQuery.EndStudyTime) +// join subjectPatient in _subjectPatientRepository.Where(t => t.Subject.TrialId == inQuery.TrialId) +// .WhereIf(!string.IsNullOrWhiteSpace(inQuery.SubjectCode), u => u.Subject.Code.Contains(inQuery.SubjectCode)) +// .WhereIf(!string.IsNullOrWhiteSpace(inQuery.SubjectSex), u => u.Subject.Sex.Contains(inQuery.SubjectSex)) +// .WhereIf(!string.IsNullOrWhiteSpace(inQuery.SubjectShortName), t => t.Subject.ShortName.Contains(inQuery.SubjectShortName)) +// on scpStudy.PatientId equals subjectPatient.PatientId +// join scpStudySubjectVisit in _studySubjectVisitRepository.AsQueryable() on scpStudy.Id equals scpStudySubjectVisit.SCPStudyId +// into dd +// from scpStudySV in dd.DefaultIfEmpty() +// select new UnbindStudyView() +// { +// PatientIdStr = scpStudy.PatientIdStr, +// PatientBirthDate = scpStudy.PatientBirthDate, +// PatientAge = scpStudy.PatientAge, +// PatientName = scpStudy.PatientName, +// PatientSex = scpStudy.PatientSex, +// Description = scpStudy.Description, +// CalledAE = scpStudy.CalledAE, +// InstanceCount = scpStudy.InstanceCount, +// Modalities = scpStudy.Modalities, +// PatientId = scpStudy.PatientId, +// SCPStudyId = scpStudy.Id, +// SeriesCount = scpStudy.SeriesCount, +// StudyTime = scpStudy.StudyTime, + +// SubjectVisitId = scpStudySV.SubjectVisitId, +// VisitName = scpStudySV.SubjectVisit.VisitName, + +// SubjectId = subjectPatient.SubjectId, +// SubjectCode = subjectPatient.Subject.Code, +// TrialId = subjectPatient.Subject.TrialId, +// SubjectAge = subjectPatient.Subject.Age, +// SubjectSex = subjectPatient.Subject.Sex, +// SubjectShortName = subjectPatient.Subject.ShortName, +// SubjectBirthDate = subjectPatient.Subject.BirthDate +// }; + +// #region 废弃 +// //var query = from subject in _subjectRepository.Where(t => t.TrialId == inQuery.TrialId) +// // .WhereIf(inQuery.SubjectAge != null, t => t.Age == inQuery.SubjectAge) +// // .WhereIf(!string.IsNullOrWhiteSpace(inQuery.SubjectCode), u => u.Code.Contains(inQuery.SubjectCode)) +// // .WhereIf(!string.IsNullOrWhiteSpace(inQuery.SubjectSex), u => u.Sex.Contains(inQuery.SubjectSex)) +// // .WhereIf(!string.IsNullOrWhiteSpace(inQuery.SubjectShortName), t => t.ShortName.Contains(inQuery.SubjectShortName)) +// // join subjectPatient in _subjectPatientRepository.AsQueryable() on subject.Id equals subjectPatient.PatientId +// // //没有绑定任何访视 +// // join scpStudy in _studyRepository.AsQueryable() +// // .WhereIf(!string.IsNullOrWhiteSpace(inQuery.PatientSex), t => t.Patient.PatientSex.Contains(inQuery.PatientSex)) +// // .WhereIf(!string.IsNullOrWhiteSpace(inQuery.PatientIdStr), u => u.Patient.PatientIdStr.Contains(inQuery.PatientIdStr)) +// // .WhereIf(inQuery.BeginStudyTime != null, t => t.StudyTime >= inQuery.BeginStudyTime) +// // .WhereIf(inQuery.EndStudyTime != null, t => t.StudyTime <= inQuery.EndStudyTime) +// // on subjectPatient.PatientId equals scpStudy.PatientId +// // select new SubjectPatientStudyView() +// // { +// // SubjectId = subject.Id, +// // SubjectAge = subject.Age, +// // SubjectSex = subject.Sex, +// // SubjectShortName = subject.ShortName, + +// // PatientList = subject.SubjectPatientList.Select(t => new PatientBasicInfo() +// // { +// // PatientId = t.PatientId, +// // PatientAge = t.Patient.PatientAge, +// // PatientBirthDate = t.Patient.PatientBirthDate, +// // PatientIdStr = t.Patient.PatientIdStr, +// // PatientSex = t.Patient.PatientSex, +// // }).ToList(), + +// // SubjectCode = subject.Code, + +// // SeriesCount = scpStudy.SeriesCount, +// // CalledAE = scpStudy.CalledAE, +// // InstanceCount = scpStudy.InstanceCount, +// // Description = scpStudy.Description, +// // Modalities = scpStudy.Modalities, +// // PatientId = scpStudy.PatientId, + +// // SCPStudyId = scpStudy.Id, +// // StudyTime = scpStudy.StudyTime + +// // }; +// #endregion + + + + + + +// var pageList = await query.ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, inQuery.SortField == string.Empty ? nameof(UnbindStudyView.StudyTime) : inQuery.SortField, inQuery.Asc); + + +// return ResponseOutput.Ok(pageList); +// } + +// /// +// /// 删除某个项目 未提交的访视检查绑定, 清理数据,方便测试自动绑定 +// /// +// /// +// /// +// [HttpDelete] +// public async Task DeleteUnSubmittedStudyBind(Guid trialId, Guid? subjectId, +// [FromServices] IRepository _visitTaskRepository, +// [FromServices] IRepository _dicomStudyRepository, +// [FromServices] IRepository _dicomSeriesRepository, +// [FromServices] IRepository _dicomInstanceRepository) +// { +// if (subjectId != null) +// { +// await _studySubjectVisitRepository.BatchDeleteNoTrackingAsync(t => t.TrialId == trialId && t.SubjectId == subjectId); + +// await _subjectVisitRepository.BatchDeleteNoTrackingAsync(t => t.SubjectId == subjectId); + +// await _visitTaskRepository.BatchDeleteNoTrackingAsync(t => t.SubjectId == subjectId); + +// await _dicomStudyRepository.BatchDeleteNoTrackingAsync(t => t.SubjectId == subjectId); +// await _dicomSeriesRepository.BatchDeleteNoTrackingAsync(t => t.SubjectId == subjectId); +// await _dicomInstanceRepository.BatchDeleteNoTrackingAsync(t => t.SubjectId == subjectId); + +// } +// else +// { +// await _studySubjectVisitRepository.BatchDeleteNoTrackingAsync(t => t.TrialId == trialId && t.SubjectVisit.SubmitState != SubmitStateEnum.Submitted); + +// } + + +// return ResponseOutput.Ok(); +// } + + +// /// +// /// 阅片管理-> 任务列表 +// /// +// /// +// /// +// [HttpPost] +// public async Task>> GetPatientVisitTaskList([FromServices] IRepository _visitTaskRepository, PatientVisitTaskQuery inQuery) +// { +// var visitTaskQueryable = _visitTaskRepository.Where(t => t.TrialId == inQuery.TrialId && t.IsAnalysisCreate == false) +// .WhereIf(inQuery.ReadingCategory != null, t => t.ReadingCategory == inQuery.ReadingCategory) +// .WhereIf(inQuery.ReadingCategory == null, t => t.ReadingCategory != ReadingCategory.Judge) + +// .WhereIf(inQuery.ReadingTaskState != null, t => t.ReadingTaskState == inQuery.ReadingTaskState) +// .WhereIf(inQuery.TaskState != null, t => t.TaskState == inQuery.TaskState) +// .WhereIf(inQuery.SubjectId != null, t => t.SubjectId == inQuery.SubjectId) +// .WhereIf(inQuery.DoctorUserId != null, t => t.DoctorUserId == inQuery.DoctorUserId) +// .WhereIf(inQuery.TrialReadingCriterionId != null, t => t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId) + +// .WhereIf(!string.IsNullOrEmpty(inQuery.TaskName), t => t.TaskName.Contains(inQuery.TaskName) || t.TaskBlindName.Contains(inQuery.TaskName)) +// .WhereIf(inQuery.BeginSignTime != null, t => t.SignTime >= inQuery.BeginSignTime) +// .WhereIf(inQuery.EndSignTime != null, t => t.SignTime <= inQuery.EndSignTime) + +// .WhereIf(inQuery.BeginTaskCreateTime != null, t => t.CreateTime >= inQuery.BeginTaskCreateTime) +// .WhereIf(inQuery.EndTaskCreateTime != null, t => t.CreateTime <= inQuery.EndTaskCreateTime) + +// .WhereIf(!string.IsNullOrWhiteSpace(inQuery.PatientIdStr), t => t.Subject.SubjectPatientList.Any(t => t.Patient.PatientIdStr.Contains(inQuery.PatientIdStr))) +// .WhereIf(!string.IsNullOrWhiteSpace(inQuery.PatientName), t => t.Subject.SubjectPatientList.Any(t => t.Patient.PatientName.Contains(inQuery.PatientName))) +// .WhereIf(!string.IsNullOrWhiteSpace(inQuery.PatientSex), t => t.Subject.SubjectPatientList.Any(t => t.Patient.PatientSex.Contains(inQuery.PatientSex))) +// .WhereIf(!string.IsNullOrEmpty(inQuery.SubjectShortName), t => t.Subject.ShortName.Contains(inQuery.SubjectShortName)) +// .WhereIf(!string.IsNullOrEmpty(inQuery.SubjectCode), t => (t.Subject.Code.Contains(inQuery.SubjectCode) && t.IsAnalysisCreate == false) || (t.BlindSubjectCode.Contains(inQuery.SubjectCode) && t.IsAnalysisCreate)) +// .ProjectTo(_mapper.ConfigurationProvider); + +// var defalutSortArray = new string[] { nameof(PatientVisitTaskDTO.SubjectId), nameof(PatientVisitTaskDTO.VisitTaskNum) }; + +// var pageList = await visitTaskQueryable.ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, inQuery.SortField, inQuery.Asc, string.IsNullOrWhiteSpace(inQuery.SortField), defalutSortArray); + +// return ResponseOutput.Ok(pageList); +// } + + +// #endregion + + + + + +// /// +// /// scp 影像推送记录表 +// /// +// /// +// /// +// [HttpPost] +// public async Task>> GetSCPImageUploadList(SCPImageUploadQuery inQuery) +// { +// var query = _repository.Where() +// .WhereIf(!string.IsNullOrWhiteSpace(inQuery.CalledAE), t => t.CalledAE.Contains(inQuery.CalledAE)) +// .WhereIf(!string.IsNullOrWhiteSpace(inQuery.CallingAEIP), t => t.CallingAEIP.Contains(inQuery.CallingAEIP)) +// .WhereIf(!string.IsNullOrWhiteSpace(inQuery.CallingAE), t => t.CallingAE.Contains(inQuery.CallingAE)) +// .WhereIf(inQuery.StartTime != null, t => t.StartTime >= inQuery.StartTime) +// .WhereIf(inQuery.EndTime != null, t => t.EndTime <= inQuery.EndTime) + +// .ProjectTo(_mapper.ConfigurationProvider); + + +// var pageList = await query.ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, inQuery.SortField == string.Empty ? nameof(SCPImageUploadView.CallingAE) : inQuery.SortField, inQuery.Asc); + + +// return ResponseOutput.Ok(pageList); +// } + + + + +// } + + + +//} diff --git a/IRaCIS.Core.Infrastructure/IRaCIS.Core.Infrastructure.csproj b/IRaCIS.Core.Infrastructure/IRaCIS.Core.Infrastructure.csproj index f2772d9ce..f2b268e49 100644 --- a/IRaCIS.Core.Infrastructure/IRaCIS.Core.Infrastructure.csproj +++ b/IRaCIS.Core.Infrastructure/IRaCIS.Core.Infrastructure.csproj @@ -9,13 +9,13 @@ - - + + - - + + - + From a615b5cefdcb965be7c6e6825f9cbd6aba5c3bab Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Wed, 3 Jul 2024 14:45:24 +0800 Subject: [PATCH 039/251] =?UTF-8?q?site=20dicomAE=20=E6=8F=90=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../TrialSiteUser/DTO/TrialSiteDicomAEViewModel.cs | 7 ++++++- .../TrialSiteUser/DTO/UserTrialViewModel.cs | 2 +- .../Interface/ITrialSiteDicomAEService.cs | 2 +- .../Service/TrialSiteUser/TrialDicomAEService.cs | 2 +- .../TrialSiteUser/TrialSiteDicomAEService.cs | 14 ++++++++------ .../Service/TrialSiteUser/_MapConfig.cs | 3 ++- IRaCIS.Core.Domain/TrialSiteUser/TrialSite.cs | 2 ++ .../TrialSiteUser/TrialSiteDicomAE.cs | 4 ++++ 8 files changed, 25 insertions(+), 11 deletions(-) diff --git a/IRaCIS.Core.Application/Service/TrialSiteUser/DTO/TrialSiteDicomAEViewModel.cs b/IRaCIS.Core.Application/Service/TrialSiteUser/DTO/TrialSiteDicomAEViewModel.cs index 94ac1e703..568583c26 100644 --- a/IRaCIS.Core.Application/Service/TrialSiteUser/DTO/TrialSiteDicomAEViewModel.cs +++ b/IRaCIS.Core.Application/Service/TrialSiteUser/DTO/TrialSiteDicomAEViewModel.cs @@ -6,6 +6,7 @@ using System; using IRaCIS.Core.Domain.Share; using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; namespace IRaCIS.Core.Application.ViewModel { /// TrialSiteDicomAEView 列表视图模型 @@ -21,8 +22,12 @@ namespace IRaCIS.Core.Application.ViewModel } ///TrialSiteDicomAEQuery 列表查询参数模型 - public class TrialSiteDicomAEQuery : PageInput + public class TrialSiteDicomAEQuery /*: PageInput*/ { + [NotDefault] + + public Guid TrialSiteId { get; set; } + public string? CallingAE { get; set; } public string? IP { get; set; } diff --git a/IRaCIS.Core.Application/Service/TrialSiteUser/DTO/UserTrialViewModel.cs b/IRaCIS.Core.Application/Service/TrialSiteUser/DTO/UserTrialViewModel.cs index a3cd5fa36..a2fdd4c03 100644 --- a/IRaCIS.Core.Application/Service/TrialSiteUser/DTO/UserTrialViewModel.cs +++ b/IRaCIS.Core.Application/Service/TrialSiteUser/DTO/UserTrialViewModel.cs @@ -259,7 +259,7 @@ namespace IRaCIS.Application.Contracts //public string ContactPhone { get; set; } = String.Empty; //public string Address { get; set; } = String.Empty; - + public List CallingAEList { get; set; } public List UserNameList { get; set; } = new List(); public int? VisitCount { get; set; } diff --git a/IRaCIS.Core.Application/Service/TrialSiteUser/Interface/ITrialSiteDicomAEService.cs b/IRaCIS.Core.Application/Service/TrialSiteUser/Interface/ITrialSiteDicomAEService.cs index a6c2323a6..c6c6fc713 100644 --- a/IRaCIS.Core.Application/Service/TrialSiteUser/Interface/ITrialSiteDicomAEService.cs +++ b/IRaCIS.Core.Application/Service/TrialSiteUser/Interface/ITrialSiteDicomAEService.cs @@ -13,7 +13,7 @@ namespace IRaCIS.Core.Application.Interfaces public interface ITrialSiteDicomAEService { - Task> GetTrialSiteDicomAEList(TrialSiteDicomAEQuery inQuery); + Task> GetTrialSiteDicomAEList(TrialSiteDicomAEQuery inQuery); Task AddOrUpdateTrialSiteDicomAE(TrialSiteDicomAEAddOrEdit addOrEditTrialSiteDicomAE); diff --git a/IRaCIS.Core.Application/Service/TrialSiteUser/TrialDicomAEService.cs b/IRaCIS.Core.Application/Service/TrialSiteUser/TrialDicomAEService.cs index 035be1e3e..982bab572 100644 --- a/IRaCIS.Core.Application/Service/TrialSiteUser/TrialDicomAEService.cs +++ b/IRaCIS.Core.Application/Service/TrialSiteUser/TrialDicomAEService.cs @@ -57,7 +57,7 @@ namespace IRaCIS.Core.Application.Service /// /// /// - public async Task> GetTrialDicomAEList(Guid trialId) + public async Task> GetTrialDicomAE(Guid trialId) { var dicomAE = _dicomAERepository.Where(t => t.TrialId == trialId).ProjectTo(_mapper.ConfigurationProvider).FirstOrDefault(); var trialConfig = _trialRepository.Where(t => t.Id == trialId).Select(t => new { t.IsPACSConnect, t.IsTrialPACSConfirmed }); diff --git a/IRaCIS.Core.Application/Service/TrialSiteUser/TrialSiteDicomAEService.cs b/IRaCIS.Core.Application/Service/TrialSiteUser/TrialSiteDicomAEService.cs index 2cfec8f8f..7b5318d44 100644 --- a/IRaCIS.Core.Application/Service/TrialSiteUser/TrialSiteDicomAEService.cs +++ b/IRaCIS.Core.Application/Service/TrialSiteUser/TrialSiteDicomAEService.cs @@ -25,23 +25,25 @@ namespace IRaCIS.Core.Application.Service } [HttpPost] - public async Task> GetTrialSiteDicomAEList(TrialSiteDicomAEQuery inQuery) + public async Task> GetTrialSiteDicomAEList(TrialSiteDicomAEQuery inQuery) { var trialSiteDicomAEQueryable = - _trialSiteDicomAERepository + _trialSiteDicomAERepository.Where(t=>t.TrialSiteId==inQuery.TrialSiteId) .WhereIf(!string.IsNullOrWhiteSpace(inQuery.IP), t => t.IP.Contains(inQuery.IP)) .WhereIf(!string.IsNullOrWhiteSpace(inQuery.Port), t => t.Port.Contains(inQuery.Port)) .WhereIf(!string.IsNullOrWhiteSpace(inQuery.Description), t => t.Description.Contains(inQuery.Description)) .WhereIf(!string.IsNullOrWhiteSpace(inQuery.CallingAE), t => t.CallingAE.Contains(inQuery.CallingAE)) .ProjectTo(_mapper.ConfigurationProvider); - var pageList = await trialSiteDicomAEQueryable - .ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, string.IsNullOrWhiteSpace(inQuery.SortField) ? nameof(TrialSiteDicomAEView.Id) : inQuery.SortField, - inQuery.Asc); + //var pageList = await trialSiteDicomAEQueryable + //.ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, string.IsNullOrWhiteSpace(inQuery.SortField) ? nameof(TrialSiteDicomAEView.Id) : inQuery.SortField, + //inQuery.Asc); - return pageList; + var list = await trialSiteDicomAEQueryable.ToListAsync(); + + return list; } diff --git a/IRaCIS.Core.Application/Service/TrialSiteUser/_MapConfig.cs b/IRaCIS.Core.Application/Service/TrialSiteUser/_MapConfig.cs index 2e38d4476..461523bfa 100644 --- a/IRaCIS.Core.Application/Service/TrialSiteUser/_MapConfig.cs +++ b/IRaCIS.Core.Application/Service/TrialSiteUser/_MapConfig.cs @@ -141,7 +141,8 @@ namespace IRaCIS.Core.Application.Service .ForMember(d => d.UserCount, u => u.MapFrom(s => s.CRCUserList.Count())) .ForMember(d => d.VisitCount, u => u.MapFrom(s => s.SubjectVisitList.Count())) .ForMember(d => d.SubjectCount, u => u.MapFrom(s => s.SubjectList.Count())) - .ForMember(d => d.UserNameList, u => u.MapFrom(s => s.CRCUserList.Where(t => t.IsDeleted == false).Select(u => u.User.FullName))); + .ForMember(d => d.UserNameList, u => u.MapFrom(s => s.CRCUserList.Where(t => t.IsDeleted == false).Select(u => u.User.FullName))) + .ForMember(d => d.CallingAEList, u => u.MapFrom(s => s.TrialSiteDicomAEList.Select(u => u.CallingAE))); //CreateMap(); diff --git a/IRaCIS.Core.Domain/TrialSiteUser/TrialSite.cs b/IRaCIS.Core.Domain/TrialSiteUser/TrialSite.cs index 63da78434..8812dd62b 100644 --- a/IRaCIS.Core.Domain/TrialSiteUser/TrialSite.cs +++ b/IRaCIS.Core.Domain/TrialSiteUser/TrialSite.cs @@ -55,7 +55,9 @@ namespace IRaCIS.Core.Domain.Models [JsonIgnore] public List SubjectList { get; set; } + [JsonIgnore] + public List TrialSiteDicomAEList { get; set; } } } \ No newline at end of file diff --git a/IRaCIS.Core.Domain/TrialSiteUser/TrialSiteDicomAE.cs b/IRaCIS.Core.Domain/TrialSiteUser/TrialSiteDicomAE.cs index a23e4d5b6..1ef1446f5 100644 --- a/IRaCIS.Core.Domain/TrialSiteUser/TrialSiteDicomAE.cs +++ b/IRaCIS.Core.Domain/TrialSiteUser/TrialSiteDicomAE.cs @@ -53,6 +53,10 @@ namespace IRaCIS.Core.Domain.Models public string Description { get; set; } + + + + public TrialSite TrialSite { get; set; } } From 0c7495870b392ad5329c53387c79f2bbc80d616f Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Thu, 4 Jul 2024 13:12:10 +0800 Subject: [PATCH 040/251] =?UTF-8?q?pacs=20=20=E7=9B=B4=E8=BF=9E=20=20?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRC.Core.SCP/Service/CStoreSCPService.cs | 86 +- IRC.Core.SCP/Service/DicomArchiveService.cs | 12 +- .../Service/Interface/IDicomArchiveService.cs | 2 +- .../IRaCIS.Core.Application.xml | 37 +- .../Service/Visit/DTO/PatientViewModel.cs | 88 +- .../Service/Visit/PatientService.cs | 1581 ++++------------- .../Service/Visit/_MapConfig.cs | 8 + IRaCIS.Core.Domain/Image/DicomStudy.cs | 3 + IRaCIS.Core.Domain/Image/SCPImageUpload.cs | 13 + IRaCIS.Core.Domain/Image/SCPPatient.cs | 10 +- IRaCIS.Core.Domain/Image/SCPStudy.cs | 10 +- 11 files changed, 516 insertions(+), 1334 deletions(-) diff --git a/IRC.Core.SCP/Service/CStoreSCPService.cs b/IRC.Core.SCP/Service/CStoreSCPService.cs index a81e11ec1..261ca563b 100644 --- a/IRC.Core.SCP/Service/CStoreSCPService.cs +++ b/IRC.Core.SCP/Service/CStoreSCPService.cs @@ -24,39 +24,7 @@ using IRaCIS.Core.Infrastructure; namespace IRaCIS.Core.SCP.Service { - /// - /// 后台托管服务的方式运行 - /// - //public class CStoreSCPHostedService : IHostedService - //{ - // private readonly ILogger _logger; - // private readonly IDicomServerFactory _dicomServerFactory; - // private IDicomServer? _server; - // public CStoreSCPHostedService(ILogger logger, IDicomServerFactory dicomServerFactory) - // { - // _logger = logger ?? throw new ArgumentNullException(nameof(logger)); - // _dicomServerFactory = dicomServerFactory ?? throw new ArgumentNullException(nameof(dicomServerFactory)); - // } - - // public async Task StartAsync(CancellationToken cancellationToken) - // { - // _logger.LogInformation("Starting DICOM server"); - // _server = _dicomServerFactory.Create(104); - // _logger.LogInformation("DICOM server is running"); - // } - - // public Task StopAsync(CancellationToken cancellationToken) - // { - // if (_server != null) - // { - // _server.Stop(); - // _server.Dispose(); - // _server = null; - // } - // return Task.CompletedTask; - // } - //} public class DicomSCPServiceOption { public List CalledAEList { get; set; } @@ -75,6 +43,11 @@ namespace IRaCIS.Core.SCP.Service private SCPImageUpload _upload { get; set; } + private Guid _trialId { get; set; } + + private Guid _trialSiteId { get; set; } + + private static readonly DicomTransferSyntax[] _acceptedTransferSyntaxes = new DicomTransferSyntax[] { @@ -121,15 +94,37 @@ namespace IRaCIS.Core.SCP.Service _serviceProvider = (IServiceProvider)this.UserState; - var option = _serviceProvider.GetService>().CurrentValue; + var _trialDicomAERepository = _serviceProvider.GetService>(); - var calledAEList = option.CalledAEList; - if (!calledAEList.Contains(association.CalledAE)) + var trialDicomAEList = _trialDicomAERepository.Select(t => new { t.CalledAE, t.TrialId }).ToList(); + var trialCalledAEList = trialDicomAEList.Select(t => t.CalledAE).ToList(); - //if (association.CalledAE != "STORESCP") + var findCalledAE = trialDicomAEList.Where(t => t.CalledAE == association.CalledAE).FirstOrDefault(); + + var isCanReceiveIamge = false; + + if (findCalledAE!=null) + { + _trialId = findCalledAE.TrialId; + + var _trialSiteDicomAERepository = _serviceProvider.GetService>(); + + + var findTrialSiteAE = _trialSiteDicomAERepository.Where(t=>t.CallingAE==association.CallingAE ).FirstOrDefault(); + + if (findTrialSiteAE!=null) + { + _trialSiteId= findTrialSiteAE.TrialSiteId; + + isCanReceiveIamge = true; + } + } + + + if (!trialCalledAEList.Contains(association.CalledAE) || isCanReceiveIamge==false) { Log.Logger.Warning($"拒绝CalledAE:{association.CalledAE}的连接"); @@ -152,6 +147,8 @@ namespace IRaCIS.Core.SCP.Service } } + + return SendAssociationAcceptAsync(association); } @@ -167,7 +164,7 @@ namespace IRaCIS.Core.SCP.Service _upload.EndTime = DateTime.Now; _upload.StudyCount = _SCPStudyIdList.Count; - await _SCPImageUploadRepository.AddAsync(_upload,true); + await _SCPImageUploadRepository.AddAsync(_upload, true); await SendAssociationReleaseResponseAsync(); } @@ -175,11 +172,9 @@ namespace IRaCIS.Core.SCP.Service private async Task DataMaintenanceAsaync() { - Log.Logger.Warning($"CallingAE:{Association.CallingAE} CalledAE:{Association.CalledAE}传输结束:开始维护数据,处理检查Modality 以及自动创建访视,绑定检查"); + Log.Logger.Warning($"CallingAE:{Association.CallingAE} CalledAE:{Association.CalledAE}传输结束:开始维护数据,处理检查Modality"); - //var patientStudyService = _serviceProvider.GetService(); - //await patientStudyService.AutoBindingPatientStudyVisitAsync(_SCPStudyIdList); //处理检查Modality var _dictionaryRepository = _serviceProvider.GetService>(); @@ -262,7 +257,7 @@ namespace IRaCIS.Core.SCP.Service var _distributedLockProvider = _serviceProvider.GetService(); var storeRelativePath = string.Empty; - var ossFolderPath = $"Dicom/{studyInstanceUid}"; + var ossFolderPath = $"{_trialId}/Image/PACS/{_trialSiteId}{studyInstanceUid}"; long fileSize = 0; @@ -295,7 +290,7 @@ namespace IRaCIS.Core.SCP.Service { try { - var scpStudyId = await dicomArchiveService.ArchiveDicomFileAsync(request.Dataset, storeRelativePath, Association.CallingAE, Association.CalledAE); + var scpStudyId = await dicomArchiveService.ArchiveDicomFileAsync(request.Dataset,_trialId,_trialSiteId, storeRelativePath, Association.CallingAE, Association.CalledAE); if (!_SCPStudyIdList.Contains(scpStudyId)) { @@ -324,11 +319,6 @@ namespace IRaCIS.Core.SCP.Service series.ImageResizePath = seriesPath; - - - //await _seriesRepository.BatchUpdateNoTrackingAsync(t => t.Id == seriesId, u => new SCPSeries() { ImageResizePath = seriesPath }); - - } } @@ -347,7 +337,7 @@ namespace IRaCIS.Core.SCP.Service //监控信息设置 _upload.FileCount++; - _upload.FileSize= _upload.FileSize+ fileSize; + _upload.FileSize = _upload.FileSize + fileSize; return new DicomCStoreResponse(request, DicomStatus.Success); } diff --git a/IRC.Core.SCP/Service/DicomArchiveService.cs b/IRC.Core.SCP/Service/DicomArchiveService.cs index 439741952..6eb9a092a 100644 --- a/IRC.Core.SCP/Service/DicomArchiveService.cs +++ b/IRC.Core.SCP/Service/DicomArchiveService.cs @@ -50,7 +50,7 @@ namespace IRaCIS.Core.SCP.Service /// /// /// - public async Task ArchiveDicomFileAsync(DicomDataset dataset, string fileRelativePath, string callingAE, string calledAE) + public async Task ArchiveDicomFileAsync(DicomDataset dataset, Guid trialId, Guid trialSiteId, string fileRelativePath, string callingAE, string calledAE) { string studyInstanceUid = dataset.GetString(DicomTag.StudyInstanceUID); string seriesInstanceUid = dataset.GetString(DicomTag.SeriesInstanceUID); @@ -59,9 +59,9 @@ namespace IRaCIS.Core.SCP.Service string patientIdStr = dataset.GetString(DicomTag.PatientID); //Guid patientId= IdentifierHelper.CreateGuid(patientIdStr); - Guid studyId = IdentifierHelper.CreateGuid(studyInstanceUid); - Guid seriesId = IdentifierHelper.CreateGuid(studyInstanceUid, seriesInstanceUid); - Guid instanceId = IdentifierHelper.CreateGuid(studyInstanceUid, seriesInstanceUid, sopInstanceUid); + Guid studyId = IdentifierHelper.CreateGuid(studyInstanceUid,trialId.ToString()); + Guid seriesId = IdentifierHelper.CreateGuid(studyInstanceUid, seriesInstanceUid, trialId.ToString()); + Guid instanceId = IdentifierHelper.CreateGuid(studyInstanceUid, seriesInstanceUid, sopInstanceUid, trialId.ToString()); var isStudyNeedAdd = false; var isSeriesNeedAdd = false; @@ -88,6 +88,8 @@ namespace IRaCIS.Core.SCP.Service findPatient = new SCPPatient() { Id = NewId.NextSequentialGuid(), + TrialId=trialId, + TrialSiteId=trialSiteId, PatientIdStr = dataset.GetSingleValueOrDefault(DicomTag.PatientID, string.Empty), PatientName = dataset.GetSingleValueOrDefault(DicomTag.PatientName, string.Empty), PatientAge = dataset.GetSingleValueOrDefault(DicomTag.PatientAge, string.Empty), @@ -145,6 +147,8 @@ namespace IRaCIS.Core.SCP.Service PatientId = findPatient.Id, Id = studyId, + TrialId = trialId, + TrialSiteId = trialSiteId, StudyInstanceUid = studyInstanceUid, StudyTime = studyTime, Modalities = dataset.GetSingleValueOrDefault(DicomTag.Modality, string.Empty), diff --git a/IRC.Core.SCP/Service/Interface/IDicomArchiveService.cs b/IRC.Core.SCP/Service/Interface/IDicomArchiveService.cs index 970b3e146..1c107e94b 100644 --- a/IRC.Core.SCP/Service/Interface/IDicomArchiveService.cs +++ b/IRC.Core.SCP/Service/Interface/IDicomArchiveService.cs @@ -5,7 +5,7 @@ namespace IRaCIS.Core.SCP.Service { public interface IDicomArchiveService { - Task ArchiveDicomFileAsync(DicomDataset dicomDataset,string fileRelativePath,string callingAE,string calledAE); + Task ArchiveDicomFileAsync(DicomDataset dicomDataset,Guid trialId,Guid trialSiteId, string fileRelativePath,string callingAE,string calledAE); } } diff --git a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml index 8232128a0..ebd172a4c 100644 --- a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml +++ b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml @@ -9818,7 +9818,7 @@ DicomAEService - + 获取项目dicom AE 配置信息,otherinfo里面有IsPACSConnect IsTrialPACSConfirmed @@ -15048,6 +15048,41 @@ 9-拒绝入组,10-确认入组 + + + scp 影像推送记录表 + + + + + + + 影像检查列表-患者为维度组织 + + + + + + + 影像检查列表-> 获取患者的检查列表 + + + + + + + 影像访视上传 检查列表 + + + + + + + 提交 患者检查和访视的绑定 + + + + 添加或更新受试者信息[New] diff --git a/IRaCIS.Core.Application/Service/Visit/DTO/PatientViewModel.cs b/IRaCIS.Core.Application/Service/Visit/DTO/PatientViewModel.cs index 72b1ee836..0c3c515f8 100644 --- a/IRaCIS.Core.Application/Service/Visit/DTO/PatientViewModel.cs +++ b/IRaCIS.Core.Application/Service/Visit/DTO/PatientViewModel.cs @@ -224,31 +224,41 @@ namespace IRaCIS.Application.Contracts { public string? PatientIdStr { get; set; } public string? PatientName { get; set; } - public List CalledAEList { get; set; } = new List(); + //public List CalledAEList { get; set; } = new List(); public string? CallingAE { get; set; } - - public string? ExperimentName { get; set; } = string.Empty; + public string? CalledAE { get; set; } public DateTime? BeginPushTime { get; set; } public DateTime? EndPushTime { get; set; } + public string SubejctCode { get; set; } + + public string TrialSiteKeyInfo { get; set; } + } - public class PatientTrialView : PatientQueryView + public class PatientSubjectView : PatientQueryView { public int? StudyCount { get; set; } - public List TrialList { get; set; } + + + public Guid? SubejctId { get; set; } + + public Guid TrialId { get; set; } + + public string? SubjectCode { get; set; } + + public string? TrialSiteCode { get; set; } + + public string? TrialSiteName { get; set; } + + public string? TrialSiteAliasName { get; set; } } - public class PatientTrialStatInfo - { - public int? VisitCount { get; set; } - public string ExperimentName { get; set; } - } public class PatientQuery : PageInput { @@ -377,7 +387,10 @@ namespace IRaCIS.Application.Contracts [NotDefault] public Guid SubjectId { get; set; } - public List SubjectVisitIdList { get; set; } + [NotDefault] + public Guid SubjectVisitId { get; set; } + + public List SCPStudyIdList { get; set; } } public class SubjectVisitSelectQuery @@ -938,6 +951,8 @@ namespace IRaCIS.Application.Contracts public class SCPImageUploadQuery : PageInput { + public string TrialSiteKeyInfo { get; set; } + public string? CallingAE { get; set; } public string? CalledAE { get; set; } @@ -966,7 +981,18 @@ namespace IRaCIS.Application.Contracts public long FileSize { get; set; } public int StudyCount { get; set; } - + + + public Guid TrialId { get; set; } + public Guid TrialSiteId { get; set; } + + + public string TrialSiteCode { get; set; } + + public string TrialSiteName { get; set; } + + public string TrialSiteAliasName { get; set; } + } public class VisitPatientStudyView : PatientStudySelectDto { @@ -990,7 +1016,20 @@ namespace IRaCIS.Application.Contracts } - public class PatientStudySimpleView + public class VisitPatientStudyFilterQuery : PageInput + { + [NotDefault] + public Guid SubjectId { get; set; } + + [NotDefault] + public Guid SubjectVisitId { get; set; } + + public DateTime? EarliestStudyTime { get; set; } + + public DateTime? LatestStudyTime { get; set; } + public string? Modalities { get; set; } + } + public class VisitPatientStudyFilterView { public Guid SCPStudyId { get; set; } @@ -1006,9 +1045,32 @@ namespace IRaCIS.Application.Contracts public string CalledAE { get; set; } = string.Empty; public string CallingAE { get; set; } = string.Empty; + } + + public class PatientStudySimpleView: VisitPatientStudyFilterView + { + + + + public Guid? SubjectVisitId { get; set; } + public string? VisitName { get; set; } + + public string? BlindName { get; set; } = string.Empty; + + + //public SubjectVisitInfo SubejectVisit { get; set; } } + public class SubjectVisitInfo + { + public Guid Id { get; set; } + + public string VisitName { get; set; } + + public decimal VisitNum { get; set; } + public string BlindName { get; set; } = string.Empty; + } public class PatientSeriesDTO diff --git a/IRaCIS.Core.Application/Service/Visit/PatientService.cs b/IRaCIS.Core.Application/Service/Visit/PatientService.cs index c4bef2800..1f0468c0e 100644 --- a/IRaCIS.Core.Application/Service/Visit/PatientService.cs +++ b/IRaCIS.Core.Application/Service/Visit/PatientService.cs @@ -1,1323 +1,374 @@ -//using IRaCIS.Application.Interfaces; -//using IRaCIS.Application.Contracts; -//using IRaCIS.Core.Application.Filter; -//using IRaCIS.Core.Domain.Share; -//using Microsoft.AspNetCore.Mvc; -//using Microsoft.AspNetCore.Authorization; -//using IRaCIS.Core.Application.Auth; -//using MassTransit; -//using Panda.DynamicWebApi.Attributes; -//using DocumentFormat.OpenXml.Spreadsheet; -//using AutoMapper.EntityFrameworkCore; -//using IRaCIS.Core.Domain.Models; -//using IRaCIS.Core.Application.Service.Reading.Dto; -//using Microsoft.Extensions.Options; -//using Microsoft.Extensions.Configuration; -//using Microsoft.Extensions.Configuration.Json; -//using Newtonsoft.Json; -//using Newtonsoft.Json.Linq; -//using SharpCompress.Common; -//using System.Reactive.Subjects; -//using Subject = IRaCIS.Core.Domain.Models.Subject; -//using IRaCIS.Core.Application.ViewModel; -//using Medallion.Threading; -//using IRaCIS.Core.Infrastructure; -//using EasyCaching.Core; -//using Pipelines.Sockets.Unofficial.Arenas; -//using IRaCIS.Core.Application.Contracts; -//using MailKit.Search; -//using DocumentFormat.OpenXml.Office2010.Excel; -//using IRaCIS.Core.Application.Contracts.Dicom.DTO; -//using IRaCIS.Core.Application.Helper; -//using NPOI.SS.Formula.Functions; -//using System.Linq; -//using System.Linq.Dynamic.Core; -//using System.Text; -//using DocumentFormat.OpenXml.EMMA; -//using Azure; -//using System.IO.Compression; -//using static IRaCIS.Core.Domain.Share.StaticData; -//using FellowOakDicom; -//using DocumentFormat.OpenXml.Office2010.Drawing; -//using EasyCaching.Core.DistributedLock; -//using IDistributedLockProvider = Medallion.Threading.IDistributedLockProvider; -//using DocumentFormat.OpenXml.InkML; - -//namespace IRaCIS.Application.Services -//{ -// [ApiExplorerSettings(GroupName = "Trial")] -// public class PatientService : BaseService -// { - -// private readonly IRepository _trialRepository; -// private readonly IRepository _patientRepository; -// private readonly IRepository _studyRepository; -// private readonly IRepository _subjectRepository; -// private readonly IRepository _subjectVisitRepository; -// private readonly IDistributedLockProvider _distributedLockProvider; - -// public PatientService(IRepository studyRepository, IRepository trialRepository, IRepository patientRepository, IRepository subjectRepository, IRepository subjectVisitRepository, IDistributedLockProvider distributedLockProvider) -// { -// _studyRepository = studyRepository; -// _trialRepository = trialRepository; -// _patientRepository = patientRepository; -// _subjectRepository = subjectRepository; -// _subjectVisitRepository = subjectVisitRepository; -// _distributedLockProvider = distributedLockProvider; -// } - - - - - -// #region 患者检查管理 - -// /// -// ///检查管理-> 检查Tab 患者列表 (带加入的项目信息 以及检查统计) 原型标注错误,不是检查列表 -// /// -// /// -// /// -// [HttpPost] -// public async Task>> GetPatientList(PatientTrialQuery inQuery) -// { - -// var isAdminOrOA = _userInfo.UserTypeEnumInt == (int)UserTypeEnum.Admin || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.OA || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.SuperAdmin; - -// #region new ok -// var query = _patientRepository -// .WhereIf(!string.IsNullOrWhiteSpace(inQuery.PatientIdStr), t => t.PatientIdStr.Contains(inQuery.PatientIdStr)) -// .WhereIf(!string.IsNullOrWhiteSpace(inQuery.PatientName), t => t.PatientName.Contains(inQuery.PatientName)) -// //.WhereIf(!string.IsNullOrWhiteSpace(inQuery.ExperimentName), t => t.SubjectPatientList.Any(t => t.Subject.Trial.ExperimentName.Contains(inQuery.ExperimentName))) -// .WhereIf(!string.IsNullOrWhiteSpace(inQuery.CallingAE), t => t.SCPStudyList.Any(t => t.CallingAE == inQuery.CallingAE)) -// .WhereIf(inQuery.BeginPushTime != null, t => t.LatestPushTime >= inQuery.BeginPushTime) -// .WhereIf(inQuery.EndPushTime != null, t => t.LatestPushTime <= inQuery.EndPushTime); - -// foreach (var calledAE in inQuery.CalledAEList) -// { -// query = query.Where(t => t.SCPStudyList.Select(c => c.CalledAE).Contains(calledAE)); -// } - - -// var resultQuery = from patient in query - -// select new PatientTrialView() -// { -// PatientId = patient.Id, -// PatientBirthDate = patient.PatientBirthDate, -// CreateTime = patient.CreateTime, -// CalledAEList = patient.SCPStudyList.Select(t => t.CalledAE).Distinct().ToList(), -// CallingAEList = patient.SCPStudyList.Select(t => t.CallingAE).Distinct().ToList(), -// CreateUserId = patient.CreateUserId, -// UpdateTime = patient.UpdateTime, -// UpdateUserId = patient.UpdateUserId, - -// EarliestStudyTime = patient.EarliestStudyTime, -// LatestStudyTime = patient.LatestStudyTime, -// LatestPushTime = patient.LatestPushTime, -// PatientAge = patient.PatientAge, -// PatientName = patient.PatientName, -// PatientIdStr = patient.PatientIdStr, -// PatientSex = patient.PatientSex, - -// StudyCount = patient.SCPStudyList.Count(), - -// TrialList = patient.SubjectPatientList.Where(t => isAdminOrOA ? true : t.Subject.Trial.TrialUserList.Any(t => t.UserId == _userInfo.Id)).Select(c => new PatientTrialStatInfo() -// { -// ExperimentName = c.Subject.Trial.ExperimentName, -// VisitCount = c.Subject.SubjectVisitList.Count() -// }).ToList(), - -// }; +using IRaCIS.Application.Interfaces; +using IRaCIS.Application.Contracts; +using IRaCIS.Core.Application.Filter; +using IRaCIS.Core.Domain.Share; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Authorization; +using IRaCIS.Core.Application.Auth; +using MassTransit; +using Panda.DynamicWebApi.Attributes; +using DocumentFormat.OpenXml.Spreadsheet; +using AutoMapper.EntityFrameworkCore; +using IRaCIS.Core.Domain.Models; +using IRaCIS.Core.Application.Service.Reading.Dto; +using Microsoft.Extensions.Options; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Configuration.Json; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using SharpCompress.Common; +using System.Reactive.Subjects; +using Subject = IRaCIS.Core.Domain.Models.Subject; +using IRaCIS.Core.Application.ViewModel; +using Medallion.Threading; +using IRaCIS.Core.Infrastructure; +using EasyCaching.Core; +using Pipelines.Sockets.Unofficial.Arenas; +using IRaCIS.Core.Application.Contracts; +using MailKit.Search; +using DocumentFormat.OpenXml.Office2010.Excel; +using IRaCIS.Core.Application.Contracts.Dicom.DTO; +using IRaCIS.Core.Application.Helper; +using NPOI.SS.Formula.Functions; +using System.Linq; +using System.Linq.Dynamic.Core; +using System.Text; +using DocumentFormat.OpenXml.EMMA; +using Azure; +using System.IO.Compression; +using static IRaCIS.Core.Domain.Share.StaticData; +using FellowOakDicom; +using DocumentFormat.OpenXml.Office2010.Drawing; +using EasyCaching.Core.DistributedLock; +using IDistributedLockProvider = Medallion.Threading.IDistributedLockProvider; +using DocumentFormat.OpenXml.InkML; + +namespace IRaCIS.Application.Services +{ + [ApiExplorerSettings(GroupName = "Trial")] + public class PatientService : BaseService + { + + private readonly IRepository _trialRepository; + private readonly IRepository _patientRepository; + private readonly IRepository _scpStudyRepository; + private readonly IRepository _subjectRepository; + private readonly IRepository _subjectVisitRepository; + private readonly IDistributedLockProvider _distributedLockProvider; + + public PatientService(IRepository studyRepository, IRepository trialRepository, IRepository patientRepository, IRepository subjectRepository, IRepository subjectVisitRepository, IDistributedLockProvider distributedLockProvider) + { + _scpStudyRepository = studyRepository; + _trialRepository = trialRepository; + _patientRepository = patientRepository; + _subjectRepository = subjectRepository; + _subjectVisitRepository = subjectVisitRepository; + _distributedLockProvider = distributedLockProvider; + } + + + /// + /// scp 影像推送记录表 + /// + /// + /// + [HttpPost] + public async Task>> GetSCPImageUploadList(SCPImageUploadQuery inQuery) + { + var query = _repository.Where() + .WhereIf(!string.IsNullOrWhiteSpace(inQuery.CalledAE), t => t.CalledAE.Contains(inQuery.CalledAE)) + .WhereIf(!string.IsNullOrWhiteSpace(inQuery.CallingAEIP), t => t.CallingAEIP.Contains(inQuery.CallingAEIP)) + .WhereIf(!string.IsNullOrWhiteSpace(inQuery.CallingAE), t => t.CallingAE.Contains(inQuery.CallingAE)) + .WhereIf(inQuery.StartTime != null, t => t.StartTime >= inQuery.StartTime) + .WhereIf(inQuery.EndTime != null, t => t.EndTime <= inQuery.EndTime) + .WhereIf(!string.IsNullOrWhiteSpace(inQuery.TrialSiteKeyInfo), t => t.TrialSite.TrialSiteCode.Contains(inQuery.TrialSiteKeyInfo) + || t.TrialSite.TrialSiteAliasName.Contains(inQuery.TrialSiteKeyInfo) || t.TrialSite.TrialSiteName.Contains(inQuery.TrialSiteKeyInfo)) + .ProjectTo(_mapper.ConfigurationProvider); + + + var pageList = await query.ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, inQuery.SortField == string.Empty ? nameof(SCPImageUploadView.CallingAE) : inQuery.SortField, inQuery.Asc); + + + return ResponseOutput.Ok(pageList); + } + + + #region 患者检查管理 + + /// + ///影像检查列表-患者为维度组织 + /// + /// + /// + [HttpPost] + public async Task>> GetPatientList(PatientTrialQuery inQuery) + { + + + #region new ok + var query = _patientRepository + .WhereIf(!string.IsNullOrWhiteSpace(inQuery.PatientIdStr), t => t.PatientIdStr.Contains(inQuery.PatientIdStr)) + .WhereIf(!string.IsNullOrWhiteSpace(inQuery.PatientName), t => t.PatientName.Contains(inQuery.PatientName)) + .WhereIf(!string.IsNullOrWhiteSpace(inQuery.SubejctCode), t => t.Subject.Code.Contains(inQuery.SubejctCode)) + .WhereIf(!string.IsNullOrWhiteSpace(inQuery.TrialSiteKeyInfo), t => t.TrialSite.TrialSiteCode.Contains(inQuery.TrialSiteKeyInfo) + || t.TrialSite.TrialSiteAliasName.Contains(inQuery.TrialSiteKeyInfo)|| t.TrialSite.TrialSiteName.Contains(inQuery.TrialSiteKeyInfo)) + .WhereIf(!string.IsNullOrWhiteSpace(inQuery.CallingAE), t => t.SCPStudyList.Any(t => t.CallingAE == inQuery.CallingAE)) + .WhereIf(!string.IsNullOrWhiteSpace(inQuery.CalledAE), t => t.SCPStudyList.Any(t => t.CalledAE == inQuery.CalledAE)) + .WhereIf(inQuery.BeginPushTime != null, t => t.LatestPushTime >= inQuery.BeginPushTime) + .WhereIf(inQuery.EndPushTime != null, t => t.LatestPushTime <= inQuery.EndPushTime); + + //foreach (var calledAE in inQuery.CalledAEList) + //{ + // query = query.Where(t => t.SCPStudyList.Select(c => c.CalledAE).Contains(calledAE)); + //} + + + var resultQuery = from patient in query + + select new PatientSubjectView() + { + PatientId = patient.Id, + PatientBirthDate = patient.PatientBirthDate, + CreateTime = patient.CreateTime, + CalledAEList = patient.SCPStudyList.Select(t => t.CalledAE).Distinct().ToList(), + CallingAEList = patient.SCPStudyList.Select(t => t.CallingAE).Distinct().ToList(), + CreateUserId = patient.CreateUserId, + UpdateTime = patient.UpdateTime, + UpdateUserId = patient.UpdateUserId, + + EarliestStudyTime = patient.EarliestStudyTime, + LatestStudyTime = patient.LatestStudyTime, + LatestPushTime = patient.LatestPushTime, + PatientAge = patient.PatientAge, + PatientName = patient.PatientName, + PatientIdStr = patient.PatientIdStr, + PatientSex = patient.PatientSex, + + StudyCount = patient.SCPStudyList.Count(), + + TrialId=patient.TrialId, + SubejctId=patient.SubjectId, + SubjectCode=patient.Subject.Code, + TrialSiteAliasName=patient.TrialSite.TrialSiteAliasName, + TrialSiteCode=patient.TrialSite.TrialSiteCode, + TrialSiteName=patient.TrialSite.TrialSiteName + + }; + + + + + var pageList = await resultQuery.ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, inQuery.SortField == string.Empty ? nameof(PatientQueryView.PatientIdStr) : inQuery.SortField, inQuery.Asc); + #endregion + + + return ResponseOutput.Ok(pageList); + } + + + + + + /// + /// 影像检查列表-> 获取患者的检查列表 + /// + /// + /// + [HttpPost] + public async Task> GetPatientStudyList(PatientStudyInfoQuery inQuery) + { + var query = from scpStudy in _scpStudyRepository.Where(t => t.PatientId == inQuery.PatientId) + .WhereIf(inQuery.EarliestStudyTime != null, t => t.StudyTime >= inQuery.EarliestStudyTime) + .WhereIf(inQuery.LatestStudyTime != null, t => t.StudyTime <= inQuery.LatestStudyTime) + .WhereIf(!string.IsNullOrWhiteSpace(inQuery.Modalities), t => t.Modalities.Contains(inQuery.Modalities)) + select new PatientStudySimpleView() + { + Description = scpStudy.Description, + CalledAE = scpStudy.CalledAE, + CallingAE = scpStudy.CallingAE, + InstanceCount = scpStudy.InstanceCount, + Modalities = scpStudy.Modalities, + PatientId = scpStudy.PatientId, + SCPStudyId = scpStudy.Id, + SeriesCount = scpStudy.SeriesCount, + StudyTime = scpStudy.StudyTime, + + SubjectVisitId= scpStudy.SubjectVisitId, + VisitName=scpStudy.SubjectVisit.VisitName, + BlindName=scpStudy.SubjectVisit.BlindName + }; + + + //var sortField = string.IsNullOrWhiteSpace(inQuery.SortField) ? nameof(PatientStudySimpleView.StudyTime) : inQuery.SortField; + //var orderQuery = inQuery.Asc ? query.OrderBy(sortField) : query.OrderBy(sortField + " desc"); + //var list = await orderQuery.ToListAsync(); + var pageList = await query.ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, inQuery.SortField == string.Empty ? nameof(PatientStudySimpleView.StudyTime) : inQuery.SortField, inQuery.Asc); + + return pageList; + } + + + public async Task> GetDicomCalledAEList() + { + var list = await _scpStudyRepository.Select(t => t.CalledAE).Distinct().ToListAsync(); + return list; + } -// var pageList = await resultQuery.ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, inQuery.SortField == string.Empty ? nameof(PatientQueryView.PatientIdStr) : inQuery.SortField, inQuery.Asc); -// #endregion + public async Task> GetDicomCallingAEList() + { + var list = await _scpStudyRepository.Select(t => t.CallingAE).Distinct().ToListAsync(); + return list; + } -// return ResponseOutput.Ok(pageList); -// } + /// + /// 影像访视上传 检查列表 + /// + /// + /// + [HttpPost] + public async Task> GetVisitPatientStudyFilterList(VisitPatientStudyFilterQuery inQuery) + { + var trialSiteId=_subjectRepository.Where(t=>t.Id==inQuery.SubjectId).Select(t=>t.TrialSiteId).FirstOrDefault(); + var query = from scpStudy in _scpStudyRepository + //未绑定的患者,或者自己已绑定但是未绑定访视的 + .Where(t => t.Patient.SubjectId == null|| (t.Patient.SubjectId == inQuery.SubjectId && t.SubjectVisitId==null)) + //中心 + .Where(t=>t.TrialSiteId==trialSiteId) + .WhereIf(inQuery.EarliestStudyTime != null, t => t.StudyTime >= inQuery.EarliestStudyTime) + .WhereIf(inQuery.LatestStudyTime != null, t => t.StudyTime <= inQuery.LatestStudyTime) + .WhereIf(!string.IsNullOrWhiteSpace(inQuery.Modalities), t => t.Modalities.Contains(inQuery.Modalities)) + select new VisitPatientStudyFilterView() + { + Description = scpStudy.Description, + CalledAE = scpStudy.CalledAE, + CallingAE = scpStudy.CallingAE, + InstanceCount = scpStudy.InstanceCount, + Modalities = scpStudy.Modalities, + PatientId = scpStudy.PatientId, + SCPStudyId = scpStudy.Id, + SeriesCount = scpStudy.SeriesCount, + StudyTime = scpStudy.StudyTime, + }; + var pageList = await query.ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, inQuery.SortField == string.Empty ? nameof(PatientStudySimpleView.StudyTime) : inQuery.SortField, inQuery.Asc); -// /// -// /// 检查管理-> 获取患者检查列表(同步影像数据之前的) -// /// -// /// -// /// -// [HttpPost] -// public async Task> GetPatientStudyList(PatientStudyInfoQuery inQuery) -// { -// var query = from scpStudy in _studyRepository.Where(t => t.PatientId == inQuery.PatientId) -// .WhereIf(inQuery.EarliestStudyTime != null, t => t.StudyTime >= inQuery.EarliestStudyTime) -// .WhereIf(inQuery.LatestStudyTime != null, t => t.StudyTime <= inQuery.LatestStudyTime) -// .WhereIf(!string.IsNullOrWhiteSpace(inQuery.Modalities), t => t.Modalities.Contains(inQuery.Modalities)) -// select new PatientStudySimpleView() -// { -// Description = scpStudy.Description, -// CalledAE = scpStudy.CalledAE, -// CallingAE = scpStudy.CallingAE, -// InstanceCount = scpStudy.InstanceCount, -// Modalities = scpStudy.Modalities, -// PatientId = scpStudy.PatientId, -// SCPStudyId = scpStudy.Id, -// SeriesCount = scpStudy.SeriesCount, -// StudyTime = scpStudy.StudyTime, -// }; + return pageList; + } -// var sortField = string.IsNullOrWhiteSpace(inQuery.SortField) ? nameof(PatientStudySimpleView.StudyTime) : inQuery.SortField; -// var orderQuery = inQuery.Asc ? query.OrderBy(sortField) : query.OrderBy(sortField + " desc"); - -// var list = await orderQuery.ToListAsync(); - -// return list; -// } - + /// + /// 提交 患者检查和访视的绑定 + /// + /// + /// + [HttpPost] + [UnitOfWork] + [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })] + public async Task SubmitVisitStudyBinding(SubmitVisitStudyBindingCommand inCommand) + { -// public async Task>> GetPatientSeriesList(Guid scpStudyId, -// [FromServices] IRepository _seriesRepository, -// [FromServices] IRepository _instanceRepository -// ) -// { + var subjectId = inCommand.SubjectId; + var subjectVisitId=inCommand.SubjectVisitId; + var trialId = inCommand.TrialId; + + -// var seriesList = await _seriesRepository.Where(s => s.StudyId == scpStudyId).OrderBy(s => s.SeriesNumber). -// ThenBy(s => s.SeriesTime).ThenBy(s => s.CreateTime) -// .ProjectTo(_mapper.ConfigurationProvider).ToListAsync(); + var @lock = _distributedLockProvider.CreateLock($"StudyCode"); -// var idList = await _instanceRepository.Where(s => s.StudyId == scpStudyId).OrderBy(t => t.SeriesId).ThenBy(t => t.InstanceNumber) -// .ThenBy(s => s.InstanceTime).ThenBy(s => s.CreateTime) -// .Select(t => new { t.SeriesId, t.Id, t.Path, t.NumberOfFrames, t.InstanceNumber }).ToListAsync();//.GroupBy(u => u.SeriesId); + using (await @lock.AcquireAsync()) + { + var dbStudyCodeIntMax = _repository.Where(s => s.TrialId == inCommand.TrialId).Select(t => t.Code).DefaultIfEmpty().Max(); -// foreach (var item in seriesList) -// { -// item.InstanceList = idList.Where(s => s.SeriesId == item.Id).Select(u => u.Id).ToList(); + int currentNextCodeInt = dbStudyCodeIntMax + 1; -// //处理多帧 -// item.InstancePathList = idList.Where(s => s.SeriesId == item.Id).OrderBy(t => t.InstanceNumber) -// .SelectMany(u => -// { + foreach (var scpStudyId in inCommand.SCPStudyIdList) + { -// if (u.NumberOfFrames > 1) -// { -// var pathList = new List(); + var find = _scpStudyRepository.Where(t => t.Id == scpStudyId).Include(t => t.SeriesList).Include(t => t.InstanceList).FirstOrDefault(); -// for (int i = 1; i <= u.NumberOfFrames; i++) -// { -// pathList.Add(u.Path + "?frame=" + (i - 1)); -// } -// return pathList; -// } -// else -// { -// return new List { u.Path }; + if (find != null) + { -// } -// }) -// .ToList(); -// } + var newStuty = _mapper.Map(find); + await _repository.AddAsync(newStuty); -// var study = await _studyRepository.FindAsync(scpStudyId); + newStuty.SeqId = Guid.Empty; + newStuty.Code = currentNextCodeInt; + newStuty.StudyCode = AppSettings.GetCodeStr(currentNextCodeInt, nameof(DicomStudy)); + newStuty.IsFromPACS = true; + newStuty.TrialId = trialId; + newStuty.SubjectId = subjectId; + newStuty.SubjectVisitId = subjectVisitId; -// return ResponseOutput.Ok(seriesList, study); -// } + var newSeriesList = _mapper.Map>(find.SeriesList); + foreach (var series in newSeriesList) + { + + series.SeqId = Guid.Empty; + series.TrialId = trialId; + series.SubjectId = subjectId; + series.SubjectVisitId = subjectVisitId; + } + await _repository.AddRangeAsync(newSeriesList); + var newInstanceList = _mapper.Map>(find.InstanceList); + foreach (var instance in newInstanceList) + { -// /// -// /// 清除该患者绑定的受试者的所有的数据、(subject subjectVisit visitTask dicom) -// /// -// /// -// /// -// [UnitOfWork] -// public async Task DeletePatientStudyAllData(Guid patientId, -// [FromServices] IRepository _visitTaskRepository, -// [FromServices] IRepository _SeriesRepository, -// [FromServices] IRepository _instanceRepository, -// [FromServices] IRepository _dicomStudyRepository, -// [FromServices] IRepository _dicomSeriesRepository, -// [FromServices] IRepository _dicomInstanceRepository, -// [FromServices] IOSSService oSSService) -// { -// //清理自己管理的项目的数据 -// var subjectPatientList = await _subjectPatientRepository.Where(t => t.PatientId == patientId && t.Subject.Trial.TrialUserList.Any(t => t.UserId == _userInfo.Id)) -// .Select(t => new { t.SubjectId, StudyInstanceUidList = t.Patient.SCPStudyList.Select(t => t.StudyInstanceUid).ToList() }).ToListAsync(); -// if (_studyRepository.Any(t => t.IsUploadFinished == false && t.PatientId == patientId)) -// { -// return ResponseOutput.NotOk("当前患者有检查正在上传,不允许清理数据"); -// } + instance.SeqId = Guid.Empty; + instance.TrialId = trialId; + instance.SubjectId = subjectId; + instance.SubjectVisitId = subjectVisitId; + + } + await _repository.AddRangeAsync(newInstanceList); + } -// foreach (var item in subjectPatientList) -// { -// var subjectId = item.SubjectId; + currentNextCodeInt++; -// await _subjectRepository.BatchDeleteNoTrackingAsync(t => t.Id == subjectId); -// await _subjectVisitRepository.BatchDeleteNoTrackingAsync(t => t.SubjectId == subjectId); -// await _visitTaskRepository.BatchDeleteNoTrackingAsync(t => t.SubjectId == subjectId); -// await _dicomStudyRepository.BatchDeleteNoTrackingAsync(t => t.SubjectId == subjectId); -// await _dicomSeriesRepository.BatchDeleteNoTrackingAsync(t => t.SubjectId == subjectId); -// await _dicomInstanceRepository.BatchDeleteNoTrackingAsync(t => t.SubjectId == subjectId); -// } + } -// var instanceUidList = subjectPatientList.SelectMany(t => t.StudyInstanceUidList).Distinct().ToList(); -// foreach (var studyInstanceUid in instanceUidList) -// { -// { -// var ossFolderPath = $"Dicom/{studyInstanceUid}"; -// await oSSService.DeleteFromPrefix(ossFolderPath); + } -// } -// } -// var sCPStudyIdList = _studyRepository.Where(t => t.PatientId == patientId).Select(t => t.Id).ToList(); + await _repository.SaveChangesAsync(); -// await _patientRepository.BatchDeleteNoTrackingAsync(t => t.Id == patientId); + return ResponseOutput.Ok(); + } -// foreach (var item in sCPStudyIdList) -// { -// await _studyRepository.BatchDeleteNoTrackingAsync(t => t.Id == item); -// await _SeriesRepository.BatchDeleteNoTrackingAsync(t => t.StudyId == item); -// await _instanceRepository.BatchDeleteNoTrackingAsync(t => t.StudyId == item); -// } + #endregion -// return ResponseOutput.Ok(); -// } -// #endregion -// #region 受试者管理 -// [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })] -// [HttpPost] -// public async Task> AddOrUpdateSubject([FromBody] AddOrUpdateSubjectCommand subjectCommand) -// { -// var svlist = new List(); -// var verifyExp1 = new EntityVerifyExp() -// { -// VerifyExp = u => u.Code == subjectCommand.Code && u.TrialId == subjectCommand.TrialId, -// //---已存在具有相关受试者编号的受试者。 -// VerifyMsg = _localizer["Subject_DuplicateSubjectNum"] -// }; -// Subject? mapedSubject = null; -// if (subjectCommand.Id == null) //insert -// { -// mapedSubject = await _subjectRepository.InsertFromDTOAsync(subjectCommand, false, verifyExp1); -// } -// else //update -// { + } -// mapedSubject = await _subjectRepository.UpdateFromDTOAsync(subjectCommand, false, false, verifyExp1/*, verifyExp2*/); -// } - - -// await _subjectRepository.SaveChangesAsync(); - -// return ResponseOutput.Ok(mapedSubject.Id.ToString()); - -// } - -// /// -// /// 受试者管理-> 受试者列表 (带患者信息,患者信息是数组) -// /// -// /// -// /// -// [HttpPost] -// public async Task>> GetPatientSubejctList(PatientSubjectQuery inQuery) -// { -// var subjectQuery = _subjectRepository.Where(u => u.TrialId == inQuery.TrialId) -// .WhereIf(!string.IsNullOrWhiteSpace(inQuery.Code), t => t.Code.Contains(inQuery.Code)) -// .WhereIf(!string.IsNullOrWhiteSpace(inQuery.ShortName), t => t.ShortName.Contains(inQuery.ShortName)) -// .WhereIf(!string.IsNullOrWhiteSpace(inQuery.Sex), t => t.Sex.Contains(inQuery.Sex)) - -// //.WhereIf(!string.IsNullOrWhiteSpace(inQuery.PatientIdStr), t => t.SubjectPatientList.Any(t => t.Patient.PatientIdStr.Contains(inQuery.PatientIdStr))) -// .WhereIf(!string.IsNullOrWhiteSpace(inQuery.PatientName), t => t.SubjectPatientList.Any(t => t.Patient.PatientName.Contains(inQuery.PatientName))) -// .WhereIf(!string.IsNullOrWhiteSpace(inQuery.PatientSex), t => t.SubjectPatientList.Any(t => t.Patient.PatientSex.Contains(inQuery.PatientSex))) - -// .WhereIf(inQuery.Status != null, t => t.Status == inQuery.Status) -// .ProjectTo(_mapper.ConfigurationProvider); - -// var pageList = await subjectQuery.ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, inQuery.SortField == string.Empty ? nameof(PatienSubejctView.Code) : inQuery.SortField, inQuery.Asc); - - -// return ResponseOutput.Ok(pageList); -// } - -// /// -// /// 受试者管理-> 患者列表 (subject 列表进入,进行关系绑定初始化列表,排除已绑定的患者和已绑定给其他subject的患者) -// /// -// /// -// /// -// [HttpPost] -// public async Task>> GetPatientInitList(PatientQuery inQuery) -// { -// var query = _patientRepository -// .WhereIf(!string.IsNullOrWhiteSpace(inQuery.PatientIdStr), t => t.PatientIdStr.Contains(inQuery.PatientIdStr)) -// .WhereIf(!string.IsNullOrWhiteSpace(inQuery.PatientName), t => t.PatientName.Contains(inQuery.PatientName)) -// .WhereIf(!string.IsNullOrWhiteSpace(inQuery.CallingAE), t => t.SCPStudyList.Any(t => t.CallingAE == inQuery.CallingAE)) -// .WhereIf(inQuery.EarliestStudyTime != null, t => t.EarliestStudyTime >= inQuery.EarliestStudyTime) -// .WhereIf(inQuery.LatestStudyTime != null, t => t.LatestStudyTime <= inQuery.LatestStudyTime) - -// //排除该受试者已绑定的患者 -// //.WhereIf(inQuery.SubjectId != null, t => !t.SubjectPatientList.Any(u => u.SubjectId == inQuery.SubjectId)) - -// //排除该项目已绑定的其他患者 -// .Where(t => !t.SubjectPatientList.Any(c => c.Subject.TrialId == inQuery.TrialId)); - -// foreach (var calledAE in inQuery.CalledAEList) -// { -// query = query.Where(t => t.SCPStudyList.Select(c => c.CalledAE).Contains(calledAE)); -// } - - -// var patientQuery = query.ProjectTo(_mapper.ConfigurationProvider); - - -// var pageList = await patientQuery.ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, inQuery.SortField == string.Empty ? nameof(PatientQueryView.PatientIdStr) : inQuery.SortField, inQuery.Asc); - - -// return ResponseOutput.Ok(pageList); -// } - -// /// -// /// 受试者管理->患者列表 Dicom AE 下拉框数据获取 -// /// -// /// -// public async Task> GetDicomCalledAEList() -// { -// var list = await _studyRepository.Select(t => t.CalledAE).Distinct().ToListAsync(); - -// return list; -// } - -// public async Task> GetDicomCallingAEList() -// { -// var list = await _studyRepository.Select(t => t.CallingAE).Distinct().ToListAsync(); - -// return list; -// } - -// /// -// ///受试者管理-> 患者列表 模糊搜索下拉 选择subject 排除已绑定并提交的 -// /// -// /// -// /// -// [HttpPost] -// public async Task> GetTrialSubejctSelectList(SubjectSelectQuery inQuery) -// { -// var list = await _subjectRepository.Where(t => t.TrialId == inQuery.TrialId && t.Status == SubjectStatus.OnVisit) -// .WhereIf(!string.IsNullOrWhiteSpace(inQuery.SubjectCode), u => u.Code.Contains(inQuery.SubjectCode)) -// .WhereIf(inQuery.SubjectId != null, t => t.Id == inQuery.SubjectId) -// //.Where(t => !t.SubjectVisitList.SelectMany(t => t.SCPStudySubjectVisitList).Any(c => c.StudyId != null)) -// .Select(t => new SubjectSelectDto() -// { -// SubejctId = t.Id, -// SubjectCode = t.Code, -// Status = t.Status, -// Sex = t.Sex, -// ShortName = t.ShortName, -// Age = t.Age, -// BirthDate = t.BirthDate, -// //PatientList = t.SubjectPatientList.Select(c => new PatienBasicInfo() { PatientId = c.PatientId, PatientIdStr = c.Patient.PatientIdStr }).ToList() -// }) -// .ToListAsync(); - -// return list; -// } - -// #endregion - - - -// #region 患者和受试者绑定,生成访视,预先绑定检查和访视 - - - - - - - -// /// -// /// 提交 患者检查和访视的绑定 -// /// -// /// -// /// -// [HttpPost] -// [UnitOfWork] -// [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })] -// public async Task SubmitVisitStudyBinding(SubmitVisitStudyBindingCommand inCommand, [FromServices] IOptionsMonitor _basicSystemConfigConfig) -// { - -// //防止访视重复 -// inCommand.SubjectVisitIdList = inCommand.SubjectVisitIdList.Distinct().ToList(); - -// //确认当前提交的最大的访视之前所有的访视都已提交,并且没有漏的 - -// var curentMaxNum = await _subjectVisitRepository.Where(t => inCommand.SubjectVisitIdList.Contains(t.Id)).Select(t => t.VisitNum).MaxAsync(); - -// var allVisitList = _subjectVisitRepository.Where(t => t.TrialId == inCommand.TrialId && t.SubjectId == inCommand.SubjectId && t.VisitNum <= curentMaxNum).Select(t => new { SubjectVisitId = t.Id, t.Subject.Status, t.VisitNum, t.SubmitState }).OrderBy(t => t.VisitNum).ToList(); - -// //批量提交 -// if (inCommand.SubjectVisitIdList.Count > 1) -// { -// if (allVisitList.Where(t => t.SubmitState != SubmitStateEnum.Submitted).Count() != inCommand.SubjectVisitIdList.Count()) -// { -// return ResponseOutput.NotOk(_localizer["当前批量提交的访视中间有遗漏的访视或者前序有访视未提交"]); -// } -// } - -// else -// { -// if (allVisitList.Any(t => t.VisitNum < curentMaxNum && t.SubmitState != SubmitStateEnum.Submitted)) -// { -// return ResponseOutput.NotOk(_localizer["前序有访视未提交,请先提交前序访视"]); -// } -// } - -// if (allVisitList.Any(t => t.Status == SubjectStatus.EndOfVisit)) -// { -// return ResponseOutput.NotOk(_localizer["受试者状态为访视结束,不允许提交访视生成任务"]); -// } - -// //var list = await _studySubjectVisitRepository.Where(t => inCommand.SubjectVisitIdList.Contains(t.SubjectVisitId)).Select(t => new { t.SCPStudyId, t.SCPStudy.PatientId, t.SubjectVisitId, t.SubjectVisit.VisitNum, t.SubjectVisit.SubjectId, SubjectCode = t.SubjectVisit.Subject.Code, t.SubjectVisit.TrialId, t.SCPStudy.StudyTime, t.StudyId, t.SCPStudy.IsUploadFinished }).OrderBy(t => t.StudyTime).ToListAsync(); - -// //if (list.Any(t => t.StudyId != null)) -// //{ -// // return ResponseOutput.NotOk(_localizer["有访视和检查处于已绑定关系,不允许再次提交绑定"]); -// //} - -// //if (list.Any(t => t.IsUploadFinished == false)) -// //{ -// // return ResponseOutput.NotOk(_localizer["有访视检查正在传输中,不允许提交"]); -// //} - - -// ////判断每个subject 批量提交的是否符合时间要求 -// //foreach (var g in list.GroupBy(t => new { t.SubjectId, t.SubjectCode })) -// //{ -// // var visitOrderStudyList = g.OrderBy(t => t.VisitNum).ThenBy(t => t.StudyTime).ToList(); - -// // var studyTimeOrderList = visitOrderStudyList.OrderBy(t => t.StudyTime).ToList(); - -// // bool arraysEqual = visitOrderStudyList.SequenceEqual(studyTimeOrderList); - -// // if (!arraysEqual) -// // { -// // return ResponseOutput.NotOk(_localizer[$"{g.Key.SubjectCode}所提交的访视中的检查时间,不符合后续访视的检查时间比前序检查的时间大的要求"]); -// // } - -// // if (DateTime.Now < studyTimeOrderList.Max(t => t.StudyTime)) -// // { -// // return ResponseOutput.NotOk(_localizer[$"您当前修改了服务器时间,试图绕过软件授权,请恢复服务器时间,并联系授权方授权才可进行操作"]); -// // } -// //} - -// var trialConfig = await _trialRepository.Where(t => t.Id == inCommand.TrialId).Select(t => new { t.IsEnrollementQualificationConfirm, t.IsPDProgressView, t.AuthorizationEncrypt }).FirstOrDefaultAsync(); - - - -// //var decodedText = Cryptography.DecryptString(trialConfig.AuthorizationEncrypt, _basicSystemConfigConfig.CurrentValue.AESKey, "Trial_AuthorizationEncrypt"); - -// //var authInfo = JsonConvert.DeserializeObject(decodedText); - - - - -// var @lock = _distributedLockProvider.CreateLock($"StudyCode"); - -// using (await @lock.AcquireAsync()) -// { -// var dbStudyCodeIntMax = _repository.Where(s => s.TrialId == inCommand.TrialId).Select(t => t.Code).DefaultIfEmpty().Max(); - -// int currentNextCodeInt = dbStudyCodeIntMax + 1; - -// foreach (var item in list) -// { - - -// var dbSubjectVisit = await _subjectVisitRepository.FirstOrDefaultAsync(t => t.Id == item.SubjectVisitId); - -// //处理脏数据,可能之前的绑定的数据状态是待上传,但是已经绑定了检查 -// if (dbSubjectVisit.SubmitState == SubmitStateEnum.ToSubmit || dbSubjectVisit.SubmitState == SubmitStateEnum.None) -// { -// dbSubjectVisit.SubmitState = SubmitStateEnum.Submitted; -// dbSubjectVisit.SubmitTime = DateTime.Now; -// dbSubjectVisit.SubmitUserId = _userInfo.Id; - -// //维护统一状态 -// //dbSubjectVisit.ReadingStatus = ReadingStatusEnum.TaskAllocate; - -// dbSubjectVisit.AuditState = AuditStateEnum.QCPassed; -// dbSubjectVisit.CheckState = CheckStateEnum.CVPassed; - -// dbSubjectVisit.IsEnrollmentConfirm = dbSubjectVisit.IsBaseLine ? trialConfig.IsEnrollementQualificationConfirm : false; - -// dbSubjectVisit.PDState = trialConfig.IsPDProgressView ? PDStateEnum.PDProgress : PDStateEnum.None; -// } - - - - -// var find = _studyRepository.Where(t => t.Id == item.SCPStudyId).Include(t => t.SeriesList).Include(t => t.InstanceList).FirstOrDefault(); - -// if (find != null) -// { -// //重新算Id -// Guid studyId = IdentifierHelper.CreateGuid(item.TrialId.ToString(), find.StudyInstanceUid); -// find.Id = studyId; -// var newStuty = _mapper.Map(find); - -// await _repository.AddAsync(newStuty); -// //newStuty.Id = NewId.NextSequentialGuid(); - -// newStuty.SeqId = Guid.Empty; -// newStuty.Code = currentNextCodeInt; -// newStuty.StudyCode = AppSettings.GetCodeStr(currentNextCodeInt, nameof(DicomStudy)); -// newStuty.TrialId = item.TrialId; -// newStuty.SubjectId = item.SubjectId; -// newStuty.SubjectVisitId = item.SubjectVisitId; - -// var newSeriesList = _mapper.Map>(find.SeriesList); - -// foreach (var series in newSeriesList) -// { -// Guid seriesId = IdentifierHelper.CreateGuid(item.TrialId.ToString(), find.StudyInstanceUid, series.SeriesInstanceUid); - -// //重新算Id -// series.Id = seriesId; -// series.StudyId = newStuty.Id; - -// series.SeqId = Guid.Empty; -// series.TrialId = item.TrialId; -// series.SubjectId = item.SubjectId; -// series.SubjectVisitId = item.SubjectVisitId; -// } - -// await _repository.AddRangeAsync(newSeriesList); - -// var newInstanceList = _mapper.Map>(find.InstanceList); - -// foreach (var instance in newInstanceList) -// { -// Guid seriesId = IdentifierHelper.CreateGuid(item.TrialId.ToString(), find.StudyInstanceUid, instance.SeriesInstanceUid); -// Guid instanceId = IdentifierHelper.CreateGuid(item.TrialId.ToString(), find.StudyInstanceUid, instance.SeriesInstanceUid, instance.SopInstanceUid); -// //重新算Id -// instance.Id = instanceId; -// instance.SeriesId = seriesId; -// instance.StudyId = newStuty.Id; - -// instance.SeqId = Guid.Empty; -// instance.TrialId = item.TrialId; -// instance.SubjectId = item.SubjectId; -// instance.SubjectVisitId = item.SubjectVisitId; -// } -// await _repository.AddRangeAsync(newInstanceList); -// } - -// currentNextCodeInt++; - -// //await _studySubjectVisitRepository.BatchUpdateNoTrackingAsync(t => t.SubjectVisitId == item.SubjectVisitId && t.SCPStudyId == item.SCPStudyId, u => new SCPStudySubjectVisit() { StudyId = find.Id }); - -// //await _subjectPatientRepository.BatchUpdateNoTrackingAsync(t => t.SubjectId == item.SubjectId && t.PatientId == item.PatientId, u => new SubjectPatient() { IsBinded = true }); - -// } - - -// } - - - -// //await _studySubjectVisitRepository.SaveChangesAsync(); - -// return ResponseOutput.Ok(); -// } - -// #endregion - -// #region 访视基本管理 - - -// /// -// /// 绑定访视 初始化患者检查列表 -// /// -// /// -// /// -// [HttpPost] -// public async Task> GetVisitPatientStudyList(PatientStudyQuery inQuery) -// { -// var patientQuery = from scpStudy in _studyRepository -// .Where(t => inQuery.PatientIdList.Contains(t.PatientId)) -// .WhereIf(inQuery.EarliestStudyTime != null, t => t.StudyTime >= inQuery.EarliestStudyTime) -// .WhereIf(inQuery.LatestStudyTime != null, t => t.StudyTime <= inQuery.LatestStudyTime) - -// join scpStudySubjectVisit in _studySubjectVisitRepository.Where(t => t.SubjectVisit.TrialId == inQuery.TrialId) on scpStudy.Id equals scpStudySubjectVisit.SCPStudyId into cc -// from scpStudySubjectVisit in cc.DefaultIfEmpty() -// select new PatientStudySelectDto() -// { -// Description = scpStudy.Description, -// CalledAE = scpStudy.CalledAE, -// InstanceCount = scpStudy.InstanceCount, -// Modalities = scpStudy.Modalities, -// PatientId = scpStudy.Patient.Id, - -// PatientIdStr = scpStudy.PatientIdStr, -// PatientAge = scpStudy.PatientAge, -// PatientBirthDate = scpStudy.PatientBirthDate, -// PatientSex = scpStudy.PatientSex, -// PatientName = scpStudy.PatientName, - -// SCPStudyId = scpStudy.Id, -// SeriesCount = scpStudy.SeriesCount, -// StudyTime = scpStudy.StudyTime, - -// CallingAE = scpStudy.CallingAE, - -// SubmitState = scpStudySubjectVisit.SubjectVisit.SubmitState, -// SubjectVisitId = scpStudySubjectVisit.SubjectVisitId -// } -// ; - -// var sortField = string.IsNullOrWhiteSpace(inQuery.SortField) ? nameof(VisitPatientStudyView.StudyTime) : inQuery.SortField; -// var orderQuery = inQuery.Asc ? patientQuery.OrderBy(sortField) : patientQuery.OrderBy(sortField + " desc"); - -// var list = await orderQuery.ToListAsync(); - - -// return list; -// } - - - -// /// -// /// 访视管理- 获取subject 已存在的访视列表 ,同时获取项目访视的配置 在otherData里 -// /// -// /// -// /// -// /// -// [HttpPost] -// public async Task GetSubjectVisitSelectList(SubjectVisitSelectQuery inQuery, [FromServices] IRepository _subjectVisitReposiotry) -// { - -// var scpStudyList = await _studySubjectVisitRepository.Where(t => t.TrialId == inQuery.TrialId && t.SubjectId == inQuery.SubjectId && t.SCPStudyId != inQuery.SCPStudyId) -// .Select(t => new { t.SubjectVisitId, StudyTime = t.SCPStudy.StudyTime }) -// .ToListAsync(); - -// var result = scpStudyList.GroupBy(t => t.SubjectVisitId) -// .Select(g => new -// { - -// SubejctVisitId = g.Key, -// VisitMaxStudyTime = g.Max(c => c.StudyTime), -// VisitMinStudyTime = g.Min(c => c.StudyTime) -// }).ToList(); - -// var list = _subjectVisitReposiotry.Where(t => t.SubjectId == inQuery.SubjectId).ProjectTo(_mapper.ConfigurationProvider).ToList(); - -// foreach (var item in list) -// { -// item.VisitMaxStudyTime = result.Where(t => t.SubejctVisitId == item.Id).FirstOrDefault()?.VisitMaxStudyTime; -// item.VisitMinStudyTime = result.Where(t => t.SubejctVisitId == item.Id).FirstOrDefault()?.VisitMinStudyTime; -// } - -// var trialconfig = _trialRepository.Where(t => t.Id == inQuery.TrialId).Select(t => new { t.BlindBaseLineName, t.BlindFollowUpPrefix }).FirstOrDefault(); - -// return ResponseOutput.Ok(list, trialconfig); -// } - - - - -// /// -// ///访视管理-> 访视列表 (带患者信息,患者信息是数组) -// /// -// /// -// /// -// [HttpPost] -// public async Task>> GetPatientSubejctVisitList(PatientSubejctVisitQuery inQuery) -// { -// var query = _subjectVisitRepository.Where(t => t.TrialId == inQuery.TrialId) -// .WhereIf(!string.IsNullOrWhiteSpace(inQuery.SubjectCode), u => u.Subject.Code.Contains(inQuery.SubjectCode)) -// .WhereIf(!string.IsNullOrWhiteSpace(inQuery.SubjectSex), u => u.Subject.Sex.Contains(inQuery.SubjectSex)) -// .WhereIf(!string.IsNullOrWhiteSpace(inQuery.SubjectShortName), u => u.Subject.ShortName.Contains(inQuery.SubjectShortName)) -// .WhereIf(!string.IsNullOrWhiteSpace(inQuery.VisitName), u => u.VisitName.Contains(inQuery.VisitName)) -// .WhereIf(inQuery.SubmitState != null, u => u.SubmitState == inQuery.SubmitState) -// .WhereIf(inQuery.BeginStudyTime != null, t => t.SCPStudySubjectVisitList.Min(t => t.SCPStudy.StudyTime) >= inQuery.BeginStudyTime) -// .WhereIf(inQuery.EndStudyTime != null, t => t.SCPStudySubjectVisitList.Max(t => t.SCPStudy.StudyTime) <= inQuery.EndStudyTime) - -// .WhereIf(!string.IsNullOrWhiteSpace(inQuery.PatientIdStr), t => t.Subject.SubjectPatientList.Any(t => t.Patient.PatientIdStr.Contains(inQuery.PatientIdStr))) -// .WhereIf(!string.IsNullOrWhiteSpace(inQuery.PatientName), t => t.Subject.SubjectPatientList.Any(t => t.Patient.PatientName.Contains(inQuery.PatientName))) -// .WhereIf(!string.IsNullOrWhiteSpace(inQuery.PatientSex), t => t.Subject.SubjectPatientList.Any(t => t.Patient.PatientSex.Contains(inQuery.PatientSex))) -// .Select(t => new PatientSubjectVisitView() -// { -// PatientList = t.Subject.SubjectPatientList.Select(c => new PatientBasicInfo() -// { -// PatientId = c.PatientId, -// PatientAge = c.Patient.PatientAge, -// PatientBirthDate = c.Patient.PatientBirthDate, -// PatientIdStr = c.Patient.PatientIdStr, -// PatientSex = c.Patient.PatientSex, -// PatientName = c.Patient.PatientName, -// }).ToList(), - -// TrialId = t.TrialId, -// SubjectId = t.SubjectId, -// SubjectVisitId = t.Id, -// SubjectAge = t.Subject.Age, -// SubjectSex = t.Subject.Sex, -// SubjectShortName = t.Subject.ShortName, -// SubjectCode = t.Subject.Code, -// SubmitState = t.SubmitState, -// SubmitTime = t.SubmitTime, -// VisitNum = t.VisitNum, -// VisitName = t.VisitName, -// VisitEarliestStudyTime = t.SCPStudySubjectVisitList.Min(t => t.SCPStudy.StudyTime), -// VisitLatestStudyTime = t.SCPStudySubjectVisitList.Max(t => t.SCPStudy.StudyTime), -// VisitImageZipPath = t.VisitImageZipPath, -// PackState = t.PackState, -// }); - -// var defalutSortArray = new string[] { nameof(PatientSubjectVisitView.SubjectId), nameof(PatientSubjectVisitView.VisitNum) }; -// var pageList = await query.ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, inQuery.SortField, inQuery.Asc, string.IsNullOrWhiteSpace(inQuery.SortField), defalutSortArray); - - - -// return ResponseOutput.Ok(pageList); -// } - - -// /// -// ///访视管理-> 获取当前访视 已绑定的患者检查 (从访视列表 进入修改绑定) -// /// -// /// -// /// -// [HttpPost] -// public async Task> GetCurrentVisitPatientStudyList(SubjectVisitStudyQuery inQuery) -// { -// var patientQuery = _studySubjectVisitRepository.Where(t => t.SubjectVisitId == inQuery.SujectVisitId && t.SubjectVisit.SubmitState != SubmitStateEnum.Submitted) -// //.WhereIf(inQuery.SubmitState != null, u => u.SubjectVisit.SubmitState == inQuery.SubmitState) -// .ProjectTo(_mapper.ConfigurationProvider); - -// var sortField = string.IsNullOrWhiteSpace(inQuery.SortField) ? nameof(VisitPatientStudyView.StudyTime) : inQuery.SortField; -// var orderQuery = inQuery.Asc ? patientQuery.OrderBy(sortField) : patientQuery.OrderBy(sortField + " desc"); - -// var list = await orderQuery.ToListAsync(); - -// return list; -// } - - -// /// -// /// 访视管理-> 获取可选访视列表 (从访视列表 进入修改绑定) -// /// -// /// -// /// -// [HttpPost] -// public async Task> GetPatientOtherStudyList(PatientStudyOtherQuery inQuery) -// { -// var query = from scpStudy in _studyRepository.Where(t => inQuery.PatientIdList.Contains(t.PatientId) && !t.SCPStudySubjectVisitList.Any(t => (t.SubjectVisitId == inQuery.SujectVisitId || t.SubjectVisit.SubmitState == SubmitStateEnum.Submitted) && t.TrialId == inQuery.TrialId)) -// .WhereIf(inQuery.EarliestStudyTime != null, t => t.StudyTime >= inQuery.EarliestStudyTime) -// .WhereIf(inQuery.LatestStudyTime != null, t => t.StudyTime <= inQuery.LatestStudyTime) -// .WhereIf(!string.IsNullOrEmpty(inQuery.PatientIdStr), t => t.PatientIdStr.Contains(inQuery.PatientIdStr)) -// //不属于该访视的检查 或者未绑定的检查 -// join scpStudySubjectVisit in _studySubjectVisitRepository.Where(c => c.TrialId == inQuery.TrialId) on scpStudy.Id equals scpStudySubjectVisit.SCPStudyId -// into dd -// from scpStudySV in dd.DefaultIfEmpty() -// select new VisitPatientStudyView() -// { -// PatientIdStr = scpStudy.PatientIdStr, -// PatientBirthDate = scpStudy.PatientBirthDate, -// PatientAge = scpStudy.PatientAge, -// PatientName = scpStudy.PatientName, -// PatientSex = scpStudy.PatientSex, -// Description = scpStudy.Description, -// CalledAE = scpStudy.CalledAE, -// CallingAE = scpStudy.CallingAE, -// InstanceCount = scpStudy.InstanceCount, -// Modalities = scpStudy.Modalities, -// PatientId = scpStudy.PatientId, -// SCPStudyId = scpStudy.Id, -// SeriesCount = scpStudy.SeriesCount, -// StudyTime = scpStudy.StudyTime, - -// SubmitState = scpStudySV.SubjectVisit.SubmitState, -// SubjectVisitId = scpStudySV.SubjectVisitId, -// VisitName = scpStudySV.SubjectVisit.VisitName, -// }; - -// #region 废弃 -// //var notCurrentVisitQuey = _studySubjectVisitRepository.Where(t => t.SubjectVisitId != inQuery.SujectVisitId && t.SCPStudy.Patient.Id == inQuery.PatientId) -// // .Select(t => new VisitPatientStudyView() -// // { -// // Description = t.SCPStudy.Description, -// // CalledAE = t.SCPStudy.CalledAE, -// // InstanceCount = t.SCPStudy.InstanceCount, -// // Modalities = t.SCPStudy.Modalities, -// // PatientId = t.SCPStudy.PatientId, -// // SCPStudyId = t.SCPStudy.PatientId, -// // SeriesCount = t.SCPStudy.SeriesCount, -// // StudyTime = t.SCPStudy.StudyTime, -// // SubjectVisitId = t.SubjectVisitId, -// // VisitName = t.SubjectVisit.VisitName, -// // }); - -// //var notBindQuery= _studyRepository.Where(t => t.PatientId == inQuery.PatientId && t.pa) - -// //var patientQuery = query - -// // .ProjectTo(_mapper.ConfigurationProvider); -// #endregion -// var sortField = string.IsNullOrWhiteSpace(inQuery.SortField) ? nameof(VisitPatientStudyView.StudyTime) : inQuery.SortField; -// var orderQuery = inQuery.Asc ? query.OrderBy(sortField) : query.OrderBy(sortField + " desc"); - -// var list = await orderQuery.ToListAsync(); - -// return list; -// } - -// #endregion - -// #region 检查管理 - - - -// /// -// ///检查管理-> 检查列表 (同步影像数据之前的) -// /// -// /// -// /// -// [HttpPost] -// public async Task>> GetPatientStudyBeforeConfirmList(TrialPatientStudyQuery inQuery) -// { -// #region 只查询已绑定的 -// //var query = _studySubjectVisitRepository.Where(t => t.SubjectVisit.TrialId == inQuery.TrialId) -// // .WhereIf(inQuery.PatientId != null, t => t.SCPStudy.PatientId == inQuery.PatientId) -// // .WhereIf(!string.IsNullOrWhiteSpace(inQuery.SubjectCode), u => u.SubjectVisit.Subject.Code.Contains(inQuery.SubjectCode)) -// // .WhereIf(!string.IsNullOrWhiteSpace(inQuery.PatientIdStr), u => u.SCPStudy.Patient.PatientIdStr.Contains(inQuery.PatientIdStr)) -// // .WhereIf(!string.IsNullOrWhiteSpace(inQuery.PatientSex), t => t.SCPStudy.Patient.PatientSex.Contains(inQuery.PatientSex)) -// // .WhereIf(inQuery.SubjectAge != null, t => t.SubjectVisit.Subject.Age == inQuery.SubjectAge) -// // .WhereIf(!string.IsNullOrWhiteSpace(inQuery.SubjectCode), u => u.SubjectVisit.Subject.Code.Contains(inQuery.SubjectCode)) -// // .WhereIf(!string.IsNullOrWhiteSpace(inQuery.SubjectSex), u => u.SubjectVisit.Subject.Sex.Contains(inQuery.SubjectSex)) -// // .WhereIf(!string.IsNullOrWhiteSpace(inQuery.SubjectShortName), t => t.SubjectVisit.Subject.ShortName.Contains(inQuery.SubjectShortName)) -// // .WhereIf(inQuery.BeginStudyTime != null, t => t.SCPStudy.StudyTime >= inQuery.BeginStudyTime) -// // .WhereIf(inQuery.EndStudyTime != null, t => t.SCPStudy.StudyTime <= inQuery.EndStudyTime) -// // .Select(t => new PatientStudyBeforeConfirmView() -// // { -// // SubjectId = t.SubjectVisit.SubjectId, -// // SubjectAge = t.SubjectVisit.Subject.Age, -// // SubjectSex = t.SubjectVisit.Subject.Sex, -// // SubjectShortName = t.SubjectVisit.Subject.ShortName, - - -// // PatientId = t.SCPStudy.PatientId, -// // PatientAge = t.SCPStudy.PatientAge, -// // PatientBirthDate = t.SCPStudy.PatientBirthDate, -// // PatientIdStr = t.SCPStudy.PatientIdStr, -// // PatientSex = t.SCPStudy.PatientSex, - -// // //PatientList = t.SubjectVisit.Subject.SubjectPatientList.Select(t => new PatientBasicInfo() -// // //{ -// // // PatientId = t.PatientId, -// // // PatientAge = t.Patient.PatientAge, -// // // PatientBirthDate = t.Patient.PatientBirthDate, -// // // PatientIdStr = t.Patient.PatientIdStr, -// // // PatientSex = t.Patient.PatientSex, -// // //}).ToList(), - -// // SubjectCode = t.SubjectVisit.Subject.Code, -// // SubmitState = t.SubjectVisit.SubmitState, -// // SubmitTime = t.SubjectVisit.SubmitTime, -// // VisitName = t.SubjectVisit.VisitName, -// // SubjectVisitId = t.SubjectVisitId, -// // VisitEarliestStudyTime = t.SubjectVisit.SCPStudySubjectVisitList.Min(t => t.SCPStudy.StudyTime), -// // VisitLatestStudyTime = t.SubjectVisit.SCPStudySubjectVisitList.Max(t => t.SCPStudy.StudyTime), - -// // StudyId = t.SCPStudyId, -// // StudyTime = t.SCPStudy.StudyTime, -// // CallingAE = t.SCPStudy.CallingAE, -// // CalledAE = t.SCPStudy.CalledAE - -// // }); -// #endregion - -// var query = from scpStudy in _studyRepository.Where(t => !t.SCPStudySubjectVisitList.Any(t => t.SubjectVisit.SubmitState == SubmitStateEnum.Submitted && t.TrialId == inQuery.TrialId)) -// .WhereIf(inQuery.IsBindedVisit == false, t => !t.SCPStudySubjectVisitList.Any(t => t.TrialId == inQuery.TrialId)) -// .WhereIf(inQuery.IsBindedVisit == true, t => t.SCPStudySubjectVisitList.Any(t => t.TrialId == inQuery.TrialId)) -// .WhereIf(!string.IsNullOrWhiteSpace(inQuery.VisitName), t => t.SCPStudySubjectVisitList.Any(t => t.TrialId == inQuery.TrialId && t.SubjectVisit.VisitName.Contains(inQuery.VisitName))) -// .WhereIf(!string.IsNullOrWhiteSpace(inQuery.PatientSex), t => t.Patient.PatientSex.Contains(inQuery.PatientSex)) -// .WhereIf(!string.IsNullOrWhiteSpace(inQuery.PatientIdStr), u => u.Patient.PatientIdStr.Contains(inQuery.PatientIdStr)) -// .WhereIf(inQuery.BeginStudyTime != null, t => t.StudyTime >= inQuery.BeginStudyTime) -// .WhereIf(inQuery.EndStudyTime != null, t => t.StudyTime <= inQuery.EndStudyTime) -// join subjectPatient in _subjectPatientRepository.Where(t => t.Subject.TrialId == inQuery.TrialId) -// .WhereIf(!string.IsNullOrWhiteSpace(inQuery.SubjectCode), u => u.Subject.Code.Contains(inQuery.SubjectCode)) -// .WhereIf(!string.IsNullOrWhiteSpace(inQuery.SubjectSex), u => u.Subject.Sex.Contains(inQuery.SubjectSex)) -// .WhereIf(!string.IsNullOrWhiteSpace(inQuery.SubjectShortName), t => t.Subject.ShortName.Contains(inQuery.SubjectShortName)) -// on scpStudy.PatientId equals subjectPatient.PatientId -// join scpStudySubjectVisit in _studySubjectVisitRepository.Where(t => t.TrialId == inQuery.TrialId) -// on scpStudy.Id equals scpStudySubjectVisit.SCPStudyId into dd -// from scpStudySV in dd.DefaultIfEmpty() -// select new PatientStudyBeforeConfirmView() -// { -// SubjectId = subjectPatient.Subject.Id, -// SubjectAge = subjectPatient.Subject.Age, -// SubjectSex = subjectPatient.Subject.Sex, -// SubjectShortName = subjectPatient.Subject.ShortName, -// SubjectCode = subjectPatient.Subject.Code, - -// PatientId = scpStudy.PatientId, -// PatientName = scpStudy.PatientName, -// PatientAge = scpStudy.PatientAge, -// PatientBirthDate = scpStudy.PatientBirthDate, -// PatientIdStr = scpStudy.PatientIdStr, -// PatientSex = scpStudy.PatientSex, - -// //PatientList = t.SubjectVisit.Subject.SubjectPatientList.Select(t => new PatientBasicInfo() -// //{ -// // PatientId = t.PatientId, -// // PatientAge = t.Patient.PatientAge, -// // PatientBirthDate = t.Patient.PatientBirthDate, -// // PatientIdStr = t.Patient.PatientIdStr, -// // PatientSex = t.Patient.PatientSex, -// //}).ToList(), - - -// SubmitState = scpStudySV.SubjectVisit.SubmitState, -// SubmitTime = scpStudySV.SubjectVisit.SubmitTime, -// VisitName = scpStudySV.SubjectVisit.VisitName, -// VisitNum = scpStudySV.SubjectVisit.VisitNum, -// SubjectVisitId = scpStudySV.SubjectVisit.Id, -// VisitEarliestStudyTime = scpStudySV.SubjectVisit.SCPStudySubjectVisitList.Min(t => t.SCPStudy.StudyTime), -// VisitLatestStudyTime = scpStudySV.SubjectVisit.SCPStudySubjectVisitList.Max(t => t.SCPStudy.StudyTime), - -// StudyId = scpStudy.Id, -// StudyTime = scpStudy.StudyTime, -// CallingAE = scpStudy.CallingAE, -// CalledAE = scpStudy.CalledAE, -// Description = scpStudy.Description, -// InstanceCount = scpStudy.InstanceCount, -// Modalities = scpStudy.Modalities, -// ModalityForEdit = scpStudy.ModalityForEdit, -// SeriesCount = scpStudy.SeriesCount - -// }; - -// var defalutSortArray = new string[] { nameof(PatientStudyBeforeConfirmView.SubjectCode), nameof(PatientStudyBeforeConfirmView.VisitNum), nameof(PatientStudyBeforeConfirmView.StudyTime) }; -// var pageList = await query.ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, inQuery.SortField, inQuery.Asc, string.IsNullOrWhiteSpace(inQuery.SortField), defalutSortArray); - - - -// return ResponseOutput.Ok(pageList); -// } - - -// /// -// ///检查管理-> 检查列表 (同步影像数据之后的 带患者信息 患者信息是数组) -// /// -// /// -// /// -// [HttpPost] -// public async Task>> GetTrialPatientStudyList(TrialPatientStudyQuery inQuery) -// { -// var query = _repository.Where(t => t.SubjectVisit.TrialId == inQuery.TrialId) -// .WhereIf(!string.IsNullOrWhiteSpace(inQuery.SubjectCode), u => u.SubjectVisit.Subject.Code.Contains(inQuery.SubjectCode)) -// .WhereIf(!string.IsNullOrWhiteSpace(inQuery.PatientIdStr), u => u.PatientIdStr.Contains(inQuery.PatientIdStr)) -// .WhereIf(!string.IsNullOrWhiteSpace(inQuery.PatientSex), t => t.PatientSex.Contains(inQuery.PatientSex)) -// .WhereIf(inQuery.SubjectAge != null, t => t.SubjectVisit.Subject.Age == inQuery.SubjectAge) -// .WhereIf(!string.IsNullOrWhiteSpace(inQuery.SubjectCode), u => u.SubjectVisit.Subject.Code.Contains(inQuery.SubjectCode)) -// .WhereIf(!string.IsNullOrWhiteSpace(inQuery.SubjectSex), u => u.SubjectVisit.Subject.Sex.Contains(inQuery.SubjectSex)) -// .WhereIf(!string.IsNullOrWhiteSpace(inQuery.SubjectShortName), t => t.SubjectVisit.Subject.ShortName.Contains(inQuery.SubjectShortName)) -// .WhereIf(inQuery.BeginStudyTime != null, t => t.StudyTime >= inQuery.BeginStudyTime) -// .WhereIf(inQuery.EndStudyTime != null, t => t.StudyTime <= inQuery.EndStudyTime) -// .Select(t => new PatientStudyView() -// { -// SubjectId = t.SubjectVisit.SubjectId, -// SubjectAge = t.Subject.Age, -// SubjectSex = t.Subject.Sex, -// SubjectShortName = t.Subject.ShortName, - - -// //PatientId = Guid.Empty, -// PatientAge = t.PatientAge, -// PatientName = t.PatientName, -// PatientBirthDate = t.PatientBirthDate, -// PatientIdStr = t.PatientIdStr, -// PatientSex = t.PatientSex, - -// //PatientList = t.Subject.SubjectPatientList.Select(t => new PatientBasicInfo() -// //{ -// // PatientId = t.PatientId, -// // PatientAge = t.Patient.PatientAge, -// // PatientBirthDate = t.Patient.PatientBirthDate, -// // PatientIdStr = t.Patient.PatientIdStr, -// // PatientSex = t.Patient.PatientSex, -// //}).ToList(), - -// Modalities = t.Modalities, -// ModalityForEdit = t.ModalityForEdit, -// SubjectCode = t.SubjectVisit.Subject.Code, -// SubmitState = t.SubjectVisit.SubmitState, -// SubmitTime = t.SubjectVisit.SubmitTime, -// VisitName = t.SubjectVisit.VisitName, -// VisitNum = t.SubjectVisit.VisitNum, -// SubjectVisitId = t.SubjectVisitId, -// VisitEarliestStudyTime = t.SubjectVisit.StudyList.Min(t => t.StudyTime), -// VisitLatestStudyTime = t.SubjectVisit.StudyList.Max(t => t.StudyTime), - -// StudyId = t.Id, -// StudyTime = t.StudyTime, -// Description = t.Description, -// SeriesCount = t.SeriesCount, -// InstanceCount = t.InstanceCount, -// }); - -// var defalutSortArray = new string[] { nameof(PatientStudyView.SubjectCode), nameof(PatientStudyView.VisitNum), nameof(PatientStudyView.StudyTime) }; - -// var pageList = await query.ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, inQuery.SortField, inQuery.Asc, string.IsNullOrWhiteSpace(inQuery.SortField), defalutSortArray); - - -// return ResponseOutput.Ok(pageList); -// } - - - -// /// -// /// 获取该项目 患者已绑定subject ,新来了的检查 可能需要新建访视 但是新增的检查未绑定访视的检查列表 -// /// -// /// -// /// -// [HttpPost] -// public async Task>> GetTrialUnbindSubjectVisitStudyList(TrialPatientStudyQuery inQuery) -// { -// //属于该项目的已绑定患者的检查,同时没有绑定任何访视 -// var query = from scpStudy in _studyRepository.Where(t => !t.SCPStudySubjectVisitList.Any(t => t.TrialId == inQuery.TrialId)) -// .WhereIf(!string.IsNullOrWhiteSpace(inQuery.PatientSex), t => t.Patient.PatientSex.Contains(inQuery.PatientSex)) -// .WhereIf(!string.IsNullOrWhiteSpace(inQuery.PatientIdStr), u => u.Patient.PatientIdStr.Contains(inQuery.PatientIdStr)) -// .WhereIf(inQuery.BeginStudyTime != null, t => t.StudyTime >= inQuery.BeginStudyTime) -// .WhereIf(inQuery.EndStudyTime != null, t => t.StudyTime <= inQuery.EndStudyTime) -// join subjectPatient in _subjectPatientRepository.Where(t => t.Subject.TrialId == inQuery.TrialId) -// .WhereIf(!string.IsNullOrWhiteSpace(inQuery.SubjectCode), u => u.Subject.Code.Contains(inQuery.SubjectCode)) -// .WhereIf(!string.IsNullOrWhiteSpace(inQuery.SubjectSex), u => u.Subject.Sex.Contains(inQuery.SubjectSex)) -// .WhereIf(!string.IsNullOrWhiteSpace(inQuery.SubjectShortName), t => t.Subject.ShortName.Contains(inQuery.SubjectShortName)) -// on scpStudy.PatientId equals subjectPatient.PatientId -// join scpStudySubjectVisit in _studySubjectVisitRepository.AsQueryable() on scpStudy.Id equals scpStudySubjectVisit.SCPStudyId -// into dd -// from scpStudySV in dd.DefaultIfEmpty() -// select new UnbindStudyView() -// { -// PatientIdStr = scpStudy.PatientIdStr, -// PatientBirthDate = scpStudy.PatientBirthDate, -// PatientAge = scpStudy.PatientAge, -// PatientName = scpStudy.PatientName, -// PatientSex = scpStudy.PatientSex, -// Description = scpStudy.Description, -// CalledAE = scpStudy.CalledAE, -// InstanceCount = scpStudy.InstanceCount, -// Modalities = scpStudy.Modalities, -// PatientId = scpStudy.PatientId, -// SCPStudyId = scpStudy.Id, -// SeriesCount = scpStudy.SeriesCount, -// StudyTime = scpStudy.StudyTime, - -// SubjectVisitId = scpStudySV.SubjectVisitId, -// VisitName = scpStudySV.SubjectVisit.VisitName, - -// SubjectId = subjectPatient.SubjectId, -// SubjectCode = subjectPatient.Subject.Code, -// TrialId = subjectPatient.Subject.TrialId, -// SubjectAge = subjectPatient.Subject.Age, -// SubjectSex = subjectPatient.Subject.Sex, -// SubjectShortName = subjectPatient.Subject.ShortName, -// SubjectBirthDate = subjectPatient.Subject.BirthDate -// }; - -// #region 废弃 -// //var query = from subject in _subjectRepository.Where(t => t.TrialId == inQuery.TrialId) -// // .WhereIf(inQuery.SubjectAge != null, t => t.Age == inQuery.SubjectAge) -// // .WhereIf(!string.IsNullOrWhiteSpace(inQuery.SubjectCode), u => u.Code.Contains(inQuery.SubjectCode)) -// // .WhereIf(!string.IsNullOrWhiteSpace(inQuery.SubjectSex), u => u.Sex.Contains(inQuery.SubjectSex)) -// // .WhereIf(!string.IsNullOrWhiteSpace(inQuery.SubjectShortName), t => t.ShortName.Contains(inQuery.SubjectShortName)) -// // join subjectPatient in _subjectPatientRepository.AsQueryable() on subject.Id equals subjectPatient.PatientId -// // //没有绑定任何访视 -// // join scpStudy in _studyRepository.AsQueryable() -// // .WhereIf(!string.IsNullOrWhiteSpace(inQuery.PatientSex), t => t.Patient.PatientSex.Contains(inQuery.PatientSex)) -// // .WhereIf(!string.IsNullOrWhiteSpace(inQuery.PatientIdStr), u => u.Patient.PatientIdStr.Contains(inQuery.PatientIdStr)) -// // .WhereIf(inQuery.BeginStudyTime != null, t => t.StudyTime >= inQuery.BeginStudyTime) -// // .WhereIf(inQuery.EndStudyTime != null, t => t.StudyTime <= inQuery.EndStudyTime) -// // on subjectPatient.PatientId equals scpStudy.PatientId -// // select new SubjectPatientStudyView() -// // { -// // SubjectId = subject.Id, -// // SubjectAge = subject.Age, -// // SubjectSex = subject.Sex, -// // SubjectShortName = subject.ShortName, - -// // PatientList = subject.SubjectPatientList.Select(t => new PatientBasicInfo() -// // { -// // PatientId = t.PatientId, -// // PatientAge = t.Patient.PatientAge, -// // PatientBirthDate = t.Patient.PatientBirthDate, -// // PatientIdStr = t.Patient.PatientIdStr, -// // PatientSex = t.Patient.PatientSex, -// // }).ToList(), - -// // SubjectCode = subject.Code, - -// // SeriesCount = scpStudy.SeriesCount, -// // CalledAE = scpStudy.CalledAE, -// // InstanceCount = scpStudy.InstanceCount, -// // Description = scpStudy.Description, -// // Modalities = scpStudy.Modalities, -// // PatientId = scpStudy.PatientId, - -// // SCPStudyId = scpStudy.Id, -// // StudyTime = scpStudy.StudyTime - -// // }; -// #endregion - - - - - - -// var pageList = await query.ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, inQuery.SortField == string.Empty ? nameof(UnbindStudyView.StudyTime) : inQuery.SortField, inQuery.Asc); - - -// return ResponseOutput.Ok(pageList); -// } - -// /// -// /// 删除某个项目 未提交的访视检查绑定, 清理数据,方便测试自动绑定 -// /// -// /// -// /// -// [HttpDelete] -// public async Task DeleteUnSubmittedStudyBind(Guid trialId, Guid? subjectId, -// [FromServices] IRepository _visitTaskRepository, -// [FromServices] IRepository _dicomStudyRepository, -// [FromServices] IRepository _dicomSeriesRepository, -// [FromServices] IRepository _dicomInstanceRepository) -// { -// if (subjectId != null) -// { -// await _studySubjectVisitRepository.BatchDeleteNoTrackingAsync(t => t.TrialId == trialId && t.SubjectId == subjectId); - -// await _subjectVisitRepository.BatchDeleteNoTrackingAsync(t => t.SubjectId == subjectId); - -// await _visitTaskRepository.BatchDeleteNoTrackingAsync(t => t.SubjectId == subjectId); - -// await _dicomStudyRepository.BatchDeleteNoTrackingAsync(t => t.SubjectId == subjectId); -// await _dicomSeriesRepository.BatchDeleteNoTrackingAsync(t => t.SubjectId == subjectId); -// await _dicomInstanceRepository.BatchDeleteNoTrackingAsync(t => t.SubjectId == subjectId); - -// } -// else -// { -// await _studySubjectVisitRepository.BatchDeleteNoTrackingAsync(t => t.TrialId == trialId && t.SubjectVisit.SubmitState != SubmitStateEnum.Submitted); - -// } - - -// return ResponseOutput.Ok(); -// } - - -// /// -// /// 阅片管理-> 任务列表 -// /// -// /// -// /// -// [HttpPost] -// public async Task>> GetPatientVisitTaskList([FromServices] IRepository _visitTaskRepository, PatientVisitTaskQuery inQuery) -// { -// var visitTaskQueryable = _visitTaskRepository.Where(t => t.TrialId == inQuery.TrialId && t.IsAnalysisCreate == false) -// .WhereIf(inQuery.ReadingCategory != null, t => t.ReadingCategory == inQuery.ReadingCategory) -// .WhereIf(inQuery.ReadingCategory == null, t => t.ReadingCategory != ReadingCategory.Judge) - -// .WhereIf(inQuery.ReadingTaskState != null, t => t.ReadingTaskState == inQuery.ReadingTaskState) -// .WhereIf(inQuery.TaskState != null, t => t.TaskState == inQuery.TaskState) -// .WhereIf(inQuery.SubjectId != null, t => t.SubjectId == inQuery.SubjectId) -// .WhereIf(inQuery.DoctorUserId != null, t => t.DoctorUserId == inQuery.DoctorUserId) -// .WhereIf(inQuery.TrialReadingCriterionId != null, t => t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId) - -// .WhereIf(!string.IsNullOrEmpty(inQuery.TaskName), t => t.TaskName.Contains(inQuery.TaskName) || t.TaskBlindName.Contains(inQuery.TaskName)) -// .WhereIf(inQuery.BeginSignTime != null, t => t.SignTime >= inQuery.BeginSignTime) -// .WhereIf(inQuery.EndSignTime != null, t => t.SignTime <= inQuery.EndSignTime) - -// .WhereIf(inQuery.BeginTaskCreateTime != null, t => t.CreateTime >= inQuery.BeginTaskCreateTime) -// .WhereIf(inQuery.EndTaskCreateTime != null, t => t.CreateTime <= inQuery.EndTaskCreateTime) - -// .WhereIf(!string.IsNullOrWhiteSpace(inQuery.PatientIdStr), t => t.Subject.SubjectPatientList.Any(t => t.Patient.PatientIdStr.Contains(inQuery.PatientIdStr))) -// .WhereIf(!string.IsNullOrWhiteSpace(inQuery.PatientName), t => t.Subject.SubjectPatientList.Any(t => t.Patient.PatientName.Contains(inQuery.PatientName))) -// .WhereIf(!string.IsNullOrWhiteSpace(inQuery.PatientSex), t => t.Subject.SubjectPatientList.Any(t => t.Patient.PatientSex.Contains(inQuery.PatientSex))) -// .WhereIf(!string.IsNullOrEmpty(inQuery.SubjectShortName), t => t.Subject.ShortName.Contains(inQuery.SubjectShortName)) -// .WhereIf(!string.IsNullOrEmpty(inQuery.SubjectCode), t => (t.Subject.Code.Contains(inQuery.SubjectCode) && t.IsAnalysisCreate == false) || (t.BlindSubjectCode.Contains(inQuery.SubjectCode) && t.IsAnalysisCreate)) -// .ProjectTo(_mapper.ConfigurationProvider); - -// var defalutSortArray = new string[] { nameof(PatientVisitTaskDTO.SubjectId), nameof(PatientVisitTaskDTO.VisitTaskNum) }; - -// var pageList = await visitTaskQueryable.ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, inQuery.SortField, inQuery.Asc, string.IsNullOrWhiteSpace(inQuery.SortField), defalutSortArray); - -// return ResponseOutput.Ok(pageList); -// } - - -// #endregion - - - - - -// /// -// /// scp 影像推送记录表 -// /// -// /// -// /// -// [HttpPost] -// public async Task>> GetSCPImageUploadList(SCPImageUploadQuery inQuery) -// { -// var query = _repository.Where() -// .WhereIf(!string.IsNullOrWhiteSpace(inQuery.CalledAE), t => t.CalledAE.Contains(inQuery.CalledAE)) -// .WhereIf(!string.IsNullOrWhiteSpace(inQuery.CallingAEIP), t => t.CallingAEIP.Contains(inQuery.CallingAEIP)) -// .WhereIf(!string.IsNullOrWhiteSpace(inQuery.CallingAE), t => t.CallingAE.Contains(inQuery.CallingAE)) -// .WhereIf(inQuery.StartTime != null, t => t.StartTime >= inQuery.StartTime) -// .WhereIf(inQuery.EndTime != null, t => t.EndTime <= inQuery.EndTime) - -// .ProjectTo(_mapper.ConfigurationProvider); - - -// var pageList = await query.ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, inQuery.SortField == string.Empty ? nameof(SCPImageUploadView.CallingAE) : inQuery.SortField, inQuery.Asc); - - -// return ResponseOutput.Ok(pageList); -// } - - - - -// } - - - -//} +} diff --git a/IRaCIS.Core.Application/Service/Visit/_MapConfig.cs b/IRaCIS.Core.Application/Service/Visit/_MapConfig.cs index 35a01056d..717c22d8e 100644 --- a/IRaCIS.Core.Application/Service/Visit/_MapConfig.cs +++ b/IRaCIS.Core.Application/Service/Visit/_MapConfig.cs @@ -112,6 +112,14 @@ namespace IRaCIS.Core.Application.Service .ForMember(d => d.InstanceInfoList, u => u.MapFrom(s => s.InstanceList)); CreateMap(); + + + CreateMap() + .ForMember(d => d.TrialSiteCode, u => u.MapFrom(s => s.TrialSite.TrialSiteCode)) + .ForMember(d => d.TrialSiteAliasName, u => u.MapFrom(s => s.TrialSite.TrialSiteAliasName)) + .ForMember(d => d.TrialSiteName, u => u.MapFrom(s => s.TrialSite.TrialSiteName)) +; + } } diff --git a/IRaCIS.Core.Domain/Image/DicomStudy.cs b/IRaCIS.Core.Domain/Image/DicomStudy.cs index e5193846b..b0d6526b5 100644 --- a/IRaCIS.Core.Domain/Image/DicomStudy.cs +++ b/IRaCIS.Core.Domain/Image/DicomStudy.cs @@ -99,5 +99,8 @@ namespace IRaCIS.Core.Domain.Models public Guid? DeleteUserId { get; set; } + public bool IsFromPACS { get; set; } + + } } diff --git a/IRaCIS.Core.Domain/Image/SCPImageUpload.cs b/IRaCIS.Core.Domain/Image/SCPImageUpload.cs index a2982fba0..10e6b4ef0 100644 --- a/IRaCIS.Core.Domain/Image/SCPImageUpload.cs +++ b/IRaCIS.Core.Domain/Image/SCPImageUpload.cs @@ -55,6 +55,19 @@ namespace IRaCIS.Core.Domain.Models public int StudyCount { get; set; } + + + + public Guid TrialId { get; set; } + public Guid TrialSiteId { get; set; } + + [JsonIgnore] + + public Trial Trial { get; set; } + + [JsonIgnore] + public TrialSite TrialSite { get; set; } + } diff --git a/IRaCIS.Core.Domain/Image/SCPPatient.cs b/IRaCIS.Core.Domain/Image/SCPPatient.cs index 21eda7f87..0c75de6d4 100644 --- a/IRaCIS.Core.Domain/Image/SCPPatient.cs +++ b/IRaCIS.Core.Domain/Image/SCPPatient.cs @@ -29,9 +29,17 @@ namespace IRaCIS.Core.Domain.Models public DateTime LatestPushTime { get; set; } + public Guid? SubjectId { get; set; } + public Guid TrialId { get; set; } + public Guid TrialSiteId { get; set; } + + [JsonIgnore] public Subject Subject { get; set; } - public Guid? SubjectId { get; set; } + [JsonIgnore] + public Trial Trial { get; set; } + [JsonIgnore] + public TrialSite TrialSite { get; set; } } } diff --git a/IRaCIS.Core.Domain/Image/SCPStudy.cs b/IRaCIS.Core.Domain/Image/SCPStudy.cs index c78222617..4af3686cd 100644 --- a/IRaCIS.Core.Domain/Image/SCPStudy.cs +++ b/IRaCIS.Core.Domain/Image/SCPStudy.cs @@ -84,12 +84,20 @@ namespace IRaCIS.Core.Domain.Models public bool IsUploadFinished { get; set; } - + public Guid TrialId { get; set; } + public Guid TrialSiteId { get; set; } public Guid? SubjectVisitId { get; set; } [JsonIgnore] public SubjectVisit SubjectVisit { get; set; } + [JsonIgnore] + + public Trial Trial { get; set; } + + [JsonIgnore] + public TrialSite TrialSite { get; set; } + } } From 6264d105abd470caddd7d131349d940c41f2d405 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Thu, 4 Jul 2024 17:22:54 +0800 Subject: [PATCH 041/251] =?UTF-8?q?=E6=B5=8F=E8=A7=88=E5=99=A8=E6=8E=A8?= =?UTF-8?q?=E8=8D=90=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Service/Common/DTO/ExploreRecommendViewModel.cs | 4 +++- .../Service/Common/ExploreRecommendService.cs | 4 ++-- IRaCIS.Core.Domain/Common/ExploreRecommend.cs | 6 ++++-- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/IRaCIS.Core.Application/Service/Common/DTO/ExploreRecommendViewModel.cs b/IRaCIS.Core.Application/Service/Common/DTO/ExploreRecommendViewModel.cs index 382271cf1..c61cb31a8 100644 --- a/IRaCIS.Core.Application/Service/Common/DTO/ExploreRecommendViewModel.cs +++ b/IRaCIS.Core.Application/Service/Common/DTO/ExploreRecommendViewModel.cs @@ -43,7 +43,9 @@ namespace IRaCIS.Core.Application.ViewModel /// ExploreRecommendAddOrEdit 列表查询参数模型 public class ExploreRecommendAddOrEdit { - public Guid Id { get; set; } + public Guid? Id { get; set; } + public string ExploreType { get; set; } + public string Version { get; set; } public string Title { get; set; } diff --git a/IRaCIS.Core.Application/Service/Common/ExploreRecommendService.cs b/IRaCIS.Core.Application/Service/Common/ExploreRecommendService.cs index b67c4f25f..17f314441 100644 --- a/IRaCIS.Core.Application/Service/Common/ExploreRecommendService.cs +++ b/IRaCIS.Core.Application/Service/Common/ExploreRecommendService.cs @@ -51,9 +51,9 @@ namespace IRaCIS.Core.Application.Service { var verifyExp2 = new EntityVerifyExp() { - VerifyExp = u => u.IsDeleted == addOrEditExploreRecommend.IsDeleted, + VerifyExp = u => u.IsDeleted == addOrEditExploreRecommend.IsDeleted && u.ExploreType == addOrEditExploreRecommend.ExploreType, - VerifyMsg = "当前启用版本只允许有一个", + VerifyMsg = "当前浏览器启用版本只允许有一个", IsVerify = addOrEditExploreRecommend.IsDeleted == false }; diff --git a/IRaCIS.Core.Domain/Common/ExploreRecommend.cs b/IRaCIS.Core.Domain/Common/ExploreRecommend.cs index db000e174..b58cd06b5 100644 --- a/IRaCIS.Core.Domain/Common/ExploreRecommend.cs +++ b/IRaCIS.Core.Domain/Common/ExploreRecommend.cs @@ -15,8 +15,10 @@ namespace IRaCIS.Core.Domain.Models [Table("ExploreRecommend")] public class ExploreRecommend : Entity, IAuditUpdate, IAuditAdd,ISoftDelete { - - public string Version { get; set; }=string.Empty; + public string ExploreType { get; set; } = string.Empty; + + + public string Version { get; set; }=string.Empty; public string Title { get; set; } = string.Empty; From 933a43f4eaadc8667328052552105e7cb37a9f02 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Thu, 4 Jul 2024 17:24:29 +0800 Subject: [PATCH 042/251] =?UTF-8?q?=E8=BF=94=E5=9B=9E=E6=8E=A8=E8=8D=90?= =?UTF-8?q?=E7=9A=84=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Service/Common/ExploreRecommendService.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/IRaCIS.Core.Application/Service/Common/ExploreRecommendService.cs b/IRaCIS.Core.Application/Service/Common/ExploreRecommendService.cs index 17f314441..163b211a1 100644 --- a/IRaCIS.Core.Application/Service/Common/ExploreRecommendService.cs +++ b/IRaCIS.Core.Application/Service/Common/ExploreRecommendService.cs @@ -73,13 +73,13 @@ namespace IRaCIS.Core.Application.Service } [AllowAnonymous] - public async Task GetExploreRecommentInfo() + public async Task > GetExploreRecommentInfo() { - var result = await _exploreRecommendRepository.Where(t => t.IsDeleted == false).ProjectTo(_mapper.ConfigurationProvider).FirstOrDefaultAsync(); + var result = await _exploreRecommendRepository.Where(t => t.IsDeleted == false).ProjectTo(_mapper.ConfigurationProvider).ToListAsync(); - if (result == null) + if (result .Count==0) { throw new QueryBusinessObjectNotExistException("系统浏览器版本推荐未维护,请联系维护人员"); } From 213787bbcf089459cde8865d5b9575b3f5e41c7f Mon Sep 17 00:00:00 2001 From: he <109787524@qq.com> Date: Wed, 3 Jul 2024 15:15:46 +0800 Subject: [PATCH 043/251] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Reading/Dto/ReadingImageTaskViewModel.cs | 9 ++++++++ .../ReadingImageTaskService.cs | 21 ++++++++++++++++++- 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/IRaCIS.Core.Application/Service/Reading/Dto/ReadingImageTaskViewModel.cs b/IRaCIS.Core.Application/Service/Reading/Dto/ReadingImageTaskViewModel.cs index 61597b830..d0288c364 100644 --- a/IRaCIS.Core.Application/Service/Reading/Dto/ReadingImageTaskViewModel.cs +++ b/IRaCIS.Core.Application/Service/Reading/Dto/ReadingImageTaskViewModel.cs @@ -1696,6 +1696,15 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto } + public class ResetReadingTaskOutDto + { + + } + + public class ResetReadingTaskInDto + { + public Guid VisitTaskId { get; set; } + } public class GetNextTaskInDto { diff --git a/IRaCIS.Core.Application/Service/Reading/ReadingImageTask/ReadingImageTaskService.cs b/IRaCIS.Core.Application/Service/Reading/ReadingImageTask/ReadingImageTaskService.cs index 3eb6fc091..660370dd1 100644 --- a/IRaCIS.Core.Application/Service/Reading/ReadingImageTask/ReadingImageTaskService.cs +++ b/IRaCIS.Core.Application/Service/Reading/ReadingImageTask/ReadingImageTaskService.cs @@ -2947,6 +2947,25 @@ namespace IRaCIS.Application.Services return task; } + + + /// + /// 重置阅片任务 + /// + /// + /// + [HttpPost] + public async Task ResetReadingTask(ResetReadingTaskInDto inDto) + { + await VerifyTaskIsSign(inDto.VisitTaskId); + var taskinfo = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).FirstNotNullAsync(); + if (taskinfo.ReadingCategory != ReadingCategory.Visit) + { + + } + + return new ResetReadingTaskOutDto() { }; + } /// /// 验证阅片休息时间 /// @@ -2954,7 +2973,7 @@ namespace IRaCIS.Application.Services [HttpPost] public async Task VerifyReadingRestTime() { - var userTypeEnum = (UserTypeEnum)_userInfo.UserTypeEnumInt; + var userTypeEnum = (UserTypeEnum)_userInfo.UserTypeEnumInt; if (userTypeEnum != UserTypeEnum.IndependentReviewer) { return; From 31d22e2b4f1bfa2466f337af71a4e0955a77ce3f Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Thu, 4 Jul 2024 14:31:50 +0800 Subject: [PATCH 044/251] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E7=BE=8E=E5=9B=BD?= =?UTF-8?q?=E7=94=9F=E4=BA=A7=E7=8E=AF=E5=A2=83=E9=85=8D=E7=BD=AE=E6=96=87?= =?UTF-8?q?=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.API/appsettings.US_Prod_IRC.json | 74 ++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 IRaCIS.Core.API/appsettings.US_Prod_IRC.json diff --git a/IRaCIS.Core.API/appsettings.US_Prod_IRC.json b/IRaCIS.Core.API/appsettings.US_Prod_IRC.json new file mode 100644 index 000000000..ff75d90b9 --- /dev/null +++ b/IRaCIS.Core.API/appsettings.US_Prod_IRC.json @@ -0,0 +1,74 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft": "Warning", + "Microsoft.Hosting.Lifetime": "Information" + } + }, + "ConnectionStrings": { + "RemoteNew": "Server=us-prod-mssql-service,1433;Database=US_IRC;User ID=sa;Password=xc@123456;TrustServerCertificate=true", + "Hangfire": "Server=us-prod-mssql-service,1433;Database=US_IRC_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true" + }, + + "ObjectStoreService": { + "ObjectStoreUse": "AWS", + "AliyunOSS": { + "regionId": "cn-shanghai", + "endPoint": "https://oss-cn-shanghai.aliyuncs.com", + "accessKeyId": "", + "accessKeySecret": "", + "bucketName": "zy-irc-test-store", + "roleArn": "acs:ram::1899121822495495:role/oss-upload", + "viewEndpoint": "https://zy-irc-test-store.oss-cn-shanghai.aliyuncs.com", + "region": "oss-cn-shanghai" + }, + + "MinIO": { + "endPoint": "192.168.3.68", + "port": "8001", + "useSSL": false, + "accessKey": "IDFkwEpWej0b4DtiuThL", + "secretKey": "Lhuu83yMhVwu7c1SnjvGY6lq74jzpYqifK6Qtj4h", + "bucketName": "test", + "viewEndpoint": "http://192.168.3.68:8001/test/" + }, + + "AWS": { + "endPoint": "s3.us-east-1.amazonaws.com", + "useSSL": true, + "accessKey": "AKIAW3MEAFJX5P32P6NA", + "secretKey": "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", + "bucketName": "ei-med-s3-lili-store", + "viewEndpoint": "https://ei-med-s3-lili-store.s3.amazonaws.com/" + } + }, + "BasicSystemConfig": { + + "OpenUserComplexPassword": false, + + "OpenSignDocumentBeforeWork": false, + + "OpenTrialRelationDelete": true, + + "OpenLoginLimit": false, + + "LoginMaxFailCount": 5, + + "LoginFailLockMinutes": 30, + "AutoLoginOutMinutes": 60 + }, + + "SystemEmailSendConfig": { + "Port": 465, + "Host": "smtp.qiye.aliyun.com", + "FromEmail": "test@extimaging.com", + "FromName": "Test_IRC", + "AuthorizationCode": "SHzyyl2021", + "CompanyName": "Elevate Imaging", + "CompanyNameCN": "上海展影医疗科技有限公司", + "CompanyShortName": "Elevate Imaging", + "CompanyShortNameCN": "展影医疗" + } + +} From b1be0e2a984b17b812d86a50a593587f7c5179f4 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Fri, 5 Jul 2024 09:07:57 +0800 Subject: [PATCH 045/251] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.API/appsettings.US_Prod_IRC.json | 2 ++ IRaCIS.Core.Application/IRaCIS.Core.Application.xml | 7 +++++++ 2 files changed, 9 insertions(+) diff --git a/IRaCIS.Core.API/appsettings.US_Prod_IRC.json b/IRaCIS.Core.API/appsettings.US_Prod_IRC.json index ff75d90b9..ceeb34e5f 100644 --- a/IRaCIS.Core.API/appsettings.US_Prod_IRC.json +++ b/IRaCIS.Core.API/appsettings.US_Prod_IRC.json @@ -9,6 +9,8 @@ "ConnectionStrings": { "RemoteNew": "Server=us-prod-mssql-service,1433;Database=US_IRC;User ID=sa;Password=xc@123456;TrustServerCertificate=true", "Hangfire": "Server=us-prod-mssql-service,1433;Database=US_IRC_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true" + //"RemoteNew": "Server=44.210.231.169,1435;Database=US_IRC;User ID=sa;Password=xc@123456;TrustServerCertificate=true", + //"Hangfire": "Server=44.210.231.169,1435;Database=US_IRC_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true", }, "ObjectStoreService": { diff --git a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml index ebd172a4c..4a3b09d4b 100644 --- a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml +++ b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml @@ -14634,6 +14634,13 @@ + + + 重置阅片任务 + + + + 验证阅片休息时间 From c6531e924988339524a025b53a7c8b054b1ee547 Mon Sep 17 00:00:00 2001 From: he <109787524@qq.com> Date: Fri, 5 Jul 2024 10:00:35 +0800 Subject: [PATCH 046/251] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ReadingImageTaskService.cs | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/IRaCIS.Core.Application/Service/Reading/ReadingImageTask/ReadingImageTaskService.cs b/IRaCIS.Core.Application/Service/Reading/ReadingImageTask/ReadingImageTaskService.cs index 660370dd1..1792d4f92 100644 --- a/IRaCIS.Core.Application/Service/Reading/ReadingImageTask/ReadingImageTaskService.cs +++ b/IRaCIS.Core.Application/Service/Reading/ReadingImageTask/ReadingImageTaskService.cs @@ -21,6 +21,7 @@ using IRaCIS.Core.Application.Service.ReadingCalculate.Interface; using AutoMapper.QueryableExtensions; using IRaCIS.Application.Contracts; using IRaCIS.Core.Domain.Models; +using static Microsoft.EntityFrameworkCore.DbLoggerCategory; namespace IRaCIS.Application.Services { @@ -2961,9 +2962,24 @@ namespace IRaCIS.Application.Services var taskinfo = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).FirstNotNullAsync(); if (taskinfo.ReadingCategory != ReadingCategory.Visit) { - + throw new BusinessValidationFailedException(_localizer["ReadingImage_CannotReset"]); } + await _readingTableAnswerRowInfoRepository.BatchDeleteNoTrackingAsync(x => x.VisitTaskId == inDto.VisitTaskId); + await _readingTaskQuestionAnswerRepository.BatchDeleteNoTrackingAsync(x => x.VisitTaskId == inDto.VisitTaskId); + await _readingTableQuestionAnswerRepository.BatchDeleteNoTrackingAsync(x => x.VisitTaskId == inDto.VisitTaskId); + await _readingTaskQuestionMarkRepository.BatchDeleteNoTrackingAsync(x => x.VisitTaskId == inDto.VisitTaskId); + await _readingCustomTagRepository.BatchDeleteNoTrackingAsync(x => x.VisitTaskId == inDto.VisitTaskId); + await _visitTaskRepository.UpdatePartialFromQueryAsync(x => x.Id == inDto.VisitTaskId, x => new VisitTask() + { + ReadingTaskState = ReadingTaskState.WaitReading + }); + await _visitTaskRepository.SaveChangesAsync(); + await _readingCalculateService.AddTaskLesionAnswerFromLastTask(new AddTaskLesionAnswerFromLastTaskInDto() + { + VisitTaskId = inDto.VisitTaskId + }); + await AddDefaultValueToTask(inDto.VisitTaskId); return new ResetReadingTaskOutDto() { }; } /// From 643574666052b383cba6b6e9748b33f95e9b574c Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Fri, 5 Jul 2024 10:24:11 +0800 Subject: [PATCH 047/251] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.API/appsettings.Prod_IRC.json | 2 +- IRaCIS.Core.API/appsettings.Test_IRC.json | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/IRaCIS.Core.API/appsettings.Prod_IRC.json b/IRaCIS.Core.API/appsettings.Prod_IRC.json index 257d517e3..fdd20e47a 100644 --- a/IRaCIS.Core.API/appsettings.Prod_IRC.json +++ b/IRaCIS.Core.API/appsettings.Prod_IRC.json @@ -42,7 +42,7 @@ "LoginMaxFailCount": 5, "LoginFailLockMinutes": 30, - "AutoLoginOutMinutes": 60, + "AutoLoginOutMinutes": 120, "OpenLoginMFA": false diff --git a/IRaCIS.Core.API/appsettings.Test_IRC.json b/IRaCIS.Core.API/appsettings.Test_IRC.json index 44e6a76ad..9ef5c0ff1 100644 --- a/IRaCIS.Core.API/appsettings.Test_IRC.json +++ b/IRaCIS.Core.API/appsettings.Test_IRC.json @@ -9,7 +9,6 @@ "ConnectionStrings": { "RemoteNew": "Server=106.14.89.110,1435;Database=Test_IRC;User ID=sa;Password=xc@123456;TrustServerCertificate=true", "Hangfire": "Server=106.14.89.110,1435;Database=Test_IRC_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true" - }, "ObjectStoreService": { @@ -35,7 +34,6 @@ "bucketName": "irc-test", "viewEndpoint": "https://hir-oss.test.extimaging.com/irc-test" }, - "AWS": { "endPoint": "s3.us-east-1.amazonaws.com", "useSSL": true, From c32ec2f1321a72f7c31cf5f4702ce360c7e85c1c Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Mon, 8 Jul 2024 11:38:47 +0800 Subject: [PATCH 048/251] =?UTF-8?q?=E7=BE=8E=E5=9B=BD=E9=AA=8C=E8=AF=81?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E9=85=8D=E7=BD=AE=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.API/appsettings.Prod_IRC.json | 2 +- IRaCIS.Core.API/appsettings.US_Prod_IRC.json | 12 +-- IRaCIS.Core.API/appsettings.US_Test_IRC.json | 82 +++++++++++++++++++ ...S_IRC.json => appsettings.US_Uat_IRC.json} | 21 +++-- 4 files changed, 103 insertions(+), 14 deletions(-) create mode 100644 IRaCIS.Core.API/appsettings.US_Test_IRC.json rename IRaCIS.Core.API/{appsettings.US_IRC.json => appsettings.US_Uat_IRC.json} (82%) diff --git a/IRaCIS.Core.API/appsettings.Prod_IRC.json b/IRaCIS.Core.API/appsettings.Prod_IRC.json index fdd20e47a..7d6013b68 100644 --- a/IRaCIS.Core.API/appsettings.Prod_IRC.json +++ b/IRaCIS.Core.API/appsettings.Prod_IRC.json @@ -42,7 +42,7 @@ "LoginMaxFailCount": 5, "LoginFailLockMinutes": 30, - "AutoLoginOutMinutes": 120, + "AutoLoginOutMinutes": 360, "OpenLoginMFA": false diff --git a/IRaCIS.Core.API/appsettings.US_Prod_IRC.json b/IRaCIS.Core.API/appsettings.US_Prod_IRC.json index ceeb34e5f..9831fa664 100644 --- a/IRaCIS.Core.API/appsettings.US_Prod_IRC.json +++ b/IRaCIS.Core.API/appsettings.US_Prod_IRC.json @@ -27,13 +27,13 @@ }, "MinIO": { - "endPoint": "192.168.3.68", - "port": "8001", + "endPoint": "44.210.231.169", + "port": "9001", "useSSL": false, - "accessKey": "IDFkwEpWej0b4DtiuThL", - "secretKey": "Lhuu83yMhVwu7c1SnjvGY6lq74jzpYqifK6Qtj4h", - "bucketName": "test", - "viewEndpoint": "http://192.168.3.68:8001/test/" + "accessKey": "e9bT1isTOqSAUxb6wd4n", + "secretKey": "b5TaDzNdQCBtCvfm8eZ3dR6yY7tfZu2JYze2Po1i", + "bucketName": "prod-irc-us", + "viewEndpoint": "http://44.210.231.169:9001/prod-irc-us/" }, "AWS": { diff --git a/IRaCIS.Core.API/appsettings.US_Test_IRC.json b/IRaCIS.Core.API/appsettings.US_Test_IRC.json new file mode 100644 index 000000000..5278ddb56 --- /dev/null +++ b/IRaCIS.Core.API/appsettings.US_Test_IRC.json @@ -0,0 +1,82 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft": "Warning", + "Microsoft.Hosting.Lifetime": "Information" + } + }, + "ConnectionStrings": { + "RemoteNew": "Server=106.14.89.110,1435;Database=Test_IRC;User ID=sa;Password=xc@123456;TrustServerCertificate=true", + "Hangfire": "Server=106.14.89.110,1435;Database=Test_IRC_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true" + }, + + "ObjectStoreService": { + + "ObjectStoreUse": "MinIO", + "AliyunOSS": { + "regionId": "cn-shanghai", + "endPoint": "https://oss-cn-shanghai.aliyuncs.com", + "accessKeyId": "LTAI5tKvzs7ed3UfSpNk3xwQ", + "accessKeySecret": "zTIceGEShlZDGnLrCFfIGFE7TXVRio", + "bucketName": "zy-irc-test-store", + "roleArn": "acs:ram::1899121822495495:role/oss-upload", + "viewEndpoint": "https://zy-irc-test-store.oss-cn-shanghai.aliyuncs.com", + "region": "oss-cn-shanghai" + }, + + "MinIO": { + //"endPoint": "hir-oss.uat.extimaging.com", + //"port": "443", + //"useSSL": true, + //"viewEndpoint": "https://hir-oss.uat.extimaging.com/hir-uat", + + "endPoint": "47.117.164.182", + "port": "9001", + "useSSL": false, + "viewEndpoint": "http://47.117.164.182:9001/test-irc-us", + + "accessKey": "b9Ul0e98xPzt6PwRXA1Q", + "secretKey": "DzMaU2L4OXl90uytwOmDXF2encN0Jf4Nxu2XkYqQ", + "bucketName": "test-irc-us" + + }, + + "AWS": { + "endPoint": "s3.us-east-1.amazonaws.com", + "useSSL": true, + "accessKey": "AKIAZQ3DRSOHFPJJ6FEU", + "secretKey": "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", + "bucketName": "ei-irc-test-store", + "viewEndpoint": "https://ei-irc-test-store.s3.amazonaws.com/" + } + }, + "BasicSystemConfig": { + + "OpenUserComplexPassword": false, + + "OpenSignDocumentBeforeWork": false, + + "OpenTrialRelationDelete": true, + + "OpenLoginLimit": false, + + "LoginMaxFailCount": 5, + + "LoginFailLockMinutes": 30, + "AutoLoginOutMinutes": 60 + }, + + "SystemEmailSendConfig": { + "Port": 465, + "Host": "smtp.qiye.aliyun.com", + "FromEmail": "test@extimaging.com", + "FromName": "Test_IRC", + "AuthorizationCode": "SHzyyl2021", + "CompanyName": "Elevate Imaging", + "CompanyNameCN": "上海展影医疗科技有限公司", + "CompanyShortName": "Elevate Imaging", + "CompanyShortNameCN": "展影医疗" + } + +} diff --git a/IRaCIS.Core.API/appsettings.US_IRC.json b/IRaCIS.Core.API/appsettings.US_Uat_IRC.json similarity index 82% rename from IRaCIS.Core.API/appsettings.US_IRC.json rename to IRaCIS.Core.API/appsettings.US_Uat_IRC.json index fe1312e46..212bae7ab 100644 --- a/IRaCIS.Core.API/appsettings.US_IRC.json +++ b/IRaCIS.Core.API/appsettings.US_Uat_IRC.json @@ -16,7 +16,7 @@ "ObjectStoreService": { - "ObjectStoreUse": "AWS", + "ObjectStoreUse": "MinIO", "AliyunOSS": { "regionId": "cn-shanghai", @@ -30,13 +30,20 @@ }, "MinIO": { - "endPoint": "192.168.3.68", - "port": "8001", + //"endPoint": "hir-oss.us.extimaging.com", + //"port": "443", + //"useSSL": true, + //"viewEndpoint": "https://hir-oss.us.extimaging.com/hir-us", + + "endPoint": "44.218.11.19", + "port": "9001", "useSSL": false, - "accessKey": "IDFkwEpWej0b4DtiuThL", - "secretKey": "Lhuu83yMhVwu7c1SnjvGY6lq74jzpYqifK6Qtj4h", - "bucketName": "test", - "viewEndpoint": "http://192.168.3.68:8001/test/" + "viewEndpoint": "http://44.218.11.19:9001/uat-irc-us", + + "accessKey": "lH8DkKskLuDqPaiubuSQ", + "secretKey": "pdPdicvvLeH7xAC5yFUrI7odMyBfOXxvVWMvKYV4", + "bucketName": "uat-irc-us" + }, "AWS": { From f9734dc5cc6b71b7e65314abc1bf3e13a455a089 Mon Sep 17 00:00:00 2001 From: he <109787524@qq.com> Date: Mon, 8 Jul 2024 16:21:58 +0800 Subject: [PATCH 049/251] =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Service/Reading/ReadingImageTask/ReadingImageTaskService.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/IRaCIS.Core.Application/Service/Reading/ReadingImageTask/ReadingImageTaskService.cs b/IRaCIS.Core.Application/Service/Reading/ReadingImageTask/ReadingImageTaskService.cs index 1792d4f92..0e741856f 100644 --- a/IRaCIS.Core.Application/Service/Reading/ReadingImageTask/ReadingImageTaskService.cs +++ b/IRaCIS.Core.Application/Service/Reading/ReadingImageTask/ReadingImageTaskService.cs @@ -1207,6 +1207,7 @@ namespace IRaCIS.Application.Services var groupList = new List(); var qusetionIds = qusetionList.Select(x => x.Id).ToList(); + var tableQuestionList = await _readingTableQuestionTrialRepository .WhereIf(inDto.QuestionClassify != null, x => x.QuestionClassify == inDto.QuestionClassify) .Where(x => qusetionIds.Contains(x.ReadingQuestionId)) From 905fdd9861919bfc8f5f12ae59409212a7ca4949 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Tue, 9 Jul 2024 09:40:32 +0800 Subject: [PATCH 050/251] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E7=BE=8E=E5=9B=BDirc?= =?UTF-8?q?=20uat=20=E6=95=B0=E6=8D=AE=E5=BA=93=E5=90=8D=E7=A7=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.API/appsettings.US_Uat_IRC.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/IRaCIS.Core.API/appsettings.US_Uat_IRC.json b/IRaCIS.Core.API/appsettings.US_Uat_IRC.json index 212bae7ab..352c2ffcb 100644 --- a/IRaCIS.Core.API/appsettings.US_Uat_IRC.json +++ b/IRaCIS.Core.API/appsettings.US_Uat_IRC.json @@ -7,8 +7,8 @@ } }, "ConnectionStrings": { - "RemoteNew": "Server=us-mssql-service,1433;Database=Prod_US_IRC;User ID=sa;Password=xc@123456;TrustServerCertificate=true", - "Hangfire": "Server=us-mssql-service,1433;Database=Prod_US_IRC_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true" + "RemoteNew": "Server=us-mssql-service,1433;Database=US_Uat_IRC;User ID=sa;Password=xc@123456;TrustServerCertificate=true", + "Hangfire": "Server=us-mssql-service,1433;Database=US_Uat_IRC_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true" //"RemoteNew": "Server=44.218.11.19,1435;Database=Prod_US_IRC;User ID=sa;Password=xc@123456;TrustServerCertificate=true", //"Hangfire": "Server=44.218.11.19,1435;Database=Prod_US_IRC_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true" From d5c628d9160709ab5a1be8812b1aca52038cce9a Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Tue, 9 Jul 2024 09:50:30 +0800 Subject: [PATCH 051/251] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=8F=91=E4=BB=B6?= =?UTF-8?q?=E7=AE=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.API/appsettings.US_Prod_IRC.json | 12 ++++++------ IRaCIS.Core.API/appsettings.US_Uat_IRC.json | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/IRaCIS.Core.API/appsettings.US_Prod_IRC.json b/IRaCIS.Core.API/appsettings.US_Prod_IRC.json index 9831fa664..ee6807a72 100644 --- a/IRaCIS.Core.API/appsettings.US_Prod_IRC.json +++ b/IRaCIS.Core.API/appsettings.US_Prod_IRC.json @@ -62,12 +62,12 @@ }, "SystemEmailSendConfig": { - "Port": 465, - "Host": "smtp.qiye.aliyun.com", - "FromEmail": "test@extimaging.com", - "FromName": "Test_IRC", - "AuthorizationCode": "SHzyyl2021", - "CompanyName": "Elevate Imaging", + "Port": 587, + "Host": "smtp-mail.outlook.com", + "FromEmail": "donotreply@elevateimaging.ai", + "FromName": "LiLi", + "AuthorizationCode": "Q#669869497420ul", + "CompanyName": "Elevate Imaging Inc.", "CompanyNameCN": "上海展影医疗科技有限公司", "CompanyShortName": "Elevate Imaging", "CompanyShortNameCN": "展影医疗" diff --git a/IRaCIS.Core.API/appsettings.US_Uat_IRC.json b/IRaCIS.Core.API/appsettings.US_Uat_IRC.json index 352c2ffcb..9da9a062d 100644 --- a/IRaCIS.Core.API/appsettings.US_Uat_IRC.json +++ b/IRaCIS.Core.API/appsettings.US_Uat_IRC.json @@ -72,12 +72,12 @@ }, "SystemEmailSendConfig": { - "Port": 465, - "Host": "smtp.qiye.aliyun.com", - "FromEmail": "test@extimaging.com", - "FromName": "Test_IRC", - "AuthorizationCode": "SHzyyl2021", - "CompanyName": "Elevate Imaging", + "Port": 587, + "Host": "smtp-mail.outlook.com", + "FromEmail": "donotreply@elevateimaging.ai", + "FromName": "LiLi", + "AuthorizationCode": "Q#669869497420ul", + "CompanyName": "Elevate Imaging Inc.", "CompanyNameCN": "上海展影医疗科技有限公司", "CompanyShortName": "Elevate Imaging", "CompanyShortNameCN": "展影医疗" From 06209a945dfc0acfbcb76d7a62b6a922a2882ff1 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Tue, 9 Jul 2024 13:12:59 +0800 Subject: [PATCH 052/251] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=8F=91=E9=80=81?= =?UTF-8?q?=E9=82=AE=E4=BB=B6=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.API/appsettings.US_Prod_IRC.json | 3 ++- IRaCIS.Core.API/appsettings.US_Uat_IRC.json | 3 ++- IRaCIS.Core.Application/Helper/SendEmailHelper.cs | 6 +++--- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/IRaCIS.Core.API/appsettings.US_Prod_IRC.json b/IRaCIS.Core.API/appsettings.US_Prod_IRC.json index ee6807a72..4641c5c50 100644 --- a/IRaCIS.Core.API/appsettings.US_Prod_IRC.json +++ b/IRaCIS.Core.API/appsettings.US_Prod_IRC.json @@ -70,7 +70,8 @@ "CompanyName": "Elevate Imaging Inc.", "CompanyNameCN": "上海展影医疗科技有限公司", "CompanyShortName": "Elevate Imaging", - "CompanyShortNameCN": "展影医疗" + "CompanyShortNameCN": "展影医疗", + "SiteUrl": "https://lili.elevateimaging.ai/login" } } diff --git a/IRaCIS.Core.API/appsettings.US_Uat_IRC.json b/IRaCIS.Core.API/appsettings.US_Uat_IRC.json index 9da9a062d..5bd1d0708 100644 --- a/IRaCIS.Core.API/appsettings.US_Uat_IRC.json +++ b/IRaCIS.Core.API/appsettings.US_Uat_IRC.json @@ -80,7 +80,8 @@ "CompanyName": "Elevate Imaging Inc.", "CompanyNameCN": "上海展影医疗科技有限公司", "CompanyShortName": "Elevate Imaging", - "CompanyShortNameCN": "展影医疗" + "CompanyShortNameCN": "展影医疗", + "SiteUrl": "https://lili.test.elevateimaging.ai/login" } } diff --git a/IRaCIS.Core.Application/Helper/SendEmailHelper.cs b/IRaCIS.Core.Application/Helper/SendEmailHelper.cs index 5120c9c83..974a60f02 100644 --- a/IRaCIS.Core.Application/Helper/SendEmailHelper.cs +++ b/IRaCIS.Core.Application/Helper/SendEmailHelper.cs @@ -29,7 +29,7 @@ public static class SendEmailHelper //await smtp.AuthenticateAsync("zhou941003@qq.com", "sqfhlpfdvnexbcab"); - await smtp.ConnectAsync(_systemEmailConfig.Host, _systemEmailConfig.Port, SecureSocketOptions.SslOnConnect); + await smtp.ConnectAsync(_systemEmailConfig.Host, _systemEmailConfig.Port, SecureSocketOptions.Auto); await smtp.AuthenticateAsync(_systemEmailConfig.FromEmail, _systemEmailConfig.AuthorizationCode); @@ -55,7 +55,7 @@ public static class SendEmailHelper using (var client = new MailKit.Net.Smtp.SmtpClient()) { - await client.ConnectAsync(_systemEmailConfig.Host, _systemEmailConfig.Port, SecureSocketOptions.SslOnConnect); + await client.ConnectAsync(_systemEmailConfig.Host, _systemEmailConfig.Port, SecureSocketOptions.Auto); await client.AuthenticateAsync(_systemEmailConfig.FromEmail, _systemEmailConfig.AuthorizationCode); @@ -133,7 +133,7 @@ public static class SendEmailHelper smtp.ServerCertificateValidationCallback = (s, c, h, e) => true; - await smtp.ConnectAsync(sMTPEmailConfig.Host, sMTPEmailConfig.Port, SecureSocketOptions.SslOnConnect); + await smtp.ConnectAsync(sMTPEmailConfig.Host, sMTPEmailConfig.Port, SecureSocketOptions.Auto); await smtp.AuthenticateAsync(sMTPEmailConfig.UserName, sMTPEmailConfig.AuthorizationCode); From e6bd7ad0ea3d93dd2deee9cb67ec1f86c93a01a5 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Tue, 9 Jul 2024 14:20:00 +0800 Subject: [PATCH 053/251] =?UTF-8?q?=E4=BF=AE=E6=94=B9pacs=20=E9=85=8D?= =?UTF-8?q?=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Service/TrialSiteUser/DTO/DicomAEViewModel.cs | 7 +++++-- .../Service/TrialSiteUser/TrialDicomAEService.cs | 2 ++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/IRaCIS.Core.Application/Service/TrialSiteUser/DTO/DicomAEViewModel.cs b/IRaCIS.Core.Application/Service/TrialSiteUser/DTO/DicomAEViewModel.cs index 6e335b36d..f3f03e1ce 100644 --- a/IRaCIS.Core.Application/Service/TrialSiteUser/DTO/DicomAEViewModel.cs +++ b/IRaCIS.Core.Application/Service/TrialSiteUser/DTO/DicomAEViewModel.cs @@ -21,9 +21,9 @@ namespace IRaCIS.Core.Application.ViewModel public bool IsTestOK { get; set; } - public bool IsPACSConnect { get; set; } + //public bool IsPACSConnect { get; set; } - public bool IsTrialPACSConfirmed { get; set; } + //public bool IsTrialPACSConfirmed { get; set; } } @@ -58,6 +58,9 @@ namespace IRaCIS.Core.Application.ViewModel public int Port { get; set; } public string Modality { get; set; } = string.Empty; public string Description { get; set; } = string.Empty; + + + public bool IsPACSConnect { get; set; } } diff --git a/IRaCIS.Core.Application/Service/TrialSiteUser/TrialDicomAEService.cs b/IRaCIS.Core.Application/Service/TrialSiteUser/TrialDicomAEService.cs index 982bab572..419c14e7b 100644 --- a/IRaCIS.Core.Application/Service/TrialSiteUser/TrialDicomAEService.cs +++ b/IRaCIS.Core.Application/Service/TrialSiteUser/TrialDicomAEService.cs @@ -86,6 +86,8 @@ namespace IRaCIS.Core.Application.Service // 在此处拷贝automapper 映射 var entity = await _dicomAERepository.InsertOrUpdateAsync(addOrEditDicomAE, true, verifyExp1); + await _trialRepository.UpdatePartialFromQueryAsync(t => t.Id == addOrEditDicomAE.TrialId, u => new Trial() { IsPACSConnect = addOrEditDicomAE.IsPACSConnect }, true); + return ResponseOutput.Ok(entity.Id.ToString()); } From e55bc5fe7a61ca5832922f3ff54e8f585f1627e3 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Tue, 9 Jul 2024 14:25:34 +0800 Subject: [PATCH 054/251] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=9F=A5=E8=AF=A2?= =?UTF-8?q?=E6=98=A0=E5=B0=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.Application/Service/TrialSiteUser/_MapConfig2.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/IRaCIS.Core.Application/Service/TrialSiteUser/_MapConfig2.cs b/IRaCIS.Core.Application/Service/TrialSiteUser/_MapConfig2.cs index 96041148e..d81b1b5c8 100644 --- a/IRaCIS.Core.Application/Service/TrialSiteUser/_MapConfig2.cs +++ b/IRaCIS.Core.Application/Service/TrialSiteUser/_MapConfig2.cs @@ -49,6 +49,9 @@ namespace IRaCIS.Core.Application.Service CreateMap(); CreateMap().ReverseMap(); + CreateMap(); + + } } From 0075c18cd8fa2a0a69702c7ec5a2c11f6082eb31 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Tue, 9 Jul 2024 14:56:47 +0800 Subject: [PATCH 055/251] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E8=BF=94=E5=9B=9E?= =?UTF-8?q?=E7=9A=84=E4=BF=A1=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Service/TrialSiteUser/TrialDicomAEService.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/IRaCIS.Core.Application/Service/TrialSiteUser/TrialDicomAEService.cs b/IRaCIS.Core.Application/Service/TrialSiteUser/TrialDicomAEService.cs index 419c14e7b..ba4624cd2 100644 --- a/IRaCIS.Core.Application/Service/TrialSiteUser/TrialDicomAEService.cs +++ b/IRaCIS.Core.Application/Service/TrialSiteUser/TrialDicomAEService.cs @@ -60,7 +60,7 @@ namespace IRaCIS.Core.Application.Service public async Task> GetTrialDicomAE(Guid trialId) { var dicomAE = _dicomAERepository.Where(t => t.TrialId == trialId).ProjectTo(_mapper.ConfigurationProvider).FirstOrDefault(); - var trialConfig = _trialRepository.Where(t => t.Id == trialId).Select(t => new { t.IsPACSConnect, t.IsTrialPACSConfirmed }); + var trialConfig = _trialRepository.Where(t => t.Id == trialId).Select(t => new { t.IsPACSConnect, t.IsTrialPACSConfirmed }).FirstOrDefaultAsync(); return ResponseOutput.Ok(dicomAE, trialConfig); } From cf45169de2caa31ce1874641db0b2dce2241f77c Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Tue, 9 Jul 2024 16:16:10 +0800 Subject: [PATCH 056/251] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E8=BF=94=E5=9B=9E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRC.Core.SCP/Service/CStoreSCPService.cs | 2 ++ .../Service/TrialSiteUser/TrialDicomAEService.cs | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/IRC.Core.SCP/Service/CStoreSCPService.cs b/IRC.Core.SCP/Service/CStoreSCPService.cs index 261ca563b..a0c276107 100644 --- a/IRC.Core.SCP/Service/CStoreSCPService.cs +++ b/IRC.Core.SCP/Service/CStoreSCPService.cs @@ -163,6 +163,8 @@ namespace IRaCIS.Core.SCP.Service _upload.EndTime = DateTime.Now; _upload.StudyCount = _SCPStudyIdList.Count; + _upload.TrialId=_trialId; + _upload.TrialSiteId=_trialSiteId; await _SCPImageUploadRepository.AddAsync(_upload, true); diff --git a/IRaCIS.Core.Application/Service/TrialSiteUser/TrialDicomAEService.cs b/IRaCIS.Core.Application/Service/TrialSiteUser/TrialDicomAEService.cs index ba4624cd2..beb413107 100644 --- a/IRaCIS.Core.Application/Service/TrialSiteUser/TrialDicomAEService.cs +++ b/IRaCIS.Core.Application/Service/TrialSiteUser/TrialDicomAEService.cs @@ -60,7 +60,7 @@ namespace IRaCIS.Core.Application.Service public async Task> GetTrialDicomAE(Guid trialId) { var dicomAE = _dicomAERepository.Where(t => t.TrialId == trialId).ProjectTo(_mapper.ConfigurationProvider).FirstOrDefault(); - var trialConfig = _trialRepository.Where(t => t.Id == trialId).Select(t => new { t.IsPACSConnect, t.IsTrialPACSConfirmed }).FirstOrDefaultAsync(); + var trialConfig = await _trialRepository.Where(t => t.Id == trialId).Select(t => new { t.IsPACSConnect, t.IsTrialPACSConfirmed }).FirstOrDefaultAsync(); return ResponseOutput.Ok(dicomAE, trialConfig); } From d483aca73b7df9295422f09bcbab12c1b22e89f0 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Tue, 9 Jul 2024 16:27:07 +0800 Subject: [PATCH 057/251] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=98=A0=E5=B0=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.Application/Service/TrialSiteUser/_MapConfig2.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/IRaCIS.Core.Application/Service/TrialSiteUser/_MapConfig2.cs b/IRaCIS.Core.Application/Service/TrialSiteUser/_MapConfig2.cs index d81b1b5c8..84c15094d 100644 --- a/IRaCIS.Core.Application/Service/TrialSiteUser/_MapConfig2.cs +++ b/IRaCIS.Core.Application/Service/TrialSiteUser/_MapConfig2.cs @@ -50,9 +50,13 @@ namespace IRaCIS.Core.Application.Service CreateMap().ReverseMap(); CreateMap(); + + CreateMap(); + + } } From d1e4863e01ff7ac57219a01a4eb6404868db7024 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Tue, 9 Jul 2024 17:03:20 +0800 Subject: [PATCH 058/251] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E7=AD=BE=E5=90=8Dbug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Service/TrialSiteUser/TrialConfigService.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/IRaCIS.Core.Application/Service/TrialSiteUser/TrialConfigService.cs b/IRaCIS.Core.Application/Service/TrialSiteUser/TrialConfigService.cs index 4be695071..91e4e0232 100644 --- a/IRaCIS.Core.Application/Service/TrialSiteUser/TrialConfigService.cs +++ b/IRaCIS.Core.Application/Service/TrialSiteUser/TrialConfigService.cs @@ -1162,11 +1162,11 @@ namespace IRaCIS.Core.Application { var trialInfo = (await _trialRepository.FirstOrDefaultAsync(t => t.Id == trialConfig.TrialId)).IfNullThrowException(); trialInfo.IsPACSConnect = trialConfig.IsPACSConnect; - trialConfig.IsTrialPACSConfirmed = trialConfig.IsTrialPACSConfirmed; + trialInfo.IsTrialPACSConfirmed = trialConfig.IsTrialPACSConfirmed; trialInfo.UpdateTime = DateTime.Now; await _trialRepository.SaveChangesAsync(); - return ResponseOutput.Ok(await _repository.SaveChangesAsync()); + return ResponseOutput.Ok(); } From 7636c82b1118d159768575b26ede5889f6d10f04 Mon Sep 17 00:00:00 2001 From: he <109787524@qq.com> Date: Tue, 9 Jul 2024 17:21:16 +0800 Subject: [PATCH 059/251] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Service/Reading/ReadingImageTask/ReadingImageTaskService.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/IRaCIS.Core.Application/Service/Reading/ReadingImageTask/ReadingImageTaskService.cs b/IRaCIS.Core.Application/Service/Reading/ReadingImageTask/ReadingImageTaskService.cs index 0e741856f..92238e196 100644 --- a/IRaCIS.Core.Application/Service/Reading/ReadingImageTask/ReadingImageTaskService.cs +++ b/IRaCIS.Core.Application/Service/Reading/ReadingImageTask/ReadingImageTaskService.cs @@ -2976,6 +2976,7 @@ namespace IRaCIS.Application.Services ReadingTaskState = ReadingTaskState.WaitReading }); await _visitTaskRepository.SaveChangesAsync(); + _userInfo.IsNotNeedInspection = true; await _readingCalculateService.AddTaskLesionAnswerFromLastTask(new AddTaskLesionAnswerFromLastTaskInDto() { VisitTaskId = inDto.VisitTaskId From 003b227f7d25526c66c2c669b47fc6f7839adeab Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Wed, 10 Jul 2024 09:08:41 +0800 Subject: [PATCH 060/251] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=8F=91=E9=80=81?= =?UTF-8?q?=E9=82=AE=E4=BB=B6=E6=8F=90=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.API/appsettings.Test_IRC.json | 31 +++++++++++++------ .../Service/Management/UserService.cs | 28 ++++++++--------- 2 files changed, 36 insertions(+), 23 deletions(-) diff --git a/IRaCIS.Core.API/appsettings.Test_IRC.json b/IRaCIS.Core.API/appsettings.Test_IRC.json index 9ef5c0ff1..d7b3cafec 100644 --- a/IRaCIS.Core.API/appsettings.Test_IRC.json +++ b/IRaCIS.Core.API/appsettings.Test_IRC.json @@ -63,17 +63,30 @@ "OpenLoginMFA": false }, + //"SystemEmailSendConfig": { + // "Port": 465, + // "Host": "smtp.qiye.aliyun.com", + // "FromEmail": "test@extimaging.com", + // "FromName": "Test_IRC", + // "AuthorizationCode": "SHzyyl2021", + // "SiteUrl": "http://irc.test.extimaging.com/login", + // "CompanyName": "Extensive Imaging", + // "CompanyNameCN": "上海展影医疗科技有限公司", + // "CompanyShortName": "Extensive Imaging", + // "CompanyShortNameCN": "展影医疗" + //} + "SystemEmailSendConfig": { - "Port": 465, - "Host": "smtp.qiye.aliyun.com", - "FromEmail": "test@extimaging.com", - "FromName": "Test_IRC", - "AuthorizationCode": "SHzyyl2021", - "SiteUrl": "http://irc.test.extimaging.com/login", - "CompanyName": "Extensive Imaging", + "Port": 587, + "Host": "smtp-mail.outlook.com", + "FromEmail": "donotreply@elevateimaging.ai", + "FromName": "LiLi", + "AuthorizationCode": "Q#669869497420ul", + "CompanyName": "Elevate Imaging Inc.", "CompanyNameCN": "上海展影医疗科技有限公司", - "CompanyShortName": "Extensive Imaging", - "CompanyShortNameCN": "展影医疗" + "CompanyShortName": "Elevate Imaging", + "CompanyShortNameCN": "展影医疗", + "SiteUrl": "https://lili.test.elevateimaging.ai/login" } } diff --git a/IRaCIS.Core.Application/Service/Management/UserService.cs b/IRaCIS.Core.Application/Service/Management/UserService.cs index 81882bdd7..e7b32a2d2 100644 --- a/IRaCIS.Core.Application/Service/Management/UserService.cs +++ b/IRaCIS.Core.Application/Service/Management/UserService.cs @@ -305,15 +305,15 @@ namespace IRaCIS.Application.Services } - try - { - await _mailVerificationService.AdminResetPwdSendEmailAsync(userId, pwd); - } - catch (Exception) - { - //---请检查邮箱地址或者联系维护人员, 邮件发送失败, 未能创建账户成功 - throw new BusinessValidationFailedException(_localizer["User_CreateFailed"]); - } + //try + //{ + await _mailVerificationService.AdminResetPwdSendEmailAsync(userId, pwd); + //} + //catch (Exception) + //{ + // //---请检查邮箱地址或者联系维护人员, 邮件发送失败, 未能创建账户成功 + // throw new BusinessValidationFailedException(_localizer["User_CreateFailed"]); + //} await _userRepository.UpdatePartialNowNoQueryAsync(userId, u => new User() @@ -644,7 +644,7 @@ namespace IRaCIS.Application.Services public async Task GetUserBasicInfo(Guid userId, string pwd) { - var info = await _userRepository.Where(u => u.Id == userId && u.Password==pwd).ProjectTo(_mapper.ConfigurationProvider).FirstNotNullAsync(); + var info = await _userRepository.Where(u => u.Id == userId && u.Password == pwd).ProjectTo(_mapper.ConfigurationProvider).FirstNotNullAsync(); return info; } @@ -656,13 +656,13 @@ namespace IRaCIS.Application.Services /// /// [AllowAnonymous] - public async Task SendMFAEmail(Guid userId, int mfaType ) + public async Task SendMFAEmail(Guid userId, int mfaType) { var userInfo = await _userRepository.Where(u => u.Id == userId).Select(t => new { t.FullName, t.EMail }).FirstOrDefaultAsync(); int verificationCode = new Random().Next(100000, 1000000); - await _mailVerificationService.SenMFAVerifyEmail(userId, userInfo.FullName, userInfo.EMail, verificationCode, (UserMFAType)mfaType ); + await _mailVerificationService.SenMFAVerifyEmail(userId, userInfo.FullName, userInfo.EMail, verificationCode, (UserMFAType)mfaType); return ResponseOutput.Ok(); } @@ -696,7 +696,7 @@ namespace IRaCIS.Application.Services //---验证码已经过期。 throw new BusinessValidationFailedException(_localizer["TrialSiteSurvey_ExpiredVerificationCode"]); - + } else //验证码正确 并且 没有超时 { @@ -813,7 +813,7 @@ namespace IRaCIS.Application.Services await _userRepository.BatchUpdateNoTrackingAsync(x => x.Id == loginUser.Id, x => new User() { LastLoginIP = _userInfo.IP, - LastLoginTime= DateTime.Now + LastLoginTime = DateTime.Now }); From 0ba439e5bd13fc1bc7213ed91fc62d88d473ab17 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Wed, 10 Jul 2024 09:10:10 +0800 Subject: [PATCH 061/251] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=8F=91=E4=BB=B6?= =?UTF-8?q?=E7=AE=B1=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.API/appsettings.Test_IRC.json | 44 +++++++++++------------ 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/IRaCIS.Core.API/appsettings.Test_IRC.json b/IRaCIS.Core.API/appsettings.Test_IRC.json index d7b3cafec..40125a016 100644 --- a/IRaCIS.Core.API/appsettings.Test_IRC.json +++ b/IRaCIS.Core.API/appsettings.Test_IRC.json @@ -63,30 +63,30 @@ "OpenLoginMFA": false }, - //"SystemEmailSendConfig": { - // "Port": 465, - // "Host": "smtp.qiye.aliyun.com", - // "FromEmail": "test@extimaging.com", - // "FromName": "Test_IRC", - // "AuthorizationCode": "SHzyyl2021", - // "SiteUrl": "http://irc.test.extimaging.com/login", - // "CompanyName": "Extensive Imaging", - // "CompanyNameCN": "上海展影医疗科技有限公司", - // "CompanyShortName": "Extensive Imaging", - // "CompanyShortNameCN": "展影医疗" - //} - "SystemEmailSendConfig": { - "Port": 587, - "Host": "smtp-mail.outlook.com", - "FromEmail": "donotreply@elevateimaging.ai", - "FromName": "LiLi", - "AuthorizationCode": "Q#669869497420ul", - "CompanyName": "Elevate Imaging Inc.", + "Port": 465, + "Host": "smtp.qiye.aliyun.com", + "FromEmail": "test@extimaging.com", + "FromName": "Test_IRC", + "AuthorizationCode": "SHzyyl2021", + "SiteUrl": "http://irc.test.extimaging.com/login", + "CompanyName": "Extensive Imaging", "CompanyNameCN": "上海展影医疗科技有限公司", - "CompanyShortName": "Elevate Imaging", - "CompanyShortNameCN": "展影医疗", - "SiteUrl": "https://lili.test.elevateimaging.ai/login" + "CompanyShortName": "Extensive Imaging", + "CompanyShortNameCN": "展影医疗" } + //"SystemEmailSendConfig": { + // "Port": 587, + // "Host": "smtp-mail.outlook.com", + // "FromEmail": "donotreply@elevateimaging.ai", + // "FromName": "LiLi", + // "AuthorizationCode": "Q#669869497420ul", + // "CompanyName": "Elevate Imaging Inc.", + // "CompanyNameCN": "上海展影医疗科技有限公司", + // "CompanyShortName": "Elevate Imaging", + // "CompanyShortNameCN": "展影医疗", + // "SiteUrl": "https://lili.test.elevateimaging.ai/login" + //} + } From 4b15bcdc55a7f25d49525f681b49b1457cecb6e2 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Wed, 10 Jul 2024 10:48:20 +0800 Subject: [PATCH 062/251] =?UTF-8?q?=E6=89=93=E5=BC=80=E5=90=8E=E7=AB=AF?= =?UTF-8?q?=E6=AD=A3=E5=BC=8F=E7=8E=AF=E5=A2=83=E9=AA=8C=E8=AF=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Service/Management/UserService.cs | 54 ++++++++++--------- 1 file changed, 29 insertions(+), 25 deletions(-) diff --git a/IRaCIS.Core.Application/Service/Management/UserService.cs b/IRaCIS.Core.Application/Service/Management/UserService.cs index e7b32a2d2..2910bdc46 100644 --- a/IRaCIS.Core.Application/Service/Management/UserService.cs +++ b/IRaCIS.Core.Application/Service/Management/UserService.cs @@ -100,32 +100,38 @@ namespace IRaCIS.Application.Services { //var dbUser = (await _userRepository.FirstOrDefaultAsync(t => t.Id == userId)).IfNullThrowException(); - if (oldPwd != null && oldPwd == newPwd) + if (_verifyConfig.CurrentValue.OpenUserComplexPassword) { - //---新密码与旧密码相同。 - throw new BusinessValidationFailedException(_localizer["User_NewOldPwdSame"]); + if (oldPwd != null && oldPwd == newPwd) + { + //---新密码与旧密码相同。 + throw new BusinessValidationFailedException(_localizer["User_NewOldPwdSame"]); + } + + + var dbUser = (await _userRepository.Where(t => t.Id == userId).FirstOrDefaultAsync()).IfNullThrowException(); + + if (oldPwd != null && dbUser.Password != oldPwd) + { + //---旧密码验证失败。 + throw new BusinessValidationFailedException(_localizer["User_OldPwdInvalid"]); + } + + if (dbUser.Password == newPwd) + { + //---新密码与旧密码相同。 + throw new BusinessValidationFailedException(_localizer["User_NewOldPwdSame"]); + } + + var passWordList = await _userPassWordLogRepository.Where(x => x.UserId == userId).OrderByDescending(x => x.CreateTime).Take(2).ToListAsync(); + + if (passWordList.Any(x => x.PassWord == newPwd)) + { + throw new BusinessValidationFailedException(_localizer["User_PassWordRepeat"]); + } + } - - var dbUser = (await _userRepository.Where(t => t.Id == userId).FirstOrDefaultAsync()).IfNullThrowException(); - - if (oldPwd != null && dbUser.Password != oldPwd) - { - //---旧密码验证失败。 - throw new BusinessValidationFailedException(_localizer["User_OldPwdInvalid"]); - } - - if (dbUser.Password == newPwd) - { - //---新密码与旧密码相同。 - throw new BusinessValidationFailedException(_localizer["User_NewOldPwdSame"]); - } - - var passWordList = await _userPassWordLogRepository.Where(x => x.UserId == userId).OrderByDescending(x => x.CreateTime).Take(2).ToListAsync(); - if (passWordList.Any(x => x.PassWord == newPwd)) - { - throw new BusinessValidationFailedException(_localizer["User_PassWordRepeat"]); - } if (oldPwd != null) { await _userPassWordLogRepository.AddAsync(new UserPassWordLog() @@ -137,7 +143,6 @@ namespace IRaCIS.Application.Services }); } - await _userRepository.BatchUpdateNoTrackingAsync(x => x.Id == userId, x => new User() { LastChangePassWordTime = DateTime.Now, @@ -145,7 +150,6 @@ namespace IRaCIS.Application.Services await _userPassWordLogRepository.SaveChangesAsync(); - await Task.CompletedTask; } From 67819fc85d72fdac0d0f06eb7306eb5df2e2175d Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Wed, 10 Jul 2024 14:00:04 +0800 Subject: [PATCH 063/251] =?UTF-8?q?=E7=BB=84=E4=BB=B6=E4=B8=80=E8=87=B4?= =?UTF-8?q?=E6=80=A7=E5=88=86=E6=9E=90=E7=AD=9B=E9=80=89=E6=9D=A1=E4=BB=B6?= =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Allocation/TaskConsistentRuleService.cs | 55 +++---------------- 1 file changed, 7 insertions(+), 48 deletions(-) diff --git a/IRaCIS.Core.Application/Service/Allocation/TaskConsistentRuleService.cs b/IRaCIS.Core.Application/Service/Allocation/TaskConsistentRuleService.cs index 9242506ef..ea11b3575 100644 --- a/IRaCIS.Core.Application/Service/Allocation/TaskConsistentRuleService.cs +++ b/IRaCIS.Core.Application/Service/Allocation/TaskConsistentRuleService.cs @@ -570,7 +570,7 @@ namespace IRaCIS.Core.Application.Service var subjectQuery = _subjectRepository.Where(t => t.TrialId == trialId && t.SubjectVisitTaskList.AsQueryable().Where(visitTaskFilter).Count() >= filterObj.PlanVisitCount) .WhereIf(filterObj.IsHaveReadingPeriod == true, u => u.SubjectVisitTaskList.AsQueryable().Where(comonTaskFilter) - .Where(t => t.ReadingCategory == ReadingCategory.Visit || t.ReadingCategory == ReadingCategory.Global).Any(t => t.ReadingCategory == ReadingCategory.Global)) + .Where(t => t.ReadingCategory == ReadingCategory.Visit || t.ReadingCategory == ReadingCategory.Global).Any(t => t.ReadingCategory == ReadingCategory.Global && t.VisitTaskNum>filterObj.PlanVisitCount-1)) ; @@ -654,13 +654,11 @@ namespace IRaCIS.Core.Application.Service /// private async Task> GetGroupConsistentQueryAsync(TaskConsistentRule filterObj, List? subejctIdList = null) { + //单重阅片没有组件一致性 var trialId = filterObj.TrialId; var trialReadingCriterionId = filterObj.TrialReadingCriterionId; - //var trialConfig = (await _repository.Where(t => t.Id == trialId).Select(t => new { TrialId = t.Id, t.ReadingType, t.IsReadingTaskViewInOrder }).FirstOrDefaultAsync()).IfNullThrowException(); - - Expression> comonTaskFilter = u => u.TrialId == trialId && u.IsAnalysisCreate == false && u.TaskState == TaskState.Effect && u.ReadingTaskState == ReadingTaskState.HaveSigned && u.TrialReadingCriterionId == trialReadingCriterionId && (u.ReReadingApplyState == ReReadingApplyState.Default || u.ReReadingApplyState == ReReadingApplyState.Reject); @@ -674,28 +672,16 @@ namespace IRaCIS.Core.Application.Service Expression> visitTaskFilter = comonTaskFilter.And(t => t.ReadingCategory == ReadingCategory.Visit); - ////所选访视数量 的访视 其中必有一个访视后有全局任务 - //if (filterObj.IsHaveReadingPeriod == true) - //{ - // //visitTaskFilter = visitTaskFilter.And(t => t.Subject.SubjectVisitTaskList.AsQueryable().Where(comonTaskFilter).Any(u => u.VisitTaskNum == t.VisitTaskNum + ReadingCommon.TaskNumDic[ReadingCategory.Global] && u.ReadingCategory == ReadingCategory.Global)); - - // //这里的过滤条件 不能用 where(comonTaskFilter) 会报错,奇怪的问题 只能重新写一遍 - // visitTaskFilter = visitTaskFilter.And(c => c.Subject.SubjectVisitTaskList.Any(t => t.VisitTaskNum == c.VisitTaskNum + ReadingCommon.TaskNumDic[ReadingCategory.Global] && t.ReadingCategory == ReadingCategory.Global && t.IsAnalysisCreate == false && t.TaskState == TaskState.Effect && t.ReadingTaskState == ReadingTaskState.HaveSigned && - // t.SignTime!.Value.AddDays(filterObj.IntervalWeeks * 7) < DateTime.Now && (t.ReReadingApplyState == ReReadingApplyState.Default || t.ReReadingApplyState == ReReadingApplyState.Reject))); - - //} - - IQueryable subjectQuery = default; - //单重阅片没有组件一致性 + //双重阅片,并且都阅片完成 subjectQuery = _subjectRepository.Where(t => t.TrialId == trialId && t.SubjectVisitTaskList.AsQueryable().Where(comonTaskFilter).Where(t => t.ReadingCategory == ReadingCategory.Visit || t.ReadingCategory == ReadingCategory.Global).Select(t => t.DoctorUserId).Distinct().Count() == 2 && t.SubjectVisitTaskList.AsQueryable().Where(visitTaskFilter).GroupBy(t => new { t.SubjectId, t.VisitTaskNum }).Where(g => g.Count() == 2).Count() >= filterObj.PlanVisitCount ) - .WhereIf(filterObj.IsHaveReadingPeriod == true, u => u.SubjectVisitTaskList.AsQueryable().Where(comonTaskFilter).Where(t => t.ReadingCategory == ReadingCategory.Visit || t.ReadingCategory == ReadingCategory.Global).OrderBy(t => t.VisitTaskNum).Take(filterObj.PlanVisitCount * 2 + 2).Any(t => t.ReadingCategory == ReadingCategory.Global)) - + //.WhereIf(filterObj.IsHaveReadingPeriod == true, u => u.SubjectVisitTaskList.AsQueryable().Where(comonTaskFilter).Where(t => t.ReadingCategory == ReadingCategory.Visit || t.ReadingCategory == ReadingCategory.Global).OrderBy(t => t.VisitTaskNum).Take(filterObj.PlanVisitCount * 2 + 2).Any(t => t.ReadingCategory == ReadingCategory.Global)) + .WhereIf(filterObj.IsHaveReadingPeriod == true, u => u.SubjectVisitTaskList.AsQueryable().Where(comonTaskFilter).Where(t => t.ReadingCategory == ReadingCategory.Global && t.VisitTaskNum> filterObj.PlanVisitCount - 1).Select(t => t.DoctorUserId).Distinct().Count() == 2) ; @@ -809,9 +795,10 @@ namespace IRaCIS.Core.Application.Service .Where(visitTaskFilter).Where(t => t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId && t.SignTime!.Value.AddDays(taskConsistentRule.IntervalWeeks * 7) < DateTime.Now && t.DoctorUserId == user.Id) .Count() >= taskConsistentRule.PlanVisitCount : + //全局要>计划访视数量后面 t.SubjectVisitTaskList.AsQueryable().Where(comonTaskFilter) .Where(t => t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId && t.SignTime!.Value.AddDays(taskConsistentRule.IntervalWeeks * 7) < DateTime.Now && t.DoctorUserId == user.Id) - .Where(t => t.ReadingCategory == ReadingCategory.Visit || t.ReadingCategory == ReadingCategory.Global).Any(t => t.ReadingCategory == ReadingCategory.Global) + .Where(t => t.ReadingCategory == ReadingCategory.Visit || t.ReadingCategory == ReadingCategory.Global).Any(t => t.ReadingCategory == ReadingCategory.Global && t.VisitTaskNum>taskConsistentRule.PlanVisitCount-1) && t.SubjectVisitTaskList.AsQueryable().Where(visitTaskFilter) .Where(t => t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId && t.SignTime!.Value.AddDays(taskConsistentRule.IntervalWeeks * 7) < DateTime.Now && t.DoctorUserId == user.Id) @@ -983,35 +970,7 @@ namespace IRaCIS.Core.Application.Service - /// - /// 随机算法,选择指定数量的 subject - /// - /// - /// - /// - public List GetRandomSubjectIdList(List matchSubjectIdList, int countToSelect) - { - // 使用 Fisher-Yates 随机置换算法来选择指定数量的 GUID - Random random = new Random(); - - for (int i = 0; i < countToSelect; i++) - { - // 生成一个随机索引 - int randomIndex = random.Next(i, matchSubjectIdList.Count); - - // 将选中的元素与当前元素交换位置 - Guid temp = matchSubjectIdList[randomIndex]; - matchSubjectIdList[randomIndex] = matchSubjectIdList[i]; - matchSubjectIdList[i] = temp; - } - - return matchSubjectIdList.Take(countToSelect).ToList(); - - // 使用洗牌算法来随机选择指定数量的GUID - //Random random = new Random(); - //return matchSubjectIdList.OrderBy(g => random.Next()).Take(countToSelect).ToList(); - } From 46af71e3dfa10850c29140256bcf0357550bc9a9 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Wed, 10 Jul 2024 16:47:25 +0800 Subject: [PATCH 064/251] =?UTF-8?q?=E5=A2=9E=E5=8A=A0uat=20irc=20=E8=87=AA?= =?UTF-8?q?=E5=8A=A8=E6=89=93=E5=8C=85=E6=88=90=E9=95=9C=E5=83=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRC.Core.SCP/Service/DicomArchiveService.cs | 2 +- irc_api.drone.yml | 129 ++++---------------- 2 files changed, 26 insertions(+), 105 deletions(-) diff --git a/IRC.Core.SCP/Service/DicomArchiveService.cs b/IRC.Core.SCP/Service/DicomArchiveService.cs index 6eb9a092a..8e66feceb 100644 --- a/IRC.Core.SCP/Service/DicomArchiveService.cs +++ b/IRC.Core.SCP/Service/DicomArchiveService.cs @@ -72,7 +72,7 @@ namespace IRaCIS.Core.SCP.Service //using (@lock.Acquire()) { - var findPatient = await _patientRepository.FirstOrDefaultAsync(t => t.PatientIdStr == patientIdStr); + var findPatient = await _patientRepository.FirstOrDefaultAsync(t => t.PatientIdStr == patientIdStr && t.TrialSiteId==trialSiteId ); var findStudy = await _studyRepository.FindAsync(studyId); var findSerice = await _seriesRepository.FindAsync(seriesId); var findInstance = await _instanceRepository.FindAsync(instanceId); diff --git a/irc_api.drone.yml b/irc_api.drone.yml index 5b36684b9..7b2be0ced 100644 --- a/irc_api.drone.yml +++ b/irc_api.drone.yml @@ -1,83 +1,31 @@ ---- kind: pipeline -type: docker -name: irc-netcore-api +type: ssh +name: ssh-linux-uat-irc-build-image +platform: + os: Linux + arch: 386 + clone: disable: true +server: + host: 47.117.164.182 + user: root + password: + from_secret: test_ssh_pwd + steps: -- name: clone-repo - image: alpine/git - pull: if-not-exists - volumes: - - name: irc-test-work - path: /work +- name: build-uat-irc commands: - - if [ ! -e /work/netcore-repo/.git ]; then - git clone -b Test.IRC http://192.168.3.68:2000/XCKJ/irc-netcore-api.git /work/netcore-repo; - else - cd /work/netcore-repo; - git pull; - fi - - - | - if [ ! -e Dockerfile ]; then - echo 'FROM mcr.microsoft.com/dotnet/aspnet:6.0 - EXPOSE 80 - WORKDIR /app - COPY publish . - ENTRYPOINT ["dotnet", "IRaCIS.Core.API.dll"]' > /work/Dockerfile - fi - -- name: restore-publish - image: mcr.microsoft.com/dotnet/sdk:6.0 - pull: if-not-exists - depends_on: - - clone-repo - volumes: - - name: nuget-packages - path: /root/.nuget/packages - - name: irc-test-work - path: /work - commands: - - cd /work/netcore-repo/IRaCIS.Core.API - - dotnet restore ./IRaCIS.Core.API.csproj - - rm -rf /work/publish - - cd /work/netcore-repo/IRaCIS.Core.API - - dotnet publish ./IRaCIS.Core.API.csproj -c Release --no-restore -o /work/publish - -- name: docker-build - image: docker - pull: if-not-exists - depends_on: - - restore-publish - commands: - - cd /work - - docker build -t test-irc:v${DRONE_BUILD_NUMBER} . - volumes: - - name: irc-test-work - path: /work - - name: dockersock - path: /var/run/docker.sock - -volumes: - - name: nuget-packages - host: - path: /opt/cicd/nuget/packages - - name: irc-test-work - host: - path: /opt/cicd/irc-test - - name: dockersock - host: - path: /var/run/docker.sock - + - cd /opt/1panel/devops/irc-uat-to-uat + - sh build-irc-uat-image.sh v${DRONE_BUILD_NUMBER} + trigger: branch: - - master - + - Uat_IRC_Net8 + --- - kind: pipeline type: ssh name: ssh-linux-test-irc-publish @@ -107,36 +55,6 @@ trigger: - Test_IRC_Net8 --- - -kind: pipeline -type: ssh -name: test-irc-publish-image-push-aliyun - -platform: - os: Linux - arch: 386 - -clone: - disable: true - -server: - host: 192.168.3.68 - user: root - password: - from_secret: local_pwd - -steps: -- name: build-and-push-image - commands: - - cd /opt/hang/netcore/irc-test - - sh test-irc.sh v${DRONE_BUILD_NUMBER} - -trigger: - branch: - - master - ---- - kind: pipeline type: ssh name: ssh-linux-test-study-publish @@ -146,10 +64,10 @@ platform: arch: 386 clone: - disable: true - + disable: true #禁用默认克隆 + server: - host: 123.56.94.154 + host: 106.14.89.110 user: root password: from_secret: test_ssh_pwd @@ -163,4 +81,7 @@ steps: trigger: branch: - - Test.Study + - Test.Study + + + \ No newline at end of file From 29ea2a0ef15bce3649558c3a566b0c54a1ec7429 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Wed, 10 Jul 2024 17:42:39 +0800 Subject: [PATCH 065/251] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=9B=BD=E9=99=85?= =?UTF-8?q?=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Service/SiteSurvey/TrialSiteUserSurveyService.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/IRaCIS.Core.Application/Service/SiteSurvey/TrialSiteUserSurveyService.cs b/IRaCIS.Core.Application/Service/SiteSurvey/TrialSiteUserSurveyService.cs index 1a842aad9..1174921f8 100644 --- a/IRaCIS.Core.Application/Service/SiteSurvey/TrialSiteUserSurveyService.cs +++ b/IRaCIS.Core.Application/Service/SiteSurvey/TrialSiteUserSurveyService.cs @@ -95,7 +95,7 @@ namespace IRaCIS.Core.Application.Contracts var verifyExp1 = new EntityVerifyExp() { VerifyExp = u => u.UserTypeId == addOrEditTrialSiteUserSurvey.UserTypeId && u.Email == addOrEditTrialSiteUserSurvey.Email && u.TrialSiteSurveyId == addOrEditTrialSiteUserSurvey.TrialSiteSurveyId, - VerifyMsg = "同一邮箱同一用户类型,生成账号的数据只允许存在一条!", + VerifyMsg = _localizer["TrialSiteUser_SingleAccountPerEmailAndUserType"],// "同一邮箱同一用户类型,生成账号的数据只允许存在一条!", IsVerify = addOrEditTrialSiteUserSurvey.IsGenerateAccount }; From cb7140ad3884d1607e4e3bc4acc1fdc59d829ec7 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Thu, 11 Jul 2024 09:20:15 +0800 Subject: [PATCH 066/251] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=9B=BD=E9=99=85?= =?UTF-8?q?=E5=8C=96=E6=9F=A5=E8=AF=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.API/appsettings.Test_IRC.json | 13 +------------ IRaCIS.Core.Application/IRaCIS.Core.Application.xml | 8 -------- .../Service/Common/InternationalizationService.cs | 2 +- 3 files changed, 2 insertions(+), 21 deletions(-) diff --git a/IRaCIS.Core.API/appsettings.Test_IRC.json b/IRaCIS.Core.API/appsettings.Test_IRC.json index 40125a016..85eecf776 100644 --- a/IRaCIS.Core.API/appsettings.Test_IRC.json +++ b/IRaCIS.Core.API/appsettings.Test_IRC.json @@ -76,17 +76,6 @@ "CompanyShortNameCN": "展影医疗" } - //"SystemEmailSendConfig": { - // "Port": 587, - // "Host": "smtp-mail.outlook.com", - // "FromEmail": "donotreply@elevateimaging.ai", - // "FromName": "LiLi", - // "AuthorizationCode": "Q#669869497420ul", - // "CompanyName": "Elevate Imaging Inc.", - // "CompanyNameCN": "上海展影医疗科技有限公司", - // "CompanyShortName": "Elevate Imaging", - // "CompanyShortNameCN": "展影医疗", - // "SiteUrl": "https://lili.test.elevateimaging.ai/login" - //} + } diff --git a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml index 4a3b09d4b..4e7dc89e5 100644 --- a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml +++ b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml @@ -214,14 +214,6 @@ - - - 随机算法,选择指定数量的 subject - - - - - 医学审核生成规则 废弃 diff --git a/IRaCIS.Core.Application/Service/Common/InternationalizationService.cs b/IRaCIS.Core.Application/Service/Common/InternationalizationService.cs index 5f0743d27..6e3edeeb9 100644 --- a/IRaCIS.Core.Application/Service/Common/InternationalizationService.cs +++ b/IRaCIS.Core.Application/Service/Common/InternationalizationService.cs @@ -100,7 +100,7 @@ namespace IRaCIS.Core.Application.Service var internationalizationQueryable = _internationalizationRepository .WhereIf(inQuery.Description != null, t => t.Description.Contains(inQuery.Description)) - .WhereIf(inQuery.Module != null, t => t.Description.Contains(inQuery.Module)) + .WhereIf(inQuery.Module != null, t => t.Module.Contains(inQuery.Module)) .WhereIf(inQuery.PublishLogId != null, t => t.PublishLogId==inQuery.PublishLogId) .WhereIf(inQuery.Code != null, t => t.Code.Contains(inQuery.Code)) .WhereIf(inQuery.State != null, t => t.State == inQuery.State) From c032c423216dd3a97a18b689070b5c0ab948ad8c Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Thu, 11 Jul 2024 10:14:46 +0800 Subject: [PATCH 067/251] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E7=94=A8=E6=88=B7?= =?UTF-8?q?=E6=9C=BA=E6=9E=84=E9=BB=98=E8=AE=A4=E5=80=BC=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.API/appsettings.Prod_IRC.json | 2 ++ IRaCIS.Core.API/appsettings.Test_IRC.json | 3 +++ IRaCIS.Core.API/appsettings.US_Prod_IRC.json | 3 +++ IRaCIS.Core.API/appsettings.US_Test_IRC.json | 18 +++++++++++------- IRaCIS.Core.API/appsettings.US_Uat_IRC.json | 3 +++ IRaCIS.Core.API/appsettings.Uat_IRC.json | 2 ++ .../Service/Management/UserService.cs | 7 +++++-- IRaCIS.Core.Domain/_Config/_AppSettings.cs | 3 +++ 8 files changed, 32 insertions(+), 9 deletions(-) diff --git a/IRaCIS.Core.API/appsettings.Prod_IRC.json b/IRaCIS.Core.API/appsettings.Prod_IRC.json index 7d6013b68..2fe6807e3 100644 --- a/IRaCIS.Core.API/appsettings.Prod_IRC.json +++ b/IRaCIS.Core.API/appsettings.Prod_IRC.json @@ -55,6 +55,8 @@ "FromName": "IRC", "AuthorizationCode": "ExtImg@2022", "SiteUrl": "http://irc.extimaging.com/login", + "OrganizationName": "Extlmaging", + "OrganizationNameCN": "Extlmaging", "CompanyName": "Extensive Imaging", "CompanyNameCN": "上海展影医疗科技有限公司", "CompanyShortName": "Extensive Imaging", diff --git a/IRaCIS.Core.API/appsettings.Test_IRC.json b/IRaCIS.Core.API/appsettings.Test_IRC.json index 85eecf776..1f4e89bd2 100644 --- a/IRaCIS.Core.API/appsettings.Test_IRC.json +++ b/IRaCIS.Core.API/appsettings.Test_IRC.json @@ -70,6 +70,9 @@ "FromName": "Test_IRC", "AuthorizationCode": "SHzyyl2021", "SiteUrl": "http://irc.test.extimaging.com/login", + + "OrganizationName": "Extlmaging", + "OrganizationNameCN": "Extlmaging", "CompanyName": "Extensive Imaging", "CompanyNameCN": "上海展影医疗科技有限公司", "CompanyShortName": "Extensive Imaging", diff --git a/IRaCIS.Core.API/appsettings.US_Prod_IRC.json b/IRaCIS.Core.API/appsettings.US_Prod_IRC.json index 4641c5c50..ca614f2ac 100644 --- a/IRaCIS.Core.API/appsettings.US_Prod_IRC.json +++ b/IRaCIS.Core.API/appsettings.US_Prod_IRC.json @@ -67,6 +67,9 @@ "FromEmail": "donotreply@elevateimaging.ai", "FromName": "LiLi", "AuthorizationCode": "Q#669869497420ul", + + "OrganizationName": "Elevate Imaging", + "OrganizationNameCN": "Elevate Imaging", "CompanyName": "Elevate Imaging Inc.", "CompanyNameCN": "上海展影医疗科技有限公司", "CompanyShortName": "Elevate Imaging", diff --git a/IRaCIS.Core.API/appsettings.US_Test_IRC.json b/IRaCIS.Core.API/appsettings.US_Test_IRC.json index 5278ddb56..19d4dbe15 100644 --- a/IRaCIS.Core.API/appsettings.US_Test_IRC.json +++ b/IRaCIS.Core.API/appsettings.US_Test_IRC.json @@ -68,15 +68,19 @@ }, "SystemEmailSendConfig": { - "Port": 465, - "Host": "smtp.qiye.aliyun.com", - "FromEmail": "test@extimaging.com", - "FromName": "Test_IRC", - "AuthorizationCode": "SHzyyl2021", - "CompanyName": "Elevate Imaging", + "Port": 587, + "Host": "smtp-mail.outlook.com", + "FromEmail": "donotreply@elevateimaging.ai", + "FromName": "LiLi", + "AuthorizationCode": "Q#669869497420ul", + + "OrganizationName": "Elevate Imaging", + "OrganizationNameCN": "Elevate Imaging", + "CompanyName": "Elevate Imaging Inc.", "CompanyNameCN": "上海展影医疗科技有限公司", "CompanyShortName": "Elevate Imaging", - "CompanyShortNameCN": "展影医疗" + "CompanyShortNameCN": "展影医疗", + "SiteUrl": "https://lili.test.elevateimaging.ai/login" } } diff --git a/IRaCIS.Core.API/appsettings.US_Uat_IRC.json b/IRaCIS.Core.API/appsettings.US_Uat_IRC.json index 5bd1d0708..8ed58013e 100644 --- a/IRaCIS.Core.API/appsettings.US_Uat_IRC.json +++ b/IRaCIS.Core.API/appsettings.US_Uat_IRC.json @@ -77,6 +77,9 @@ "FromEmail": "donotreply@elevateimaging.ai", "FromName": "LiLi", "AuthorizationCode": "Q#669869497420ul", + + "OrganizationName": "Elevate Imaging", + "OrganizationNameCN": "Elevate Imaging", "CompanyName": "Elevate Imaging Inc.", "CompanyNameCN": "上海展影医疗科技有限公司", "CompanyShortName": "Elevate Imaging", diff --git a/IRaCIS.Core.API/appsettings.Uat_IRC.json b/IRaCIS.Core.API/appsettings.Uat_IRC.json index c4b925a17..ddc5ad7ad 100644 --- a/IRaCIS.Core.API/appsettings.Uat_IRC.json +++ b/IRaCIS.Core.API/appsettings.Uat_IRC.json @@ -61,6 +61,8 @@ "FromName": "UAT_IRC", "AuthorizationCode": "SHzyyl2021", "SiteUrl": "http://irc.uat.extimaging.com/login", + "OrganizationName": "Extlmaging", + "OrganizationNameCN": "Extlmaging", "CompanyName": "Extensive Imaging", "CompanyNameCN": "上海展影医疗科技有限公司", "CompanyShortName": "Extensive Imaging", diff --git a/IRaCIS.Core.Application/Service/Management/UserService.cs b/IRaCIS.Core.Application/Service/Management/UserService.cs index 2910bdc46..151b5c907 100644 --- a/IRaCIS.Core.Application/Service/Management/UserService.cs +++ b/IRaCIS.Core.Application/Service/Management/UserService.cs @@ -36,7 +36,7 @@ namespace IRaCIS.Application.Services private readonly IEasyCachingProvider _cache; private readonly IReadingImageTaskService _readingImageTaskService; private readonly IOptionsMonitor _verifyConfig; - + private readonly SystemEmailSendConfig _systemEmailConfig; public UserService(IRepository userRepository, @@ -47,6 +47,7 @@ namespace IRaCIS.Application.Services IReadingImageTaskService readingImageTaskService, IRepository userTrialRepository, IOptionsMonitor verifyConfig, + IOptionsMonitor systemEmailConfig, IRepository userLogRepository, IRepository userPassWordLogRepository , @@ -64,6 +65,8 @@ namespace IRaCIS.Application.Services _userTrialRepository = userTrialRepository; _userLogRepository = userLogRepository; _distributedLockProvider = distributedLockProvider; + + _systemEmailConfig = systemEmailConfig.CurrentValue; } @@ -593,7 +596,7 @@ namespace IRaCIS.Application.Services if (user.IsZhiZhun) { - user.OrganizationName = AppSettings.DefaultInternalOrganizationName; + user.OrganizationName = _userInfo.IsEn_Us? _systemEmailConfig.OrganizationName: _systemEmailConfig.OrganizationNameCN ; } await _userLogRepository.AddAsync(new UserLog() { IP = _userInfo.IP, LoginUserId = _userInfo.Id, OptUserId = model.Id, OptType = UserOptType.UpdateUser }, true); diff --git a/IRaCIS.Core.Domain/_Config/_AppSettings.cs b/IRaCIS.Core.Domain/_Config/_AppSettings.cs index 679d6d101..1361360fb 100644 --- a/IRaCIS.Core.Domain/_Config/_AppSettings.cs +++ b/IRaCIS.Core.Domain/_Config/_AppSettings.cs @@ -41,6 +41,9 @@ namespace IRaCIS.Core.Domain.Share public string SiteUrl { get; set; } + public string OrganizationName { get; set; } + public string OrganizationNameCN { get; set; } + public string CompanyName { get; set; } public string CompanyNameCN { get; set; } From 73b77a477aca6717b35ac462c3217e9bfd13e81d Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Thu, 11 Jul 2024 15:26:22 +0800 Subject: [PATCH 068/251] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=8F=91=E5=B8=83?= =?UTF-8?q?=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- irc_api.drone.yml | 67 ++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 60 insertions(+), 7 deletions(-) diff --git a/irc_api.drone.yml b/irc_api.drone.yml index 7b2be0ced..55df5dea8 100644 --- a/irc_api.drone.yml +++ b/irc_api.drone.yml @@ -18,8 +18,8 @@ server: steps: - name: build-uat-irc commands: - - cd /opt/1panel/devops/irc-uat-to-uat - - sh build-irc-uat-image.sh v${DRONE_BUILD_NUMBER} + - cd /opt/1panel/xc-deploy/Uat_IRC/devops-build-publish/Uat-To-Uat + - sh pull-build-uat-irc-image.sh v${DRONE_BUILD_NUMBER} trigger: branch: @@ -46,9 +46,7 @@ server: steps: - name: publish-test-irc commands: - - echo start publish test-irc-api - - cd /opt/1panel/hang/devops/test-irc - - sh test-irc.sh v${DRONE_BUILD_NUMBER} + - cd /opt/1panel/xc-deploy/Test_IRC/devops-build-publish;sh test-irc-update-or-create-stack.sh v${DRONE_BUILD_NUMBER} trigger: branch: @@ -75,13 +73,68 @@ server: steps: - name: publish-test-study commands: - - echo start publish test-study-api - - cd /opt/1panel/hang/devops/test-study + - cd /opt/1panel/xc-deploy/Test_Study/devops-build-publish - sh test-study.sh v${DRONE_BUILD_NUMBER} trigger: branch: - Test.Study + +--- +kind: pipeline +type: ssh +name: ssh-linux-test-scp-publish + +platform: + os: Linux + arch: 386 + +clone: + disable: true #禁用默认克隆 + +server: + host: 106.14.89.110 + user: root + password: + from_secret: test_ssh_pwd + +steps: +- name: publish-test-hir-scp + commands: + - cd /opt/1panel/xc-deploy/Test_HIR_SCP/devops-build-publish;sh pull-build-test-hir-scp-image.sh v${DRONE_BUILD_NUMBER} + - cd /opt/1panel/xc-deploy/Test_HIR_SCP ;sh update-image-if-need-then-pull-aliyun.sh v${DRONE_BUILD_NUMBER} +trigger: + branch: + - Test_HIR + +--- + + +kind: pipeline +type: ssh +name: ssh-linux-test-hir-publish + +platform: + os: Linux + arch: 386 + +clone: + disable: true #禁用默认克隆 + +server: + host: 106.14.89.110 + user: root + password: + from_secret: test_ssh_pwd + +steps: +- name: publish-test-hir + commands: + - cd /opt/1panel/xc-deploy/Test_HIR/devops-build-publish;sh pull-build-test-hir-image.sh v${DRONE_BUILD_NUMBER} + - cd /opt/1panel/xc-deploy/Test_HIR ; sh update-image-if-need-then-pull-aliyun.sh v${DRONE_BUILD_NUMBER} +trigger: + branch: + - Test_HIR \ No newline at end of file From 239e0b84c22ec4f5590b62494b7a37f6b9dfac5e Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Thu, 11 Jul 2024 16:07:11 +0800 Subject: [PATCH 069/251] =?UTF-8?q?study=20=20net8=20=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=E6=89=93=E5=8C=85=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- irc_api.drone.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/irc_api.drone.yml b/irc_api.drone.yml index 55df5dea8..b791bbfd1 100644 --- a/irc_api.drone.yml +++ b/irc_api.drone.yml @@ -73,12 +73,12 @@ server: steps: - name: publish-test-study commands: - - cd /opt/1panel/xc-deploy/Test_Study/devops-build-publish - - sh test-study.sh v${DRONE_BUILD_NUMBER} + - cd /opt/1panel/xc-deploy/Test_Study/devops-build-publish ; sh pull-build-test-study-image.sh v${DRONE_BUILD_NUMBER} + - cd /opt/1panel/xc-deploy/Test_Study ;sh update-image-if-need-then-pull-aliyun.sh v${DRONE_BUILD_NUMBER} trigger: branch: - - Test.Study + - Test_Study_Net8 --- kind: pipeline From 0827ede4b6ae3ee659f2edb2f031944f09be31bc Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Thu, 11 Jul 2024 16:59:58 +0800 Subject: [PATCH 070/251] =?UTF-8?q?=E5=A2=9E=E5=8A=A0irc-scp=E5=8F=91?= =?UTF-8?q?=E5=B8=83=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRC.Core.SCP/HostConfig/AutofacModuleSetup.cs | 2 +- IRC.Core.SCP/Properties/launchSettings.json | 4 +-- irc_api.drone.yml | 28 +++++++++++++++++++ 3 files changed, 31 insertions(+), 3 deletions(-) diff --git a/IRC.Core.SCP/HostConfig/AutofacModuleSetup.cs b/IRC.Core.SCP/HostConfig/AutofacModuleSetup.cs index 183eb235b..6567c9735 100644 --- a/IRC.Core.SCP/HostConfig/AutofacModuleSetup.cs +++ b/IRC.Core.SCP/HostConfig/AutofacModuleSetup.cs @@ -40,7 +40,7 @@ namespace IRaCIS.Core.SCP - Assembly application = Assembly.LoadFrom(AppDomain.CurrentDomain.BaseDirectory + "IRaCIS.Core.SCP.dll"); + Assembly application = Assembly.LoadFrom(AppDomain.CurrentDomain.BaseDirectory + typeof(BaseService).Assembly.GetName().Name+".dll"); containerBuilder.RegisterAssemblyTypes(application).Where(t => t.FullName.Contains("Service")) .PropertiesAutowired().AsImplementedInterfaces(); diff --git a/IRC.Core.SCP/Properties/launchSettings.json b/IRC.Core.SCP/Properties/launchSettings.json index ec782f999..d3d3ca4bc 100644 --- a/IRC.Core.SCP/Properties/launchSettings.json +++ b/IRC.Core.SCP/Properties/launchSettings.json @@ -9,14 +9,14 @@ } }, "profiles": { - "http": { + "Test_IRC_SCP": { "commandName": "Project", "dotnetRunMessages": true, "launchBrowser": true, "launchUrl": "swagger", "applicationUrl": "http://localhost:5243", "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" + "ASPNETCORE_ENVIRONMENT": "IRC_Test_SCP" } }, "IIS Express": { diff --git a/irc_api.drone.yml b/irc_api.drone.yml index b791bbfd1..53d88f149 100644 --- a/irc_api.drone.yml +++ b/irc_api.drone.yml @@ -48,6 +48,34 @@ steps: commands: - cd /opt/1panel/xc-deploy/Test_IRC/devops-build-publish;sh test-irc-update-or-create-stack.sh v${DRONE_BUILD_NUMBER} +trigger: + branch: + - Test_IRC_Net8 + +--- +kind: pipeline +type: ssh +name: ssh-linux-test-irc-publish + +platform: + os: Linux + arch: 386 + +clone: + disable: true + +server: + host: 106.14.89.110 + user: root + password: + from_secret: test_ssh_pwd + +steps: +- name: publish-test-irc-scp + commands: + - cd /opt/1panel/xc-deploy/Test_IRC_SCP/devops-build-publish;sh pull-build-test-irc-scp-image.sh v${DRONE_BUILD_NUMBER} + - cd /opt/1panel/xc-deploy/Test_IRC_SCP ;sh update-image-if-need-then-pull-aliyun.sh v${DRONE_BUILD_NUMBER} + trigger: branch: - Test_IRC_Net8 From 8c16bc2ac5f41397eff2ce28993418dd5bdc1ef2 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Thu, 11 Jul 2024 17:01:50 +0800 Subject: [PATCH 071/251] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E7=AE=A1=E9=81=93?= =?UTF-8?q?=E5=90=8D=E5=AD=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- irc_api.drone.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/irc_api.drone.yml b/irc_api.drone.yml index 53d88f149..290fa2b13 100644 --- a/irc_api.drone.yml +++ b/irc_api.drone.yml @@ -55,7 +55,7 @@ trigger: --- kind: pipeline type: ssh -name: ssh-linux-test-irc-publish +name: ssh-linux-test-irc-scp-publish platform: os: Linux From ded0dbaa2dd6d7d8c2c22d94e75d08dbd6b544b0 Mon Sep 17 00:00:00 2001 From: he <109787524@qq.com> Date: Thu, 11 Jul 2024 17:28:18 +0800 Subject: [PATCH 072/251] =?UTF-8?q?=E9=98=85=E7=89=87=E6=97=B6=E9=97=B4?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=88=B0=E9=85=8D=E7=BD=AE=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.API/appsettings.Test_IRC.json | 6 +++++- .../ReadingImageTask/ReadingImageTaskService.cs | 8 ++++++-- IRaCIS.Core.Domain/_Config/_AppSettings.cs | 11 +++++++++++ 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/IRaCIS.Core.API/appsettings.Test_IRC.json b/IRaCIS.Core.API/appsettings.Test_IRC.json index 1f4e89bd2..28ea34260 100644 --- a/IRaCIS.Core.API/appsettings.Test_IRC.json +++ b/IRaCIS.Core.API/appsettings.Test_IRC.json @@ -60,7 +60,11 @@ "AutoLoginOutMinutes": 1, - "OpenLoginMFA": false + "OpenLoginMFA": false, + + "ContinuousReadingTimeMin": 120, + + "ReadingRestTimeMin": 10 }, "SystemEmailSendConfig": { diff --git a/IRaCIS.Core.Application/Service/Reading/ReadingImageTask/ReadingImageTaskService.cs b/IRaCIS.Core.Application/Service/Reading/ReadingImageTask/ReadingImageTaskService.cs index 92238e196..0158e60b5 100644 --- a/IRaCIS.Core.Application/Service/Reading/ReadingImageTask/ReadingImageTaskService.cs +++ b/IRaCIS.Core.Application/Service/Reading/ReadingImageTask/ReadingImageTaskService.cs @@ -21,6 +21,7 @@ using IRaCIS.Core.Application.Service.ReadingCalculate.Interface; using AutoMapper.QueryableExtensions; using IRaCIS.Application.Contracts; using IRaCIS.Core.Domain.Models; +using Microsoft.Extensions.Options; using static Microsoft.EntityFrameworkCore.DbLoggerCategory; namespace IRaCIS.Application.Services @@ -43,6 +44,7 @@ namespace IRaCIS.Application.Services private readonly IReadingCalculateService _readingCalculateService; private readonly IRepository _subjectVisitRepository; private readonly IRepository _subjectRepository; + private readonly IOptionsMonitor _verifyConfig; private readonly IRepository _readingGlobalTaskInfoRepository; private readonly IRepository _readingCriterionPageRepository; private readonly IRepository _readingTaskRelationRepository; @@ -85,6 +87,7 @@ namespace IRaCIS.Application.Services IReadingCalculateService readingCalculateService, IRepository subjectVisitRepository, IRepository subjectRepository, + IOptionsMonitor verifyConfig, IRepository readingGlobalTaskInfoRepository, IRepository readingCriterionPageRepository, IRepository readingTaskRelationRepository, @@ -126,6 +129,7 @@ namespace IRaCIS.Application.Services this._readingCalculateService = readingCalculateService; this._subjectVisitRepository = subjectVisitRepository; this._subjectRepository = subjectRepository; + this._verifyConfig = verifyConfig; this._readingGlobalTaskInfoRepository = readingGlobalTaskInfoRepository; this._readingCriterionPageRepository = readingCriterionPageRepository; this._readingTaskRelationRepository = readingTaskRelationRepository; @@ -2999,8 +3003,8 @@ namespace IRaCIS.Application.Services var startReadingTimeKey = _userInfo.Id.ToString() + "StartReadingTime"; var startRestTimeKey = _userInfo.Id.ToString() + "StartRestTime"; - int readingMinute = 120; // 为60整数 - int restMinute = 10; // + int readingMinute = _verifyConfig.CurrentValue.ContinuousReadingTimeMin; // 为60整数 + int restMinute = _verifyConfig.CurrentValue.ReadingRestTimeMin; // var startReadingTime = _provider.Get(startReadingTimeKey).Value; var startRestTime = _provider.Get(startRestTimeKey).Value; if (startReadingTime == null && startRestTime == null) diff --git a/IRaCIS.Core.Domain/_Config/_AppSettings.cs b/IRaCIS.Core.Domain/_Config/_AppSettings.cs index 1361360fb..80aed90e8 100644 --- a/IRaCIS.Core.Domain/_Config/_AppSettings.cs +++ b/IRaCIS.Core.Domain/_Config/_AppSettings.cs @@ -24,6 +24,17 @@ namespace IRaCIS.Core.Domain.Share public int AutoLoginOutMinutes { get; set; } public bool OpenLoginMFA { get; set; } + + /// + /// 连续阅片时间 (min) + /// + public int ContinuousReadingTimeMin { get; set; } + + /// + /// 休息时间 (min) + /// + public int ReadingRestTimeMin { get; set; } + } public class SystemEmailSendConfig From 7baf3017856d5c7440789b492ef0417cd346a236 Mon Sep 17 00:00:00 2001 From: he <109787524@qq.com> Date: Thu, 11 Jul 2024 17:29:38 +0800 Subject: [PATCH 073/251] =?UTF-8?q?=E9=85=8D=E7=BD=AE=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.API/appsettings.Event_IRC.json | 6 +++++- IRaCIS.Core.API/appsettings.Prod_IRC.json | 6 +++++- IRaCIS.Core.API/appsettings.US_Prod_IRC.json | 6 +++++- IRaCIS.Core.API/appsettings.US_Test_IRC.json | 6 +++++- IRaCIS.Core.API/appsettings.US_Uat_IRC.json | 6 +++++- IRaCIS.Core.API/appsettings.Uat_IRC.json | 6 +++++- 6 files changed, 30 insertions(+), 6 deletions(-) diff --git a/IRaCIS.Core.API/appsettings.Event_IRC.json b/IRaCIS.Core.API/appsettings.Event_IRC.json index 077f2e820..2e9f86342 100644 --- a/IRaCIS.Core.API/appsettings.Event_IRC.json +++ b/IRaCIS.Core.API/appsettings.Event_IRC.json @@ -42,7 +42,11 @@ "LoginMaxFailCount": 5, "LoginFailLockMinutes": 30, - "AutoLoginOutMinutes": 60 + "AutoLoginOutMinutes": 60, + + "ContinuousReadingTimeMin": 120, + + "ReadingRestTimeMin": 10 }, "SystemEmailSendConfig": { "Port": 465, diff --git a/IRaCIS.Core.API/appsettings.Prod_IRC.json b/IRaCIS.Core.API/appsettings.Prod_IRC.json index 2fe6807e3..02e0a3b74 100644 --- a/IRaCIS.Core.API/appsettings.Prod_IRC.json +++ b/IRaCIS.Core.API/appsettings.Prod_IRC.json @@ -44,7 +44,11 @@ "AutoLoginOutMinutes": 360, - "OpenLoginMFA": false + "OpenLoginMFA": false, + + "ContinuousReadingTimeMin": 120, + + "ReadingRestTimeMin": 10 }, diff --git a/IRaCIS.Core.API/appsettings.US_Prod_IRC.json b/IRaCIS.Core.API/appsettings.US_Prod_IRC.json index ca614f2ac..8957701a9 100644 --- a/IRaCIS.Core.API/appsettings.US_Prod_IRC.json +++ b/IRaCIS.Core.API/appsettings.US_Prod_IRC.json @@ -58,7 +58,11 @@ "LoginMaxFailCount": 5, "LoginFailLockMinutes": 30, - "AutoLoginOutMinutes": 60 + "AutoLoginOutMinutes": 60, + + "ContinuousReadingTimeMin": 120, + + "ReadingRestTimeMin": 10 }, "SystemEmailSendConfig": { diff --git a/IRaCIS.Core.API/appsettings.US_Test_IRC.json b/IRaCIS.Core.API/appsettings.US_Test_IRC.json index 19d4dbe15..815a762e3 100644 --- a/IRaCIS.Core.API/appsettings.US_Test_IRC.json +++ b/IRaCIS.Core.API/appsettings.US_Test_IRC.json @@ -64,7 +64,11 @@ "LoginMaxFailCount": 5, "LoginFailLockMinutes": 30, - "AutoLoginOutMinutes": 60 + "AutoLoginOutMinutes": 60, + + "ContinuousReadingTimeMin": 120, + + "ReadingRestTimeMin": 10 }, "SystemEmailSendConfig": { diff --git a/IRaCIS.Core.API/appsettings.US_Uat_IRC.json b/IRaCIS.Core.API/appsettings.US_Uat_IRC.json index 8ed58013e..d3f3950c8 100644 --- a/IRaCIS.Core.API/appsettings.US_Uat_IRC.json +++ b/IRaCIS.Core.API/appsettings.US_Uat_IRC.json @@ -68,7 +68,11 @@ "LoginMaxFailCount": 5, "LoginFailLockMinutes": 30, - "AutoLoginOutMinutes": 60 + "AutoLoginOutMinutes": 60, + + "ContinuousReadingTimeMin": 120, + + "ReadingRestTimeMin": 10 }, "SystemEmailSendConfig": { diff --git a/IRaCIS.Core.API/appsettings.Uat_IRC.json b/IRaCIS.Core.API/appsettings.Uat_IRC.json index ddc5ad7ad..77945da7d 100644 --- a/IRaCIS.Core.API/appsettings.Uat_IRC.json +++ b/IRaCIS.Core.API/appsettings.Uat_IRC.json @@ -51,7 +51,11 @@ "LoginFailLockMinutes": 30, "AutoLoginOutMinutes": 60, - "OpenLoginMFA": false + "OpenLoginMFA": false, + + "ContinuousReadingTimeMin": 120, + + "ReadingRestTimeMin": 10 }, "SystemEmailSendConfig": { From cec678a24bdfe1d660458a17682173db27cb5051 Mon Sep 17 00:00:00 2001 From: he <109787524@qq.com> Date: Fri, 12 Jul 2024 10:30:44 +0800 Subject: [PATCH 074/251] =?UTF-8?q?=E6=8F=90=E7=A4=BA=E8=AF=AD=E4=BF=AE?= =?UTF-8?q?=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Service/Reading/ReadingImageTask/ReadingImageTaskService.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/IRaCIS.Core.Application/Service/Reading/ReadingImageTask/ReadingImageTaskService.cs b/IRaCIS.Core.Application/Service/Reading/ReadingImageTask/ReadingImageTaskService.cs index 0158e60b5..96aaf7e28 100644 --- a/IRaCIS.Core.Application/Service/Reading/ReadingImageTask/ReadingImageTaskService.cs +++ b/IRaCIS.Core.Application/Service/Reading/ReadingImageTask/ReadingImageTaskService.cs @@ -3017,7 +3017,7 @@ namespace IRaCIS.Application.Services int timespanMin = (DateTime.Now - cacheStartRestTime).Minutes; if (timespanMin <= restMinute) { - throw new BusinessValidationFailedException(_localizer["ReadingImage_NeedRest", readingMinute / 60m, restMinute]); + throw new BusinessValidationFailedException(_localizer["ReadingImage_NeedRest", 2, 10]); } else { From d62d2770f46e390f8af69045f9356d467eeb8164 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Fri, 12 Jul 2024 13:52:45 +0800 Subject: [PATCH 075/251] =?UTF-8?q?=E4=BF=AE=E6=94=B9scp=20=E9=85=8D?= =?UTF-8?q?=E7=BD=AE=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRC.Core.SCP/appsettings.IRC_US_SCP.json | 76 ------------------- ...SCP.json => appsettings.Prod_IRC_SCP.json} | 0 ...SCP.json => appsettings.Test_IRC_SCP.json} | 0 ..._SCP.json => appsettings.Uat_IRC_SCP.json} | 0 4 files changed, 76 deletions(-) delete mode 100644 IRC.Core.SCP/appsettings.IRC_US_SCP.json rename IRC.Core.SCP/{appsettings.IRC_Prod_SCP.json => appsettings.Prod_IRC_SCP.json} (100%) rename IRC.Core.SCP/{appsettings.IRC_Test_SCP.json => appsettings.Test_IRC_SCP.json} (100%) rename IRC.Core.SCP/{appsettings.IRC_Uat_SCP.json => appsettings.Uat_IRC_SCP.json} (100%) diff --git a/IRC.Core.SCP/appsettings.IRC_US_SCP.json b/IRC.Core.SCP/appsettings.IRC_US_SCP.json deleted file mode 100644 index 7821a16b8..000000000 --- a/IRC.Core.SCP/appsettings.IRC_US_SCP.json +++ /dev/null @@ -1,76 +0,0 @@ -{ - "Logging": { - "LogLevel": { - "Default": "Information", - "Microsoft": "Warning", - "Microsoft.Hosting.Lifetime": "Information" - } - }, - "ObjectStoreService": { - "ObjectStoreUse": "MinIO", - "AliyunOSS": { - "regionId": "cn-shanghai", - "endpoint": "https://oss-cn-shanghai.aliyuncs.com", - "accessKeyId": "LTAI5tKvzs7ed3UfSpNk3xwQ", - "accessKeySecret": "zTIceGEShlZDGnLrCFfIGFE7TXVRio", - "bucketName": "zy-sir-test-store", - "roleArn": "acs:ram::1899121822495495:role/oss-upload", - "viewEndpoint": "https://zy-sir-test-store.oss-cn-shanghai.aliyuncs.com", - "region": "oss-cn-shanghai" - }, - - "MinIO": { - "endPoint": "44.218.11.19", - "port": "9001", - "useSSL": false, - "accessKey": "lH8DkKskLuDqPaiubuSQ", - "secretKey": "pdPdicvvLeH7xAC5yFUrI7odMyBfOXxvVWMvKYV4", - "bucketName": "hir-us", - "viewEndpoint": "http://hir.us.extimaging.com/oss/hir-us" - }, - - "AWS": { - "endPoint": "s3.us-east-1.amazonaws.com", - "useSSL": false, - "accessKey": "AKIAZQ3DRSOHFPJJ6FEU", - "secretKey": "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", - "bucketName": "ei-irc-test-store", - "viewEndpoint": "https://ei-irc-test-store.s3.amazonaws.com/" - } - }, - "ConnectionStrings": { - "RemoteNew": "Server=44.218.11.19,1435;Database=US_HIR;User ID=sa;Password=xc@123456;TrustServerCertificate=true", - "Hangfire": "Server=44.218.11.19,1435;Database=US_HIR_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true" - }, - "BasicSystemConfig": { - - "OpenUserComplexPassword": false, - - "OpenSignDocumentBeforeWork": false, - - "OpenTrialRelationDelete": true, - - "OpenLoginLimit": false, - "LoginMaxFailCount": 5, - - "LoginFailLockMinutes": 30 - }, - - "SystemEmailSendConfig": { - "Port": 465, - "Host": "smtp.qiye.aliyun.com", - "FromEmail": "uat-study@extimaging.com", - "FromName": "Uat_Study", - "AuthorizationCode": "zhanying123", - "SiteUrl": "http://study.uat.extimaging.com/login" - }, - "DicomSCPServiceConfig": { - "CalledAEList": [ - "STORESCP", - "Value1", - "Value2", - "Value3" - ], - "ServerPort": 11112 - } -} diff --git a/IRC.Core.SCP/appsettings.IRC_Prod_SCP.json b/IRC.Core.SCP/appsettings.Prod_IRC_SCP.json similarity index 100% rename from IRC.Core.SCP/appsettings.IRC_Prod_SCP.json rename to IRC.Core.SCP/appsettings.Prod_IRC_SCP.json diff --git a/IRC.Core.SCP/appsettings.IRC_Test_SCP.json b/IRC.Core.SCP/appsettings.Test_IRC_SCP.json similarity index 100% rename from IRC.Core.SCP/appsettings.IRC_Test_SCP.json rename to IRC.Core.SCP/appsettings.Test_IRC_SCP.json diff --git a/IRC.Core.SCP/appsettings.IRC_Uat_SCP.json b/IRC.Core.SCP/appsettings.Uat_IRC_SCP.json similarity index 100% rename from IRC.Core.SCP/appsettings.IRC_Uat_SCP.json rename to IRC.Core.SCP/appsettings.Uat_IRC_SCP.json From e0c6e9aabf7af081ff644930f6a65665071e953b Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Mon, 15 Jul 2024 15:46:31 +0800 Subject: [PATCH 076/251] =?UTF-8?q?=E4=BF=AE=E6=94=B9ivus=E5=BD=B1?= =?UTF-8?q?=E5=83=8F=E4=B8=8B=E8=BD=BD=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Properties/launchSettings.json | 4 +- .../ImageAndDoc/DownloadAndUploadService.cs | 216 +++++++++++------- .../DTO/TrialSiteSurveyViewModel.cs | 2 +- .../SiteSurvey/TrialSiteSurveyService.cs | 4 +- .../TrialSiteUser/TrialConfigService.cs | 8 + .../Trial/TrialExpedited.cs | 21 +- IRaCIS.Core.Domain/Trial/Trial.cs | 3 +- IRaCIS.Core.Domain/Visit/SubjectVisit.cs | 4 + 8 files changed, 174 insertions(+), 88 deletions(-) diff --git a/IRaCIS.Core.API/Properties/launchSettings.json b/IRaCIS.Core.API/Properties/launchSettings.json index 2456ff45f..dbe673470 100644 --- a/IRaCIS.Core.API/Properties/launchSettings.json +++ b/IRaCIS.Core.API/Properties/launchSettings.json @@ -54,11 +54,11 @@ }, "applicationUrl": "http://localhost:6100" }, - "IRaCIS.US_IRC": { + "IRaCIS.US_Uat_IRC": { "commandName": "Project", "launchBrowser": true, "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "US_IRC" + "ASPNETCORE_ENVIRONMENT": "US_Uat_IRC" }, "applicationUrl": "http://localhost:6100" } diff --git a/IRaCIS.Core.Application/Service/ImageAndDoc/DownloadAndUploadService.cs b/IRaCIS.Core.Application/Service/ImageAndDoc/DownloadAndUploadService.cs index f8e3c2606..dab399123 100644 --- a/IRaCIS.Core.Application/Service/ImageAndDoc/DownloadAndUploadService.cs +++ b/IRaCIS.Core.Application/Service/ImageAndDoc/DownloadAndUploadService.cs @@ -23,7 +23,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc { public interface IDownloadAndUploadService { - Task PackageAndAnonymizImage(Guid trialId, Guid subjectVisitId, bool isAnonymize = true); + Task PackageAndAnonymizImage(Guid trialId, Guid subjectVisitId, bool isDicom, bool isAnonymize = true); } [ApiExplorerSettings(GroupName = "Trial")] public class DownloadAndUploadService : BaseService, IDownloadAndUploadService @@ -107,8 +107,8 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc { await SubejctRandomReadingTaskNameDeal(subjectId, trialReadingCriterionId); - var query = _repository.Where(t => t.SubjectId == subjectId && t.TrialReadingCriterionId == trialReadingCriterionId && t.SourceSubjectVisitId != null - && t.DoctorUserId == _userInfo.Id && t.TaskState==TaskState.Effect) + var query = _repository.Where(t => t.SubjectId == subjectId && t.TrialReadingCriterionId == trialReadingCriterionId && t.SourceSubjectVisitId != null + && t.DoctorUserId == _userInfo.Id && t.TaskState == TaskState.Effect) .Select(u => new SubjectImageUploadDTO() { VisitTaskId = u.Id, @@ -129,7 +129,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc PackState = u.SourceSubjectVisit.PackState, OrginalStudyList = u.SourceSubjectVisit.StudyList - .Where(t => u.TrialReadingCriterion.IsImageFilter ?("|"+u.TrialReadingCriterion.CriterionModalitys+"|").Contains("|"+t.ModalityForEdit+"|" ) : true) + .Where(t => u.TrialReadingCriterion.IsImageFilter ? ("|" + u.TrialReadingCriterion.CriterionModalitys + "|").Contains("|" + t.ModalityForEdit + "|") : true) .Select(t => new StudyBasicInfo() { Id = t.Id, @@ -484,24 +484,38 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc /// /// /// + /// /// /// - public async Task RequestPackageAndAnonymizImage(Guid trialId, Guid subjectVisitId, bool isAnonymize = true) + public async Task RequestPackageAndAnonymizImage(Guid trialId, Guid subjectVisitId, bool isDicom, bool isAnonymize = true) { var subjectVisit = await _subjectVisitRepository.FirstOrDefaultAsync(t => t.Id == subjectVisitId); - if (subjectVisit.PackState == PackState.WaitPack) - { - HangfireJobHelper.NotImmediatelyOnceOnlyJob(t => t.PackageAndAnonymizImage(trialId, subjectVisitId, isAnonymize), TimeSpan.FromSeconds(1)); + var packState = isDicom ? subjectVisit.PackState : subjectVisit.NoDicomPackState; + + if (packState == PackState.WaitPack) + { + + if (isDicom) + { + subjectVisit.PackState = PackState.Packing; + HangfireJobHelper.NotImmediatelyOnceOnlyJob(t => t.PackageAndAnonymizImage(trialId, subjectVisitId,true, isAnonymize), TimeSpan.FromSeconds(1)); + + } + else + { + subjectVisit.NoDicomPackState = PackState.Packing; + + HangfireJobHelper.NotImmediatelyOnceOnlyJob(t => t.PackageAndAnonymizImage(trialId, subjectVisitId, false, isAnonymize), TimeSpan.FromSeconds(1)); + } - subjectVisit.PackState = PackState.Packing; await _subjectVisitRepository.SaveChangesAsync(); } - return ResponseOutput.Ok(subjectVisit.VisitImageZipPath); + return ResponseOutput.Ok(isDicom ? subjectVisit.VisitImageZipPath : subjectVisit.VisitNoDicomImageZipPath); } @@ -544,9 +558,10 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc /// /// /// + /// /// /// - public async Task PackageAndAnonymizImage(Guid trialId, Guid subjectVisitId, bool isAnonymize = true) + public async Task PackageAndAnonymizImage(Guid trialId, Guid subjectVisitId, bool isDicom, bool isAnonymize = true) { var subjectVisit = await _subjectVisitRepository.FirstOrDefaultAsync(t => t.Id == subjectVisitId); @@ -590,6 +605,20 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc }) }) + }), + + NoneDicomStudyList = sv.NoneDicomStudyList.Select(nd => new + { + nd.Modality, + nd.StudyCode, + nd.ImageDate, + + FileList = nd.NoneDicomFileList.Select(file => new + { + file.FileName, + file.Path, + file.FileType + }) }) }; @@ -601,107 +630,138 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc string tempFolderPath = Path.Combine(Directory.GetCurrentDirectory(), $"DownloadTemp_{NewId.NextGuid()}"); Directory.CreateDirectory(tempFolderPath); - // 遍历查询结果 - foreach (var studyInfo in info.StudyList) + //dicom 处理 + + if (isDicom) { - // 遍历 Series - foreach (var seriesInfo in studyInfo.SeriesList) + // 遍历查询结果 + foreach (var studyInfo in info.StudyList) { - string studyFolderPath = Path.Combine(tempFolderPath, $"{info.SubjectCode}_{info.VisitName}", $"{studyInfo.StudyCode}_{studyInfo.StudyTime?.ToString("yyyy-MM-dd")}_{seriesInfo.Modality}"); - - // 创建 影像 文件夹 - Directory.CreateDirectory(studyFolderPath); - - // 遍历 InstancePathList - foreach (var instanceInfo in seriesInfo.InstancePathList) + // 遍历 Series + foreach (var seriesInfo in studyInfo.SeriesList) { - // 复制文件到相应的文件夹 - string destinationPath = Path.Combine(studyFolderPath, Path.GetFileName(instanceInfo.Path)); + string studyDicomFolderPath = Path.Combine(tempFolderPath, "Dicom", $"{info.SubjectCode}_{info.VisitName}", $"{studyInfo.StudyCode}_{studyInfo.StudyTime?.ToString("yyyy-MM-dd")}_{seriesInfo.Modality}"); - //下载到当前目录 - await _oSSService.DownLoadFromOSSAsync(instanceInfo.Path, destinationPath); + // 创建 影像 文件夹 + Directory.CreateDirectory(studyDicomFolderPath); - #region 匿名化逻辑 - - - if (isAnonymize) + // 遍历 InstancePathList + foreach (var instanceInfo in seriesInfo.InstancePathList) { - //受试者随机阅片,需要匿名化检查时间 - DicomFile dicomFile = await DicomFile.OpenAsync(destinationPath, Encoding.Default); - DicomDataset dataset = dicomFile.Dataset; - dataset.AddOrUpdate(DicomTag.StudyDate, string.Empty); - dataset.AddOrUpdate(DicomTag.StudyTime, string.Empty); + // 复制文件到相应的文件夹 + string destinationPath = Path.Combine(studyDicomFolderPath, Path.GetFileName(instanceInfo.Path)); - #region 前端已经匿名化,不需要做相关tag匿名化 - //DicomFile dicomFile = await DicomFile.OpenAsync(destinationPath, Encoding.Default); + //下载到当前目录 + await _oSSService.DownLoadFromOSSAsync(instanceInfo.Path, destinationPath); - //DicomDataset dataset = dicomFile.Dataset; + #region 匿名化逻辑 - //foreach (var item in addOrUpdateFixedFieldList) - //{ - // var dicomTag = new DicomTag(Convert.ToUInt16(item.Group, 16), Convert.ToUInt16(item.Element, 16)); + if (isAnonymize) + { + //受试者随机阅片,需要匿名化检查时间 + DicomFile dicomFile = await DicomFile.OpenAsync(destinationPath, Encoding.Default); + DicomDataset dataset = dicomFile.Dataset; + dataset.AddOrUpdate(DicomTag.StudyDate, string.Empty); + dataset.AddOrUpdate(DicomTag.StudyTime, string.Empty); - // dataset.AddOrUpdate(dicomTag, item.ReplaceValue); - //} + #region 前端已经匿名化,不需要做相关tag匿名化 + //DicomFile dicomFile = await DicomFile.OpenAsync(destinationPath, Encoding.Default); - //foreach (var item in ircFieldList) - //{ + //DicomDataset dataset = dicomFile.Dataset; - // var dicomTag = new DicomTag(Convert.ToUInt16(item.Group, 16), Convert.ToUInt16(item.Element, 16)); + //foreach (var item in addOrUpdateFixedFieldList) + //{ - // if (dicomTag == DicomTag.ClinicalTrialProtocolID) - // { - // dataset.AddOrUpdate(dicomTag, subjectAndVisitInfo.TrialCode); + // var dicomTag = new DicomTag(Convert.ToUInt16(item.Group, 16), Convert.ToUInt16(item.Element, 16)); - // } - // if (dicomTag == DicomTag.ClinicalTrialSiteID) - // { - // //dataset.AddOrUpdate(dicomTag, subjectAndVisitInfo.TrialSiteCode); + // dataset.AddOrUpdate(dicomTag, item.ReplaceValue); + //} - // } - // if (dicomTag == DicomTag.ClinicalTrialSubjectID) - // { - // dataset.AddOrUpdate(dicomTag, subjectAndVisitInfo.SubjectCode); + //foreach (var item in ircFieldList) + //{ - // } - // if (dicomTag == DicomTag.ClinicalTrialTimePointID) - // { - // dataset.AddOrUpdate(dicomTag, subjectAndVisitInfo.VisitNum.ToString()); + // var dicomTag = new DicomTag(Convert.ToUInt16(item.Group, 16), Convert.ToUInt16(item.Element, 16)); - // } - // if (dicomTag == DicomTag.PatientID) - // { - // dataset.AddOrUpdate(dicomTag, subjectAndVisitInfo.TrialCode + "_" + subjectAndVisitInfo.SubjectCode); + // if (dicomTag == DicomTag.ClinicalTrialProtocolID) + // { + // dataset.AddOrUpdate(dicomTag, subjectAndVisitInfo.TrialCode); - // } + // } + // if (dicomTag == DicomTag.ClinicalTrialSiteID) + // { + // //dataset.AddOrUpdate(dicomTag, subjectAndVisitInfo.TrialSiteCode); - //} + // } + // if (dicomTag == DicomTag.ClinicalTrialSubjectID) + // { + // dataset.AddOrUpdate(dicomTag, subjectAndVisitInfo.SubjectCode); + + // } + // if (dicomTag == DicomTag.ClinicalTrialTimePointID) + // { + // dataset.AddOrUpdate(dicomTag, subjectAndVisitInfo.VisitNum.ToString()); + + // } + // if (dicomTag == DicomTag.PatientID) + // { + // dataset.AddOrUpdate(dicomTag, subjectAndVisitInfo.TrialCode + "_" + subjectAndVisitInfo.SubjectCode); + + // } + + //} + #endregion + + } #endregion - } - #endregion } } + + + var zipDicomPath = Path.Combine(Directory.GetCurrentDirectory(), $"{info.SubjectCode}_{info.VisitName}_ImageStudy_Dicom.zip"); + ZipFile.CreateFromDirectory(Path.Combine(tempFolderPath, "Dicom"), zipDicomPath); + //上传到Oss + var relativeDicomPath = await _oSSService.UploadToOSSAsync(zipDicomPath, $"download_zip", false); + + await _subjectVisitRepository.BatchUpdateNoTrackingAsync(t => t.Id == subjectVisitId, u => new SubjectVisit() { PackState = PackState.Packed, VisitImageZipPath = relativeDicomPath }); + + + File.Delete(zipDicomPath); } + else + { + //非dicom 处理 - var zipPath = Path.Combine(Directory.GetCurrentDirectory(), $"{info.SubjectCode}_{info.VisitName}_ImageStudy.zip"); + foreach (var noneDicomStudy in info.NoneDicomStudyList) + { + string studyNoneDicomFolderPath = Path.Combine(tempFolderPath, "NoneDicom", $"{info.SubjectCode}_{info.VisitName}", $"{noneDicomStudy.StudyCode}_{noneDicomStudy.ImageDate.ToString("yyyy-MM-dd")}_{noneDicomStudy.Modality}"); - ZipFile.CreateFromDirectory(tempFolderPath, zipPath); + Directory.CreateDirectory(studyNoneDicomFolderPath); - //上传到Oss - var relativePath = await _oSSService.UploadToOSSAsync(zipPath, $"download_zip", false); + foreach (var file in noneDicomStudy.FileList) + { + string destinationPath = Path.Combine(studyNoneDicomFolderPath, Path.GetFileName(file.FileName)); + + //下载到当前目录 + await _oSSService.DownLoadFromOSSAsync(file.Path, destinationPath); + } + } - //subjectVisit.PackState = PackState.Packed; - //subjectVisit.VisitImageZipPath = relativePath; - //await _subjectVisitRepository.SaveChangesAsync(); - await _subjectVisitRepository.BatchUpdateNoTrackingAsync(t => t.Id == subjectVisitId, u => new SubjectVisit() { PackState = PackState.Packed, VisitImageZipPath = relativePath }); + var zipNoneDicomPath = Path.Combine(Directory.GetCurrentDirectory(), $"{info.SubjectCode}_{info.VisitName}_ImageStudy_NoneDicom.zip"); + ZipFile.CreateFromDirectory(Path.Combine(tempFolderPath, "NoneDicom"), zipNoneDicomPath); + var relativeNoneDicomPath = await _oSSService.UploadToOSSAsync(zipNoneDicomPath, $"download_zip", false); + File.Delete(zipNoneDicomPath); + + await _subjectVisitRepository.BatchUpdateNoTrackingAsync(t => t.Id == subjectVisitId, u => new SubjectVisit() { PackState = PackState.Packed, VisitNoDicomImageZipPath = relativeNoneDicomPath }); + + + } //清理文件夹 Directory.Delete(tempFolderPath, true); - File.Delete(zipPath); } } diff --git a/IRaCIS.Core.Application/Service/SiteSurvey/DTO/TrialSiteSurveyViewModel.cs b/IRaCIS.Core.Application/Service/SiteSurvey/DTO/TrialSiteSurveyViewModel.cs index e74d6726c..6dd3f284d 100644 --- a/IRaCIS.Core.Application/Service/SiteSurvey/DTO/TrialSiteSurveyViewModel.cs +++ b/IRaCIS.Core.Application/Service/SiteSurvey/DTO/TrialSiteSurveyViewModel.cs @@ -72,7 +72,7 @@ namespace IRaCIS.Core.Application.Contracts public List TrialSiteUserSurveyList { get; set; } = new List(); - public SiteSurveyFiledConfig SiteSurveyFiledConfig { get; set; } + public TrialExtraConfig SiteSurveyFiledConfig { get; set; } } public class TrialSiteUserSurveyAllDTO : TrialSiteUserSurveyView diff --git a/IRaCIS.Core.Application/Service/SiteSurvey/TrialSiteSurveyService.cs b/IRaCIS.Core.Application/Service/SiteSurvey/TrialSiteSurveyService.cs index 27779454a..957bdba54 100644 --- a/IRaCIS.Core.Application/Service/SiteSurvey/TrialSiteSurveyService.cs +++ b/IRaCIS.Core.Application/Service/SiteSurvey/TrialSiteSurveyService.cs @@ -391,9 +391,9 @@ namespace IRaCIS.Core.Application.Contracts 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).Select(t => t.Trial.SiteSurveyConfigJsonStr).FirstOrDefault()??string.Empty; + var siteSurveryConfig = _trialSiteSurveyRepository.Where(t => t.Id == trialSiteSurveyId).Select(t => t.Trial.TrialExtraConfigJsonStr).FirstOrDefault()??string.Empty; - result.SiteSurveyFiledConfig = JsonConvert.DeserializeObject(siteSurveryConfig) ?? new SiteSurveyFiledConfig(); + result.SiteSurveyFiledConfig = JsonConvert.DeserializeObject(siteSurveryConfig) ?? new TrialExtraConfig(); return result; } diff --git a/IRaCIS.Core.Application/Service/TrialSiteUser/TrialConfigService.cs b/IRaCIS.Core.Application/Service/TrialSiteUser/TrialConfigService.cs index 91e4e0232..f976c86ea 100644 --- a/IRaCIS.Core.Application/Service/TrialSiteUser/TrialConfigService.cs +++ b/IRaCIS.Core.Application/Service/TrialSiteUser/TrialConfigService.cs @@ -21,6 +21,7 @@ using DocumentFormat.OpenXml.Office.CustomUI; using IRaCIS.Core.Domain.Models; using IRaCIS.Application.Contracts; using SixLabors.ImageSharp.Formats.Tiff.Compression.Decompressors; +using Newtonsoft.Json; namespace IRaCIS.Core.Application { @@ -1373,5 +1374,12 @@ namespace IRaCIS.Core.Application return ResponseOutput.Ok(cro.Id.ToString(), ApiResponseCodeEnum.NeedTips); } + + public async Task GetTrialExtralConfig(Guid trialId) + { + var extralConfig = _trialRepository.Where(t => t.Id == trialId).Select(t => t.TrialExtraConfigJsonStr).FirstOrDefault() ?? string.Empty; + + return JsonConvert.DeserializeObject(extralConfig) ?? new TrialExtraConfig(); + } } } diff --git a/IRaCIS.Core.Domain.Share/Trial/TrialExpedited.cs b/IRaCIS.Core.Domain.Share/Trial/TrialExpedited.cs index 04d5da70a..506830ba6 100644 --- a/IRaCIS.Core.Domain.Share/Trial/TrialExpedited.cs +++ b/IRaCIS.Core.Domain.Share/Trial/TrialExpedited.cs @@ -41,11 +41,26 @@ namespace IRaCIS.Core.Domain.Share } - public class SiteSurveyFiledConfig + public class TrialExtraConfig { - public List NotShowFieldList { get; set; }=new List(); + #region MyRegion + + //QC质控 + public bool IsSupportQCDownloadImage { get; set; } = false; + + #endregion + + + + #region 中心调研 + + public List NotShowFieldList { get; set; } = new List(); + + public List ModifyFiledList { get; set; } = new List(); + + #endregion + - public List ModifyFiledList { get; set; }=new List(); } diff --git a/IRaCIS.Core.Domain/Trial/Trial.cs b/IRaCIS.Core.Domain/Trial/Trial.cs index d00d43d55..2160203ab 100644 --- a/IRaCIS.Core.Domain/Trial/Trial.cs +++ b/IRaCIS.Core.Domain/Trial/Trial.cs @@ -182,9 +182,8 @@ namespace IRaCIS.Core.Domain.Models - //public List - public string SiteSurveyConfigJsonStr { get; set; } = string.Empty; + public string TrialExtraConfigJsonStr { get; set; } = string.Empty; public bool VisitPlanConfirmed { get; set; } diff --git a/IRaCIS.Core.Domain/Visit/SubjectVisit.cs b/IRaCIS.Core.Domain/Visit/SubjectVisit.cs index e847167a0..0d7364316 100644 --- a/IRaCIS.Core.Domain/Visit/SubjectVisit.cs +++ b/IRaCIS.Core.Domain/Visit/SubjectVisit.cs @@ -248,6 +248,10 @@ namespace IRaCIS.Core.Domain.Models public string VisitImageZipPath { get; set; } = string.Empty; public PackState PackState { get; set; } + + public PackState NoDicomPackState { get; set; } + + public string VisitNoDicomImageZipPath { get; set;} = string.Empty; } /// /// 影像下载打包状态 From 0c94ef86b0114d08813b500b7e8d58aa1d8174be Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Mon, 15 Jul 2024 16:27:06 +0800 Subject: [PATCH 077/251] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=89=93=E5=8C=85?= =?UTF-8?q?=E4=B8=8B=E8=BD=BD=E9=AA=8C=E8=AF=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Service/ImageAndDoc/DownloadAndUploadService.cs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/IRaCIS.Core.Application/Service/ImageAndDoc/DownloadAndUploadService.cs b/IRaCIS.Core.Application/Service/ImageAndDoc/DownloadAndUploadService.cs index dab399123..56a9364f2 100644 --- a/IRaCIS.Core.Application/Service/ImageAndDoc/DownloadAndUploadService.cs +++ b/IRaCIS.Core.Application/Service/ImageAndDoc/DownloadAndUploadService.cs @@ -11,6 +11,7 @@ using MassTransit; using MathNet.Numerics; using Medallion.Threading; using Microsoft.AspNetCore.Mvc; +using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Data; @@ -490,6 +491,15 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc public async Task RequestPackageAndAnonymizImage(Guid trialId, Guid subjectVisitId, bool isDicom, bool isAnonymize = true) { + var extralConfig = _repository.Where(t => t.Id == trialId).Select(t => t.TrialExtraConfigJsonStr).FirstOrDefault() ?? string.Empty; + + var config= JsonConvert.DeserializeObject(extralConfig) ?? new TrialExtraConfig(); + + if(config.IsSupportQCDownloadImage==false) + { + throw new BusinessValidationFailedException("该项目不支持QC下载影像"); + } + var subjectVisit = await _subjectVisitRepository.FirstOrDefaultAsync(t => t.Id == subjectVisitId); var packState = isDicom ? subjectVisit.PackState : subjectVisit.NoDicomPackState; From b77d2d916062bc70b2a53f0e3a5234741da536dd Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Mon, 15 Jul 2024 16:55:21 +0800 Subject: [PATCH 078/251] =?UTF-8?q?=E5=87=8F=E5=B0=91=E5=8E=8B=E7=BC=A9?= =?UTF-8?q?=E5=8C=85=E8=AE=BF=E8=A7=86=E5=B1=82=E7=BA=A7=EF=BC=8C=E5=90=8C?= =?UTF-8?q?=E6=97=B6=E5=A4=84=E7=90=86=E5=8D=95=E4=B8=AA=E9=9D=9Edicom=20?= =?UTF-8?q?=E7=89=B9=E6=AE=8A=E6=83=85=E5=86=B5=E5=8E=8B=E7=BC=A9=E5=8C=85?= =?UTF-8?q?=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ImageAndDoc/DownloadAndUploadService.cs | 56 +++++++++++-------- 1 file changed, 33 insertions(+), 23 deletions(-) diff --git a/IRaCIS.Core.Application/Service/ImageAndDoc/DownloadAndUploadService.cs b/IRaCIS.Core.Application/Service/ImageAndDoc/DownloadAndUploadService.cs index 56a9364f2..509cf43a3 100644 --- a/IRaCIS.Core.Application/Service/ImageAndDoc/DownloadAndUploadService.cs +++ b/IRaCIS.Core.Application/Service/ImageAndDoc/DownloadAndUploadService.cs @@ -493,15 +493,17 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc { var extralConfig = _repository.Where(t => t.Id == trialId).Select(t => t.TrialExtraConfigJsonStr).FirstOrDefault() ?? string.Empty; - var config= JsonConvert.DeserializeObject(extralConfig) ?? new TrialExtraConfig(); + var config = JsonConvert.DeserializeObject(extralConfig) ?? new TrialExtraConfig(); - if(config.IsSupportQCDownloadImage==false) + if (config.IsSupportQCDownloadImage == false) { throw new BusinessValidationFailedException("该项目不支持QC下载影像"); } var subjectVisit = await _subjectVisitRepository.FirstOrDefaultAsync(t => t.Id == subjectVisitId); + var sujectCode = await _subjectVisitRepository.Where(t => t.Id == subjectVisitId).Select(t => t.Subject.Code).FirstOrDefaultAsync(); + var packState = isDicom ? subjectVisit.PackState : subjectVisit.NoDicomPackState; if (packState == PackState.WaitPack) @@ -510,7 +512,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc if (isDicom) { subjectVisit.PackState = PackState.Packing; - HangfireJobHelper.NotImmediatelyOnceOnlyJob(t => t.PackageAndAnonymizImage(trialId, subjectVisitId,true, isAnonymize), TimeSpan.FromSeconds(1)); + HangfireJobHelper.NotImmediatelyOnceOnlyJob(t => t.PackageAndAnonymizImage(trialId, subjectVisitId, true, isAnonymize), TimeSpan.FromSeconds(1)); } else @@ -522,10 +524,10 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc await _subjectVisitRepository.SaveChangesAsync(); - } - return ResponseOutput.Ok(isDicom ? subjectVisit.VisitImageZipPath : subjectVisit.VisitNoDicomImageZipPath); + return ResponseOutput.Ok(isDicom ? subjectVisit.VisitImageZipPath : subjectVisit.VisitNoDicomImageZipPath, + new { FileName = $"{sujectCode}_{subjectVisit.VisitName}_ImageStudy_{(isDicom ? "Dicom" : "NoneDicom")}.zip" }); } @@ -650,7 +652,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc // 遍历 Series foreach (var seriesInfo in studyInfo.SeriesList) { - string studyDicomFolderPath = Path.Combine(tempFolderPath, "Dicom", $"{info.SubjectCode}_{info.VisitName}", $"{studyInfo.StudyCode}_{studyInfo.StudyTime?.ToString("yyyy-MM-dd")}_{seriesInfo.Modality}"); + string studyDicomFolderPath = Path.Combine(tempFolderPath, "Dicom",/* $"{info.SubjectCode}_{info.VisitName}",*/ $"{studyInfo.StudyCode}_{studyInfo.StudyTime?.ToString("yyyy-MM-dd")}_{seriesInfo.Modality}"); // 创建 影像 文件夹 Directory.CreateDirectory(studyDicomFolderPath); @@ -741,31 +743,39 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc } else { - //非dicom 处理 + var relativeNoneDicomPath = string.Empty; - foreach (var noneDicomStudy in info.NoneDicomStudyList) + if (info.NoneDicomStudyList.Count() == 1 && info.NoneDicomStudyList.SelectMany(t => t.FileList).Count() == 1) { - string studyNoneDicomFolderPath = Path.Combine(tempFolderPath, "NoneDicom", $"{info.SubjectCode}_{info.VisitName}", $"{noneDicomStudy.StudyCode}_{noneDicomStudy.ImageDate.ToString("yyyy-MM-dd")}_{noneDicomStudy.Modality}"); + relativeNoneDicomPath = info.NoneDicomStudyList.First().FileList.First().Path; + } + else + { + //非dicom 处理 - Directory.CreateDirectory(studyNoneDicomFolderPath); - - foreach (var file in noneDicomStudy.FileList) + foreach (var noneDicomStudy in info.NoneDicomStudyList) { - string destinationPath = Path.Combine(studyNoneDicomFolderPath, Path.GetFileName(file.FileName)); + string studyNoneDicomFolderPath = Path.Combine(tempFolderPath, "NoneDicom", /*$"{info.SubjectCode}_{info.VisitName}",*/ $"{noneDicomStudy.StudyCode}_{noneDicomStudy.ImageDate.ToString("yyyy-MM-dd")}_{noneDicomStudy.Modality}"); - //下载到当前目录 - await _oSSService.DownLoadFromOSSAsync(file.Path, destinationPath); + Directory.CreateDirectory(studyNoneDicomFolderPath); + + foreach (var file in noneDicomStudy.FileList) + { + string destinationPath = Path.Combine(studyNoneDicomFolderPath, Path.GetFileName(file.FileName)); + + //下载到当前目录 + await _oSSService.DownLoadFromOSSAsync(file.Path, destinationPath); + } } + + var zipNoneDicomPath = Path.Combine(Directory.GetCurrentDirectory(), $"{info.SubjectCode}_{info.VisitName}_ImageStudy_NoneDicom.zip"); + ZipFile.CreateFromDirectory(Path.Combine(tempFolderPath, "NoneDicom"), zipNoneDicomPath); + relativeNoneDicomPath = await _oSSService.UploadToOSSAsync(zipNoneDicomPath, $"download_zip", false); + + File.Delete(zipNoneDicomPath); } - - var zipNoneDicomPath = Path.Combine(Directory.GetCurrentDirectory(), $"{info.SubjectCode}_{info.VisitName}_ImageStudy_NoneDicom.zip"); - ZipFile.CreateFromDirectory(Path.Combine(tempFolderPath, "NoneDicom"), zipNoneDicomPath); - var relativeNoneDicomPath = await _oSSService.UploadToOSSAsync(zipNoneDicomPath, $"download_zip", false); - - File.Delete(zipNoneDicomPath); - - await _subjectVisitRepository.BatchUpdateNoTrackingAsync(t => t.Id == subjectVisitId, u => new SubjectVisit() { PackState = PackState.Packed, VisitNoDicomImageZipPath = relativeNoneDicomPath }); + await _subjectVisitRepository.BatchUpdateNoTrackingAsync(t => t.Id == subjectVisitId, u => new SubjectVisit() { PackState = PackState.Packed, VisitNoDicomImageZipPath = relativeNoneDicomPath }); } From 6e7545be6528ff529c8074a41d527124e83fbcbf Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Tue, 16 Jul 2024 15:28:04 +0800 Subject: [PATCH 079/251] =?UTF-8?q?=E8=BF=94=E5=9B=9E=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=E5=AD=97=E6=AE=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRC.Core.SCP/Service/CStoreSCPService.cs | 2 +- .../Service/TrialSiteUser/DTO/TrialConfigDTO.cs | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/IRC.Core.SCP/Service/CStoreSCPService.cs b/IRC.Core.SCP/Service/CStoreSCPService.cs index a0c276107..a296bfd6f 100644 --- a/IRC.Core.SCP/Service/CStoreSCPService.cs +++ b/IRC.Core.SCP/Service/CStoreSCPService.cs @@ -113,7 +113,7 @@ namespace IRaCIS.Core.SCP.Service var _trialSiteDicomAERepository = _serviceProvider.GetService>(); - var findTrialSiteAE = _trialSiteDicomAERepository.Where(t=>t.CallingAE==association.CallingAE ).FirstOrDefault(); + var findTrialSiteAE = _trialSiteDicomAERepository.Where(t=>t.CallingAE==association.CallingAE).FirstOrDefault(); if (findTrialSiteAE!=null) { diff --git a/IRaCIS.Core.Application/Service/TrialSiteUser/DTO/TrialConfigDTO.cs b/IRaCIS.Core.Application/Service/TrialSiteUser/DTO/TrialConfigDTO.cs index 2508214e5..6cb000dfb 100644 --- a/IRaCIS.Core.Application/Service/TrialSiteUser/DTO/TrialConfigDTO.cs +++ b/IRaCIS.Core.Application/Service/TrialSiteUser/DTO/TrialConfigDTO.cs @@ -224,6 +224,10 @@ namespace IRaCIS.Core.Application.Contracts public TrialQCProcess QCProcessEnum { get; set; } = TrialQCProcess.DoubleAudit; public bool IsImageConsistencyVerification { get; set; } = true; + + public bool IsPACSConnect { get; set; } + + public bool IsTrialPACSConfirmed { get; set; } } public class TrialTaskConfigView : TrialTaskConfig From 594574c846920496372115b71bdcaacba359df48 Mon Sep 17 00:00:00 2001 From: he <109787524@qq.com> Date: Tue, 16 Jul 2024 15:43:04 +0800 Subject: [PATCH 080/251] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=9F=BA=E7=BA=BF?= =?UTF-8?q?=E7=9A=84=E9=95=BF=E5=BE=84=E7=9F=AD=E5=BE=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Service/Reading/ReadingImageTask/ReadingImageTaskService.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/IRaCIS.Core.Application/Service/Reading/ReadingImageTask/ReadingImageTaskService.cs b/IRaCIS.Core.Application/Service/Reading/ReadingImageTask/ReadingImageTaskService.cs index 96aaf7e28..546e7470e 100644 --- a/IRaCIS.Core.Application/Service/Reading/ReadingImageTask/ReadingImageTaskService.cs +++ b/IRaCIS.Core.Application/Service/Reading/ReadingImageTask/ReadingImageTaskService.cs @@ -1489,6 +1489,8 @@ namespace IRaCIS.Application.Services answers.Add("LastTaskState", lastTaskTableAnswer.Where(n => n.QuestionId == item.Id && n.ReadingTableQuestionTrial.QuestionMark == QuestionMark.State && n.RowIndex == x).Select(n => n.Answer).FirstOrDefault() ?? string.Empty); answers.Add("LastTaskMajorAxis", lastTaskTableAnswer.Where(n => n.QuestionId == item.Id && n.ReadingTableQuestionTrial.QuestionMark == QuestionMark.MajorAxis && n.RowIndex == x).Select(n => n.Answer).FirstOrDefault() ?? string.Empty); answers.Add("LastTaskShortAxis", lastTaskTableAnswer.Where(n => n.QuestionId == item.Id && n.ReadingTableQuestionTrial.QuestionMark == QuestionMark.ShortAxis && n.RowIndex == x).Select(n => n.Answer).FirstOrDefault() ?? string.Empty); + answers.Add("BaseLineMajorAxis", baseLineTableAnswer.Where(n => n.QuestionId == item.Id && n.ReadingTableQuestionTrial.QuestionMark == QuestionMark.MajorAxis && n.RowIndex == x).Select(n => n.Answer).FirstOrDefault() ?? string.Empty); + answers.Add("BaseLineShortAxis", baseLineTableAnswer.Where(n => n.QuestionId == item.Id && n.ReadingTableQuestionTrial.QuestionMark == QuestionMark.ShortAxis && n.RowIndex == x).Select(n => n.Answer).FirstOrDefault() ?? string.Empty); if (rowInfo.LesionType == LesionType.BaselineLesions) { answers.Add("BaseLineLesionNumber", baseLineTableAnswer.Where(n => n.ReadingTableQuestionTrial.QuestionMark == QuestionMark.LesionNumber && n.RowIndex == rowInfo.RowIndex).Select(x => x.Answer).FirstIsNullReturnEmpty()); From 5041ebd58bf6df8e1af6434456098decf62620a1 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Tue, 16 Jul 2024 16:09:22 +0800 Subject: [PATCH 081/251] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E9=A1=B9=E7=9B=AEId?= =?UTF-8?q?=20=E6=9F=A5=E8=AF=A2=E6=9D=A1=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.Application/Service/Visit/DTO/PatientViewModel.cs | 3 +++ IRaCIS.Core.Application/Service/Visit/PatientService.cs | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/IRaCIS.Core.Application/Service/Visit/DTO/PatientViewModel.cs b/IRaCIS.Core.Application/Service/Visit/DTO/PatientViewModel.cs index 0c3c515f8..3c257e873 100644 --- a/IRaCIS.Core.Application/Service/Visit/DTO/PatientViewModel.cs +++ b/IRaCIS.Core.Application/Service/Visit/DTO/PatientViewModel.cs @@ -222,6 +222,9 @@ namespace IRaCIS.Application.Contracts public class PatientTrialQuery : PageInput { + [NotDefault] + public Guid TrialId { get; set; } + public string? PatientIdStr { get; set; } public string? PatientName { get; set; } //public List CalledAEList { get; set; } = new List(); diff --git a/IRaCIS.Core.Application/Service/Visit/PatientService.cs b/IRaCIS.Core.Application/Service/Visit/PatientService.cs index 1f0468c0e..572ffef2b 100644 --- a/IRaCIS.Core.Application/Service/Visit/PatientService.cs +++ b/IRaCIS.Core.Application/Service/Visit/PatientService.cs @@ -106,7 +106,7 @@ namespace IRaCIS.Application.Services #region new ok - var query = _patientRepository + var query = _patientRepository.Where(t=>t.TrialId==inQuery.TrialId) .WhereIf(!string.IsNullOrWhiteSpace(inQuery.PatientIdStr), t => t.PatientIdStr.Contains(inQuery.PatientIdStr)) .WhereIf(!string.IsNullOrWhiteSpace(inQuery.PatientName), t => t.PatientName.Contains(inQuery.PatientName)) .WhereIf(!string.IsNullOrWhiteSpace(inQuery.SubejctCode), t => t.Subject.Code.Contains(inQuery.SubejctCode)) From 9924375f8255567dd69bbaf44153d14db5fa0fa1 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Tue, 16 Jul 2024 16:13:57 +0800 Subject: [PATCH 082/251] =?UTF-8?q?=E4=B8=8B=E6=8B=89=E6=A1=86=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=E5=8F=82=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.Application/Service/Visit/PatientService.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/IRaCIS.Core.Application/Service/Visit/PatientService.cs b/IRaCIS.Core.Application/Service/Visit/PatientService.cs index 572ffef2b..1f04338f8 100644 --- a/IRaCIS.Core.Application/Service/Visit/PatientService.cs +++ b/IRaCIS.Core.Application/Service/Visit/PatientService.cs @@ -210,16 +210,16 @@ namespace IRaCIS.Application.Services } - public async Task> GetDicomCalledAEList() + public async Task> GetDicomCalledAEList(Guid trialId) { - var list = await _scpStudyRepository.Select(t => t.CalledAE).Distinct().ToListAsync(); + var list = await _scpStudyRepository.Where(t=>t.TrialId==trialId).Select(t => t.CalledAE).Distinct().ToListAsync(); return list; } - public async Task> GetDicomCallingAEList() + public async Task> GetDicomCallingAEList(Guid trialId) { - var list = await _scpStudyRepository.Select(t => t.CallingAE).Distinct().ToListAsync(); + var list = await _scpStudyRepository.Where(t => t.TrialId == trialId).Select(t => t.CallingAE).Distinct().ToListAsync(); return list; } From 8fedcdaf00de9069004c3f5865d364b32dba16ab Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Tue, 16 Jul 2024 17:30:01 +0800 Subject: [PATCH 083/251] =?UTF-8?q?=E6=A3=80=E6=9F=A5=E5=88=97=E8=A1=A8?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=9F=A5=E8=AF=A2=20=E5=8C=BA=E5=88=86?= =?UTF-8?q?=E6=98=AF=E5=90=A6=E6=9D=A5=E8=87=AAPacs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.Application/IRaCIS.Core.Application.xml | 6 ++++-- .../Service/ImageAndDoc/DTO/UnionStudyViewDodel.cs | 7 ++++++- .../Service/ImageAndDoc/StudyService.cs | 4 +++- 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml index 4e7dc89e5..3eebc5573 100644 --- a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml +++ b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml @@ -875,21 +875,23 @@ - + 打包和匿名化影像 默认是匿名化打包,也可以不匿名化打包 + - + 后台任务调用,前端忽略该接口 + diff --git a/IRaCIS.Core.Application/Service/ImageAndDoc/DTO/UnionStudyViewDodel.cs b/IRaCIS.Core.Application/Service/ImageAndDoc/DTO/UnionStudyViewDodel.cs index 8226693c0..6be7f1de5 100644 --- a/IRaCIS.Core.Application/Service/ImageAndDoc/DTO/UnionStudyViewDodel.cs +++ b/IRaCIS.Core.Application/Service/ImageAndDoc/DTO/UnionStudyViewDodel.cs @@ -44,6 +44,9 @@ namespace IRaCIS.Core.Application.Contracts public string RecordPath { get; set; } = string.Empty; public bool IsDicom { get; set; } + + + } public class UnionStudyMonitorModel : UnionStudyBaseModel @@ -124,7 +127,7 @@ namespace IRaCIS.Core.Application.Contracts public Guid Id { get; set; } - + public bool IsFromPACS { get; set; } public int? Count { get; set; } @@ -164,6 +167,8 @@ namespace IRaCIS.Core.Application.Contracts public bool? IsSuccess { get; set; } public string? StudyCode { get; set; } + + public bool? IsFromPACS { get; set; } } diff --git a/IRaCIS.Core.Application/Service/ImageAndDoc/StudyService.cs b/IRaCIS.Core.Application/Service/ImageAndDoc/StudyService.cs index 50c2882a5..96051495f 100644 --- a/IRaCIS.Core.Application/Service/ImageAndDoc/StudyService.cs +++ b/IRaCIS.Core.Application/Service/ImageAndDoc/StudyService.cs @@ -372,6 +372,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc VisitNum = t.SubjectVisit.VisitNum, IsDicom = true, + IsFromPACS=t.IsFromPACS, SubjectCode = t.Subject.Code, @@ -455,7 +456,8 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc var unionQuery = dicomStudyQuery.Union(nodeDicomStudyQuery) .WhereIf(studyQuery.SubjectId != null, t => t.SubjectId == studyQuery.SubjectId) .WhereIf(studyQuery.SubjectVisitId != null, t => t.SubjectId == studyQuery.SubjectVisitId) - .WhereIf(studyQuery.TrialSiteId != null, t => t.TrialSiteId == studyQuery.TrialSiteId); + .WhereIf(studyQuery.TrialSiteId != null, t => t.TrialSiteId == studyQuery.TrialSiteId) + .WhereIf(studyQuery.IsFromPACS != null, t => t.IsFromPACS == studyQuery.IsFromPACS); return await unionQuery.ToPagedListAsync(studyQuery.PageIndex, studyQuery.PageSize, studyQuery.SortField, studyQuery.Asc); } From 0e0dd0c7d384448140b3024754e484b6a50d22e2 Mon Sep 17 00:00:00 2001 From: he <109787524@qq.com> Date: Mon, 15 Jul 2024 14:43:49 +0800 Subject: [PATCH 084/251] =?UTF-8?q?=E8=B7=B3=E8=BF=87=E9=98=85=E7=89=87?= =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ReadingImageTask/ReadingImageTaskService.cs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/IRaCIS.Core.Application/Service/Reading/ReadingImageTask/ReadingImageTaskService.cs b/IRaCIS.Core.Application/Service/Reading/ReadingImageTask/ReadingImageTaskService.cs index 546e7470e..0d1b212f4 100644 --- a/IRaCIS.Core.Application/Service/Reading/ReadingImageTask/ReadingImageTaskService.cs +++ b/IRaCIS.Core.Application/Service/Reading/ReadingImageTask/ReadingImageTaskService.cs @@ -2770,14 +2770,20 @@ namespace IRaCIS.Application.Services var subjectIndex = subjectTaskList.Where(x => x.SubjectId == inDto.SubjectId && x.SubjectCode == inDto.SubjectCode).Select(x => x.Index).FirstOrDefault(); - var currentSubject = subjectTaskList.Where(x => x.Index >= subjectIndex && !x.ExistReadingApply).OrderBy(x => x.Index).FirstOrDefault(); + + var currentSubject = subjectTaskList.Where(x => x.Index >= subjectIndex && !x.ExistReadingApply) + // 排除跳过的 + .Where(x=> x.UnReadCanReadTaskList.Select(y => y.Id).Intersect(cacheSkipIds).Count()==0) + .OrderBy(x => x.Index).FirstOrDefault(); + if (currentSubject == null) { throw new BusinessValidationFailedException(_localizer["ReadingImage_TaskFinish"], ApiResponseCodeEnum.CloseCurrentWindows); } - task = currentSubject.UnReadCanReadTaskList.Select(x => new GetReadingTaskDto() + task = currentSubject.UnReadCanReadTaskList + .Select(x => new GetReadingTaskDto() { ReadingCategory = x.ReadingCategory, SubjectCode = currentSubject.SubjectCode, From 49e21a6342f305b1356763dcc5af49f7ccc8649e Mon Sep 17 00:00:00 2001 From: he <109787524@qq.com> Date: Tue, 16 Jul 2024 09:57:33 +0800 Subject: [PATCH 085/251] =?UTF-8?q?=E5=8A=A0=E8=BF=94=E5=9B=9E=E5=8F=82?= =?UTF-8?q?=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Reading/ReadingImageTask/ReadingImageTaskService.cs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/IRaCIS.Core.Application/Service/Reading/ReadingImageTask/ReadingImageTaskService.cs b/IRaCIS.Core.Application/Service/Reading/ReadingImageTask/ReadingImageTaskService.cs index 0d1b212f4..5c507b269 100644 --- a/IRaCIS.Core.Application/Service/Reading/ReadingImageTask/ReadingImageTaskService.cs +++ b/IRaCIS.Core.Application/Service/Reading/ReadingImageTask/ReadingImageTaskService.cs @@ -22,6 +22,8 @@ using AutoMapper.QueryableExtensions; using IRaCIS.Application.Contracts; using IRaCIS.Core.Domain.Models; using Microsoft.Extensions.Options; +using System.Linq; +using NPOI.SS.Formula.Functions; using static Microsoft.EntityFrameworkCore.DbLoggerCategory; namespace IRaCIS.Application.Services @@ -3001,7 +3003,7 @@ namespace IRaCIS.Application.Services /// /// [HttpPost] - public async Task VerifyReadingRestTime() + public async Task VerifyReadingRestTime() { var userTypeEnum = (UserTypeEnum)_userInfo.UserTypeEnumInt; if (userTypeEnum != UserTypeEnum.IndependentReviewer) @@ -3051,6 +3053,8 @@ namespace IRaCIS.Application.Services #endregion } + + return true; } /// @@ -3058,7 +3062,7 @@ namespace IRaCIS.Application.Services /// /// [HttpPost] - public async Task ResetReadingRestTime(Guid? userID) + public async Task ResetReadingRestTime(Guid? userID) { if (userID == null) { @@ -3085,6 +3089,7 @@ namespace IRaCIS.Application.Services { _provider.Set(startReadingTimeKey, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), TimeSpan.FromHours(48)); } + return true; } /// From 74aec46a94858ba107b57e25df128269e74549a0 Mon Sep 17 00:00:00 2001 From: he <109787524@qq.com> Date: Tue, 16 Jul 2024 10:10:12 +0800 Subject: [PATCH 086/251] =?UTF-8?q?=E8=BF=94=E5=9B=9E=E5=80=BC=E4=BF=AE?= =?UTF-8?q?=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Service/Reading/Interface/IReadingImageTaskService.cs | 2 +- .../Service/Reading/ReadingImageTask/ReadingImageTaskService.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/IRaCIS.Core.Application/Service/Reading/Interface/IReadingImageTaskService.cs b/IRaCIS.Core.Application/Service/Reading/Interface/IReadingImageTaskService.cs index 95c4bac51..22e12adaa 100644 --- a/IRaCIS.Core.Application/Service/Reading/Interface/IReadingImageTaskService.cs +++ b/IRaCIS.Core.Application/Service/Reading/Interface/IReadingImageTaskService.cs @@ -37,7 +37,7 @@ namespace IRaCIS.Core.Application.Contracts Task> GetManualList(GetManualListInDto inDto); - Task ResetReadingRestTime(Guid? userId); + Task ResetReadingRestTime(Guid? userId); Task> GetReadingPastResultList(GetReadingPastResultListInDto inDto); diff --git a/IRaCIS.Core.Application/Service/Reading/ReadingImageTask/ReadingImageTaskService.cs b/IRaCIS.Core.Application/Service/Reading/ReadingImageTask/ReadingImageTaskService.cs index 5c507b269..32597aa5e 100644 --- a/IRaCIS.Core.Application/Service/Reading/ReadingImageTask/ReadingImageTaskService.cs +++ b/IRaCIS.Core.Application/Service/Reading/ReadingImageTask/ReadingImageTaskService.cs @@ -3008,7 +3008,7 @@ namespace IRaCIS.Application.Services var userTypeEnum = (UserTypeEnum)_userInfo.UserTypeEnumInt; if (userTypeEnum != UserTypeEnum.IndependentReviewer) { - return; + return true; } var startReadingTimeKey = _userInfo.Id.ToString() + "StartReadingTime"; var startRestTimeKey = _userInfo.Id.ToString() + "StartRestTime"; From 4026eca65690302a2392ef739fade1ba56384a87 Mon Sep 17 00:00:00 2001 From: he <109787524@qq.com> Date: Wed, 17 Jul 2024 10:10:28 +0800 Subject: [PATCH 087/251] =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Reading/ReadingImageTask/ReadingImageTaskService.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/IRaCIS.Core.Application/Service/Reading/ReadingImageTask/ReadingImageTaskService.cs b/IRaCIS.Core.Application/Service/Reading/ReadingImageTask/ReadingImageTaskService.cs index 32597aa5e..2748d09e1 100644 --- a/IRaCIS.Core.Application/Service/Reading/ReadingImageTask/ReadingImageTaskService.cs +++ b/IRaCIS.Core.Application/Service/Reading/ReadingImageTask/ReadingImageTaskService.cs @@ -2707,6 +2707,12 @@ namespace IRaCIS.Application.Services } + var c = _provider.Get(clearSkipReadingCacheKey).Value; + Console.WriteLine(c); + // 加这个测试 + Thread.Sleep(3000); // 3000毫秒 = 3秒 + return true; + } /// From 85a303171c3f18b25244178e3b2dba66f89790a7 Mon Sep 17 00:00:00 2001 From: he <109787524@qq.com> Date: Wed, 17 Jul 2024 10:19:51 +0800 Subject: [PATCH 088/251] =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ReadingImageTaskService.cs | 40 +++++++++++++++++-- 1 file changed, 36 insertions(+), 4 deletions(-) diff --git a/IRaCIS.Core.Application/Service/Reading/ReadingImageTask/ReadingImageTaskService.cs b/IRaCIS.Core.Application/Service/Reading/ReadingImageTask/ReadingImageTaskService.cs index 2748d09e1..950364f69 100644 --- a/IRaCIS.Core.Application/Service/Reading/ReadingImageTask/ReadingImageTaskService.cs +++ b/IRaCIS.Core.Application/Service/Reading/ReadingImageTask/ReadingImageTaskService.cs @@ -2707,10 +2707,29 @@ namespace IRaCIS.Application.Services } - var c = _provider.Get(clearSkipReadingCacheKey).Value; - Console.WriteLine(c); - // 加这个测试 - Thread.Sleep(3000); // 3000毫秒 = 3秒 + /// + /// 设置跳过阅片的缓存 + /// + /// + /// + [HttpPost] + public async Task SetSkipReadingCache(SetSkipReadingCacheInDto inDto ) + { + var clearSkipReadingCacheKey = _userInfo.Id.ToString() + "SkipReadingCache"; + var clearSkipReadingCache = _provider.Get(clearSkipReadingCacheKey).Value; + if (clearSkipReadingCache == null|| clearSkipReadingCache==string.Empty) + { + List cacheIds = new List(); + cacheIds.Add(inDto.VisitTaskId); + + _provider.Set(clearSkipReadingCacheKey, JsonConvert.SerializeObject(cacheIds), TimeSpan.FromHours(24)); + } + else + { + List? cacheIds=JsonConvert.DeserializeObject>(clearSkipReadingCache); + cacheIds.Add(inDto.VisitTaskId); + _provider.Set(clearSkipReadingCacheKey, JsonConvert.SerializeObject(cacheIds), TimeSpan.FromHours(24)); + } return true; } @@ -2820,12 +2839,25 @@ namespace IRaCIS.Application.Services })).CurrentPageData; + + + + + if (subjectTaskList.Count() == 0) { throw new BusinessValidationFailedException(_localizer["ReadingImage_TaskFinish"], ApiResponseCodeEnum.CloseCurrentWindows); } var taskList = subjectTaskList.FirstOrDefault()!.UnReadCanReadTaskList; + // 排除跳过的 + List remainingItems = taskList.Select(x => x.Id).Except(cacheSkipIds).ToList(); + + taskList = taskList.Where(x => remainingItems.Contains(x.Id)).ToList(); + if (taskList.Count() == 0) + { + throw new BusinessValidationFailedException(_localizer["ReadingImage_TaskFinish"], ApiResponseCodeEnum.CloseCurrentWindows); + } Random random = new Random(); //返回的范围是 0- taskList.Count-1 From d72f3e89a24efdeb67447c328644477f8768033a Mon Sep 17 00:00:00 2001 From: he <109787524@qq.com> Date: Wed, 17 Jul 2024 11:06:47 +0800 Subject: [PATCH 089/251] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Reading/Dto/ReadingImageTaskViewModel.cs | 5 ++++ .../ReadingImageTaskService.cs | 28 ++++++++++++++++--- 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/IRaCIS.Core.Application/Service/Reading/Dto/ReadingImageTaskViewModel.cs b/IRaCIS.Core.Application/Service/Reading/Dto/ReadingImageTaskViewModel.cs index d0288c364..605c64b6e 100644 --- a/IRaCIS.Core.Application/Service/Reading/Dto/ReadingImageTaskViewModel.cs +++ b/IRaCIS.Core.Application/Service/Reading/Dto/ReadingImageTaskViewModel.cs @@ -1701,6 +1701,11 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto } + public class SetSkipReadingCacheInDto + { + public Guid VisitTaskId { get; set; } + } + public class ResetReadingTaskInDto { public Guid VisitTaskId { get; set; } diff --git a/IRaCIS.Core.Application/Service/Reading/ReadingImageTask/ReadingImageTaskService.cs b/IRaCIS.Core.Application/Service/Reading/ReadingImageTask/ReadingImageTaskService.cs index 950364f69..7c007f802 100644 --- a/IRaCIS.Core.Application/Service/Reading/ReadingImageTask/ReadingImageTaskService.cs +++ b/IRaCIS.Core.Application/Service/Reading/ReadingImageTask/ReadingImageTaskService.cs @@ -2707,6 +2707,20 @@ namespace IRaCIS.Application.Services } + + /// + /// 清除跳过阅片的缓存 + /// + /// + [HttpPost] + public async Task ClearSkipReadingCache() + { + var clearSkipReadingCacheKey = _userInfo.Id.ToString() + "SkipReadingCache"; + _provider.Remove(clearSkipReadingCacheKey); + return true; + } + + /// /// 设置跳过阅片的缓存 /// @@ -2757,6 +2771,16 @@ namespace IRaCIS.Application.Services throw new BusinessValidationFailedException(_localizer["ReadingImage_IDMust"]); } + + #region 跳过阅片 + var clearSkipReadingCacheKey = _userInfo.Id.ToString() + "SkipReadingCache"; + var clearSkipReadingCache = _provider.Get(clearSkipReadingCacheKey).Value; + List cacheSkipIds = new List(); + if (clearSkipReadingCache != null && clearSkipReadingCache != string.Empty) + { + cacheSkipIds = JsonConvert.DeserializeObject>(clearSkipReadingCache); + } + #endregion var trialReadingCriterion = await _readingQuestionCriterionTrialRepository.FindAsync(trialReadingCriterionId ?? Guid.Empty); if (inDto.VisitTaskId != null) @@ -2840,10 +2864,6 @@ namespace IRaCIS.Application.Services })).CurrentPageData; - - - - if (subjectTaskList.Count() == 0) { throw new BusinessValidationFailedException(_localizer["ReadingImage_TaskFinish"], ApiResponseCodeEnum.CloseCurrentWindows); From d9fc5e3646360ee2422d5aeed3098cc909f5a223 Mon Sep 17 00:00:00 2001 From: he <109787524@qq.com> Date: Wed, 17 Jul 2024 13:37:01 +0800 Subject: [PATCH 090/251] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E4=B8=8A=E4=B8=80?= =?UTF-8?q?=E6=AC=A1=E4=BB=BB=E5=8A=A1=E7=9A=84=E7=AD=94=E6=A1=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Reading/Dto/ReadingImageTaskViewModel.cs | 2 ++ .../ReadingImageTaskService.cs | 33 +++++++++++++++++-- 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/IRaCIS.Core.Application/Service/Reading/Dto/ReadingImageTaskViewModel.cs b/IRaCIS.Core.Application/Service/Reading/Dto/ReadingImageTaskViewModel.cs index 605c64b6e..0cb0ecae0 100644 --- a/IRaCIS.Core.Application/Service/Reading/Dto/ReadingImageTaskViewModel.cs +++ b/IRaCIS.Core.Application/Service/Reading/Dto/ReadingImageTaskViewModel.cs @@ -609,6 +609,8 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto { public string Answer { get; set; } + public string LastTaskAnswer { get; set; } + public bool IsFirstChangeTask { get; set; } = false; public List CrterionDictionaryGroup { get; set; } diff --git a/IRaCIS.Core.Application/Service/Reading/ReadingImageTask/ReadingImageTaskService.cs b/IRaCIS.Core.Application/Service/Reading/ReadingImageTask/ReadingImageTaskService.cs index 7c007f802..3cae0656b 100644 --- a/IRaCIS.Core.Application/Service/Reading/ReadingImageTask/ReadingImageTaskService.cs +++ b/IRaCIS.Core.Application/Service/Reading/ReadingImageTask/ReadingImageTaskService.cs @@ -874,10 +874,33 @@ namespace IRaCIS.Application.Services var answers = new List(); + var lastTaskAnswer = new List(); + if (visitTaskId != null) { answers = await _readingTaskQuestionAnswerRepository.Where(x => x.VisitTaskId == visitTaskId).ToListAsync(); + var taskInfo = await _visitTaskRepository.Where(x => x.Id == visitTaskId).FirstNotNullAsync(); + + var laskTaskId = await _visitTaskRepository.Where(x => + (x.SubjectId == taskInfo.SubjectId && x.TaskState == TaskState.Effect + && x.IsAnalysisCreate == taskInfo.IsAnalysisCreate + && x.DoctorUserId == taskInfo.DoctorUserId + && x.IsSelfAnalysis == taskInfo.IsSelfAnalysis + && x.VisitTaskNum < taskInfo.VisitTaskNum + && x.ArmEnum == taskInfo.ArmEnum + && x.TrialReadingCriterionId == taskInfo.TrialReadingCriterionId + && x.ReadingCategory == ReadingCategory.Visit) || x.Id == taskInfo.BeforeConvertedTaskId + ).OrderByDescending(x => x.VisitTaskNum).Select(x => x.Id).FirstOrDefaultAsync(); + if (criterionIdInfo.IsReadingTaskViewInOrder != ReadingOrder.InOrder) + { + // 无序的话 不要查 + laskTaskId = Guid.NewGuid(); + } + + lastTaskAnswer = await _readingTaskQuestionAnswerRepository.Where(x => x.VisitTaskId == laskTaskId).ToListAsync(); + + var taskinfo = await _visitTaskRepository.Where(x => x.Id == visitTaskId).ProjectTo(_mapper.ConfigurationProvider).FirstNotNullAsync(); if (taskinfo.VisitTaskNum == 0) @@ -922,24 +945,28 @@ namespace IRaCIS.Application.Services foreach (var item in result) { - GetDicomReadingAnswer(item, questions, answers); + GetDicomReadingAnswer(item, questions, answers, lastTaskAnswer); } return result; } - private void GetDicomReadingAnswer(DicomReadingQuestionAnswer item, List questions, List answers) + private void GetDicomReadingAnswer(DicomReadingQuestionAnswer item, List questions, List answers, List lastTaskAnswers) { var answer = answers.Where(x => x.ReadingQuestionTrialId == item.Id).Select(x => x.Answer).FirstIsNullReturnEmpty(); item.Answer = answer.IsNullOrEmpty() ? item.DefaultValue : answer; + var lastTaskAnswer = lastTaskAnswers.Where(x => x.ReadingQuestionTrialId == item.Id).Select(x => x.Answer).FirstIsNullReturnEmpty(); + item.LastTaskAnswer = lastTaskAnswer.IsNullOrEmpty() ? item.DefaultValue : lastTaskAnswer; + + item.Childrens = questions.Where(x => x.ParentId == item.Id || (x.GroupId == item.Id && x.ParentId == null)).ToList(); if (item.Childrens != null && item.Childrens.Count > 0) { foreach (var question in item.Childrens) { - GetDicomReadingAnswer(question, questions, answers); + GetDicomReadingAnswer(question, questions, answers, lastTaskAnswers); } } From c65a484b13cd68d9466634b64eeeac6a34f0d84d Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Wed, 17 Jul 2024 14:20:36 +0800 Subject: [PATCH 091/251] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=82=A3=E8=80=85?= =?UTF-8?q?=E4=BF=A1=E6=81=AF=E6=9F=A5=E8=AF=A2=EF=BC=8C=E5=92=8CModality?= =?UTF-8?q?=E6=9F=A5=E8=AF=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Service/Visit/DTO/PatientViewModel.cs | 7 +++ .../Service/Visit/PatientService.cs | 55 ++++++++++++------- 2 files changed, 41 insertions(+), 21 deletions(-) diff --git a/IRaCIS.Core.Application/Service/Visit/DTO/PatientViewModel.cs b/IRaCIS.Core.Application/Service/Visit/DTO/PatientViewModel.cs index 3c257e873..5acd1f0bb 100644 --- a/IRaCIS.Core.Application/Service/Visit/DTO/PatientViewModel.cs +++ b/IRaCIS.Core.Application/Service/Visit/DTO/PatientViewModel.cs @@ -1031,6 +1031,8 @@ namespace IRaCIS.Application.Contracts public DateTime? LatestStudyTime { get; set; } public string? Modalities { get; set; } + + public string? PatientInfo { get; set; } } public class VisitPatientStudyFilterView { @@ -1048,6 +1050,11 @@ namespace IRaCIS.Application.Contracts public string CalledAE { get; set; } = string.Empty; public string CallingAE { get; set; } = string.Empty; + + public string PatientIdStr { get; set; } = string.Empty; + public string PatientName { get; set; } = string.Empty; + public string PatientAge { get; set; } = string.Empty; + public string PatientSex { get; set; } = string.Empty; } public class PatientStudySimpleView: VisitPatientStudyFilterView diff --git a/IRaCIS.Core.Application/Service/Visit/PatientService.cs b/IRaCIS.Core.Application/Service/Visit/PatientService.cs index 1f04338f8..6cb4ab6d4 100644 --- a/IRaCIS.Core.Application/Service/Visit/PatientService.cs +++ b/IRaCIS.Core.Application/Service/Visit/PatientService.cs @@ -106,12 +106,12 @@ namespace IRaCIS.Application.Services #region new ok - var query = _patientRepository.Where(t=>t.TrialId==inQuery.TrialId) + var query = _patientRepository.Where(t => t.TrialId == inQuery.TrialId) .WhereIf(!string.IsNullOrWhiteSpace(inQuery.PatientIdStr), t => t.PatientIdStr.Contains(inQuery.PatientIdStr)) .WhereIf(!string.IsNullOrWhiteSpace(inQuery.PatientName), t => t.PatientName.Contains(inQuery.PatientName)) .WhereIf(!string.IsNullOrWhiteSpace(inQuery.SubejctCode), t => t.Subject.Code.Contains(inQuery.SubejctCode)) .WhereIf(!string.IsNullOrWhiteSpace(inQuery.TrialSiteKeyInfo), t => t.TrialSite.TrialSiteCode.Contains(inQuery.TrialSiteKeyInfo) - || t.TrialSite.TrialSiteAliasName.Contains(inQuery.TrialSiteKeyInfo)|| t.TrialSite.TrialSiteName.Contains(inQuery.TrialSiteKeyInfo)) + || t.TrialSite.TrialSiteAliasName.Contains(inQuery.TrialSiteKeyInfo) || t.TrialSite.TrialSiteName.Contains(inQuery.TrialSiteKeyInfo)) .WhereIf(!string.IsNullOrWhiteSpace(inQuery.CallingAE), t => t.SCPStudyList.Any(t => t.CallingAE == inQuery.CallingAE)) .WhereIf(!string.IsNullOrWhiteSpace(inQuery.CalledAE), t => t.SCPStudyList.Any(t => t.CalledAE == inQuery.CalledAE)) .WhereIf(inQuery.BeginPushTime != null, t => t.LatestPushTime >= inQuery.BeginPushTime) @@ -146,13 +146,13 @@ namespace IRaCIS.Application.Services StudyCount = patient.SCPStudyList.Count(), - TrialId=patient.TrialId, - SubejctId=patient.SubjectId, - SubjectCode=patient.Subject.Code, - TrialSiteAliasName=patient.TrialSite.TrialSiteAliasName, - TrialSiteCode=patient.TrialSite.TrialSiteCode, - TrialSiteName=patient.TrialSite.TrialSiteName - + TrialId = patient.TrialId, + SubejctId = patient.SubjectId, + SubjectCode = patient.Subject.Code, + TrialSiteAliasName = patient.TrialSite.TrialSiteAliasName, + TrialSiteCode = patient.TrialSite.TrialSiteCode, + TrialSiteName = patient.TrialSite.TrialSiteName + }; @@ -193,9 +193,9 @@ namespace IRaCIS.Application.Services SeriesCount = scpStudy.SeriesCount, StudyTime = scpStudy.StudyTime, - SubjectVisitId= scpStudy.SubjectVisitId, - VisitName=scpStudy.SubjectVisit.VisitName, - BlindName=scpStudy.SubjectVisit.BlindName + SubjectVisitId = scpStudy.SubjectVisitId, + VisitName = scpStudy.SubjectVisit.VisitName, + BlindName = scpStudy.SubjectVisit.BlindName }; @@ -212,7 +212,7 @@ namespace IRaCIS.Application.Services public async Task> GetDicomCalledAEList(Guid trialId) { - var list = await _scpStudyRepository.Where(t=>t.TrialId==trialId).Select(t => t.CalledAE).Distinct().ToListAsync(); + var list = await _scpStudyRepository.Where(t => t.TrialId == trialId).Select(t => t.CalledAE).Distinct().ToListAsync(); return list; } @@ -224,6 +224,13 @@ namespace IRaCIS.Application.Services return list; } + public async Task> GetDicomModalityList(Guid trialId) + { + var list = await _scpStudyRepository.Where(t => t.TrialId == trialId).SelectMany(t => t.SeriesList).Select(t=>t.Modality).Distinct().ToListAsync(); + + return list; + } + /// /// 影像访视上传 检查列表 /// @@ -233,16 +240,17 @@ namespace IRaCIS.Application.Services public async Task> GetVisitPatientStudyFilterList(VisitPatientStudyFilterQuery inQuery) { - var trialSiteId=_subjectRepository.Where(t=>t.Id==inQuery.SubjectId).Select(t=>t.TrialSiteId).FirstOrDefault(); + var trialSiteId = _subjectRepository.Where(t => t.Id == inQuery.SubjectId).Select(t => t.TrialSiteId).FirstOrDefault(); var query = from scpStudy in _scpStudyRepository //未绑定的患者,或者自己已绑定但是未绑定访视的 - .Where(t => t.Patient.SubjectId == null|| (t.Patient.SubjectId == inQuery.SubjectId && t.SubjectVisitId==null)) + .Where(t => t.Patient.SubjectId == null || (t.Patient.SubjectId == inQuery.SubjectId && t.SubjectVisitId == null)) //中心 - .Where(t=>t.TrialSiteId==trialSiteId) + .Where(t => t.TrialSiteId == trialSiteId) .WhereIf(inQuery.EarliestStudyTime != null, t => t.StudyTime >= inQuery.EarliestStudyTime) .WhereIf(inQuery.LatestStudyTime != null, t => t.StudyTime <= inQuery.LatestStudyTime) .WhereIf(!string.IsNullOrWhiteSpace(inQuery.Modalities), t => t.Modalities.Contains(inQuery.Modalities)) + .WhereIf(!string.IsNullOrWhiteSpace(inQuery.PatientInfo), t => t.PatientIdStr.Contains(inQuery.PatientInfo) || t.PatientName.Contains(inQuery.PatientInfo) || t.PatientSex.Contains(inQuery.PatientInfo)) select new VisitPatientStudyFilterView() { Description = scpStudy.Description, @@ -254,6 +262,11 @@ namespace IRaCIS.Application.Services SCPStudyId = scpStudy.Id, SeriesCount = scpStudy.SeriesCount, StudyTime = scpStudy.StudyTime, + + PatientAge = scpStudy.PatientAge, + PatientIdStr = scpStudy.PatientIdStr, + PatientName = scpStudy.PatientName, + PatientSex = scpStudy.PatientSex, }; @@ -276,10 +289,10 @@ namespace IRaCIS.Application.Services { var subjectId = inCommand.SubjectId; - var subjectVisitId=inCommand.SubjectVisitId; + var subjectVisitId = inCommand.SubjectVisitId; var trialId = inCommand.TrialId; - - + + var @lock = _distributedLockProvider.CreateLock($"StudyCode"); @@ -313,7 +326,7 @@ namespace IRaCIS.Application.Services foreach (var series in newSeriesList) { - + series.SeqId = Guid.Empty; series.TrialId = trialId; series.SubjectId = subjectId; @@ -332,7 +345,7 @@ namespace IRaCIS.Application.Services instance.TrialId = trialId; instance.SubjectId = subjectId; instance.SubjectVisitId = subjectVisitId; - + } await _repository.AddRangeAsync(newInstanceList); } From 425bd7bf9ad47876bd7198631225ede854bf0b17 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Wed, 17 Jul 2024 14:44:37 +0800 Subject: [PATCH 092/251] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=9F=A5=E8=AF=A2?= =?UTF-8?q?=E5=88=97=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../IRaCIS.Core.Application.xml | 13 ++++++++++++ .../Service/Visit/DTO/PatientViewModel.cs | 21 +++++++++++++++++-- .../Service/Visit/PatientService.cs | 5 +++++ 3 files changed, 37 insertions(+), 2 deletions(-) diff --git a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml index 3eebc5573..0be0d769e 100644 --- a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml +++ b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml @@ -14621,6 +14621,19 @@ + + + 清除跳过阅片的缓存 + + + + + + 设置跳过阅片的缓存 + + + + 获取下一个阅片任务 diff --git a/IRaCIS.Core.Application/Service/Visit/DTO/PatientViewModel.cs b/IRaCIS.Core.Application/Service/Visit/DTO/PatientViewModel.cs index 5acd1f0bb..f3c8d4a72 100644 --- a/IRaCIS.Core.Application/Service/Visit/DTO/PatientViewModel.cs +++ b/IRaCIS.Core.Application/Service/Visit/DTO/PatientViewModel.cs @@ -1051,16 +1051,33 @@ namespace IRaCIS.Application.Contracts public string CallingAE { get; set; } = string.Empty; + public string BodyPartExamined { get; set; } = string.Empty; + public string PatientIdStr { get; set; } = string.Empty; public string PatientName { get; set; } = string.Empty; public string PatientAge { get; set; } = string.Empty; public string PatientSex { get; set; } = string.Empty; + + public string PatientBirthDate { get; set; } = string.Empty; } - public class PatientStudySimpleView: VisitPatientStudyFilterView + public class PatientStudySimpleView { - + public Guid SCPStudyId { get; set; } + + public Guid PatientId { get; set; } + + public DateTime? StudyTime { get; set; } + public string Modalities { get; set; } = string.Empty; + + public string Description { get; set; } = string.Empty; + public int SeriesCount { get; set; } = 0; + public int InstanceCount { get; set; } = 0; + + public string CalledAE { get; set; } = string.Empty; + + public string CallingAE { get; set; } = string.Empty; public Guid? SubjectVisitId { get; set; } public string? VisitName { get; set; } diff --git a/IRaCIS.Core.Application/Service/Visit/PatientService.cs b/IRaCIS.Core.Application/Service/Visit/PatientService.cs index 6cb4ab6d4..dc49fe0ad 100644 --- a/IRaCIS.Core.Application/Service/Visit/PatientService.cs +++ b/IRaCIS.Core.Application/Service/Visit/PatientService.cs @@ -192,6 +192,9 @@ namespace IRaCIS.Application.Services SCPStudyId = scpStudy.Id, SeriesCount = scpStudy.SeriesCount, StudyTime = scpStudy.StudyTime, + + + SubjectVisitId = scpStudy.SubjectVisitId, VisitName = scpStudy.SubjectVisit.VisitName, @@ -262,7 +265,9 @@ namespace IRaCIS.Application.Services SCPStudyId = scpStudy.Id, SeriesCount = scpStudy.SeriesCount, StudyTime = scpStudy.StudyTime, + BodyPartExamined=scpStudy.BodyPartExamined, + PatientBirthDate=scpStudy.PatientBirthDate, PatientAge = scpStudy.PatientAge, PatientIdStr = scpStudy.PatientIdStr, PatientName = scpStudy.PatientName, From 0b3542e9c3e69f2d452ca38ffb8e12232f5754b8 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Wed, 17 Jul 2024 14:52:53 +0800 Subject: [PATCH 093/251] =?UTF-8?q?=E8=87=AA=E5=8A=A8=E8=AE=A1=E7=AE=97?= =?UTF-8?q?=E6=82=A3=E8=80=85=E5=B9=B4=E9=BE=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRC.Core.SCP/Service/DicomArchiveService.cs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/IRC.Core.SCP/Service/DicomArchiveService.cs b/IRC.Core.SCP/Service/DicomArchiveService.cs index 8e66feceb..8632cd4e8 100644 --- a/IRC.Core.SCP/Service/DicomArchiveService.cs +++ b/IRC.Core.SCP/Service/DicomArchiveService.cs @@ -11,6 +11,7 @@ using FellowOakDicom.Network; using IRaCIS.Core.SCP.Service; using IRaCIS.Core.Infra.EFCore; using MassTransit; +using System.Runtime.Intrinsics.X86; namespace IRaCIS.Core.SCP.Service { @@ -115,6 +116,20 @@ namespace IRaCIS.Core.SCP.Service { findPatient.PatientBirthDate = birthDateStr; + DateTime birthDate; + + if (findPatient.PatientAge == string.Empty && studyTime.HasValue && DateTime.TryParse(findPatient.PatientBirthDate,out birthDate)) + { + var patientAge = studyTime.Value.Year - birthDate.Year; + // 如果生日还未到,年龄减去一岁 + if (studyTime.Value < birthDate.AddYears(patientAge)) + { + patientAge--; + } + + findPatient.PatientAge = patientAge.ToString(); + } + } else { From 353b2c99cb0f993fbd1100e60810b121dcce5241 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Wed, 17 Jul 2024 18:00:17 +0800 Subject: [PATCH 094/251] =?UTF-8?q?url=20=E8=A7=A3=E7=A0=81=E4=B8=8B?= =?UTF-8?q?=E8=BD=BD=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Service/ImageAndDoc/DownloadAndUploadService.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/IRaCIS.Core.Application/Service/ImageAndDoc/DownloadAndUploadService.cs b/IRaCIS.Core.Application/Service/ImageAndDoc/DownloadAndUploadService.cs index 509cf43a3..9f71bad89 100644 --- a/IRaCIS.Core.Application/Service/ImageAndDoc/DownloadAndUploadService.cs +++ b/IRaCIS.Core.Application/Service/ImageAndDoc/DownloadAndUploadService.cs @@ -19,6 +19,7 @@ using System.IO.Compression; using System.Linq; using System.Text; using System.Threading.Tasks; +using System.Web; namespace IRaCIS.Core.Application.Service.ImageAndDoc { @@ -491,6 +492,8 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc public async Task RequestPackageAndAnonymizImage(Guid trialId, Guid subjectVisitId, bool isDicom, bool isAnonymize = true) { + + var extralConfig = _repository.Where(t => t.Id == trialId).Select(t => t.TrialExtraConfigJsonStr).FirstOrDefault() ?? string.Empty; var config = JsonConvert.DeserializeObject(extralConfig) ?? new TrialExtraConfig(); @@ -762,9 +765,9 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc foreach (var file in noneDicomStudy.FileList) { string destinationPath = Path.Combine(studyNoneDicomFolderPath, Path.GetFileName(file.FileName)); - + //下载到当前目录 - await _oSSService.DownLoadFromOSSAsync(file.Path, destinationPath); + await _oSSService.DownLoadFromOSSAsync(HttpUtility.UrlDecode(file.Path) , destinationPath); } } From 924ba90384d0ffc6d02746072f6537d9d7e49ed0 Mon Sep 17 00:00:00 2001 From: he <109787524@qq.com> Date: Thu, 18 Jul 2024 10:05:26 +0800 Subject: [PATCH 095/251] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E9=AB=98=E4=BA=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Reading/Dto/ReadingImageTaskViewModel.cs | 8 ++++ .../Reading/Dto/ReadingQuestionViewModel.cs | 48 ++++++++++++++----- .../ReadingQuestionService.cs | 3 +- .../IRECIST1Point1CalculateService.cs | 4 ++ .../LuganoCalculateService.cs | 4 ++ .../LuganoWithoutPETCalculateService.cs | 4 ++ .../ReadingCalculate/PCWG3CalculateService.cs | 4 ++ .../RECIST1Point1CalculateService.cs | 4 ++ .../RECIST1Point1_BMCalculateService.cs | 4 ++ .../SelfDefineCalculateService.cs | 4 ++ .../ReadingQuestionSystem.cs | 27 ++++++++++- .../ReadingQuestionTrial.cs | 35 ++++++++++++-- 12 files changed, 130 insertions(+), 19 deletions(-) diff --git a/IRaCIS.Core.Application/Service/Reading/Dto/ReadingImageTaskViewModel.cs b/IRaCIS.Core.Application/Service/Reading/Dto/ReadingImageTaskViewModel.cs index 0cb0ecae0..2829ee398 100644 --- a/IRaCIS.Core.Application/Service/Reading/Dto/ReadingImageTaskViewModel.cs +++ b/IRaCIS.Core.Application/Service/Reading/Dto/ReadingImageTaskViewModel.cs @@ -1,5 +1,6 @@ using IRaCIS.Core.Domain.Share; using MassTransit; +using Newtonsoft.Json; using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; @@ -141,6 +142,13 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto public string ReportMark { get; set; } = string.Empty; + /// + /// 高亮问题的答案 + /// + public string HighlightAnswer { get; set; } = "[]"; + + public List HighlightAnswerList { get; set; } = new List(); + /// /// 问题英文分组 diff --git a/IRaCIS.Core.Application/Service/Reading/Dto/ReadingQuestionViewModel.cs b/IRaCIS.Core.Application/Service/Reading/Dto/ReadingQuestionViewModel.cs index e7cada86e..566e9679c 100644 --- a/IRaCIS.Core.Application/Service/Reading/Dto/ReadingQuestionViewModel.cs +++ b/IRaCIS.Core.Application/Service/Reading/Dto/ReadingQuestionViewModel.cs @@ -1,7 +1,9 @@ using IRaCIS.Core.Domain.Share; +using Newtonsoft.Json; using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; using System.Linq; using System.Text; using System.Threading.Tasks; @@ -892,11 +894,14 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto /// public string ParentDictionaryCode { get; set; } = string.Empty; + public List HighlightAnswerList { get; set; } = new List(); + - /// - /// 系统标准Id - /// - public Guid ReadingQuestionCriterionTrialId { get; set; } + + /// + /// 系统标准Id + /// + public Guid ReadingQuestionCriterionTrialId { get; set; } /// /// 是否复制病灶 @@ -1118,6 +1123,9 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto public List ParentTriggerValueList { get; set; } = new List(); public List RelevanceValueList { get; set; } = new List(); + + public List HighlightAnswerList { get; set; } = new List(); + /// /// 备注 /// @@ -1660,10 +1668,14 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto /// public LimitShow LimitShow { get; set; } = LimitShow.AllShow; - /// - /// 最大答案长度 - /// - public int? MaxAnswerLength { get; set; } + + public List HighlightAnswerList { get; set; }= new List(); + + + /// + /// 最大答案长度 + /// + public int? MaxAnswerLength { get; set; } /// /// 文件类型 @@ -1728,10 +1740,15 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto /// public string RelevanceValue { get; set; } = string.Empty; - /// - /// 类型 - /// - public string Type { get; set; } + /// + /// 高亮问题的答案 + /// + public string HighlightAnswer { get; set; } = "[]"; + + /// + /// 类型 + /// + public string Type { get; set; } /// /// 父问题触发 @@ -1846,6 +1863,13 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto public bool IsAdditional { get; set; } + /// + /// 高亮问题的答案 + /// + public string HighlightAnswer { get; set; } = "[]"; + + public List HighlightAnswerList { get; set; } = new List(); + /// /// 分类算法 /// diff --git a/IRaCIS.Core.Application/Service/Reading/ReadingCriterion/ReadingQuestionService.cs b/IRaCIS.Core.Application/Service/Reading/ReadingCriterion/ReadingQuestionService.cs index f4ce30663..4089e8676 100644 --- a/IRaCIS.Core.Application/Service/Reading/ReadingCriterion/ReadingQuestionService.cs +++ b/IRaCIS.Core.Application/Service/Reading/ReadingCriterion/ReadingQuestionService.cs @@ -274,6 +274,7 @@ namespace IRaCIS.Application.Services { indto.ParentTriggerValue = string.Join(',', indto.ParentTriggerValueList); indto.RelevanceValue = string.Join(',', indto.RelevanceValueList); + indto.HighlightAnswer=JsonConvert.SerializeObject(indto.HighlightAnswerList); if (indto.Id != null) { var trialIdList = await _readingQuestionTrialRepository.Where(x => x.ReadingQuestionSystemId == indto.Id && x.IsJudgeQuestion && x.JudgeType != JudgeTypeEnum.None) @@ -439,7 +440,7 @@ namespace IRaCIS.Application.Services } indto.ParentTriggerValue = string.Join(',', indto.ParentTriggerValueList); indto.RelevanceValue = string.Join(',', indto.RelevanceValueList); - + indto.HighlightAnswer =JsonConvert.SerializeObject(indto.HighlightAnswerList); if (indto.Id != null) { diff --git a/IRaCIS.Core.Application/Service/ReadingCalculate/IRECIST1Point1CalculateService.cs b/IRaCIS.Core.Application/Service/ReadingCalculate/IRECIST1Point1CalculateService.cs index 51c3433ad..0cfebf074 100644 --- a/IRaCIS.Core.Application/Service/ReadingCalculate/IRECIST1Point1CalculateService.cs +++ b/IRaCIS.Core.Application/Service/ReadingCalculate/IRECIST1Point1CalculateService.cs @@ -217,6 +217,8 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate Unit = x.Unit, CustomUnit=x.CustomUnit, ReportLayType= ReportLayType.Group, + HighlightAnswer = x.HighlightAnswer, + HighlightAnswerList = x.HighlightAnswerList, }).ToList(); // 分组 @@ -242,6 +244,8 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate Unit = x.Unit, CustomUnit=x.CustomUnit, ReportLayType = ReportLayType.Question, + HighlightAnswer = x.HighlightAnswer, + HighlightAnswerList = x.HighlightAnswerList, }).ToList(); // 问题 diff --git a/IRaCIS.Core.Application/Service/ReadingCalculate/LuganoCalculateService.cs b/IRaCIS.Core.Application/Service/ReadingCalculate/LuganoCalculateService.cs index 1abb95c98..22d76219b 100644 --- a/IRaCIS.Core.Application/Service/ReadingCalculate/LuganoCalculateService.cs +++ b/IRaCIS.Core.Application/Service/ReadingCalculate/LuganoCalculateService.cs @@ -213,6 +213,8 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate Unit = x.Unit, CustomUnit = x.CustomUnit, ReportLayType = ReportLayType.Group, + HighlightAnswer = x.HighlightAnswer, + HighlightAnswerList = x.HighlightAnswerList, }).ToList(); // 分组 @@ -238,6 +240,8 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate Unit = x.Unit, CustomUnit = x.CustomUnit, ReportLayType = ReportLayType.Question, + HighlightAnswer = x.HighlightAnswer, + HighlightAnswerList = x.HighlightAnswerList, }).ToList(); // 问题 diff --git a/IRaCIS.Core.Application/Service/ReadingCalculate/LuganoWithoutPETCalculateService.cs b/IRaCIS.Core.Application/Service/ReadingCalculate/LuganoWithoutPETCalculateService.cs index 672d3087a..c7cccd3e0 100644 --- a/IRaCIS.Core.Application/Service/ReadingCalculate/LuganoWithoutPETCalculateService.cs +++ b/IRaCIS.Core.Application/Service/ReadingCalculate/LuganoWithoutPETCalculateService.cs @@ -213,6 +213,8 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate Unit = x.Unit, CustomUnit = x.CustomUnit, ReportLayType = ReportLayType.Group, + HighlightAnswer = x.HighlightAnswer, + HighlightAnswerList = x.HighlightAnswerList, }).ToList(); // 分组 @@ -238,6 +240,8 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate Unit = x.Unit, CustomUnit = x.CustomUnit, ReportLayType = ReportLayType.Question, + HighlightAnswer = x.HighlightAnswer, + HighlightAnswerList = x.HighlightAnswerList, }).ToList(); // 问题 diff --git a/IRaCIS.Core.Application/Service/ReadingCalculate/PCWG3CalculateService.cs b/IRaCIS.Core.Application/Service/ReadingCalculate/PCWG3CalculateService.cs index 543d30833..e13ced660 100644 --- a/IRaCIS.Core.Application/Service/ReadingCalculate/PCWG3CalculateService.cs +++ b/IRaCIS.Core.Application/Service/ReadingCalculate/PCWG3CalculateService.cs @@ -178,6 +178,8 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate CustomUnit=x.CustomUnit, Unit = x.Unit, ReportLayType=ReportLayType.Group, + HighlightAnswer = x.HighlightAnswer, + HighlightAnswerList = x.HighlightAnswerList, }).ToList(); // 分组 @@ -204,6 +206,8 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate Unit = x.Unit, CustomUnit=x.CustomUnit, ReportLayType = ReportLayType.Question, + HighlightAnswer = x.HighlightAnswer, + HighlightAnswerList = x.HighlightAnswerList, }).ToList(); // 问题 diff --git a/IRaCIS.Core.Application/Service/ReadingCalculate/RECIST1Point1CalculateService.cs b/IRaCIS.Core.Application/Service/ReadingCalculate/RECIST1Point1CalculateService.cs index 289356dd4..51cc7ff8f 100644 --- a/IRaCIS.Core.Application/Service/ReadingCalculate/RECIST1Point1CalculateService.cs +++ b/IRaCIS.Core.Application/Service/ReadingCalculate/RECIST1Point1CalculateService.cs @@ -171,6 +171,8 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate Unit = x.Unit, CustomUnit=x.CustomUnit, ReportLayType= ReportLayType.Group, + HighlightAnswer=x.HighlightAnswer, + HighlightAnswerList=x.HighlightAnswerList, }).ToList(); // 分组 @@ -196,6 +198,8 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate Unit = x.Unit, CustomUnit=x.CustomUnit, ReportLayType = ReportLayType.Question, + HighlightAnswer = x.HighlightAnswer, + HighlightAnswerList = x.HighlightAnswerList, }).ToList(); // 问题 diff --git a/IRaCIS.Core.Application/Service/ReadingCalculate/RECIST1Point1_BMCalculateService.cs b/IRaCIS.Core.Application/Service/ReadingCalculate/RECIST1Point1_BMCalculateService.cs index d19fb0e0b..e0c335572 100644 --- a/IRaCIS.Core.Application/Service/ReadingCalculate/RECIST1Point1_BMCalculateService.cs +++ b/IRaCIS.Core.Application/Service/ReadingCalculate/RECIST1Point1_BMCalculateService.cs @@ -167,6 +167,8 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate Unit = x.Unit, CustomUnit=x.CustomUnit, ReportLayType= ReportLayType.Group, + HighlightAnswer = x.HighlightAnswer, + HighlightAnswerList = x.HighlightAnswerList, }).ToList(); // 分组 @@ -192,6 +194,8 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate Unit = x.Unit, CustomUnit=x.CustomUnit, ReportLayType = ReportLayType.Question, + HighlightAnswer = x.HighlightAnswer, + HighlightAnswerList = x.HighlightAnswerList, }).ToList(); // 问题 diff --git a/IRaCIS.Core.Application/Service/ReadingCalculate/SelfDefineCalculateService.cs b/IRaCIS.Core.Application/Service/ReadingCalculate/SelfDefineCalculateService.cs index 6d08584c1..55cfa4e3d 100644 --- a/IRaCIS.Core.Application/Service/ReadingCalculate/SelfDefineCalculateService.cs +++ b/IRaCIS.Core.Application/Service/ReadingCalculate/SelfDefineCalculateService.cs @@ -175,6 +175,8 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate Unit = x.Unit, CustomUnit=x.CustomUnit, ReportLayType = ReportLayType.Group, + HighlightAnswer = x.HighlightAnswer, + HighlightAnswerList = x.HighlightAnswerList, }).ToList(); // 分组 @@ -203,6 +205,8 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate Unit = x.Unit, CustomUnit=x.CustomUnit, ReportLayType = ReportLayType.Question, + HighlightAnswer = x.HighlightAnswer, + HighlightAnswerList = x.HighlightAnswerList, }).ToList(); // 问题 diff --git a/IRaCIS.Core.Domain/Reading/ReadingCriterionQuestion/ReadingQuestionSystem.cs b/IRaCIS.Core.Domain/Reading/ReadingCriterionQuestion/ReadingQuestionSystem.cs index 1de10ce86..bc02ee3b4 100644 --- a/IRaCIS.Core.Domain/Reading/ReadingCriterionQuestion/ReadingQuestionSystem.cs +++ b/IRaCIS.Core.Domain/Reading/ReadingCriterionQuestion/ReadingQuestionSystem.cs @@ -217,7 +217,12 @@ namespace IRaCIS.Core.Domain.Models /// public QuestionClassify? QuestionClassify { get; set; } - [JsonIgnore] + /// + /// 高亮问题的答案 + /// + public string HighlightAnswer { get; set; } = "[]"; + + [JsonIgnore] [ForeignKey("GroupId")] public ReadingQuestionSystem GroupInfo { get; set; } @@ -272,6 +277,26 @@ namespace IRaCIS.Core.Domain.Models } + [NotMapped] + public List HighlightAnswerList + { + get + { + + try + { + var result = JsonConvert.DeserializeObject>(this.HighlightAnswer); + return result == null ? new List() : result; + } + catch (Exception) + { + + return new List(); + } + + } + } + } diff --git a/IRaCIS.Core.Domain/Reading/ReadingCriterionQuestion/ReadingQuestionTrial.cs b/IRaCIS.Core.Domain/Reading/ReadingCriterionQuestion/ReadingQuestionTrial.cs index 5c315bf9b..7bf00b885 100644 --- a/IRaCIS.Core.Domain/Reading/ReadingCriterionQuestion/ReadingQuestionTrial.cs +++ b/IRaCIS.Core.Domain/Reading/ReadingCriterionQuestion/ReadingQuestionTrial.cs @@ -302,10 +302,15 @@ namespace IRaCIS.Core.Domain.Models [ForeignKey("GroupId")] public ReadingQuestionTrial GroupInfo { get; set; } - /// - /// 分页标准 - /// - [ForeignKey("ReadingCriterionPageId")] + /// + /// 高亮问题的答案 + /// + public string HighlightAnswer { get; set; } = "[]"; + + /// + /// 分页标准 + /// + [ForeignKey("ReadingCriterionPageId")] [JsonIgnore] public ReadingCriterionPage ReadingCriterionPage { get; set; } [JsonIgnore] @@ -380,7 +385,27 @@ namespace IRaCIS.Core.Domain.Models } } - } + [NotMapped] + public List HighlightAnswerList + { + get + { + + try + { + var result = JsonConvert.DeserializeObject>(this.HighlightAnswer); + return result == null ? new List() : result; + } + catch (Exception) + { + + return new List(); + } + + } + } + + } public class CalculateInfo From ff4136e02dd8358508622646a25f2f893b0651e1 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Thu, 18 Jul 2024 10:32:27 +0800 Subject: [PATCH 096/251] =?UTF-8?q?=E4=BF=AE=E6=94=B9AE=20=E9=85=8D?= =?UTF-8?q?=E7=BD=AE=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRC.Core.SCP/appsettings.Test_IRC_SCP.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/IRC.Core.SCP/appsettings.Test_IRC_SCP.json b/IRC.Core.SCP/appsettings.Test_IRC_SCP.json index 5e93530c7..aa6c2223b 100644 --- a/IRC.Core.SCP/appsettings.Test_IRC_SCP.json +++ b/IRC.Core.SCP/appsettings.Test_IRC_SCP.json @@ -40,8 +40,8 @@ }, "ConnectionStrings": { - "RemoteNew": "Server=106.14.89.110,1435;Database=Test_HIR;User ID=sa;Password=xc@123456;TrustServerCertificate=true", - "Hangfire": "Server=106.14.89.110,1435;Database=Test_HIR_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true" + "RemoteNew": "Server=106.14.89.110,1435;Database=Test_IRC;User ID=sa;Password=xc@123456;TrustServerCertificate=true", + "Hangfire": "Server=106.14.89.110,1435;Database=Test_IRC_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true" }, "BasicSystemConfig": { From 22c9386101d7a3a81e4f394477e1e56a46746d17 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Thu, 18 Jul 2024 10:55:47 +0800 Subject: [PATCH 097/251] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=B5=8B=E8=AF=95AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRC.Core.SCP/Properties/launchSettings.json | 21 ++-------------- IRC.Core.SCP/Service/CStoreSCPService.cs | 28 +++++++++++++-------- 2 files changed, 20 insertions(+), 29 deletions(-) diff --git a/IRC.Core.SCP/Properties/launchSettings.json b/IRC.Core.SCP/Properties/launchSettings.json index d3d3ca4bc..11587df61 100644 --- a/IRC.Core.SCP/Properties/launchSettings.json +++ b/IRC.Core.SCP/Properties/launchSettings.json @@ -1,31 +1,14 @@ { "$schema": "http://json.schemastore.org/launchsettings.json", - "iisSettings": { - "windowsAuthentication": false, - "anonymousAuthentication": true, - "iisExpress": { - "applicationUrl": "http://localhost:36358", - "sslPort": 0 - } - }, "profiles": { "Test_IRC_SCP": { "commandName": "Project", "dotnetRunMessages": true, "launchBrowser": true, "launchUrl": "swagger", - "applicationUrl": "http://localhost:5243", + "applicationUrl": "http://localhost:6200", "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "IRC_Test_SCP" - } - }, - "IIS Express": { - "commandName": "IISExpress", - "launchBrowser": true, - "launchUrl": "swagger", - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" + "ASPNETCORE_ENVIRONMENT": "Test_IRC_SCP" } } - } } diff --git a/IRC.Core.SCP/Service/CStoreSCPService.cs b/IRC.Core.SCP/Service/CStoreSCPService.cs index a296bfd6f..949065199 100644 --- a/IRC.Core.SCP/Service/CStoreSCPService.cs +++ b/IRC.Core.SCP/Service/CStoreSCPService.cs @@ -102,29 +102,37 @@ namespace IRaCIS.Core.SCP.Service var trialDicomAEList = _trialDicomAERepository.Select(t => new { t.CalledAE, t.TrialId }).ToList(); var trialCalledAEList = trialDicomAEList.Select(t => t.CalledAE).ToList(); + Log.Logger.Information("当前系统配置:", string.Join('|', trialDicomAEList)); + var findCalledAE = trialDicomAEList.Where(t => t.CalledAE == association.CalledAE).FirstOrDefault(); var isCanReceiveIamge = false; - if (findCalledAE!=null) + if (findCalledAE != null) { _trialId = findCalledAE.TrialId; var _trialSiteDicomAERepository = _serviceProvider.GetService>(); - var findTrialSiteAE = _trialSiteDicomAERepository.Where(t=>t.CallingAE==association.CallingAE).FirstOrDefault(); + var findTrialSiteAE = _trialSiteDicomAERepository.Where(t => t.CallingAE == association.CallingAE).FirstOrDefault(); - if (findTrialSiteAE!=null) + if (findTrialSiteAE != null) { - _trialSiteId= findTrialSiteAE.TrialSiteId; + _trialSiteId = findTrialSiteAE.TrialSiteId; isCanReceiveIamge = true; } - } - - if (!trialCalledAEList.Contains(association.CalledAE) || isCanReceiveIamge==false) + + } + + if (association.CallingAE == "test-callingAE") + { + isCanReceiveIamge = true; + } + + if (!trialCalledAEList.Contains(association.CalledAE) || isCanReceiveIamge == false) { Log.Logger.Warning($"拒绝CalledAE:{association.CalledAE}的连接"); @@ -163,8 +171,8 @@ namespace IRaCIS.Core.SCP.Service _upload.EndTime = DateTime.Now; _upload.StudyCount = _SCPStudyIdList.Count; - _upload.TrialId=_trialId; - _upload.TrialSiteId=_trialSiteId; + _upload.TrialId = _trialId; + _upload.TrialSiteId = _trialSiteId; await _SCPImageUploadRepository.AddAsync(_upload, true); @@ -292,7 +300,7 @@ namespace IRaCIS.Core.SCP.Service { try { - var scpStudyId = await dicomArchiveService.ArchiveDicomFileAsync(request.Dataset,_trialId,_trialSiteId, storeRelativePath, Association.CallingAE, Association.CalledAE); + var scpStudyId = await dicomArchiveService.ArchiveDicomFileAsync(request.Dataset, _trialId, _trialSiteId, storeRelativePath, Association.CallingAE, Association.CalledAE); if (!_SCPStudyIdList.Contains(scpStudyId)) { From 32ba46206b3352fd39cdc2ca2eaddac77ee56060 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Thu, 18 Jul 2024 15:18:40 +0800 Subject: [PATCH 098/251] =?UTF-8?q?=E5=A2=9E=E5=8A=A0ACC=20number?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Dockerfile | 4 ++++ IRC.Core.SCP/Service/CStoreSCPService.cs | 2 +- .../IRaCIS.Core.Application.xml | 15 +++++++++++++++ .../Service/Visit/DTO/PatientViewModel.cs | 2 +- .../Service/Visit/PatientService.cs | 1 + .../Service/Visit/_MapConfig.cs | 8 +++++++- 6 files changed, 29 insertions(+), 3 deletions(-) create mode 100644 Dockerfile diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 000000000..551c83917 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,4 @@ +FROM registry.cn-shanghai.aliyuncs.com/extimaging/aspnetcore:v8.2 +WORKDIR /app +COPY publish . +ENTRYPOINT ["dotnet", "IRaCIS.Core.API.dll"] diff --git a/IRC.Core.SCP/Service/CStoreSCPService.cs b/IRC.Core.SCP/Service/CStoreSCPService.cs index 949065199..eaa4d3b1b 100644 --- a/IRC.Core.SCP/Service/CStoreSCPService.cs +++ b/IRC.Core.SCP/Service/CStoreSCPService.cs @@ -135,7 +135,7 @@ namespace IRaCIS.Core.SCP.Service if (!trialCalledAEList.Contains(association.CalledAE) || isCanReceiveIamge == false) { - Log.Logger.Warning($"拒绝CalledAE:{association.CalledAE}的连接"); + Log.Logger.Warning($"拒绝CallingAE:{association.CallingAE} CalledAE:{association.CalledAE}的连接"); return SendAssociationRejectAsync( DicomRejectResult.Permanent, diff --git a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml index 0be0d769e..160a1ae97 100644 --- a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml +++ b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml @@ -5641,6 +5641,11 @@ 单位 + + + 高亮问题的答案 + + 问题英文分组 @@ -8632,6 +8637,11 @@ 关联Value + + + 高亮问题的答案 + + 类型 @@ -8732,6 +8742,11 @@ Id + + + 高亮问题的答案 + + 分类算法 diff --git a/IRaCIS.Core.Application/Service/Visit/DTO/PatientViewModel.cs b/IRaCIS.Core.Application/Service/Visit/DTO/PatientViewModel.cs index f3c8d4a72..178dc34b8 100644 --- a/IRaCIS.Core.Application/Service/Visit/DTO/PatientViewModel.cs +++ b/IRaCIS.Core.Application/Service/Visit/DTO/PatientViewModel.cs @@ -1052,7 +1052,7 @@ namespace IRaCIS.Application.Contracts public string CallingAE { get; set; } = string.Empty; public string BodyPartExamined { get; set; } = string.Empty; - + public string AccessionNumber { get; set; } = string.Empty; public string PatientIdStr { get; set; } = string.Empty; public string PatientName { get; set; } = string.Empty; public string PatientAge { get; set; } = string.Empty; diff --git a/IRaCIS.Core.Application/Service/Visit/PatientService.cs b/IRaCIS.Core.Application/Service/Visit/PatientService.cs index dc49fe0ad..f0f6f684a 100644 --- a/IRaCIS.Core.Application/Service/Visit/PatientService.cs +++ b/IRaCIS.Core.Application/Service/Visit/PatientService.cs @@ -266,6 +266,7 @@ namespace IRaCIS.Application.Services SeriesCount = scpStudy.SeriesCount, StudyTime = scpStudy.StudyTime, BodyPartExamined=scpStudy.BodyPartExamined, + AccessionNumber=scpStudy.AccessionNumber, PatientBirthDate=scpStudy.PatientBirthDate, PatientAge = scpStudy.PatientAge, diff --git a/IRaCIS.Core.Application/Service/Visit/_MapConfig.cs b/IRaCIS.Core.Application/Service/Visit/_MapConfig.cs index 717c22d8e..9909f3eba 100644 --- a/IRaCIS.Core.Application/Service/Visit/_MapConfig.cs +++ b/IRaCIS.Core.Application/Service/Visit/_MapConfig.cs @@ -119,7 +119,13 @@ namespace IRaCIS.Core.Application.Service .ForMember(d => d.TrialSiteAliasName, u => u.MapFrom(s => s.TrialSite.TrialSiteAliasName)) .ForMember(d => d.TrialSiteName, u => u.MapFrom(s => s.TrialSite.TrialSiteName)) ; - + + + CreateMap(); + CreateMap(); + CreateMap(); + + } } From 795cb0aba2654231bb44c818833b3f333c125559 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Fri, 19 Jul 2024 09:04:55 +0800 Subject: [PATCH 099/251] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E9=9D=9Edicom=20?= =?UTF-8?q?=E7=9B=91=E6=8E=A7=E4=B8=8A=E4=BC=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.API/Controllers/UploadDownLoadController.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/IRaCIS.Core.API/Controllers/UploadDownLoadController.cs b/IRaCIS.Core.API/Controllers/UploadDownLoadController.cs index 8fff9be23..aa4d6a673 100644 --- a/IRaCIS.Core.API/Controllers/UploadDownLoadController.cs +++ b/IRaCIS.Core.API/Controllers/UploadDownLoadController.cs @@ -530,6 +530,7 @@ namespace IRaCIS.Core.API.Controllers studyMonitor.StudyCode = noneDicomStudy.StudyCode; studyMonitor.ArchiveFinishedTime = DateTime.Now; studyMonitor.IP = _userInfo.IP; + studyMonitor.IsSuccess = true; await _repository.SaveChangesAsync(); From d7f0fdd0e74c751aabf1748f7b85f9640ca8a8ef Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Fri, 19 Jul 2024 16:12:59 +0800 Subject: [PATCH 100/251] =?UTF-8?q?oss=20=E4=B8=8B=E8=BD=BD=E8=B5=B0?= =?UTF-8?q?=E5=86=85=E7=BD=91=E5=9C=B0=E5=9D=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.API/appsettings.Event_IRC.json | 1 + IRaCIS.Core.API/appsettings.Prod_IRC.json | 1 + IRaCIS.Core.API/appsettings.Test_IRC.json | 1 + IRaCIS.Core.API/appsettings.US_Prod_IRC.json | 1 + IRaCIS.Core.API/appsettings.US_Test_IRC.json | 1 + IRaCIS.Core.API/appsettings.US_Uat_IRC.json | 1 + IRaCIS.Core.API/appsettings.Uat_IRC.json | 1 + IRaCIS.Core.Application/Helper/OSSService.cs | 11 +++++++---- 8 files changed, 14 insertions(+), 4 deletions(-) diff --git a/IRaCIS.Core.API/appsettings.Event_IRC.json b/IRaCIS.Core.API/appsettings.Event_IRC.json index 2e9f86342..216571d78 100644 --- a/IRaCIS.Core.API/appsettings.Event_IRC.json +++ b/IRaCIS.Core.API/appsettings.Event_IRC.json @@ -14,6 +14,7 @@ "ObjectStoreUse": "AliyunOSS", "AliyunOSS": { "regionId": "cn-shanghai", + "internalEndpoint": "https://oss-cn-shanghai-internal.aliyuncs.com", "endpoint": "https://oss-cn-shanghai.aliyuncs.com", "accessKeyId": "LTAI5tKvzs7ed3UfSpNk3xwQ", "accessKeySecret": "zTIceGEShlZDGnLrCFfIGFE7TXVRio", diff --git a/IRaCIS.Core.API/appsettings.Prod_IRC.json b/IRaCIS.Core.API/appsettings.Prod_IRC.json index 02e0a3b74..7b2b1d376 100644 --- a/IRaCIS.Core.API/appsettings.Prod_IRC.json +++ b/IRaCIS.Core.API/appsettings.Prod_IRC.json @@ -16,6 +16,7 @@ "ObjectStoreUse": "AliyunOSS", "AliyunOSS": { "regionId": "cn-shanghai", + "internalEndpoint": "https://oss-cn-shanghai-internal.aliyuncs.com", "endpoint": "https://oss-cn-shanghai.aliyuncs.com", "accessKeyId": "LTAI5tKvzs7ed3UfSpNk3xwQ", "accessKeySecret": "zTIceGEShlZDGnLrCFfIGFE7TXVRio", diff --git a/IRaCIS.Core.API/appsettings.Test_IRC.json b/IRaCIS.Core.API/appsettings.Test_IRC.json index 28ea34260..c397ac52d 100644 --- a/IRaCIS.Core.API/appsettings.Test_IRC.json +++ b/IRaCIS.Core.API/appsettings.Test_IRC.json @@ -17,6 +17,7 @@ "AliyunOSS": { "regionId": "cn-shanghai", + "internalEndpoint": "https://oss-cn-shanghai-internal.aliyuncs.com", "endPoint": "https://oss-cn-shanghai.aliyuncs.com", "accessKeyId": "LTAI5tKvzs7ed3UfSpNk3xwQ", "accessKeySecret": "zTIceGEShlZDGnLrCFfIGFE7TXVRio", diff --git a/IRaCIS.Core.API/appsettings.US_Prod_IRC.json b/IRaCIS.Core.API/appsettings.US_Prod_IRC.json index 8957701a9..0c7ed8158 100644 --- a/IRaCIS.Core.API/appsettings.US_Prod_IRC.json +++ b/IRaCIS.Core.API/appsettings.US_Prod_IRC.json @@ -17,6 +17,7 @@ "ObjectStoreUse": "AWS", "AliyunOSS": { "regionId": "cn-shanghai", + "internalEndpoint": "https://oss-cn-shanghai-internal.aliyuncs.com", "endPoint": "https://oss-cn-shanghai.aliyuncs.com", "accessKeyId": "", "accessKeySecret": "", diff --git a/IRaCIS.Core.API/appsettings.US_Test_IRC.json b/IRaCIS.Core.API/appsettings.US_Test_IRC.json index 815a762e3..67d4b1fe7 100644 --- a/IRaCIS.Core.API/appsettings.US_Test_IRC.json +++ b/IRaCIS.Core.API/appsettings.US_Test_IRC.json @@ -16,6 +16,7 @@ "ObjectStoreUse": "MinIO", "AliyunOSS": { "regionId": "cn-shanghai", + "internalEndpoint": "https://oss-cn-shanghai-internal.aliyuncs.com", "endPoint": "https://oss-cn-shanghai.aliyuncs.com", "accessKeyId": "LTAI5tKvzs7ed3UfSpNk3xwQ", "accessKeySecret": "zTIceGEShlZDGnLrCFfIGFE7TXVRio", diff --git a/IRaCIS.Core.API/appsettings.US_Uat_IRC.json b/IRaCIS.Core.API/appsettings.US_Uat_IRC.json index d3f3950c8..87b6305f1 100644 --- a/IRaCIS.Core.API/appsettings.US_Uat_IRC.json +++ b/IRaCIS.Core.API/appsettings.US_Uat_IRC.json @@ -20,6 +20,7 @@ "AliyunOSS": { "regionId": "cn-shanghai", + "internalEndpoint": "https://oss-cn-shanghai-internal.aliyuncs.com", "endPoint": "https://oss-cn-shanghai.aliyuncs.com", "accessKeyId": "LTAI5tKvzs7ed3UfSpNk3xwQ", "accessKeySecret": "zTIceGEShlZDGnLrCFfIGFE7TXVRio", diff --git a/IRaCIS.Core.API/appsettings.Uat_IRC.json b/IRaCIS.Core.API/appsettings.Uat_IRC.json index 77945da7d..923001d1a 100644 --- a/IRaCIS.Core.API/appsettings.Uat_IRC.json +++ b/IRaCIS.Core.API/appsettings.Uat_IRC.json @@ -16,6 +16,7 @@ "AliyunOSS": { "regionId": "cn-shanghai", + "internalEndpoint": "https://oss-cn-shanghai-internal.aliyuncs.com", "endpoint": "https://oss-cn-shanghai.aliyuncs.com", "accessKeyId": "LTAI5tKvzs7ed3UfSpNk3xwQ", "accessKeySecret": "zTIceGEShlZDGnLrCFfIGFE7TXVRio", diff --git a/IRaCIS.Core.Application/Helper/OSSService.cs b/IRaCIS.Core.Application/Helper/OSSService.cs index 93c6c62bb..9d5a754ad 100644 --- a/IRaCIS.Core.Application/Helper/OSSService.cs +++ b/IRaCIS.Core.Application/Helper/OSSService.cs @@ -39,6 +39,9 @@ namespace IRaCIS.Core.Application.Helper public string regionId { get; set; } public string accessKeyId { get; set; } public string accessKeySecret { get; set; } + + public string internalEndpoint { get; set; } + public string endPoint { get; set; } public string bucketName { get; set; } @@ -144,7 +147,7 @@ namespace IRaCIS.Core.Application.Helper { var aliConfig = ObjectStoreServiceOptions.AliyunOSS; - var _ossClient = new OssClient(aliConfig.endPoint, aliConfig.accessKeyId, aliConfig.accessKeySecret); + var _ossClient = new OssClient(aliConfig.internalEndpoint, aliConfig.accessKeyId, aliConfig.accessKeySecret); @@ -220,7 +223,7 @@ namespace IRaCIS.Core.Application.Helper { var aliConfig = ObjectStoreServiceOptions.AliyunOSS; - var _ossClient = new OssClient(aliConfig.endPoint, aliConfig.accessKeyId, aliConfig.accessKeySecret); + var _ossClient = new OssClient(aliConfig.internalEndpoint, aliConfig.accessKeyId, aliConfig.accessKeySecret); // 上传文件 var result = _ossClient.PutObject(aliConfig.bucketName, ossRelativePath, localFilePath); @@ -279,7 +282,7 @@ namespace IRaCIS.Core.Application.Helper { var aliConfig = ObjectStoreServiceOptions.AliyunOSS; - var _ossClient = new OssClient(aliConfig.endPoint, aliConfig.accessKeyId, aliConfig.accessKeySecret); + var _ossClient = new OssClient(aliConfig.internalEndpoint, aliConfig.accessKeyId, aliConfig.accessKeySecret); // 上传文件 var result = _ossClient.GetObject(aliConfig.bucketName, ossRelativePath); @@ -351,7 +354,7 @@ namespace IRaCIS.Core.Application.Helper { var aliConfig = ObjectStoreServiceOptions.AliyunOSS; - var _ossClient = new OssClient(aliConfig.endPoint, aliConfig.accessKeyId, aliConfig.accessKeySecret); + var _ossClient = new OssClient(aliConfig.internalEndpoint, aliConfig.accessKeyId, aliConfig.accessKeySecret); // 生成签名URL。 var req = new GeneratePresignedUriRequest(aliConfig.bucketName, ossRelativePath, SignHttpMethod.Get) From 9898673dbf4a63c0bcdc6da994a942f46e5f9e57 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Mon, 22 Jul 2024 14:04:56 +0800 Subject: [PATCH 101/251] =?UTF-8?q?=E4=BF=AE=E6=94=B9study=E6=9F=A5?= =?UTF-8?q?=E8=AF=A2bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.Application/Service/ImageAndDoc/StudyService.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/IRaCIS.Core.Application/Service/ImageAndDoc/StudyService.cs b/IRaCIS.Core.Application/Service/ImageAndDoc/StudyService.cs index 96051495f..5bf595a63 100644 --- a/IRaCIS.Core.Application/Service/ImageAndDoc/StudyService.cs +++ b/IRaCIS.Core.Application/Service/ImageAndDoc/StudyService.cs @@ -422,6 +422,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc VisitNum = t.SubjectVisit.VisitNum, IsDicom = false, + IsFromPACS=false, SubjectCode = t.Subject.Code, From 99be08dc207ed98d582407528299925c58222d7e Mon Sep 17 00:00:00 2001 From: he <109787524@qq.com> Date: Mon, 22 Jul 2024 15:20:18 +0800 Subject: [PATCH 102/251] =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Reading/MedicalAudit/ReadingMedicalReviewService.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/IRaCIS.Core.Application/Service/Reading/MedicalAudit/ReadingMedicalReviewService.cs b/IRaCIS.Core.Application/Service/Reading/MedicalAudit/ReadingMedicalReviewService.cs index c0dcd1578..4c0ffe513 100644 --- a/IRaCIS.Core.Application/Service/Reading/MedicalAudit/ReadingMedicalReviewService.cs +++ b/IRaCIS.Core.Application/Service/Reading/MedicalAudit/ReadingMedicalReviewService.cs @@ -803,13 +803,13 @@ namespace IRaCIS.Core.Application.Service if (index + 1 == list.CurrentPageData.Count()) // 最后一个 { - throw new BusinessValidationFailedException(_localizer["MedicalReview_IRFinish"], ApiResponseCodeEnum.CloseCurrentWindows); + throw new BusinessValidationFailedException(_localizer["MedicalReview_IRFinish"]); } else if (index == -1 || list.CurrentPageData.Count == 1) // 第一个或者只有一个 { if (list.CurrentPageData[0].Id == inDto.TaskMedicalReviewId) { - throw new BusinessValidationFailedException(_localizer["MedicalReview_IRFinish"], ApiResponseCodeEnum.CloseCurrentWindows); + throw new BusinessValidationFailedException(_localizer["MedicalReview_IRFinish"]); } result = list.CurrentPageData[0]; } From 5246c10e32891fd72dc51a10e95c2ac5ce5f7fce Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Mon, 22 Jul 2024 15:41:16 +0800 Subject: [PATCH 103/251] =?UTF-8?q?=E5=A4=84=E7=90=86=E6=A3=80=E6=9F=A5?= =?UTF-8?q?=E5=88=A0=E9=99=A4=E3=80=81=E6=B7=BB=E5=8A=A0=E3=80=81=E7=BB=B4?= =?UTF-8?q?=E6=8A=A4=E7=BB=91=E5=AE=9A=E5=85=B3=E7=B3=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Service/QC/QCOperationService.cs | 39 ++++++++++++++----- .../Service/Visit/PatientService.cs | 21 +++++----- IRaCIS.Core.Domain/Image/SCPStudy.cs | 1 + 3 files changed, 42 insertions(+), 19 deletions(-) diff --git a/IRaCIS.Core.Application/Service/QC/QCOperationService.cs b/IRaCIS.Core.Application/Service/QC/QCOperationService.cs index bd00eef1f..d67743443 100644 --- a/IRaCIS.Core.Application/Service/QC/QCOperationService.cs +++ b/IRaCIS.Core.Application/Service/QC/QCOperationService.cs @@ -17,6 +17,7 @@ using IRaCIS.Core.Application.ViewModel; using IRaCIS.Core.Domain.Models; using IRaCIS.Core.Application.Service; using Medallion.Threading; +using DocumentFormat.OpenXml.Office2010.Excel; namespace IRaCIS.Core.Application.Image.QA { @@ -802,28 +803,46 @@ namespace IRaCIS.Core.Application.Image.QA var succeess2 = await _repository.BatchDeleteAsync(t => t.StudyId == id); var success3 = await _dicomSeriesrepository.BatchDeleteNoTrackingAsync(t => t.StudyId == id); + await _repository.BatchUpdateAsync(t => t.Id == id,u=>new SCPStudy() { SubjectVisitId=null}); + + + //var success3 = await _dicomSeriesrepository.DeleteFromQueryAsync(t => t.StudyId == id, true); //var success4 = await _repository.BatchDeleteAsync(t => t.StudyId == id); //删除 物理文件 - var instancePathList = await _repository.Where(t => t.StudyId == id) - .Select(t => t.Path).ToListAsync(); + //var instancePathList = await _repository.Where(t => t.StudyId == id) + // .Select(t => t.Path).ToListAsync(); - instancePathList.ForEach(path => - { + //instancePathList.ForEach(path => + //{ - var physicalPath = FileStoreHelper.GetPhysicalFilePath(_hostEnvironment, path); + // var physicalPath = FileStoreHelper.GetPhysicalFilePath(_hostEnvironment, path); - if (System.IO.File.Exists(physicalPath)) - { - File.Delete(physicalPath); - } - }); + // if (System.IO.File.Exists(physicalPath)) + // { + // File.Delete(physicalPath); + // } + //}); } + var subjectId=waitDeleteStudyList.Select(t=>t.SubjectId).FirstOrDefault(); + + var patientList = _repository.Where(t => t.SubjectId == subjectId).Select(t => t.Id).ToList(); + + foreach (var patientId in patientList) + { + if (_repository.Where(t=>t.Id== patientId).Any(t => t.SCPStudyList.Count() == t.SCPStudyList.Where(t => t.SubjectVisitId == null).Count())) + { + await _repository.BatchUpdateAsync(t => t.Id == patientId, u => new SCPPatient() { SubjectId = null }); + } + } + + + await _subjectVisitRepository.SaveChangesAsync(); diff --git a/IRaCIS.Core.Application/Service/Visit/PatientService.cs b/IRaCIS.Core.Application/Service/Visit/PatientService.cs index f0f6f684a..da2f95207 100644 --- a/IRaCIS.Core.Application/Service/Visit/PatientService.cs +++ b/IRaCIS.Core.Application/Service/Visit/PatientService.cs @@ -192,7 +192,7 @@ namespace IRaCIS.Application.Services SCPStudyId = scpStudy.Id, SeriesCount = scpStudy.SeriesCount, StudyTime = scpStudy.StudyTime, - + @@ -229,7 +229,7 @@ namespace IRaCIS.Application.Services public async Task> GetDicomModalityList(Guid trialId) { - var list = await _scpStudyRepository.Where(t => t.TrialId == trialId).SelectMany(t => t.SeriesList).Select(t=>t.Modality).Distinct().ToListAsync(); + var list = await _scpStudyRepository.Where(t => t.TrialId == trialId).SelectMany(t => t.SeriesList).Select(t => t.Modality).Distinct().ToListAsync(); return list; } @@ -265,10 +265,10 @@ namespace IRaCIS.Application.Services SCPStudyId = scpStudy.Id, SeriesCount = scpStudy.SeriesCount, StudyTime = scpStudy.StudyTime, - BodyPartExamined=scpStudy.BodyPartExamined, - AccessionNumber=scpStudy.AccessionNumber, + BodyPartExamined = scpStudy.BodyPartExamined, + AccessionNumber = scpStudy.AccessionNumber, - PatientBirthDate=scpStudy.PatientBirthDate, + PatientBirthDate = scpStudy.PatientBirthDate, PatientAge = scpStudy.PatientAge, PatientIdStr = scpStudy.PatientIdStr, PatientName = scpStudy.PatientName, @@ -311,12 +311,12 @@ namespace IRaCIS.Application.Services foreach (var scpStudyId in inCommand.SCPStudyIdList) { - var find = _scpStudyRepository.Where(t => t.Id == scpStudyId).Include(t => t.SeriesList).Include(t => t.InstanceList).FirstOrDefault(); + var find = _scpStudyRepository.Where(t => t.Id == scpStudyId).Select(t => new { SCPStudy = t, t.SeriesList, t.InstanceList }).FirstOrDefault(); if (find != null) { - var newStuty = _mapper.Map(find); + var newStuty = _mapper.Map(find.SCPStudy); await _repository.AddAsync(newStuty); @@ -345,8 +345,6 @@ namespace IRaCIS.Application.Services foreach (var instance in newInstanceList) { - - instance.SeqId = Guid.Empty; instance.TrialId = trialId; instance.SubjectId = subjectId; @@ -358,6 +356,10 @@ namespace IRaCIS.Application.Services currentNextCodeInt++; + await _repository.BatchUpdateAsync(t => t.Id == find.SCPStudy.PatientId, u => new SCPPatient() { SubjectId = subjectId }); + await _repository.BatchUpdateAsync(t => t.Id == scpStudyId, u => new SCPStudy() { SubjectVisitId = subjectVisitId }); + + } @@ -367,6 +369,7 @@ namespace IRaCIS.Application.Services await _repository.SaveChangesAsync(); + return ResponseOutput.Ok(); } diff --git a/IRaCIS.Core.Domain/Image/SCPStudy.cs b/IRaCIS.Core.Domain/Image/SCPStudy.cs index 4af3686cd..2fff33c5f 100644 --- a/IRaCIS.Core.Domain/Image/SCPStudy.cs +++ b/IRaCIS.Core.Domain/Image/SCPStudy.cs @@ -99,5 +99,6 @@ namespace IRaCIS.Core.Domain.Models [JsonIgnore] public TrialSite TrialSite { get; set; } + } } From fc36cbcb7585ef19eafdcf2950e3e5f777b7acd4 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Tue, 23 Jul 2024 10:35:38 +0800 Subject: [PATCH 104/251] =?UTF-8?q?=E4=BF=AE=E6=94=B9Dicom=20=E6=8E=A8?= =?UTF-8?q?=E9=80=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRC.Core.SCP/Service/CStoreSCPService.cs | 2 +- .../TrialSiteUser/TrialSiteDicomAEService.cs | 14 +++++++++++--- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/IRC.Core.SCP/Service/CStoreSCPService.cs b/IRC.Core.SCP/Service/CStoreSCPService.cs index eaa4d3b1b..97c2b636c 100644 --- a/IRC.Core.SCP/Service/CStoreSCPService.cs +++ b/IRC.Core.SCP/Service/CStoreSCPService.cs @@ -115,7 +115,7 @@ namespace IRaCIS.Core.SCP.Service var _trialSiteDicomAERepository = _serviceProvider.GetService>(); - var findTrialSiteAE = _trialSiteDicomAERepository.Where(t => t.CallingAE == association.CallingAE).FirstOrDefault(); + var findTrialSiteAE = _trialSiteDicomAERepository.Where(t => t.CallingAE == association.CallingAE && t.TrialId==_trialId).FirstOrDefault(); if (findTrialSiteAE != null) { diff --git a/IRaCIS.Core.Application/Service/TrialSiteUser/TrialSiteDicomAEService.cs b/IRaCIS.Core.Application/Service/TrialSiteUser/TrialSiteDicomAEService.cs index 7b5318d44..a0e9fa70e 100644 --- a/IRaCIS.Core.Application/Service/TrialSiteUser/TrialSiteDicomAEService.cs +++ b/IRaCIS.Core.Application/Service/TrialSiteUser/TrialSiteDicomAEService.cs @@ -51,13 +51,21 @@ namespace IRaCIS.Core.Application.Service { var verifyExp1 = new EntityVerifyExp() { - VerifyExp = u => u.IP == addOrEditTrialSiteDicomAE.IP && u.Port == addOrEditTrialSiteDicomAE.Port &&u.CallingAE==addOrEditTrialSiteDicomAE.CallingAE && u.TrialId == addOrEditTrialSiteDicomAE.TrialId, + VerifyExp = u => u.IP == addOrEditTrialSiteDicomAE.IP && u.Port == addOrEditTrialSiteDicomAE.Port + && u.CallingAE == addOrEditTrialSiteDicomAE.CallingAE && u.TrialId == addOrEditTrialSiteDicomAE.TrialId + && u.TrialSiteId == addOrEditTrialSiteDicomAE.TrialSiteId, - VerifyMsg = "不允许添加相同的IP和端口的记录" + VerifyMsg = "不允许添加相同的记录" + }; + var verifyExp2 = new EntityVerifyExp() + { + VerifyExp = u => u.CallingAE == addOrEditTrialSiteDicomAE.CallingAE && u.TrialId == addOrEditTrialSiteDicomAE.TrialId && u.TrialSiteId!=addOrEditTrialSiteDicomAE.TrialSiteId, + + VerifyMsg = "其他中心已有该CallingAE" }; - var entity = await _trialSiteDicomAERepository.InsertOrUpdateAsync(addOrEditTrialSiteDicomAE, true, verifyExp1); + var entity = await _trialSiteDicomAERepository.InsertOrUpdateAsync(addOrEditTrialSiteDicomAE, true, verifyExp1, verifyExp2); return ResponseOutput.Ok(entity.Id.ToString()); From 76792a127fb861db45dfe42ffbee8385fefb9cfd Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Tue, 23 Jul 2024 14:58:40 +0800 Subject: [PATCH 105/251] =?UTF-8?q?=E6=95=B4=E4=BD=93=E8=82=BF=E7=98=A4?= =?UTF-8?q?=E8=AF=84=E4=BC=B0=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 --- .../Service/Common/ExcelExportService.cs | 24 +++++++++++++++++-- .../Service/QC/DTO/QCListViewModel.cs | 19 +++++++++------ .../Service/QC/_MapConfig.cs | 7 +++++- .../ReadingConsistentClinicalData.cs | 2 +- .../ReadingConsistentClinicalDataPDF.cs | 8 +++---- 5 files changed, 45 insertions(+), 15 deletions(-) diff --git a/IRaCIS.Core.Application/Service/Common/ExcelExportService.cs b/IRaCIS.Core.Application/Service/Common/ExcelExportService.cs index cfcfc40e7..3dc67bdc4 100644 --- a/IRaCIS.Core.Application/Service/Common/ExcelExportService.cs +++ b/IRaCIS.Core.Application/Service/Common/ExcelExportService.cs @@ -1153,6 +1153,7 @@ namespace IRaCIS.Core.Application.Service.Common var resultList = list.Where(t => t.ReadingCategory != ReadingCategory.Judge).ToList(); + if (arbitrationRule == ArbitrationRule.Visit) { @@ -1165,11 +1166,30 @@ namespace IRaCIS.Core.Application.Service.Common } if (arbitrationRule == ArbitrationRule.Reading) { + //先确定裁判选定的是谁 foreach (var item in resultList) { + //以最后一次裁判为准 找到最大的裁判的裁判选择的Arm,相同就设置裁判标记 item.IsGenerateJudge = list.Where(t => t.ReadingCategory == ReadingCategory.Judge && t.SubjectCode == item.SubjectCode && t.VisitTaskNum > item.VisitTaskNum ).OrderByDescending(t => t.VisitTaskNum).FirstOrDefault()?.JudgeArmEnum == item.ArmEnum ? true : false; + } + //全局裁判了,选择了那个全局,那么对应全局下面的访视 设置裁判标记 + foreach (var item in resultList.Where(t => t.ReadingCategory == ReadingCategory.Visit)) + { + + var selectJudegeGlobalList = resultList.Where(t => t.ReadingCategory == ReadingCategory.Global && t.IsGenerateJudge == true).ToList(); + + //全局修改了答案,那么给访视上赋值全局的结果 并且取的是最后的全局 + var existGlobalAnswer = selectJudegeGlobalList.Where(t => t.SubjectCode == item.SubjectCode).SelectMany(t => t.GlobalTaskAnswerList).Where(t => t.VisitTaskId == item.Id) + .OrderByDescending(t => t.GlobalTaskVisitNum).FirstOrDefault()?.Answer; + + item.OverallTumorEvaluationResult = string.IsNullOrEmpty(existGlobalAnswer) ? item.OverallTumorEvaluationResult : existGlobalAnswer; + + item.IsGenerateJudge = true; + } + + } //如果没有产生裁判,默认选择R1 @@ -1247,7 +1267,7 @@ namespace IRaCIS.Core.Application.Service.Common //处理裁判标记 list = DealJudgeMark(criterion.ArbitrationRule, list); - exportInfo.List = ExportExcelConverterDate.ConvertToClientTimeInObject(list, _userInfo.TimeZoneId); + exportInfo.List = ExportExcelConverterDate.ConvertToClientTimeInObject(list.Where(t => t.ReadingCategory != ReadingCategory.Global).ToList(), _userInfo.TimeZoneId); exportInfo.IsEn_US = _userInfo.IsEn_Us; exportInfo.ClientZoneId = _userInfo.TimeZoneId; @@ -1307,7 +1327,7 @@ namespace IRaCIS.Core.Application.Service.Common //处理裁判标记 list = DealJudgeMark(criterion.ArbitrationRule, list); - exportInfo.List = ExportExcelConverterDate.ConvertToClientTimeInObject(list, _userInfo.TimeZoneId); + exportInfo.List = ExportExcelConverterDate.ConvertToClientTimeInObject(list.Where(t=>t.ReadingCategory!=ReadingCategory.Global).ToList(), _userInfo.TimeZoneId); exportInfo.IsEn_US = _userInfo.IsEn_Us; exportInfo.ClientZoneId = _userInfo.TimeZoneId; diff --git a/IRaCIS.Core.Application/Service/QC/DTO/QCListViewModel.cs b/IRaCIS.Core.Application/Service/QC/DTO/QCListViewModel.cs index 82c491a75..2db5966a6 100644 --- a/IRaCIS.Core.Application/Service/QC/DTO/QCListViewModel.cs +++ b/IRaCIS.Core.Application/Service/QC/DTO/QCListViewModel.cs @@ -865,13 +865,6 @@ namespace IRaCIS.Core.Application.Contracts public string OverallTumorEvaluationResult { get; set; } - #region old 废弃 - - //public Guid? JudgeResultTaskId { get; set; } - - //[DictionaryTranslateAttribute("YesOrNo")] - //public bool IsGenerateJudge => JudgeResultTaskId != null; - #endregion public Arm? JudgeArmEnum { get; set; } @@ -882,8 +875,20 @@ namespace IRaCIS.Core.Application.Contracts public bool IsGenerateJudge { get; set; } + [JsonIgnore] + + public List GlobalTaskAnswerList { get; set; } + } + public class GlobalAnswerInfo + { + public decimal GlobalTaskVisitNum { get; set; } + public Guid VisitTaskId { get; set; } + + public string Answer { get; set; } + + } public class RECIST1Point1EvaluationOfTumorEfficacyExport : OverallTumorEvaluationExport diff --git a/IRaCIS.Core.Application/Service/QC/_MapConfig.cs b/IRaCIS.Core.Application/Service/QC/_MapConfig.cs index 7bb30bb77..2110ce0bd 100644 --- a/IRaCIS.Core.Application/Service/QC/_MapConfig.cs +++ b/IRaCIS.Core.Application/Service/QC/_MapConfig.cs @@ -182,7 +182,12 @@ namespace IRaCIS.Core.Application.Service .ForMember(o => o.TrialSiteCode, t => t.MapFrom(u => u.Subject.TrialSite.TrialSiteCode)) .ForMember(o => o.SubjectCode, t => t.MapFrom(u => u.Subject.Code)) - .ForMember(o => o.UserName, t => t.MapFrom(u => u.DoctorUser.UserName)); + .ForMember(o => o.UserName, t => t.MapFrom(u => u.DoctorUser.UserName)) + .ForMember(o => o.GlobalTaskAnswerList, t => t.MapFrom(u => u.GlobalVisitResultList.Where(t=>t.GlobalAnswerType== GlobalAnswerType.Question) + .Select(c=>new GlobalAnswerInfo() { GlobalTaskVisitNum=c.VisitTask.VisitTaskNum,VisitTaskId=c.TaskId ,Answer=c.Answer}))) + + + ; CreateMap().IncludeBase() .ForMember(o => o.TargetlesionEvaluationResult, t => t.MapFrom(u => u.ReadingTaskQuestionAnswerList.Where(c => c.ReadingQuestionTrial.QuestionType == QuestionType.TargetLesion).FirstOrDefault()!.Answer)) diff --git a/IRaCIS.Core.Domain/Reading/ClinicalData/ReadingConsistentClinicalData.cs b/IRaCIS.Core.Domain/Reading/ClinicalData/ReadingConsistentClinicalData.cs index 66c216fc9..c57fc08e7 100644 --- a/IRaCIS.Core.Domain/Reading/ClinicalData/ReadingConsistentClinicalData.cs +++ b/IRaCIS.Core.Domain/Reading/ClinicalData/ReadingConsistentClinicalData.cs @@ -9,7 +9,7 @@ using System.Collections.Generic; namespace IRaCIS.Core.Domain.Models { /// - /// 项目的临床数据 + /// 一致性分析临床数据 /// [Table("ReadingConsistentClinicalData")] public class ReadingConsistentClinicalData : Entity, IAuditAdd diff --git a/IRaCIS.Core.Domain/Reading/ClinicalData/ReadingConsistentClinicalDataPDF.cs b/IRaCIS.Core.Domain/Reading/ClinicalData/ReadingConsistentClinicalDataPDF.cs index ce3183971..ab442df64 100644 --- a/IRaCIS.Core.Domain/Reading/ClinicalData/ReadingConsistentClinicalDataPDF.cs +++ b/IRaCIS.Core.Domain/Reading/ClinicalData/ReadingConsistentClinicalDataPDF.cs @@ -7,10 +7,10 @@ using System.ComponentModel.DataAnnotations.Schema; namespace IRaCIS.Core.Domain.Models { - /// - /// 项目的临床数据 - /// - [Table("ReadingConsistentClinicalDataPDF")] + /// + /// 一致性分析临床数据 + /// + [Table("ReadingConsistentClinicalDataPDF")] public class ReadingConsistentClinicalDataPDF : Entity, IAuditAdd { [JsonIgnore] From 3cdfd3a771fee33c3f99a8c699d3dbb78925a714 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Tue, 23 Jul 2024 15:35:49 +0800 Subject: [PATCH 106/251] =?UTF-8?q?=E4=BF=AE=E6=94=B9dicom=20ae=20?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../TrialSiteUser/DTO/DicomAEViewModel.cs | 6 +++--- .../TrialSiteUser/TrialDicomAEService.cs | 17 +++++++++++++---- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/IRaCIS.Core.Application/Service/TrialSiteUser/DTO/DicomAEViewModel.cs b/IRaCIS.Core.Application/Service/TrialSiteUser/DTO/DicomAEViewModel.cs index f3f03e1ce..50cc7d550 100644 --- a/IRaCIS.Core.Application/Service/TrialSiteUser/DTO/DicomAEViewModel.cs +++ b/IRaCIS.Core.Application/Service/TrialSiteUser/DTO/DicomAEViewModel.cs @@ -53,9 +53,9 @@ namespace IRaCIS.Core.Application.ViewModel [NotDefault] public Guid TrialId { get; set; } - public string CalledAE { get; set; } - public string IP { get; set; } - public int Port { get; set; } + public string CalledAE { get; set; } = string.Empty; + public string IP { get; set; } = string.Empty; + public int? Port { get; set; } public string Modality { get; set; } = string.Empty; public string Description { get; set; } = string.Empty; diff --git a/IRaCIS.Core.Application/Service/TrialSiteUser/TrialDicomAEService.cs b/IRaCIS.Core.Application/Service/TrialSiteUser/TrialDicomAEService.cs index beb413107..c5b11ba00 100644 --- a/IRaCIS.Core.Application/Service/TrialSiteUser/TrialDicomAEService.cs +++ b/IRaCIS.Core.Application/Service/TrialSiteUser/TrialDicomAEService.cs @@ -83,12 +83,21 @@ namespace IRaCIS.Core.Application.Service // IsVerify=addOrEditDicomAE.Id==null //}; - // 在此处拷贝automapper 映射 - var entity = await _dicomAERepository.InsertOrUpdateAsync(addOrEditDicomAE, true, verifyExp1); - await _trialRepository.UpdatePartialFromQueryAsync(t => t.Id == addOrEditDicomAE.TrialId, u => new Trial() { IsPACSConnect = addOrEditDicomAE.IsPACSConnect }, true); - return ResponseOutput.Ok(entity.Id.ToString()); + + if (addOrEditDicomAE.IsPACSConnect) + { + // 在此处拷贝automapper 映射 + var entity = await _dicomAERepository.InsertOrUpdateAsync(addOrEditDicomAE, true, verifyExp1); + + return ResponseOutput.Ok(entity.Id.ToString()); + } + else + { + return ResponseOutput.Ok(); + } + } From 8021d6a860c67e47f3de485b2985c3090078c989 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Wed, 24 Jul 2024 09:54:43 +0800 Subject: [PATCH 107/251] =?UTF-8?q?=E9=98=B2=E6=AD=A2=E7=94=9F=E6=88=90sql?= =?UTF-8?q?=E7=94=9F=E6=88=90GETDATE()=20=E6=97=B6=E5=8C=BA=E5=AF=BC?= =?UTF-8?q?=E8=87=B4=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Allocation/TaskConsistentRuleService.cs | 18 ++++++++++++------ .../Service/Common/ExcelExportService.cs | 1 - .../Service/Doctor/DoctorService.cs | 5 ++++- .../Service/Doctor/VacationService.cs | 5 ++++- .../Service/Management/SystemNoticeService.cs | 15 +++++++++++---- .../TrialSiteUser/PersonalWorkstation.cs | 5 +++-- .../TrialSiteUser/TrialDicomAEService.cs | 2 +- 7 files changed, 35 insertions(+), 16 deletions(-) diff --git a/IRaCIS.Core.Application/Service/Allocation/TaskConsistentRuleService.cs b/IRaCIS.Core.Application/Service/Allocation/TaskConsistentRuleService.cs index ea11b3575..0941f9d25 100644 --- a/IRaCIS.Core.Application/Service/Allocation/TaskConsistentRuleService.cs +++ b/IRaCIS.Core.Application/Service/Allocation/TaskConsistentRuleService.cs @@ -541,10 +541,13 @@ namespace IRaCIS.Core.Application.Service var trialReadingCriterionId = filterObj.TrialReadingCriterionId; + //防止生成sql生成GETDATE() 时区导致的问题 + var appDateTimeNow = DateTime.Now; + #region Subejct 维度 Expression> comonTaskFilter = u => u.TrialId == trialId && u.IsAnalysisCreate == false && u.TaskState == TaskState.Effect && u.ReadingTaskState == ReadingTaskState.HaveSigned && u.TrialReadingCriterionId == trialReadingCriterionId && - u.SignTime!.Value.AddDays(filterObj.IntervalWeeks * 7) < DateTime.Now && (u.ReReadingApplyState == ReReadingApplyState.Default || u.ReReadingApplyState == ReReadingApplyState.Reject) && u.DoctorUserId == doctorUserId; + u.SignTime!.Value.AddDays(filterObj.IntervalWeeks * 7) < appDateTimeNow && (u.ReReadingApplyState == ReReadingApplyState.Default || u.ReReadingApplyState == ReReadingApplyState.Reject) && u.DoctorUserId == doctorUserId; @@ -562,7 +565,7 @@ namespace IRaCIS.Core.Application.Service //{ // //这里的过滤条件 不能用 where(comonTaskFilter) 会报错,奇怪的问题 只能重新写一遍 // visitTaskFilter = visitTaskFilter.And(c => c.Subject.SubjectVisitTaskList.Any(t => t.VisitTaskNum == c.VisitTaskNum + ReadingCommon.TaskNumDic[ReadingCategory.Global] && t.ReadingCategory == ReadingCategory.Global && t.IsAnalysisCreate == false && t.TaskState == TaskState.Effect && t.ReadingTaskState == ReadingTaskState.HaveSigned && - // t.SignTime!.Value.AddDays(filterObj.IntervalWeeks * 7) < DateTime.Now && (t.ReReadingApplyState == ReReadingApplyState.Default || t.ReReadingApplyState == ReReadingApplyState.Reject))); + // t.SignTime!.Value.AddDays(filterObj.IntervalWeeks * 7) < appDateTimeNow && (t.ReReadingApplyState == ReReadingApplyState.Default || t.ReReadingApplyState == ReReadingApplyState.Reject))); //} @@ -758,9 +761,12 @@ namespace IRaCIS.Core.Application.Service var trialId = inQuery.TrialId; + //防止生成sql生成GETDATE() 时区导致的问题 + var appDateTimeNow = DateTime.Now; + Expression> comonTaskFilter = u => u.TrialId == trialId && u.IsAnalysisCreate == false && u.TaskState == TaskState.Effect && u.ReadingTaskState == ReadingTaskState.HaveSigned && (u.ReReadingApplyState == ReReadingApplyState.Default || u.ReReadingApplyState == ReReadingApplyState.Reject); - //&& u.TrialReadingCriterionId == trialReadingCriterionId &&u.SignTime!.Value.AddDays(filterObj.IntervalWeeks * 7) < DateTime.Now && u.DoctorUserId == doctorUserId; + //&& u.TrialReadingCriterionId == trialReadingCriterionId &&u.SignTime!.Value.AddDays(filterObj.IntervalWeeks * 7) < appDateTimeNow && u.DoctorUserId == doctorUserId; Expression> visitTaskFilter = comonTaskFilter.And(t => t.ReadingCategory == ReadingCategory.Visit); @@ -792,16 +798,16 @@ namespace IRaCIS.Core.Application.Service MatchSubejctCount = taskConsistentRule.Trial.SubjectList.AsQueryable() .Where(t => taskConsistentRule.IsHaveReadingPeriod == false ? t.SubjectVisitTaskList.AsQueryable() - .Where(visitTaskFilter).Where(t => t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId && t.SignTime!.Value.AddDays(taskConsistentRule.IntervalWeeks * 7) < DateTime.Now && t.DoctorUserId == user.Id) + .Where(visitTaskFilter).Where(t => t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId && t.SignTime!.Value.AddDays(taskConsistentRule.IntervalWeeks * 7) < appDateTimeNow && t.DoctorUserId == user.Id) .Count() >= taskConsistentRule.PlanVisitCount : //全局要>计划访视数量后面 t.SubjectVisitTaskList.AsQueryable().Where(comonTaskFilter) - .Where(t => t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId && t.SignTime!.Value.AddDays(taskConsistentRule.IntervalWeeks * 7) < DateTime.Now && t.DoctorUserId == user.Id) + .Where(t => t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId && t.SignTime!.Value.AddDays(taskConsistentRule.IntervalWeeks * 7) < appDateTimeNow && t.DoctorUserId == user.Id) .Where(t => t.ReadingCategory == ReadingCategory.Visit || t.ReadingCategory == ReadingCategory.Global).Any(t => t.ReadingCategory == ReadingCategory.Global && t.VisitTaskNum>taskConsistentRule.PlanVisitCount-1) && t.SubjectVisitTaskList.AsQueryable().Where(visitTaskFilter) - .Where(t => t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId && t.SignTime!.Value.AddDays(taskConsistentRule.IntervalWeeks * 7) < DateTime.Now && t.DoctorUserId == user.Id) + .Where(t => t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId && t.SignTime!.Value.AddDays(taskConsistentRule.IntervalWeeks * 7) < appDateTimeNow && t.DoctorUserId == user.Id) .Count()>= taskConsistentRule.PlanVisitCount ) diff --git a/IRaCIS.Core.Application/Service/Common/ExcelExportService.cs b/IRaCIS.Core.Application/Service/Common/ExcelExportService.cs index 3dc67bdc4..f4fae36d3 100644 --- a/IRaCIS.Core.Application/Service/Common/ExcelExportService.cs +++ b/IRaCIS.Core.Application/Service/Common/ExcelExportService.cs @@ -164,7 +164,6 @@ namespace IRaCIS.Core.Application.Service.Common .WhereIf(queryParam.UserTypeId != null, t => t.UserTypeId == queryParam.UserTypeId) .WhereIf(queryParam.IsGenerateAccount != null, t => t.IsGenerateAccount == queryParam.IsGenerateAccount) .WhereIf(queryParam.State != null && queryParam.State != TrialSiteUserStateEnum.OverTime, t => t.InviteState == queryParam.State) - //.WhereIf(queryParam.State != null && queryParam.State == TrialSiteUserStateEnum.OverTime, t => t.InviteState == TrialSiteUserStateEnum.HasSend && t.ExpireTime < DateTime.Now) .WhereIf(!string.IsNullOrEmpty(queryParam.UserName), t => (t.LastName + " / " + t.FirstName).Contains(queryParam.UserName)) .WhereIf(!string.IsNullOrEmpty(queryParam.OrganizationName), t => t.OrganizationName.Contains(queryParam.OrganizationName)) .ProjectTo(_mapper.ConfigurationProvider); diff --git a/IRaCIS.Core.Application/Service/Doctor/DoctorService.cs b/IRaCIS.Core.Application/Service/Doctor/DoctorService.cs index c9178a1d5..bf0a5b710 100644 --- a/IRaCIS.Core.Application/Service/Doctor/DoctorService.cs +++ b/IRaCIS.Core.Application/Service/Doctor/DoctorService.cs @@ -536,10 +536,13 @@ namespace IRaCIS.Application.Services [HttpGet("{doctorId:guid}")] public async Task GetAuditState(Guid doctorId) { + //防止生成sql生成GETDATE() 时区导致的问题 + var appDateTimeNow = DateTime.Now; + var doctor = (await _doctorRepository .ProjectTo(_mapper.ConfigurationProvider).FirstOrDefaultAsync(t => t.Id == doctorId)).IfNullThrowException(); - doctor.InHoliday = (await _repository.CountAsync(x => x.DoctorId == doctorId && x.EndDate <= DateTime.Now && x.StartDate <= DateTime.Now)) > 0; + doctor.InHoliday = (await _repository.CountAsync(x => x.DoctorId == doctorId && x.EndDate <= appDateTimeNow && x.StartDate <= appDateTimeNow)) > 0; return doctor; } diff --git a/IRaCIS.Core.Application/Service/Doctor/VacationService.cs b/IRaCIS.Core.Application/Service/Doctor/VacationService.cs index 54f7b4ba0..118688920 100644 --- a/IRaCIS.Core.Application/Service/Doctor/VacationService.cs +++ b/IRaCIS.Core.Application/Service/Doctor/VacationService.cs @@ -79,7 +79,10 @@ namespace IRaCIS.Application.Services [NonDynamicMethod] public async Task OnVacation(Guid doctorId) { - var count = await _vacationRepository.CountAsync(u => u.DoctorId == doctorId && u.EndDate >= DateTime.Now && u.StartDate <= DateTime.Now); + //防止生成sql生成GETDATE() 时区导致的问题 + var appDateTimeNow = DateTime.Now; + + var count = await _vacationRepository.CountAsync(u => u.DoctorId == doctorId && u.EndDate >= appDateTimeNow && u.StartDate <= appDateTimeNow); return ResponseOutput.Result(count > 0); } diff --git a/IRaCIS.Core.Application/Service/Management/SystemNoticeService.cs b/IRaCIS.Core.Application/Service/Management/SystemNoticeService.cs index 9bbe12288..e4735770c 100644 --- a/IRaCIS.Core.Application/Service/Management/SystemNoticeService.cs +++ b/IRaCIS.Core.Application/Service/Management/SystemNoticeService.cs @@ -27,14 +27,15 @@ namespace IRaCIS.Core.Application.Service [HttpPost] public async Task> GetSystemNoticeList(SystemNoticeQuery querySystemNotice) { - + //防止生成sql生成GETDATE() 时区导致的问题 + var appDateTimeNow = DateTime.Now; var systemNoticeQueryable = _systemNoticeRepository .WhereIf(querySystemNotice.ApplicableProjectEnum != null, t => t.ApplicableProjectEnum == querySystemNotice.ApplicableProjectEnum) .WhereIf(querySystemNotice.NoticeLevelEnum != null, t => t.NoticeLevelEnum == querySystemNotice.NoticeLevelEnum) .WhereIf(querySystemNotice.NoticeModeEnum != null, t => t.NoticeModeEnum == querySystemNotice.NoticeModeEnum) .WhereIf(querySystemNotice.NoticeStateEnum != null && querySystemNotice.NoticeStateEnum != Domain.Share.Management.SystemNotice_NoticeStateEnum.HaveExpired, t => t.NoticeStateEnum == querySystemNotice.NoticeStateEnum) - .WhereIf(querySystemNotice.NoticeModeEnum != null && querySystemNotice.NoticeStateEnum == Domain.Share.Management.SystemNotice_NoticeStateEnum.HaveExpired, t => t.NoticeStateEnum == Domain.Share.Management.SystemNotice_NoticeStateEnum.HavePublished && t.EndDate !=null && t.EndDate < DateTime.Now) + .WhereIf(querySystemNotice.NoticeModeEnum != null && querySystemNotice.NoticeStateEnum == Domain.Share.Management.SystemNotice_NoticeStateEnum.HaveExpired, t => t.NoticeStateEnum == Domain.Share.Management.SystemNotice_NoticeStateEnum.HavePublished && t.EndDate !=null && t.EndDate < appDateTimeNow) .WhereIf(querySystemNotice.NoticeTypeEnum != null, t => t.NoticeTypeEnum == querySystemNotice.NoticeTypeEnum) .WhereIf(!string.IsNullOrWhiteSpace(querySystemNotice.FileName), t => t.FileName.Contains(querySystemNotice.FileName)) .WhereIf(!string.IsNullOrWhiteSpace(querySystemNotice.NoticeContent), t => t.NoticeContent.Contains(querySystemNotice.NoticeContent)) @@ -117,13 +118,16 @@ namespace IRaCIS.Core.Application.Service [HttpPost] public async Task> GetUserSystemNoticeList(SystemNoticeQuery querySystemNotice) { + //防止生成sql生成GETDATE() 时区导致的问题 + var appDateTimeNow = DateTime.Now; + var systemNoticeQueryable = _systemNoticeRepository .Where(t => t.NoticeUserTypeList.Any(t => t.UserTypeId == _userInfo.UserTypeId) && t.NoticeStateEnum==Domain.Share.Management.SystemNotice_NoticeStateEnum.HavePublished) .WhereIf(querySystemNotice.ApplicableProjectEnum != null, t => t.ApplicableProjectEnum == querySystemNotice.ApplicableProjectEnum) .WhereIf(querySystemNotice.NoticeLevelEnum != null, t => t.NoticeLevelEnum == querySystemNotice.NoticeLevelEnum) .WhereIf(querySystemNotice.NoticeModeEnum != null, t => t.NoticeModeEnum == querySystemNotice.NoticeModeEnum) .WhereIf(querySystemNotice.NoticeStateEnum != null && querySystemNotice.NoticeStateEnum != Domain.Share.Management.SystemNotice_NoticeStateEnum.HaveExpired, t => t.NoticeStateEnum == querySystemNotice.NoticeStateEnum) - .WhereIf(querySystemNotice.NoticeModeEnum != null && querySystemNotice.NoticeStateEnum == Domain.Share.Management.SystemNotice_NoticeStateEnum.HaveExpired, t => t.NoticeStateEnum == Domain.Share.Management.SystemNotice_NoticeStateEnum.HavePublished && t.EndDate != null && t.EndDate < DateTime.Now) + .WhereIf(querySystemNotice.NoticeModeEnum != null && querySystemNotice.NoticeStateEnum == Domain.Share.Management.SystemNotice_NoticeStateEnum.HaveExpired, t => t.NoticeStateEnum == Domain.Share.Management.SystemNotice_NoticeStateEnum.HavePublished && t.EndDate != null && t.EndDate < appDateTimeNow) .WhereIf(querySystemNotice.NoticeTypeEnum != null, t => t.NoticeTypeEnum == querySystemNotice.NoticeTypeEnum) .WhereIf(!string.IsNullOrWhiteSpace(querySystemNotice.FileName), t => t.FileName.Contains(querySystemNotice.FileName)) .WhereIf(!string.IsNullOrWhiteSpace(querySystemNotice.NoticeContent), t => t.NoticeContent.Contains(querySystemNotice.NoticeContent)) @@ -135,9 +139,12 @@ namespace IRaCIS.Core.Application.Service public async Task> GetUserNoticeList() { + //防止生成sql生成GETDATE() 时区导致的问题 + var appDateTimeNow = DateTime.Now; + var query = _systemNoticeRepository .Where(t => t.NoticeUserTypeList.Any(t => t.UserTypeId == _userInfo.UserTypeId) && t.NoticeStateEnum == Domain.Share.Management.SystemNotice_NoticeStateEnum.HavePublished && !t.NoticeUserReadList.Any(t => t.CreateUserId == _userInfo.Id)) - .Where(t=>t.EndDate==null || t.EndDate != null && t.EndDate > DateTime.Now) + .Where(t=>t.EndDate==null || t.EndDate != null && t.EndDate > appDateTimeNow) .ProjectTo(_mapper.ConfigurationProvider, new { token = _userInfo.UserToken, userId = _userInfo.Id }); return await query.ToListAsync(); diff --git a/IRaCIS.Core.Application/Service/TrialSiteUser/PersonalWorkstation.cs b/IRaCIS.Core.Application/Service/TrialSiteUser/PersonalWorkstation.cs index ae62d3db5..936d470b7 100644 --- a/IRaCIS.Core.Application/Service/TrialSiteUser/PersonalWorkstation.cs +++ b/IRaCIS.Core.Application/Service/TrialSiteUser/PersonalWorkstation.cs @@ -1248,7 +1248,8 @@ namespace IRaCIS.Core.Application //} - + //防止生成sql生成GETDATE() 时区导致的问题 + var appDateTimeNow = DateTime.Now; var record = new UserToBeDoneRecord() { @@ -1264,7 +1265,7 @@ namespace IRaCIS.Core.Application SysNoticeUnReadCount= await _systemNoticeRepository.Where(t => t.NoticeUserTypeList.Any(t => t.UserTypeId == _userInfo.UserTypeId) && t.NoticeStateEnum == Domain.Share.Management.SystemNotice_NoticeStateEnum.HavePublished && !t.NoticeUserReadList.Any(t => t.CreateUserId == _userInfo.Id)) - .Where(t => t.EndDate == null || t.EndDate != null && t.EndDate > DateTime.Now) + .Where(t => t.EndDate == null || t.EndDate != null && t.EndDate > appDateTimeNow) .CountAsync(), #region PM diff --git a/IRaCIS.Core.Application/Service/TrialSiteUser/TrialDicomAEService.cs b/IRaCIS.Core.Application/Service/TrialSiteUser/TrialDicomAEService.cs index c5b11ba00..4c68b5992 100644 --- a/IRaCIS.Core.Application/Service/TrialSiteUser/TrialDicomAEService.cs +++ b/IRaCIS.Core.Application/Service/TrialSiteUser/TrialDicomAEService.cs @@ -29,7 +29,7 @@ namespace IRaCIS.Core.Application.Service _trialRepository = trialRepository; _dicomAERepository = dicomAERepository; } - + [HttpPost] public async Task>> GetDicomAEList(DicomAEQuery inQuery) { From 4f4dda7a09bec16a0ba02b13a7acfa31c43e87ed Mon Sep 17 00:00:00 2001 From: he <109787524@qq.com> Date: Wed, 24 Jul 2024 13:33:48 +0800 Subject: [PATCH 108/251] =?UTF-8?q?=E6=A0=BC=E5=BC=8F=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ReadingClinicalDataService.cs | 307 +++++++++--------- 1 file changed, 156 insertions(+), 151 deletions(-) diff --git a/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs b/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs index be62b141e..3cafc03c8 100644 --- a/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs +++ b/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs @@ -84,7 +84,7 @@ namespace IRaCIS.Application.Services { var existsQuery = _readingClinicalDataRepository .WhereIf(indto.Id != null, x => x.Id != indto.Id) - .Where(x => x.ClinicalDataTrialSetId == indto.ClinicalDataTrialSetId && x.ReadingId == indto.ReadingId&&x.StudyId==indto.StudyId); + .Where(x => x.ClinicalDataTrialSetId == indto.ClinicalDataTrialSetId && x.ReadingId == indto.ReadingId && x.StudyId == indto.StudyId); @@ -189,60 +189,60 @@ namespace IRaCIS.Application.Services public async Task> GetStudyClinicalData(GetStudyClinicalDataInDto inDto) { - var cRCClinicalDataList = await _readingClinicalDataRepository.Where(x => x.ReadingId == inDto.SubjectVisitId) - .Where(x => x.ClinicalDataTrialSet.ClinicalDataLevel == ClinicalLevel.Study).Select(x => new GetCRCClinicalDataOutDto() - { - Id = x.Id, - ClinicalDataSetName = x.ClinicalDataTrialSet.ClinicalDataSetName.LanguageName(x.ClinicalDataTrialSet.ClinicalDataSetEnName, _userInfo.IsEn_Us), - ClinicalUploadType = x.ClinicalDataTrialSet.ClinicalUploadType, - ClinicalDataLevel = x.ClinicalDataTrialSet.ClinicalDataLevel, - ClinicalDataSetEnName = x.ClinicalDataTrialSet.ClinicalDataSetEnName, - ClinicalDataTrialSetId = x.ClinicalDataTrialSet.Id, - FileName = x.ClinicalDataTrialSet.FileName, - UploadRole = x.ClinicalDataTrialSet.UploadRole, - Path = x.ClinicalDataTrialSet.Path, - IsBlind = x.IsBlind, - IsComplete = x.IsComplete, - ClinicalFromList = x.Subject.ClinicalFormList.Where(y => y.ReadingId == x.ReadingId && y.ClinicalDataTrialSetId == x.ClinicalDataTrialSetId).Select(y => new ClinicalFromData() - { - CheckDate = y.CheckDate, - ClinicalFormId = y.Id - }).ToList(), - PDFFileList = x.ReadingClinicalDataPDFList.Select(y => new GetFileDto() - { - Id = y.Id, + var cRCClinicalDataList = await _readingClinicalDataRepository.Where(x => x.ReadingId == inDto.SubjectVisitId) + .Where(x => x.ClinicalDataTrialSet.ClinicalDataLevel == ClinicalLevel.Study).Select(x => new GetCRCClinicalDataOutDto() + { + Id = x.Id, + ClinicalDataSetName = x.ClinicalDataTrialSet.ClinicalDataSetName.LanguageName(x.ClinicalDataTrialSet.ClinicalDataSetEnName, _userInfo.IsEn_Us), + ClinicalUploadType = x.ClinicalDataTrialSet.ClinicalUploadType, + ClinicalDataLevel = x.ClinicalDataTrialSet.ClinicalDataLevel, + ClinicalDataSetEnName = x.ClinicalDataTrialSet.ClinicalDataSetEnName, + ClinicalDataTrialSetId = x.ClinicalDataTrialSet.Id, + FileName = x.ClinicalDataTrialSet.FileName, + UploadRole = x.ClinicalDataTrialSet.UploadRole, + Path = x.ClinicalDataTrialSet.Path, + IsBlind = x.IsBlind, + IsComplete = x.IsComplete, + ClinicalFromList = x.Subject.ClinicalFormList.Where(y => y.ReadingId == x.ReadingId && y.ClinicalDataTrialSetId == x.ClinicalDataTrialSetId).Select(y => new ClinicalFromData() + { + CheckDate = y.CheckDate, + ClinicalFormId = y.Id + }).ToList(), + PDFFileList = x.ReadingClinicalDataPDFList.Select(y => new GetFileDto() + { + Id = y.Id, Size = y.Size, Type = y.Type, FileName = y.FileName, - Path = y.Path, - CreateTime = y.CreateTime, - }).ToList(), + Path = y.Path, + CreateTime = y.CreateTime, + }).ToList(), - }).ToListAsync(); + }).ToListAsync(); - var previousHistoryList = await _previousHistoryRepository.Where(x => x.SubjectVisitId == inDto.SubjectVisitId).ProjectTo(_mapper.ConfigurationProvider).ToListAsync(); - var previousOtherList = await _previousOtherRepository.Where(x => x.SubjectVisitId == inDto.SubjectVisitId).ProjectTo(_mapper.ConfigurationProvider).ToListAsync(); - var previousSurgeryList = await _previousSurgeryRepository.Where(x => x.SubjectVisitId == inDto.SubjectVisitId).ProjectTo(_mapper.ConfigurationProvider).ToListAsync(); + var previousHistoryList = await _previousHistoryRepository.Where(x => x.SubjectVisitId == inDto.SubjectVisitId).ProjectTo(_mapper.ConfigurationProvider).ToListAsync(); + var previousOtherList = await _previousOtherRepository.Where(x => x.SubjectVisitId == inDto.SubjectVisitId).ProjectTo(_mapper.ConfigurationProvider).ToListAsync(); + var previousSurgeryList = await _previousSurgeryRepository.Where(x => x.SubjectVisitId == inDto.SubjectVisitId).ProjectTo(_mapper.ConfigurationProvider).ToListAsync(); - foreach (var item in cRCClinicalDataList) - { - item.ClinicalTableData = new ClinicalDataTable() - { - PreviousHistoryList = previousHistoryList.Where(x => x.ClinicalDataTrialSetId == item.ClinicalDataTrialSetId).ToList(), - PreviousOtherList = previousOtherList.Where(x => x.ClinicalDataTrialSetId == item.ClinicalDataTrialSetId).ToList(), - PreviousSurgeryList = previousSurgeryList.Where(x => x.ClinicalDataTrialSetId == item.ClinicalDataTrialSetId).ToList(), - }; + foreach (var item in cRCClinicalDataList) + { + item.ClinicalTableData = new ClinicalDataTable() + { + PreviousHistoryList = previousHistoryList.Where(x => x.ClinicalDataTrialSetId == item.ClinicalDataTrialSetId).ToList(), + PreviousOtherList = previousOtherList.Where(x => x.ClinicalDataTrialSetId == item.ClinicalDataTrialSetId).ToList(), + PreviousSurgeryList = previousSurgeryList.Where(x => x.ClinicalDataTrialSetId == item.ClinicalDataTrialSetId).ToList(), + }; - } - return cRCClinicalDataList; - } + } + return cRCClinicalDataList; + } - /// - /// 获取CRC上传的文件 - /// - /// - /// - [HttpPost] + /// + /// 获取CRC上传的文件 + /// + /// + /// + [HttpPost] public async Task> GetCRCClinicalData(GetCRCClinicalDataInDto inDto) { @@ -258,26 +258,27 @@ namespace IRaCIS.Application.Services .WhereIf(!inDto.IsBaseline, x => x.ClinicalDataTrialSet.ClinicalDataLevel == ClinicalLevel.SubjectVisit) .Where(x => x.ClinicalDataTrialSet.TrialId == inDto.TrialId && x.ClinicalDataTrialSet.UploadRole == UploadRole.CRC); - } + } - List cRCClinicalDataList = await query - .Select(x => new GetCRCClinicalDataOutDto() + List cRCClinicalDataList = await query + .Select(x => new GetCRCClinicalDataOutDto() { Id = x.Id, - ClinicalDataSetName = x.ClinicalDataTrialSet.ClinicalDataSetName.LanguageName(x.ClinicalDataTrialSet.ClinicalDataSetEnName, _userInfo.IsEn_Us) , + ClinicalDataSetName = x.ClinicalDataTrialSet.ClinicalDataSetName.LanguageName(x.ClinicalDataTrialSet.ClinicalDataSetEnName, _userInfo.IsEn_Us), ClinicalUploadType = x.ClinicalDataTrialSet.ClinicalUploadType, - ClinicalDataLevel=x.ClinicalDataTrialSet.ClinicalDataLevel, - ClinicalDataSetEnName =x.ClinicalDataTrialSet.ClinicalDataSetEnName, + ClinicalDataLevel = x.ClinicalDataTrialSet.ClinicalDataLevel, + ClinicalDataSetEnName = x.ClinicalDataTrialSet.ClinicalDataSetEnName, ClinicalDataTrialSetId = x.ClinicalDataTrialSet.Id, FileName = x.ClinicalDataTrialSet.FileName, UploadRole = x.ClinicalDataTrialSet.UploadRole, Path = x.ClinicalDataTrialSet.Path, IsBlind = x.IsBlind, IsComplete = x.IsComplete, - ClinicalFromList=x.Subject.ClinicalFormList.Where(y=>y.ReadingId==x.ReadingId&&y.ClinicalDataTrialSetId==x.ClinicalDataTrialSetId).Select(y=> new ClinicalFromData() { - CheckDate=y.CheckDate, - ClinicalFormId=y.Id + ClinicalFromList = x.Subject.ClinicalFormList.Where(y => y.ReadingId == x.ReadingId && y.ClinicalDataTrialSetId == x.ClinicalDataTrialSetId).Select(y => new ClinicalFromData() + { + CheckDate = y.CheckDate, + ClinicalFormId = y.Id }).ToList(), PDFFileList = x.ReadingClinicalDataPDFList.Select(y => new GetFileDto() { @@ -288,7 +289,7 @@ namespace IRaCIS.Application.Services Type = y.Type, CreateTime = y.CreateTime, }).ToList(), - + }).ToListAsync(); var previousHistoryList = await _previousHistoryRepository.Where(x => x.SubjectVisitId == inDto.SubjectVisitId).ProjectTo(_mapper.ConfigurationProvider).ToListAsync(); @@ -310,7 +311,7 @@ namespace IRaCIS.Application.Services { cRCClinicalDataList = cRCClinicalDataList.Where(x => !(x.ClinicalFromList.Count() == 0 && x.ClinicalUploadType == ClinicalUploadType.Structuring)).ToList(); - } + } return cRCClinicalDataList; } @@ -367,7 +368,7 @@ namespace IRaCIS.Application.Services //} data.IsBlind = inDto.IsBlind; - data.IsComplete=inDto.IsComplete; + data.IsComplete = inDto.IsComplete; data.IsSign = true; data.ReadingClinicalDataState = ReadingClinicalDataStatus.HaveSigned; @@ -385,8 +386,8 @@ namespace IRaCIS.Application.Services //await this.iServiceProvider.GetService().AddOncologyTask(readingId); //如果先生成了任务,再签名subject级别 PM 临床数据,那么会导致其他标准的任务签名状态无法得到维护 - - if (await _repository.AnyAsync(t=>t.Id == data.ClinicalDataTrialSetId && t.UploadRole == UploadRole.PM && t.ClinicalDataLevel == ClinicalLevel.Subject)) + + if (await _repository.AnyAsync(t => t.Id == data.ClinicalDataTrialSetId && t.UploadRole == UploadRole.PM && t.ClinicalDataLevel == ClinicalLevel.Subject)) { var needDealTrialReadingCriterionIdList = _repository.Where(t => t.Id == data.ClinicalDataTrialSetId) .SelectMany(t => t.TrialClinicalDataSetCriteriaList) @@ -412,7 +413,7 @@ namespace IRaCIS.Application.Services public async Task DealVisiTaskClinicalDataSignedAsync(Guid trialId, Guid subjectId, Guid readingId, bool isVisit, Guid trialReadingCritrialId) { //获取确认的临床数据配置 - var trialClinicalDataSetList = _clinicalDataTrialSetRepository.Where(t => t.TrialId == trialId && t.IsConfirm).Include(t => t.TrialClinicalDataSetCriteriaList).ToList(); + var trialClinicalDataSetList = _clinicalDataTrialSetRepository.Where(t => t.TrialId == trialId && t.IsConfirm).Include(t => t.TrialClinicalDataSetCriteriaList).ToList(); //var criterionType = await _readingQuestionCriterionTrialRepository.Where(t => t.Id == trialReadingCritrialId).Select(t => t.CriterionType).FirstOrDefaultAsync(); @@ -427,7 +428,7 @@ namespace IRaCIS.Application.Services { var isBaseLine = await _subjectVisitRepository.Where(t => t.Id == readingId).Select(t => t.IsBaseLine).FirstOrDefaultAsync(); - + //判断是否基线 if (isBaseLine) @@ -513,7 +514,7 @@ namespace IRaCIS.Application.Services } //有序阅片才维护 IsFrontTaskNeedSignButNotSign 这个状态 - if (_readingQuestionCriterionTrialRepository.Any(t=>t.Id==trialReadingCritrialId && t.IsReadingTaskViewInOrder == ReadingOrder.InOrder)) + if (_readingQuestionCriterionTrialRepository.Any(t => t.Id == trialReadingCritrialId && t.IsReadingTaskViewInOrder == ReadingOrder.InOrder)) { @@ -538,8 +539,8 @@ namespace IRaCIS.Application.Services (t.Subject.SubjectVisitTaskList.AsQueryable().Where(visitTaskLambda).Any(c => c.IsNeedClinicalDataSign == true && c.IsClinicalDataSign == false && c.VisitTaskNum < t.VisitTaskNum) // 前序存在 未一致性核查未通过的 - || t.Subject.SubjectVisitList.Any(sv => sv.CheckState != CheckStateEnum.CVPassed && t.VisitTaskNum>sv.VisitNum) - + || t.Subject.SubjectVisitList.Any(sv => sv.CheckState != CheckStateEnum.CVPassed && t.VisitTaskNum > sv.VisitNum) + )) .Select(t => t.Id); @@ -551,7 +552,7 @@ namespace IRaCIS.Application.Services var visitTaskIdQueryable2 = _visitTaskRepository.Where(visitTaskLambda) //该Subject 该标准的任务 - + .Where(t => t.IsFrontTaskNeedSignButNotSign == true && //前序任务 不存在需要签名 但是没签名 @@ -570,14 +571,14 @@ namespace IRaCIS.Application.Services } - + } // 废弃 接口合并到签名哪里 - + [HttpPut] public async Task PMClinicalDataConfirm(PMClinicalDataConfirmCommand command) { @@ -631,7 +632,7 @@ namespace IRaCIS.Application.Services keyValuePairs.Add(ModuleTypeEnum.Oncology, ClinicalLevel.OncologyRead); - + var usedIdsQuery = _readingClinicalDataRepository.Where(x => x.ReadingId == inDto.ReadingId && x.Id != inDto.ReadingClinicalDataId).Select(x => x.ClinicalDataTrialSetId); @@ -646,20 +647,20 @@ namespace IRaCIS.Application.Services .WhereIf(inDto.IsVisit && !inDto.IsBaseLine, x => x.ClinicalDataLevel == ClinicalLevel.SubjectVisit) .WhereIf(!inDto.IsVisit, x => x.ClinicalDataLevel == ClinicalLevel.ImageRead || x.ClinicalDataLevel == ClinicalLevel.OncologyRead) .WhereIf(readModule != null, x => x.ClinicalDataLevel == keyValuePairs[readModule!.ModuleType]) - .WhereIf(inDto.TrialReadingCriterionId!=null,x=>x.TrialClinicalDataSetCriteriaList.Any(y=>y.TrialReadingCriterionId== inDto.TrialReadingCriterionId)) + .WhereIf(inDto.TrialReadingCriterionId != null, x => x.TrialClinicalDataSetCriteriaList.Any(y => y.TrialReadingCriterionId == inDto.TrialReadingCriterionId)) //.WhereIf(criterion!=null,x=>x.CriterionEnumListStr.Contains($"|{(int)criterion.CriterionType}|")) .Select(x => new GetTrialClinicalDataSelectOutDto() { ClinicalDataLevel = x.ClinicalDataLevel, ClinicalDataSetName = x.ClinicalDataSetName.LanguageName(x.ClinicalDataSetEnName, _userInfo.IsEn_Us), - ClinicalDataSetEnName=x.ClinicalDataSetEnName, + ClinicalDataSetEnName = x.ClinicalDataSetEnName, ClinicalUploadType = x.ClinicalUploadType, FileName = x.FileName, Path = x.Path, Id = x.Id, CriterionEnumList = x.CriterionEnumList, }).ToListAsync(); - + return clinicalList; } @@ -713,8 +714,8 @@ namespace IRaCIS.Application.Services {ClinicalLevel.ImageRead,2 }, {ClinicalLevel.OncologyRead,3 }, {ClinicalLevel.Subject,4 }, - {ClinicalLevel.Study,5 }, - }; + {ClinicalLevel.Study,5 }, + }; result = result.OrderBy(x => keys[x.ClinicalDataLevel]).ToList(); @@ -809,20 +810,21 @@ namespace IRaCIS.Application.Services Path = y.Path, CreateTime = y.CreateTime, }).ToList(), - + }); var result = new List(); if (!inDto.IsOnlyGetCRCReadModule) { - result = await resultQuery.ToListAsync(); + result = await resultQuery.ToListAsync(); } var readingIds = result.Select(x => x.ReadingId).ToList(); - var clinical = await _clinicalFormRepository.Where(x => readingIds.Contains(x.ReadingId??default(Guid))).ToListAsync(); - result.Where(x => x.ClinicalUploadType == ClinicalUploadType.Structuring).ForEach(x => { + var clinical = await _clinicalFormRepository.Where(x => readingIds.Contains(x.ReadingId ?? default(Guid))).ToListAsync(); + result.Where(x => x.ClinicalUploadType == ClinicalUploadType.Structuring).ForEach(x => + { - x.ClinicalFromList = clinical.Where(y => y.ReadingId == x.ReadingId&&y.ClinicalDataTrialSetId==x.ClinicalDataTrialSetId).Select(y => new ClinicalFromData() + x.ClinicalFromList = clinical.Where(y => y.ReadingId == x.ReadingId && y.ClinicalDataTrialSetId == x.ClinicalDataTrialSetId).Select(y => new ClinicalFromData() { CheckDate = y.CheckDate, ClinicalFormId = y.Id @@ -833,35 +835,36 @@ namespace IRaCIS.Application.Services // 这里处理CRC上传 阅片期的临床数据 var readModule = await _readModuleRepository.Where(x => x.Id == inDto.ReadingId) - .WhereIf(inDto.SelectIsSign,x=>x.IsPMConfirm) - .WhereIf(!inDto.SelectIsSign, x => x.IsCRCConfirm) - .FirstOrDefaultAsync(); + .WhereIf(inDto.SelectIsSign, x => x.IsPMConfirm) + .WhereIf(!inDto.SelectIsSign, x => x.IsCRCConfirm) + .FirstOrDefaultAsync(); if (readModule != null) { var moduleCriterionFromList = await _readModuleCriterionFromRepository .WhereIf(inDto.ClinicalDataTrialSetId != null, x => x.ClinicalForm.ClinicalDataTrialSetId == inDto.ClinicalDataTrialSetId) - .Where(x => x.ReadModuleId == readModule.Id).Select(x => new{ - ClinicalFormId= x.ClinicalFormId, - CheckDate= x.ClinicalForm.CheckDate, - ClinicalDataTrialSetId= x.ClinicalForm.ClinicalDataTrialSetId - - - }).ToListAsync(); + .Where(x => x.ReadModuleId == readModule.Id).Select(x => new + { + ClinicalFormId = x.ClinicalFormId, + CheckDate = x.ClinicalForm.CheckDate, + ClinicalDataTrialSetId = x.ClinicalForm.ClinicalDataTrialSetId + + + }).ToListAsync(); var clinicalresult = await _clinicalDataTrialSetRepository.Where(x => x.UploadRole == UploadRole.CRC && x.ClinicalUploadType == ClinicalUploadType.Structuring) .WhereIf(readModule.ReadingSetType == ReadingSetType.ImageReading, x => x.ClinicalDataLevel == ClinicalLevel.ImageRead) .WhereIf(readModule.ReadingSetType == ReadingSetType.TumorReading, x => x.ClinicalDataLevel == ClinicalLevel.OncologyRead) - .Where(x=>x.TrialClinicalDataSetCriteriaList.Any(y=>y.TrialReadingCriterionId==readModule.TrialReadingCriterionId)) + .Where(x => x.TrialClinicalDataSetCriteriaList.Any(y => y.TrialReadingCriterionId == readModule.TrialReadingCriterionId)) .Select(x => new GetReadingClinicalDataListOutDto() { ClinicalDataLevel = x.ClinicalDataLevel, SubjectId = inDto.SubjectId, ReadingId = default(Guid), - IsCRCApplicationRevoke=readModule.IsCRCApplicationRevoke, - IsCRCConfirm= readModule.IsCRCConfirm, - IsPMConfirm= readModule.IsPMConfirm, + IsCRCApplicationRevoke = readModule.IsCRCApplicationRevoke, + IsCRCConfirm = readModule.IsCRCConfirm, + IsPMConfirm = readModule.IsPMConfirm, ClinicalDataSetName = x.ClinicalDataSetName.LanguageName(x.ClinicalDataSetEnName, _userInfo.IsEn_Us), ClinicalDataSetEnName = x.ClinicalDataSetEnName, ClinicalDataTrialSetId = x.Id, @@ -872,7 +875,7 @@ namespace IRaCIS.Application.Services IsCRCUpload = x.UploadRole == UploadRole.CRC, IsNeedMerge = true, ReadModuleId = readModule.Id, - TrialClinicalDataSetCriteriaList=x.TrialClinicalDataSetCriteriaList, + TrialClinicalDataSetCriteriaList = x.TrialClinicalDataSetCriteriaList, //FileCount = x.FileCount, //ReadingClinicalDataState = x.ReadingClinicalDataState, @@ -901,8 +904,8 @@ namespace IRaCIS.Application.Services }); - result.AddRange(clinicalresult); - } + result.AddRange(clinicalresult); + } @@ -923,7 +926,7 @@ namespace IRaCIS.Application.Services result = result.Where(x => x.UploadRole == UploadRole.PM).ToList(); break; case GetClinicalType.CRCConfirm: - result = result.Where(x => x.UploadRole == UploadRole.CRC&&x.IsCRCConfirm&&!x.IsPMConfirm).ToList(); + result = result.Where(x => x.UploadRole == UploadRole.CRC && x.IsCRCConfirm && !x.IsPMConfirm).ToList(); break; case GetClinicalType.HasSign: result = result.Where(x => x.IsSign).ToList(); @@ -959,15 +962,15 @@ namespace IRaCIS.Application.Services { var resultQuery = _readingClinicalDataRepository.Where(x => x.SubjectId == inDto.SubjectId) .Where(x => x.ReadingId == inDto.ReadingId) - .WhereIf(inDto.ClinicalDataTrialSetId!=null, x=>x.ClinicalDataTrialSetId==inDto.TrialReadingCriterionId) - .Where(x => x.ClinicalDataTrialSet.TrialClinicalDataSetCriteriaList.Any(t=>t.TrialReadingCriterionId==inDto.TrialReadingCriterionId)) + .WhereIf(inDto.ClinicalDataTrialSetId != null, x => x.ClinicalDataTrialSetId == inDto.TrialReadingCriterionId) + .Where(x => x.ClinicalDataTrialSet.TrialClinicalDataSetCriteriaList.Any(t => t.TrialReadingCriterionId == inDto.TrialReadingCriterionId)) .Select(x => new GetReadingClinicalDataListOutDto() { ClinicalDataLevel = x.ClinicalDataTrialSet.ClinicalDataLevel, SubjectId = x.SubjectId, ReadingId = x.ReadingId, ClinicalDataSetName = x.ClinicalDataTrialSet.ClinicalDataSetName.LanguageName(x.ClinicalDataTrialSet.ClinicalDataSetEnName, _userInfo.IsEn_Us), - ClinicalDataSetEnName =x.ClinicalDataTrialSet.ClinicalDataSetEnName, + ClinicalDataSetEnName = x.ClinicalDataTrialSet.ClinicalDataSetEnName, ClinicalDataTrialSetId = x.ClinicalDataTrialSetId, IsSign = x.IsSign, ClinicalUploadType = x.ClinicalDataTrialSet.ClinicalUploadType, @@ -994,7 +997,8 @@ namespace IRaCIS.Application.Services var readingIds = result.Select(x => x.ReadingId).ToList(); var clinical = await _clinicalFormRepository.Where(x => readingIds.Contains(x.ReadingId ?? default(Guid))).ToListAsync(); - result.Where(x => x.ClinicalUploadType == ClinicalUploadType.Structuring).ForEach(x => { + result.Where(x => x.ClinicalUploadType == ClinicalUploadType.Structuring).ForEach(x => + { x.ClinicalFromList = clinical.Where(y => y.ReadingId == x.ReadingId && y.ClinicalDataTrialSetId == x.ClinicalDataTrialSetId).Select(y => new ClinicalFromData() { @@ -1005,77 +1009,78 @@ namespace IRaCIS.Application.Services }); // 这里处理CRC上传 阅片期的临床数据 - var readModule = await _readModuleRepository.Where(x => x.Id == inDto.ReadingId&&x.IsCRCConfirm) + var readModule = await _readModuleRepository.Where(x => x.Id == inDto.ReadingId && x.IsCRCConfirm) .FirstOrDefaultAsync(); if (readModule != null) { - var moduleCriterionFromList = await _readModuleCriterionFromRepository.Where(x => x.ReadModuleId == readModule.Id) + var moduleCriterionFromList = await _readModuleCriterionFromRepository.Where(x => x.ReadModuleId == readModule.Id) .WhereIf(inDto.ClinicalDataTrialSetId != null, x => x.ClinicalForm.ClinicalDataTrialSetId == inDto.TrialReadingCriterionId) - .Select(x => new { - ClinicalFormId = x.ClinicalFormId, - CheckDate = x.ClinicalForm.CheckDate, - ClinicalDataTrialSetId = x.ClinicalForm.ClinicalDataTrialSetId + .Select(x => new + { + ClinicalFormId = x.ClinicalFormId, + CheckDate = x.ClinicalForm.CheckDate, + ClinicalDataTrialSetId = x.ClinicalForm.ClinicalDataTrialSetId - }).ToListAsync(); + }).ToListAsync(); - - var clinicalresult = await _clinicalDataTrialSetRepository.Where(x => x.UploadRole == UploadRole.CRC&&x.ClinicalUploadType== ClinicalUploadType.Structuring) - .WhereIf(readModule.ReadingSetType == ReadingSetType.ImageReading,x=>x.ClinicalDataLevel== ClinicalLevel.ImageRead) + + var clinicalresult = await _clinicalDataTrialSetRepository.Where(x => x.UploadRole == UploadRole.CRC && x.ClinicalUploadType == ClinicalUploadType.Structuring) + .WhereIf(readModule.ReadingSetType == ReadingSetType.ImageReading, x => x.ClinicalDataLevel == ClinicalLevel.ImageRead) .WhereIf(readModule.ReadingSetType == ReadingSetType.TumorReading, x => x.ClinicalDataLevel == ClinicalLevel.OncologyRead) .Where(x => x.TrialClinicalDataSetCriteriaList.Any(y => y.TrialReadingCriterionId == readModule.TrialReadingCriterionId)) .Select(x => new GetReadingClinicalDataListOutDto() - { + { - ClinicalDataLevel = x.ClinicalDataLevel, - SubjectId = inDto.SubjectId, - ReadingId = default(Guid), - IsCRCApplicationRevoke= readModule.IsCRCApplicationRevoke, + ClinicalDataLevel = x.ClinicalDataLevel, + SubjectId = inDto.SubjectId, + ReadingId = default(Guid), + IsCRCApplicationRevoke = readModule.IsCRCApplicationRevoke, IsCRCConfirm = readModule.IsCRCConfirm, - IsPMConfirm=readModule.IsPMConfirm, + IsPMConfirm = readModule.IsPMConfirm, ClinicalDataSetName = x.ClinicalDataSetName.LanguageName(x.ClinicalDataSetEnName, _userInfo.IsEn_Us), - ClinicalDataSetEnName = x.ClinicalDataSetEnName, - ClinicalDataTrialSetId = x.Id, - IsSign = readModule.IsPMConfirm, - ClinicalUploadType = x.ClinicalUploadType, - Id = default(Guid), - UploadRole = x.UploadRole, - IsCRCUpload = x.UploadRole == UploadRole.CRC, - IsNeedMerge = true, - ReadModuleId = readModule.Id, - //FileCount = x.FileCount, + ClinicalDataSetEnName = x.ClinicalDataSetEnName, + ClinicalDataTrialSetId = x.Id, + IsSign = readModule.IsPMConfirm, + ClinicalUploadType = x.ClinicalUploadType, + Id = default(Guid), + UploadRole = x.UploadRole, + IsCRCUpload = x.UploadRole == UploadRole.CRC, + IsNeedMerge = true, + ReadModuleId = readModule.Id, + //FileCount = x.FileCount, - //ReadingClinicalDataState = x.ReadingClinicalDataState, + //ReadingClinicalDataState = x.ReadingClinicalDataState, - //FileList = x.ReadingClinicalDataPDFList.Select(y => new GetFileDto() - //{ - // Id = y.Id, - // FileName = y.FileName, - // Path = y.Path, - // CreateTime = y.CreateTime, - //}).ToList() + //FileList = x.ReadingClinicalDataPDFList.Select(y => new GetFileDto() + //{ + // Id = y.Id, + // FileName = y.FileName, + // Path = y.Path, + // CreateTime = y.CreateTime, + //}).ToList() - }).ToListAsync(); + }).ToListAsync(); - clinicalresult.ForEach(x => - { - x.FileCount = moduleCriterionFromList.Where(y => y.ClinicalDataTrialSetId == x.ClinicalDataTrialSetId).Count(); - x.ClinicalFromList = moduleCriterionFromList.Where(y => y.ClinicalDataTrialSetId == x.ClinicalDataTrialSetId).OrderBy(y => y.CheckDate).Select(x => new ClinicalFromData - { - CheckDate = x.CheckDate, - ClinicalFormId = x.ClinicalFormId + clinicalresult.ForEach(x => + { + x.FileCount = moduleCriterionFromList.Where(y => y.ClinicalDataTrialSetId == x.ClinicalDataTrialSetId).Count(); + x.ClinicalFromList = moduleCriterionFromList.Where(y => y.ClinicalDataTrialSetId == x.ClinicalDataTrialSetId).OrderBy(y => y.CheckDate).Select(x => new ClinicalFromData + { + CheckDate = x.CheckDate, + ClinicalFormId = x.ClinicalFormId - }).ToList(); + }).ToList(); - x.IsSign = readModule.IsPMConfirm ?true : false; + x.IsSign = readModule.IsPMConfirm ? true : false; x.ReadingClinicalDataState = readModule.IsPMConfirm ? ReadingClinicalDataStatus.HaveSigned : ReadingClinicalDataStatus.HaveChecked; - }); + }); - result.AddRange(clinicalresult); - } + result.AddRange(clinicalresult); + } if (inDto.GetClinicalType != null) @@ -1086,7 +1091,7 @@ namespace IRaCIS.Application.Services result = result.Where(x => x.UploadRole == UploadRole.PM).ToList(); break; case GetClinicalType.CRCConfirm: - result = result.Where(x => x.UploadRole == UploadRole.CRC&&x.IsCRCConfirm&&!x.IsPMConfirm).ToList(); + result = result.Where(x => x.UploadRole == UploadRole.CRC && x.IsCRCConfirm && !x.IsPMConfirm).ToList(); break; case GetClinicalType.HasSign: result = result.Where(x => x.IsSign).ToList(); @@ -1094,7 +1099,7 @@ namespace IRaCIS.Application.Services } } - + return result; } From 94e942e3447dfd636c84462dfae3e2c9e23c9e63 Mon Sep 17 00:00:00 2001 From: he <109787524@qq.com> Date: Wed, 24 Jul 2024 14:46:49 +0800 Subject: [PATCH 109/251] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ReadingClinicalDataService.cs | 167 ++---------------- .../Reading/Dto/ReadingClinicalDataDto.cs | 5 +- .../Interface/IReadingClinicalDataService.cs | 1 - .../ReadingOncologyTaskService.cs | 2 +- 4 files changed, 20 insertions(+), 155 deletions(-) diff --git a/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs b/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs index 3cafc03c8..c60da920d 100644 --- a/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs +++ b/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs @@ -10,6 +10,7 @@ using System.Linq.Expressions; using IRaCIS.Core.Infrastructure; using System.Linq.Dynamic.Core; using Microsoft.Extensions.Logging; +using IRaCIS.Core.Infrastructure.Extention; namespace IRaCIS.Application.Services { @@ -750,7 +751,14 @@ namespace IRaCIS.Application.Services var isBaseLine = await _subjectVisitRepository.AnyAsync(x => x.Id == inDto.ReadingId && x.IsBaseLine); - var result = await this.GetReadingClinicalList(inDto); + var result = await this.GetClinicalDataList(new GetReadingOrTaskClinicalDataListInDto() { + ClinicalDataTrialSetId = inDto.ClinicalDataTrialSetId, + GetClinicalType=inDto.GetClinicalType, + SubjectId=inDto.SubjectId, + TrialId=inDto.TrialId, + ReadingId=inDto.ReadingId, + TrialReadingCriterionId = inDto.TrialReadingCriterionId, + }); var readingIds = result.Select(x => x.ReadingId).ToList(); var previousHistoryList = await _previousHistoryRepository.Where(x => readingIds.Contains(x.SubjectVisitId)).ProjectTo(_mapper.ConfigurationProvider).ToListAsync(); @@ -788,6 +796,7 @@ namespace IRaCIS.Application.Services .WhereIf(inDto.ClinicalDataTrialSetId != null, x => x.ClinicalDataTrialSetId == inDto.ClinicalDataTrialSetId) .WhereIf(inDto.SelectIsSign, x => x.IsSign == true) .Where(x => x.ReadingId == inDto.ReadingId) + .WhereIf(inDto.TrialReadingCriterionId!=null, x => x.ClinicalDataTrialSet.TrialClinicalDataSetCriteriaList.Any(t => t.TrialReadingCriterionId == inDto.TrialReadingCriterionId)) .Select(x => new GetReadingClinicalDataListOutDto() { ClinicalDataLevel = x.ClinicalDataTrialSet.ClinicalDataLevel, @@ -803,6 +812,10 @@ namespace IRaCIS.Application.Services Id = x.Id, UploadRole = x.ClinicalDataTrialSet.UploadRole, IsCRCUpload = x.ClinicalDataTrialSet.UploadRole == UploadRole.CRC, + IsBlind = x.IsBlind, + IsComplete = x.IsComplete, + FileCount = x.FileCount, + ReadingClinicalDataState = x.ReadingClinicalDataState, FileList = x.ReadingClinicalDataPDFList.Select(y => new GetFileDto() { Id = y.Id, @@ -835,6 +848,7 @@ namespace IRaCIS.Application.Services // 这里处理CRC上传 阅片期的临床数据 var readModule = await _readModuleRepository.Where(x => x.Id == inDto.ReadingId) + //.Where(x=>x.IsCRCConfirm) .WhereIf(inDto.SelectIsSign, x => x.IsPMConfirm) .WhereIf(!inDto.SelectIsSign, x => x.IsCRCConfirm) .FirstOrDefaultAsync(); @@ -952,157 +966,6 @@ namespace IRaCIS.Application.Services return result; } - - /// - /// 获取临床数据集合 - /// - /// - [NonDynamicMethod] - public async Task> GetReadingClinicalList(GetReadingClinicalDataListIndto inDto) - { - var resultQuery = _readingClinicalDataRepository.Where(x => x.SubjectId == inDto.SubjectId) - .Where(x => x.ReadingId == inDto.ReadingId) - .WhereIf(inDto.ClinicalDataTrialSetId != null, x => x.ClinicalDataTrialSetId == inDto.TrialReadingCriterionId) - .Where(x => x.ClinicalDataTrialSet.TrialClinicalDataSetCriteriaList.Any(t => t.TrialReadingCriterionId == inDto.TrialReadingCriterionId)) - .Select(x => new GetReadingClinicalDataListOutDto() - { - ClinicalDataLevel = x.ClinicalDataTrialSet.ClinicalDataLevel, - SubjectId = x.SubjectId, - ReadingId = x.ReadingId, - ClinicalDataSetName = x.ClinicalDataTrialSet.ClinicalDataSetName.LanguageName(x.ClinicalDataTrialSet.ClinicalDataSetEnName, _userInfo.IsEn_Us), - ClinicalDataSetEnName = x.ClinicalDataTrialSet.ClinicalDataSetEnName, - ClinicalDataTrialSetId = x.ClinicalDataTrialSetId, - IsSign = x.IsSign, - ClinicalUploadType = x.ClinicalDataTrialSet.ClinicalUploadType, - Id = x.Id, - UploadRole = x.ClinicalDataTrialSet.UploadRole, - IsCRCUpload = x.ClinicalDataTrialSet.UploadRole == UploadRole.CRC, - IsBlind = x.IsBlind, - IsComplete = x.IsComplete, - FileCount = x.FileCount, - - ReadingClinicalDataState = x.ReadingClinicalDataState, - - FileList = x.ReadingClinicalDataPDFList.Select(y => new GetFileDto() - { - Id = y.Id, - FileName = y.FileName, - Path = y.Path, - CreateTime = y.CreateTime, - }).ToList() - }); - - var result = await resultQuery.ToListAsync(); - - - var readingIds = result.Select(x => x.ReadingId).ToList(); - var clinical = await _clinicalFormRepository.Where(x => readingIds.Contains(x.ReadingId ?? default(Guid))).ToListAsync(); - result.Where(x => x.ClinicalUploadType == ClinicalUploadType.Structuring).ForEach(x => - { - - x.ClinicalFromList = clinical.Where(y => y.ReadingId == x.ReadingId && y.ClinicalDataTrialSetId == x.ClinicalDataTrialSetId).Select(y => new ClinicalFromData() - { - CheckDate = y.CheckDate, - ClinicalFormId = y.Id - }).ToList(); - x.FileCount = x.ClinicalFromList.Count; - }); - - // 这里处理CRC上传 阅片期的临床数据 - var readModule = await _readModuleRepository.Where(x => x.Id == inDto.ReadingId && x.IsCRCConfirm) - .FirstOrDefaultAsync(); - if (readModule != null) - { - var moduleCriterionFromList = await _readModuleCriterionFromRepository.Where(x => x.ReadModuleId == readModule.Id) - - .WhereIf(inDto.ClinicalDataTrialSetId != null, x => x.ClinicalForm.ClinicalDataTrialSetId == inDto.TrialReadingCriterionId) - .Select(x => new - { - ClinicalFormId = x.ClinicalFormId, - CheckDate = x.ClinicalForm.CheckDate, - ClinicalDataTrialSetId = x.ClinicalForm.ClinicalDataTrialSetId - - - }).ToListAsync(); - - - var clinicalresult = await _clinicalDataTrialSetRepository.Where(x => x.UploadRole == UploadRole.CRC && x.ClinicalUploadType == ClinicalUploadType.Structuring) - .WhereIf(readModule.ReadingSetType == ReadingSetType.ImageReading, x => x.ClinicalDataLevel == ClinicalLevel.ImageRead) - .WhereIf(readModule.ReadingSetType == ReadingSetType.TumorReading, x => x.ClinicalDataLevel == ClinicalLevel.OncologyRead) - .Where(x => x.TrialClinicalDataSetCriteriaList.Any(y => y.TrialReadingCriterionId == readModule.TrialReadingCriterionId)) - .Select(x => new GetReadingClinicalDataListOutDto() - { - - ClinicalDataLevel = x.ClinicalDataLevel, - SubjectId = inDto.SubjectId, - ReadingId = default(Guid), - IsCRCApplicationRevoke = readModule.IsCRCApplicationRevoke, - IsCRCConfirm = readModule.IsCRCConfirm, - IsPMConfirm = readModule.IsPMConfirm, - - ClinicalDataSetName = x.ClinicalDataSetName.LanguageName(x.ClinicalDataSetEnName, _userInfo.IsEn_Us), - ClinicalDataSetEnName = x.ClinicalDataSetEnName, - ClinicalDataTrialSetId = x.Id, - IsSign = readModule.IsPMConfirm, - ClinicalUploadType = x.ClinicalUploadType, - Id = default(Guid), - UploadRole = x.UploadRole, - IsCRCUpload = x.UploadRole == UploadRole.CRC, - IsNeedMerge = true, - ReadModuleId = readModule.Id, - //FileCount = x.FileCount, - - //ReadingClinicalDataState = x.ReadingClinicalDataState, - - //FileList = x.ReadingClinicalDataPDFList.Select(y => new GetFileDto() - //{ - // Id = y.Id, - // FileName = y.FileName, - // Path = y.Path, - // CreateTime = y.CreateTime, - //}).ToList() - - }).ToListAsync(); - - clinicalresult.ForEach(x => - { - x.FileCount = moduleCriterionFromList.Where(y => y.ClinicalDataTrialSetId == x.ClinicalDataTrialSetId).Count(); - x.ClinicalFromList = moduleCriterionFromList.Where(y => y.ClinicalDataTrialSetId == x.ClinicalDataTrialSetId).OrderBy(y => y.CheckDate).Select(x => new ClinicalFromData - { - CheckDate = x.CheckDate, - ClinicalFormId = x.ClinicalFormId - - }).ToList(); - - x.IsSign = readModule.IsPMConfirm ? true : false; - x.ReadingClinicalDataState = readModule.IsPMConfirm ? ReadingClinicalDataStatus.HaveSigned : ReadingClinicalDataStatus.HaveChecked; - - }); - - result.AddRange(clinicalresult); - } - - - if (inDto.GetClinicalType != null) - { - switch (inDto.GetClinicalType) - { - case GetClinicalType.PMUpload: - result = result.Where(x => x.UploadRole == UploadRole.PM).ToList(); - break; - case GetClinicalType.CRCConfirm: - result = result.Where(x => x.UploadRole == UploadRole.CRC && x.IsCRCConfirm && !x.IsPMConfirm).ToList(); - break; - case GetClinicalType.HasSign: - result = result.Where(x => x.IsSign).ToList(); - break; - } - } - - - return result; - } - #endregion diff --git a/IRaCIS.Core.Application/Service/Reading/Dto/ReadingClinicalDataDto.cs b/IRaCIS.Core.Application/Service/Reading/Dto/ReadingClinicalDataDto.cs index b4cca0cfa..6f2d364bb 100644 --- a/IRaCIS.Core.Application/Service/Reading/Dto/ReadingClinicalDataDto.cs +++ b/IRaCIS.Core.Application/Service/Reading/Dto/ReadingClinicalDataDto.cs @@ -199,7 +199,10 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto public class GetReadingOrTaskClinicalDataListInDto { - [NotDefault] + + public Guid? TrialReadingCriterionId { get; set; } + + [NotDefault] public Guid SubjectId { get; set; } [NotDefault] diff --git a/IRaCIS.Core.Application/Service/Reading/Interface/IReadingClinicalDataService.cs b/IRaCIS.Core.Application/Service/Reading/Interface/IReadingClinicalDataService.cs index ccbbc510e..795bab0fc 100644 --- a/IRaCIS.Core.Application/Service/Reading/Interface/IReadingClinicalDataService.cs +++ b/IRaCIS.Core.Application/Service/Reading/Interface/IReadingClinicalDataService.cs @@ -22,7 +22,6 @@ namespace IRaCIS.Core.Application.Contracts // Task<(List, object)> GetReadingClinicalDataList(GetReadingClinicalDataListIndto inDto); - Task> GetReadingClinicalList(GetReadingClinicalDataListIndto inDto); Task> GetStudyClinicalData(GetStudyClinicalDataInDto inDto); diff --git a/IRaCIS.Core.Application/Service/Reading/ReadingImageTask/ReadingOncologyTaskService.cs b/IRaCIS.Core.Application/Service/Reading/ReadingImageTask/ReadingOncologyTaskService.cs index 594aa2137..e4e374694 100644 --- a/IRaCIS.Core.Application/Service/Reading/ReadingImageTask/ReadingOncologyTaskService.cs +++ b/IRaCIS.Core.Application/Service/Reading/ReadingImageTask/ReadingOncologyTaskService.cs @@ -470,7 +470,7 @@ namespace IRaCIS.Application.Services if (finishReading) { // 获取临床数据 - var clinicalData = await _readingClinicalDataService.GetReadingClinicalList(new GetReadingClinicalDataListIndto() + var clinicalData = await _readingClinicalDataService.GetClinicalDataList(new GetReadingOrTaskClinicalDataListInDto() { SubjectId = readModuleInfo.SubjectId, ReadingId = readModuleInfo.Id, From 81f55a9e079fbb05c5e6b7358b6d087c324161b1 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Wed, 24 Jul 2024 15:05:07 +0800 Subject: [PATCH 110/251] =?UTF-8?q?=E5=8C=BB=E5=AD=A6=E5=AE=A1=E6=A0=B8?= =?UTF-8?q?=E5=88=97=E8=A1=A8=EF=BC=8C=E6=9F=A5=E8=AF=A2=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Service/Allocation/TaskMedicalReviewService.cs | 4 ++-- IRaCIS.Core.Application/Service/Allocation/_MapConfig.cs | 2 +- IRaCIS.Core.Application/Service/Common/ExcelExportService.cs | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/IRaCIS.Core.Application/Service/Allocation/TaskMedicalReviewService.cs b/IRaCIS.Core.Application/Service/Allocation/TaskMedicalReviewService.cs index d272aef84..10a9f59a4 100644 --- a/IRaCIS.Core.Application/Service/Allocation/TaskMedicalReviewService.cs +++ b/IRaCIS.Core.Application/Service/Allocation/TaskMedicalReviewService.cs @@ -56,8 +56,8 @@ namespace IRaCIS.Core.Application.Service var taskMedicalReviewQueryable = _taskMedicalReviewRepository.Where(t => t.VisitTask.TrialId == inQuery.TrialId) - .WhereIf(inQuery.IsEffect == true, t => t.VisitTask.TaskState == TaskState.Effect || t.VisitTask.TaskState == TaskState.Freeze) - .WhereIf(inQuery.IsEffect == false, t => t.VisitTask.TaskState == TaskState.Adbandon || t.VisitTask.TaskState == TaskState.HaveReturned) + //.WhereIf(inQuery.IsEffect == true, t => t.VisitTask.TaskState == TaskState.Effect || t.VisitTask.TaskState == TaskState.Freeze) + //.WhereIf(inQuery.IsEffect == false, t => t.VisitTask.TaskState == TaskState.Adbandon || t.VisitTask.TaskState == TaskState.HaveReturned) .WhereIf(inQuery.TrialSiteId != null, t => t.VisitTask.Subject.TrialSiteId == inQuery.TrialSiteId) .WhereIf(inQuery.SubjectId != null, t => t.VisitTask.SubjectId == inQuery.SubjectId) diff --git a/IRaCIS.Core.Application/Service/Allocation/_MapConfig.cs b/IRaCIS.Core.Application/Service/Allocation/_MapConfig.cs index 35612f29d..510ee9b8b 100644 --- a/IRaCIS.Core.Application/Service/Allocation/_MapConfig.cs +++ b/IRaCIS.Core.Application/Service/Allocation/_MapConfig.cs @@ -238,7 +238,7 @@ namespace IRaCIS.Core.Application.Service .ForMember(o => o.TrialReadingCriterionName, t => t.MapFrom(u => u.TrialReadingCriterion.CriterionName)) .ForMember(o => o.TrialSiteCode, t => t.MapFrom(u => /*u.IsAnalysisCreate == true ? u.BlindTrialSiteCode :*/ u.Subject.TrialSite.TrialSiteCode)) .ForMember(o => o.SubjectCode, t => t.MapFrom(u => /*u.IsAnalysisCreate == true ? u.BlindSubjectCode :*/ u.Subject.Code)) - .ForMember(o => o.GeneratedMedicalReviewCount, t => t.MapFrom(u => u.TaskMedicalReviewList.Count())) + .ForMember(o => o.GeneratedMedicalReviewCount, t => t.MapFrom(u => u.TaskMedicalReviewList.Count(t=>t.MedicalManagerUserId!=null))) .ForMember(o => o.MedicalNo, t => t.MapFrom(u => u.Subject.MedicalNo)) .ForMember(o => o.IsGeneratedJudge, t => t.MapFrom(u => u.JudgeVisitTaskId != null)) .ForMember(o => o.ReadingDurationTimeSpan, t => t.MapFrom(u => u.SignTime - u.FirstReadingTime)) diff --git a/IRaCIS.Core.Application/Service/Common/ExcelExportService.cs b/IRaCIS.Core.Application/Service/Common/ExcelExportService.cs index f4fae36d3..96ece98b1 100644 --- a/IRaCIS.Core.Application/Service/Common/ExcelExportService.cs +++ b/IRaCIS.Core.Application/Service/Common/ExcelExportService.cs @@ -873,7 +873,7 @@ namespace IRaCIS.Core.Application.Service.Common [FromServices] IRepository _trialRepository) { - var list = await _repository.Where(t => t.VisitTask.TrialId == inQuery.TrialId) + var list = await _repository.Where(t => t.VisitTask.TrialId == inQuery.TrialId && t.MedicalManagerUserId!=null) .WhereIf(inQuery.TrialSiteId != null, t => t.VisitTask.Subject.TrialSiteId == inQuery.TrialSiteId) .WhereIf(inQuery.SubjectId != null, t => t.VisitTask.SubjectId == inQuery.SubjectId) .WhereIf(!string.IsNullOrEmpty(inQuery.SubjectCode), t => t.VisitTask.Subject.Code.Contains(inQuery.SubjectCode)) From 39736c3ce454574ebd6225fd674c79b0801afcdb Mon Sep 17 00:00:00 2001 From: he <109787524@qq.com> Date: Wed, 24 Jul 2024 16:05:27 +0800 Subject: [PATCH 111/251] =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Reading/MedicalAudit/ReadingMedicalReviewService.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/IRaCIS.Core.Application/Service/Reading/MedicalAudit/ReadingMedicalReviewService.cs b/IRaCIS.Core.Application/Service/Reading/MedicalAudit/ReadingMedicalReviewService.cs index 4c0ffe513..6d410e1f7 100644 --- a/IRaCIS.Core.Application/Service/Reading/MedicalAudit/ReadingMedicalReviewService.cs +++ b/IRaCIS.Core.Application/Service/Reading/MedicalAudit/ReadingMedicalReviewService.cs @@ -794,7 +794,8 @@ namespace IRaCIS.Core.Application.Service TrialId=inDto.TrialId, TrialReadingCriterionId=inDto.TrialReadingCriterionId, PageIndex=1, - PageSize=99999, + AuditState= MedicalReviewAuditState.Auditing, + PageSize =99999, }); var index = list.CurrentPageData.ToList().FindIndex(x => x.Id == inDto.TaskMedicalReviewId); From de5fc7c27781b290ee905f7a1f825d92e7b74162 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Thu, 25 Jul 2024 10:12:09 +0800 Subject: [PATCH 112/251] =?UTF-8?q?=E4=BF=AE=E6=94=B9=EF=BC=8C=E6=97=A0?= =?UTF-8?q?=E5=BA=8F=E9=87=8D=E9=98=85=20=E5=92=8C=E5=AE=A1=E6=89=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Service/Allocation/VisitTaskService.cs | 33 +++++++++++++++---- .../Allocation/AllocationRelation.cs | 4 ++- 2 files changed, 30 insertions(+), 7 deletions(-) diff --git a/IRaCIS.Core.Application/Service/Allocation/VisitTaskService.cs b/IRaCIS.Core.Application/Service/Allocation/VisitTaskService.cs index e9aeb5a17..dc1eeddb7 100644 --- a/IRaCIS.Core.Application/Service/Allocation/VisitTaskService.cs +++ b/IRaCIS.Core.Application/Service/Allocation/VisitTaskService.cs @@ -1416,6 +1416,13 @@ namespace IRaCIS.Core.Application.Service.Allocation { task.ReReadingApplyState = ReReadingApplyState.DocotorHaveApplyed; + + //在PM 的申请重阅的影响列表里也不能申请重阅 + + var pmApply = await _visitTaskReReadingRepository.Where(t => t.OriginalReReadingTask.TrialId == task.TrialId && t.OriginalReReadingTask.SubjectId == task.SubjectId && t.OriginalReReadingTask.TaskState == TaskState.Effect && t.OriginalReReadingTask.ReadingCategory == ReadingCategory.Visit + && t.OriginalReReadingTask.ReadingTaskState == ReadingTaskState.HaveSigned && t.RequestReReadingType == RequestReReadingType.TrialGroupApply && t.RequestReReadingResultEnum == RequestReReadingResult.Default).Include(t => t.OriginalReReadingTask).FirstOrDefaultAsync(); + + // 有序 if (criterionConfig.IsReadingTaskViewInOrder == ReadingOrder.InOrder) { @@ -1429,10 +1436,6 @@ namespace IRaCIS.Core.Application.Service.Allocation } - //在PM 的申请重阅的影响列表里也不能申请重阅 - - var pmApply = await _visitTaskReReadingRepository.Where(t => t.OriginalReReadingTask.TrialId == task.TrialId && t.OriginalReReadingTask.SubjectId == task.SubjectId && t.OriginalReReadingTask.TaskState == TaskState.Effect && t.OriginalReReadingTask.ReadingCategory == ReadingCategory.Visit - && t.OriginalReReadingTask.ReadingTaskState == ReadingTaskState.HaveSigned && t.RequestReReadingType == RequestReReadingType.TrialGroupApply && t.RequestReReadingResultEnum == RequestReReadingResult.Default).Include(t => t.OriginalReReadingTask).FirstOrDefaultAsync(); if (pmApply != null) { @@ -1461,13 +1464,13 @@ namespace IRaCIS.Core.Application.Service.Allocation throw new BusinessValidationFailedException(_localizer["VisitTask_LastReading"]); } - if (task.ReadingCategory == ReadingCategory.Oncology && await _visitTaskRepository.AnyAsync(filterExpression.And(t => t.ReadingCategory == ReadingCategory.Oncology))) + if (task.ReadingCategory == ReadingCategory.Oncology && await _visitTaskRepository.AnyAsync(filterExpression.And(t => t.ReadingCategory == ReadingCategory.Oncology && t.ReadingTaskState==ReadingTaskState.HaveSigned))) { //---有序阅片,只允许申请该受试者阅片人最后一次完成肿瘤学任务重阅 throw new BusinessValidationFailedException(_localizer["VisitTask_LastOncologistRecheck"]); } - if (task.ReadingCategory == ReadingCategory.Judge && await _visitTaskRepository.AnyAsync(filterExpression.And(t => t.ReadingCategory == ReadingCategory.Judge))) + if (task.ReadingCategory == ReadingCategory.Judge && await _visitTaskRepository.AnyAsync(filterExpression.And(t => t.ReadingCategory == ReadingCategory.Judge && t.ReadingTaskState == ReadingTaskState.HaveSigned))) { //---有序阅片,只允许申请该受试者阅片人最后一次完成裁判的任务重阅 throw new BusinessValidationFailedException(_localizer["VisitTask_LastAdjudicatorRecheck"]); @@ -1476,6 +1479,22 @@ namespace IRaCIS.Core.Application.Service.Allocation } else { + + if (pmApply != null) + { + var originalTask = pmApply.OriginalReReadingTask; + + //PM 无序影响列表 + if (await _visitTaskRepository.Where(t => t.TrialId == originalTask.TrialId && t.SubjectId == originalTask.SubjectId && t.TaskState == TaskState.Effect && t.TaskAllocationState == TaskAllocationState.Allocated && t.IsAnalysisCreate == false && t.TrialReadingCriterionId == originalTask.TrialReadingCriterionId ) + .Where(t=>t.Id==originalTask.Id||t.Id==originalTask.JudgeVisitTaskId) + .AnyAsync(t => t.VisitTaskNum == task.VisitTaskNum)) + { + //---当前为无序阅片,影像存在问题,项目组已申请回退,暂不能申请重阅 + throw new BusinessValidationFailedException(_localizer["VisitTask_RandomInvalidRereading"]); + } + + } + //也要支持裁判重阅240701 if (task.ReadingCategory != ReadingCategory.Visit && task.ReadingCategory != ReadingCategory.Judge) @@ -1608,6 +1627,8 @@ namespace IRaCIS.Core.Application.Service.Allocation if ((origenalTask.TaskState != TaskState.Effect && origenalTask.TaskState != TaskState.Freeze)) { + await _visitTaskReReadingRepository.BatchUpdateNoTrackingAsync(t => t.Id == item.Id, u => new VisitTaskReReading() { RequestReReadingConfirmUserId = _userInfo.Id, RequestReReadingResultEnum = RequestReReadingResult.Invalid }); + //---当前申请重阅任务的状态,已被其他任务重阅已影响,不允许对该状态下的任务进行重阅同意与否操作 return ResponseOutput.NotOk(_localizer["VisitTask_ReapplyStatusConflict"]); } diff --git a/IRaCIS.Core.Domain.Share/Allocation/AllocationRelation.cs b/IRaCIS.Core.Domain.Share/Allocation/AllocationRelation.cs index d5c6dec54..5159dd58a 100644 --- a/IRaCIS.Core.Domain.Share/Allocation/AllocationRelation.cs +++ b/IRaCIS.Core.Domain.Share/Allocation/AllocationRelation.cs @@ -368,7 +368,9 @@ namespace IRaCIS.Core.Domain.Share Agree = 1, - Reject = 2 + Reject = 2, + + Invalid = 3, } public enum ReReadingApplyState From 6311884a5c1d4b4f9c05331659094cc706665909 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Thu, 25 Jul 2024 12:22:56 +0800 Subject: [PATCH 113/251] =?UTF-8?q?dicom=20AE=20=20=E6=B5=8F=E8=A7=88?= =?UTF-8?q?=E5=99=A8=E6=8E=A8=E8=8D=90=20=20=E5=8F=91=E5=B8=83=E8=AE=B0?= =?UTF-8?q?=E5=BD=95=20=E5=9B=BD=E9=99=85=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Service/Common/ExploreRecommendService.cs | 9 +++++---- .../Service/Common/PublishLogService.cs | 13 ++++++++----- .../Service/TrialSiteUser/TrialDicomAEService.cs | 3 ++- .../TrialSiteUser/TrialSiteDicomAEService.cs | 6 ++++-- 4 files changed, 19 insertions(+), 12 deletions(-) diff --git a/IRaCIS.Core.Application/Service/Common/ExploreRecommendService.cs b/IRaCIS.Core.Application/Service/Common/ExploreRecommendService.cs index 163b211a1..944a72442 100644 --- a/IRaCIS.Core.Application/Service/Common/ExploreRecommendService.cs +++ b/IRaCIS.Core.Application/Service/Common/ExploreRecommendService.cs @@ -53,7 +53,8 @@ namespace IRaCIS.Core.Application.Service { VerifyExp = u => u.IsDeleted == addOrEditExploreRecommend.IsDeleted && u.ExploreType == addOrEditExploreRecommend.ExploreType, - VerifyMsg = "当前浏览器启用版本只允许有一个", + // "当前类型浏览器启用版本只允许有一个" + VerifyMsg = _localizer["ExploreRecommend_OnlyOneTypePerType"] , IsVerify = addOrEditExploreRecommend.IsDeleted == false }; @@ -68,7 +69,7 @@ namespace IRaCIS.Core.Application.Service [HttpDelete("{exploreRecommendId:guid}")] public async Task DeleteExploreRecommend(Guid exploreRecommendId) { - var success = await _exploreRecommendRepository.DeleteFromQueryAsync(t => t.Id == exploreRecommendId, true); + var success = await _exploreRecommendRepository.DeleteFromQueryAsync(t => t.Id == exploreRecommendId, true,true); return ResponseOutput.Ok(); } @@ -80,8 +81,8 @@ namespace IRaCIS.Core.Application.Service var result = await _exploreRecommendRepository.Where(t => t.IsDeleted == false).ProjectTo(_mapper.ConfigurationProvider).ToListAsync(); if (result .Count==0) - { - throw new QueryBusinessObjectNotExistException("系统浏览器版本推荐未维护,请联系维护人员"); + { //"系统浏览器版本推荐未维护,请联系维护人员" + throw new QueryBusinessObjectNotExistException(_localizer["ExploreRecommend_NoExporeRecord"]); } return result; diff --git a/IRaCIS.Core.Application/Service/Common/PublishLogService.cs b/IRaCIS.Core.Application/Service/Common/PublishLogService.cs index ca2eb25a0..f5e0bc35d 100644 --- a/IRaCIS.Core.Application/Service/Common/PublishLogService.cs +++ b/IRaCIS.Core.Application/Service/Common/PublishLogService.cs @@ -50,21 +50,24 @@ namespace IRaCIS.Core.Application.Service if (!Version.TryParse(addOrEditPublishLog.Version, out version)) { - return ResponseOutput.NotOk("版本号不符合要求"); + //"版本号不符合要求" + return ResponseOutput.NotOk(_localizer["PublishLog_NotValidVersion"] ); } var verifyExp1 = new EntityVerifyExp() { VerifyExp = u => u.Version == addOrEditPublishLog.Version, - VerifyMsg = "发布编号不能重复" + //"发布编号不能重复" + VerifyMsg = _localizer["PublishLog_RepeatVersion"] }; var verifyExp2 = new EntityVerifyExp() { VerifyExp = u => u.IsCurrentVersion == addOrEditPublishLog.IsCurrentVersion, - VerifyMsg = "当前发布版本只允许有一个", + //"当前发布版本只允许有一个" + VerifyMsg = _localizer["PublishLog_OnlyOneCurrentVersion"] , IsVerify=addOrEditPublishLog.IsCurrentVersion==true }; @@ -90,8 +93,8 @@ namespace IRaCIS.Core.Application.Service if (result == null) { - //系统当前版本未标记,请联系维护人员 - throw new QueryBusinessObjectNotExistException("系统当前版本未标记,请联系维护人员"); + //"系统当前版本未标记,请联系维护人员" + throw new QueryBusinessObjectNotExistException(_localizer["PublishLog_NoCurrentVersion"] ); } return result; diff --git a/IRaCIS.Core.Application/Service/TrialSiteUser/TrialDicomAEService.cs b/IRaCIS.Core.Application/Service/TrialSiteUser/TrialDicomAEService.cs index 4c68b5992..7c24b56c9 100644 --- a/IRaCIS.Core.Application/Service/TrialSiteUser/TrialDicomAEService.cs +++ b/IRaCIS.Core.Application/Service/TrialSiteUser/TrialDicomAEService.cs @@ -72,7 +72,8 @@ namespace IRaCIS.Core.Application.Service { VerifyExp = u => u.IP == addOrEditDicomAE.IP && u.Port == addOrEditDicomAE.Port && u.TrialId == addOrEditDicomAE.TrialId, - VerifyMsg = "不允许添加相同的IP和端口的记录" + //"不允许添加相同的IP和端口的记录" + VerifyMsg = _localizer["TrialDicomAE_RepeatIPAndPort"] }; //var verifyExp2 = new EntityVerifyExp() diff --git a/IRaCIS.Core.Application/Service/TrialSiteUser/TrialSiteDicomAEService.cs b/IRaCIS.Core.Application/Service/TrialSiteUser/TrialSiteDicomAEService.cs index a0e9fa70e..7bd160513 100644 --- a/IRaCIS.Core.Application/Service/TrialSiteUser/TrialSiteDicomAEService.cs +++ b/IRaCIS.Core.Application/Service/TrialSiteUser/TrialSiteDicomAEService.cs @@ -55,13 +55,15 @@ namespace IRaCIS.Core.Application.Service && u.CallingAE == addOrEditTrialSiteDicomAE.CallingAE && u.TrialId == addOrEditTrialSiteDicomAE.TrialId && u.TrialSiteId == addOrEditTrialSiteDicomAE.TrialSiteId, - VerifyMsg = "不允许添加相同的记录" + //"不允许添加相同的记录" + VerifyMsg = _localizer["TrialSiteDicomAE_RepeatRecord"] }; var verifyExp2 = new EntityVerifyExp() { VerifyExp = u => u.CallingAE == addOrEditTrialSiteDicomAE.CallingAE && u.TrialId == addOrEditTrialSiteDicomAE.TrialId && u.TrialSiteId!=addOrEditTrialSiteDicomAE.TrialSiteId, - VerifyMsg = "其他中心已有该CallingAE" + // "其他中心已有该CallingAE" + VerifyMsg = _localizer["TrialSiteDicomAE_OtherSiteExistCallingAE"] }; From 44bcdf797322e49fe7932f08a186a6d01c7babaf Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Thu, 25 Jul 2024 14:46:13 +0800 Subject: [PATCH 114/251] =?UTF-8?q?=E7=B3=BB=E7=BB=9F=E9=82=AE=E4=BB=B6?= =?UTF-8?q?=E4=B8=8A=E7=BA=BF=E5=88=B0=E9=85=8D=E7=BD=AE=E9=A2=84=E4=BF=AE?= =?UTF-8?q?=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Service/Common/DTO/EmailNoticeConfigViewModel.cs | 2 ++ .../Service/Common/EmailNoticeConfigService.cs | 2 +- IRaCIS.Core.Domain/Common/EmailNoticeConfig.cs | 1 + 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/IRaCIS.Core.Application/Service/Common/DTO/EmailNoticeConfigViewModel.cs b/IRaCIS.Core.Application/Service/Common/DTO/EmailNoticeConfigViewModel.cs index 691b1e8bf..211be32dc 100644 --- a/IRaCIS.Core.Application/Service/Common/DTO/EmailNoticeConfigViewModel.cs +++ b/IRaCIS.Core.Application/Service/Common/DTO/EmailNoticeConfigViewModel.cs @@ -63,6 +63,8 @@ namespace IRaCIS.Core.Application.Contracts public bool? IsDistinguishCriteria { get; set; } + public bool IsSystemLevel { get; set; } = false; + } /// EmailNoticeConfigAddOrEdit 列表查询参数模型 diff --git a/IRaCIS.Core.Application/Service/Common/EmailNoticeConfigService.cs b/IRaCIS.Core.Application/Service/Common/EmailNoticeConfigService.cs index aa07c35c1..b634370e5 100644 --- a/IRaCIS.Core.Application/Service/Common/EmailNoticeConfigService.cs +++ b/IRaCIS.Core.Application/Service/Common/EmailNoticeConfigService.cs @@ -28,7 +28,7 @@ namespace IRaCIS.Core.Application.Contracts [HttpPost] public async Task> GetEmailNoticeConfigList(EmailNoticeConfigQuery queryEmailNoticeConfig) { - var emailNoticeConfigQueryable = _emailNoticeConfigrepository + var emailNoticeConfigQueryable = _emailNoticeConfigrepository.Where(t=>t.IsSystemLevel==queryEmailNoticeConfig.IsSystemLevel) .WhereIf(queryEmailNoticeConfig.IsDistinguishCriteria != null, t => t.IsDistinguishCriteria == queryEmailNoticeConfig.IsDistinguishCriteria) .WhereIf(queryEmailNoticeConfig.CriterionTypeEnum != null, t => t.CriterionTypeEnum == queryEmailNoticeConfig.CriterionTypeEnum) .WhereIf(queryEmailNoticeConfig.BusinessScenarioEnum != null, t => t.BusinessScenarioEnum == queryEmailNoticeConfig.BusinessScenarioEnum) diff --git a/IRaCIS.Core.Domain/Common/EmailNoticeConfig.cs b/IRaCIS.Core.Domain/Common/EmailNoticeConfig.cs index 74ab2ac60..31c4dfec9 100644 --- a/IRaCIS.Core.Domain/Common/EmailNoticeConfig.cs +++ b/IRaCIS.Core.Domain/Common/EmailNoticeConfig.cs @@ -69,6 +69,7 @@ namespace IRaCIS.Core.Domain.Models + public bool IsSystemLevel { get; set; } /// /// 是否区分标准 From 9a958276db7939c8a1db487bf415ae78a07fe6ca Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Thu, 25 Jul 2024 16:41:42 +0800 Subject: [PATCH 115/251] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E9=A1=B9=E7=9B=AE?= =?UTF-8?q?=E9=83=A8=E4=BD=8Dbug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.Application/BackGroundJob/IRaCISCHangfireJob.cs | 6 +++--- .../Service/TrialSiteUser/TrialConfigService.cs | 5 ++++- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/IRaCIS.Core.Application/BackGroundJob/IRaCISCHangfireJob.cs b/IRaCIS.Core.Application/BackGroundJob/IRaCISCHangfireJob.cs index 81da08136..f135121b6 100644 --- a/IRaCIS.Core.Application/BackGroundJob/IRaCISCHangfireJob.cs +++ b/IRaCIS.Core.Application/BackGroundJob/IRaCISCHangfireJob.cs @@ -142,7 +142,7 @@ namespace IRaCIS.Application.Services.BackGroundJob }; // 添加文件更改事件的处理程序 - FileSystemWatcher_US.Changed += (sender, e) => LoadJsonFile(usJsonPath); + FileSystemWatcher_US.Changed += (sender, e) => LoadJsonFile(StaticData.Folder.Resources+"\\"+ StaticData.En_US_Json); FileSystemWatcher_CN = new FileSystemWatcher @@ -153,7 +153,7 @@ namespace IRaCIS.Application.Services.BackGroundJob EnableRaisingEvents = true, }; - FileSystemWatcher_CN.Changed += (sender, e) => LoadJsonFile(cnJsonPath); + FileSystemWatcher_CN.Changed += (sender, e) => LoadJsonFile(StaticData.Folder.Resources + "\\" + StaticData.Zh_CN_Json); } @@ -163,7 +163,7 @@ namespace IRaCIS.Application.Services.BackGroundJob private void LoadJsonFile(string filePath) { Console.WriteLine("刷新json内存数据"); - IConfigurationBuilder builder = new ConfigurationBuilder().AddJsonFile(filePath,false,true); + IConfigurationBuilder builder = new ConfigurationBuilder().AddJsonFile(filePath,false,false); IConfigurationRoot enConfiguration = builder.Build(); diff --git a/IRaCIS.Core.Application/Service/TrialSiteUser/TrialConfigService.cs b/IRaCIS.Core.Application/Service/TrialSiteUser/TrialConfigService.cs index f976c86ea..636a8c3b2 100644 --- a/IRaCIS.Core.Application/Service/TrialSiteUser/TrialConfigService.cs +++ b/IRaCIS.Core.Application/Service/TrialSiteUser/TrialConfigService.cs @@ -1346,12 +1346,15 @@ namespace IRaCIS.Core.Application public async Task AddOrUpdateTrialBodyPart(AddOrUpdateTrialBodyPartCommand incommand) { - var codeList = await _repository.Where(t => t.TrialId == incommand.TrialId).Select(t => t.Code).ToListAsync(); + var codeList = await _repository.Where(t => t.TrialId == incommand.TrialId) + .WhereIf(incommand.Id!=null,t=>t.Id!=incommand.Id) + .Select(t => t.Code).ToListAsync(); var newString = incommand.Code; // 检查字符串是否在集合中存在,如果存在,则在后面加上一个数字 int count = 1; + while (codeList.Contains(newString)) { newString = $"{newString}{count}"; From b0302d0e6db3822b5648c624934f369954985eb4 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Thu, 25 Jul 2024 13:54:57 +0800 Subject: [PATCH 116/251] =?UTF-8?q?=E5=90=8C=E6=84=8F=E9=87=8D=E9=98=85?= =?UTF-8?q?=EF=BC=8C=E6=88=90=E5=8A=9F=EF=BC=8C=E4=BD=86=E6=98=AF=E7=BB=99?= =?UTF-8?q?=E5=87=BA=E8=87=AA=E5=8A=A8=E5=A4=B1=E6=95=88=E7=9A=84=E6=8F=90?= =?UTF-8?q?=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.Application/Service/Allocation/VisitTaskService.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/IRaCIS.Core.Application/Service/Allocation/VisitTaskService.cs b/IRaCIS.Core.Application/Service/Allocation/VisitTaskService.cs index dc1eeddb7..0665ed727 100644 --- a/IRaCIS.Core.Application/Service/Allocation/VisitTaskService.cs +++ b/IRaCIS.Core.Application/Service/Allocation/VisitTaskService.cs @@ -1630,7 +1630,7 @@ namespace IRaCIS.Core.Application.Service.Allocation await _visitTaskReReadingRepository.BatchUpdateNoTrackingAsync(t => t.Id == item.Id, u => new VisitTaskReReading() { RequestReReadingConfirmUserId = _userInfo.Id, RequestReReadingResultEnum = RequestReReadingResult.Invalid }); //---当前申请重阅任务的状态,已被其他任务重阅已影响,不允许对该状态下的任务进行重阅同意与否操作 - return ResponseOutput.NotOk(_localizer["VisitTask_ReapplyStatusConflict"]); + return ResponseOutput.Ok(_localizer["VisitTask_ReapplyStatusConflict"]); } From c6e5d31244381eba829beaf13b30104f97e857e1 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Thu, 25 Jul 2024 14:22:19 +0800 Subject: [PATCH 117/251] =?UTF-8?q?=E9=87=8D=E9=98=85=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=E5=A4=B1=E6=95=88=EF=BC=8C=E9=94=99=E8=AF=AF=E6=B6=88=E6=81=AF?= =?UTF-8?q?=E4=BD=8D=E7=BD=AE=E6=94=B9=E5=8F=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.Application/Service/Allocation/VisitTaskService.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/IRaCIS.Core.Application/Service/Allocation/VisitTaskService.cs b/IRaCIS.Core.Application/Service/Allocation/VisitTaskService.cs index 0665ed727..b030d49ec 100644 --- a/IRaCIS.Core.Application/Service/Allocation/VisitTaskService.cs +++ b/IRaCIS.Core.Application/Service/Allocation/VisitTaskService.cs @@ -1630,7 +1630,7 @@ namespace IRaCIS.Core.Application.Service.Allocation await _visitTaskReReadingRepository.BatchUpdateNoTrackingAsync(t => t.Id == item.Id, u => new VisitTaskReReading() { RequestReReadingConfirmUserId = _userInfo.Id, RequestReReadingResultEnum = RequestReReadingResult.Invalid }); //---当前申请重阅任务的状态,已被其他任务重阅已影响,不允许对该状态下的任务进行重阅同意与否操作 - return ResponseOutput.Ok(_localizer["VisitTask_ReapplyStatusConflict"]); + return ResponseOutput.Ok(string.Empty, msg:_localizer["VisitTask_ReapplyStatusConflict"]); } From cad7132b0a2d18efbc6f176b7eb2eb3c20635336 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Fri, 26 Jul 2024 09:04:34 +0800 Subject: [PATCH 118/251] =?UTF-8?q?=E9=80=9A=E8=BF=87=E7=9B=B8=E5=AF=B9?= =?UTF-8?q?=E8=B7=AF=E5=BE=84=E8=8E=B7=E5=8F=96=E6=8E=88=E6=9D=83=E7=AD=BE?= =?UTF-8?q?=E5=90=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.Application/Helper/OSSService.cs | 18 +++++++++++++----- .../IRaCIS.Core.Application.xml | 6 ------ IRaCIS.Core.Application/TestService.cs | 9 ++++++--- 3 files changed, 19 insertions(+), 14 deletions(-) diff --git a/IRaCIS.Core.Application/Helper/OSSService.cs b/IRaCIS.Core.Application/Helper/OSSService.cs index 9d5a754ad..175367992 100644 --- a/IRaCIS.Core.Application/Helper/OSSService.cs +++ b/IRaCIS.Core.Application/Helper/OSSService.cs @@ -375,10 +375,6 @@ namespace IRaCIS.Core.Application.Helper .WithCredentials(minIOConfig.accessKey, minIOConfig.secretKey).WithSSL(minIOConfig.useSSL) .Build(); - //var reqParams = new Dictionary(StringComparer.Ordinal) - // { - // { "response-content-type", "application/json" } - // }; var args = new PresignedGetObjectArgs() .WithBucket(minIOConfig.bucketName) @@ -404,7 +400,19 @@ namespace IRaCIS.Core.Application.Helper .WithCredentials(minIOConfig.accessKey, minIOConfig.secretKey).WithSSL(minIOConfig.useSSL) .Build(); - return string.Empty; + var args = new PresignedGetObjectArgs() + .WithBucket(minIOConfig.bucketName) + .WithObject(ossRelativePath) + .WithExpiry(3600); + + var presignedUrl = await minioClient.PresignedGetObjectAsync(args); + + Uri uri = new Uri(presignedUrl); + + string relativePath = uri.PathAndQuery; + + + return relativePath; } else { diff --git a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml index 160a1ae97..1525d317b 100644 --- a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml +++ b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml @@ -14096,12 +14096,6 @@ - - - 获取临床数据集合 - - - 获取单个阅片临床数据的所有文件 diff --git a/IRaCIS.Core.Application/TestService.cs b/IRaCIS.Core.Application/TestService.cs index 98cd71e87..f00d2ac7a 100644 --- a/IRaCIS.Core.Application/TestService.cs +++ b/IRaCIS.Core.Application/TestService.cs @@ -120,11 +120,14 @@ namespace IRaCIS.Application.Services public async Task TestMinIO([FromServices] IOSSService oSSService) { - await oSSService.UploadToOSSAsync("C:\\Users\\Administrator\\Desktop\\TrialSiteUserImportTemplate.xlsx", "myfolder"); + var str= await oSSService.GetSignedUrl("/01000000-c0a8-0242-1c98-08dc7ebcd37d/Read/01000000-c0a8-0242-1c98-08dc7ebcd37d/Visit/1716872544006_1716872544003.png"); - await oSSService.DownLoadFromOSSAsync("/myfolder/TrialSiteUserImportTemplate.xlsx", "C:\\Users\\Administrator\\Desktop\\aws.xlsx"); - return ResponseOutput.Ok(); + //await oSSService.UploadToOSSAsync("C:\\Users\\Administrator\\Desktop\\TrialSiteUserImportTemplate.xlsx", "myfolder"); + + //await oSSService.DownLoadFromOSSAsync("/myfolder/TrialSiteUserImportTemplate.xlsx", "C:\\Users\\Administrator\\Desktop\\aws.xlsx"); + + return ResponseOutput.Ok(str); } [AllowAnonymous] From 0536a570753a75422776e1cf0f9ddaabab99ff9a Mon Sep 17 00:00:00 2001 From: he <109787524@qq.com> Date: Fri, 26 Jul 2024 10:16:08 +0800 Subject: [PATCH 119/251] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ReadingClinicalDataService.cs | 118 +++++++++++++----- 1 file changed, 86 insertions(+), 32 deletions(-) diff --git a/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs b/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs index c60da920d..620580abd 100644 --- a/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs +++ b/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs @@ -21,6 +21,7 @@ namespace IRaCIS.Application.Services public class ReadingClinicalDataService : BaseService, IReadingClinicalDataService { private readonly IRepository _readingClinicalDataRepository; + private readonly IRepository _readingConsistentClinicalDataRepository; private readonly IRepository _clinicalDataTrialSetRepository; private readonly IRepository _visitTaskRepository; private readonly IRepository _previousPDFRepository; @@ -38,6 +39,7 @@ namespace IRaCIS.Application.Services private readonly IRepository _readingClinicalDataPDFRepository; public ReadingClinicalDataService(IRepository readingClinicalDataRepository, + IRepository readingConsistentClinicalDataRepository, IRepository clinicalDataTrialSetRepository, IRepository previousPDFRepository, IRepository subjectVisitRepository, @@ -56,6 +58,7 @@ namespace IRaCIS.Application.Services IRepository visitTaskRepository) { this._readingClinicalDataRepository = readingClinicalDataRepository; + this._readingConsistentClinicalDataRepository = readingConsistentClinicalDataRepository; this._clinicalDataTrialSetRepository = clinicalDataTrialSetRepository; this._previousPDFRepository = previousPDFRepository; this._subjectVisitRepository = subjectVisitRepository; @@ -785,46 +788,97 @@ namespace IRaCIS.Application.Services public async Task> GetClinicalDataList(GetReadingOrTaskClinicalDataListInDto inDto) { + var resultQuery = _readingClinicalDataRepository.Where(x=>1==1).Select(x=> new GetReadingClinicalDataListOutDto() { }); + bool isSelfAnalysis = false; if (inDto.ReadingId == null) { var visitTask = await _visitTaskRepository.FirstOrDefaultAsync(x => x.Id == inDto.VisitTaskId); inDto.ReadingId = visitTask.SouceReadModuleId ?? visitTask.SourceSubjectVisitId; + + + if (visitTask.IsAnalysisCreate && visitTask.IsSelfAnalysis == true) + { + isSelfAnalysis = true; + } } + // 一致性分析 + if (isSelfAnalysis) + { + resultQuery = _readingConsistentClinicalDataRepository.Where(x => x.SubjectId == inDto.SubjectId) + .WhereIf(inDto.ReadingClinicalDataId != null, x => x.Id == inDto.ReadingClinicalDataId) + .WhereIf(inDto.ClinicalDataTrialSetId != null, x => x.ClinicalDataTrialSetId == inDto.ClinicalDataTrialSetId) + .WhereIf(inDto.SelectIsSign, x => x.IsSign == true) + .Where(x => x.ReadingId == inDto.ReadingId) + .WhereIf(inDto.TrialReadingCriterionId != null, x => x.ClinicalDataTrialSet.TrialClinicalDataSetCriteriaList.Any(t => t.TrialReadingCriterionId == inDto.TrialReadingCriterionId)) + .Select(x => new GetReadingClinicalDataListOutDto() + { + ClinicalDataLevel = x.ClinicalDataTrialSet.ClinicalDataLevel, + SubjectId = x.SubjectId, + ReadingId = x.ReadingId, + ClinicalDataSetEnName = x.ClinicalDataTrialSet.ClinicalDataSetEnName, + ClinicalDataSetName = x.ClinicalDataTrialSet.ClinicalDataSetName.LanguageName(x.ClinicalDataTrialSet.ClinicalDataSetEnName, _userInfo.IsEn_Us), + ClinicalDataTrialSetId = x.ClinicalDataTrialSetId, + IsSign = x.IsSign, + ClinicalUploadType = x.ClinicalDataTrialSet.ClinicalUploadType, + CriterionEnumList = x.ClinicalDataTrialSet.CriterionEnumList, + TrialClinicalDataSetCriteriaList = x.ClinicalDataTrialSet.TrialClinicalDataSetCriteriaList, + Id = x.Id, + UploadRole = x.ClinicalDataTrialSet.UploadRole, + IsCRCUpload = x.ClinicalDataTrialSet.UploadRole == UploadRole.CRC, + IsBlind = x.IsBlind, + IsComplete = x.IsComplete, + FileCount = x.FileCount, + ReadingClinicalDataState = x.ReadingClinicalDataState, + FileList = x.ReadingClinicalDataPDFList.Select(y => new GetFileDto() + { + Id = y.Id, + FileName = y.FileName, + Path = y.Path, + CreateTime = y.CreateTime, + }).ToList(), - var resultQuery = _readingClinicalDataRepository.Where(x => x.SubjectId == inDto.SubjectId) - .WhereIf(inDto.ReadingClinicalDataId != null, x => x.Id == inDto.ReadingClinicalDataId) - .WhereIf(inDto.ClinicalDataTrialSetId != null, x => x.ClinicalDataTrialSetId == inDto.ClinicalDataTrialSetId) - .WhereIf(inDto.SelectIsSign, x => x.IsSign == true) - .Where(x => x.ReadingId == inDto.ReadingId) - .WhereIf(inDto.TrialReadingCriterionId!=null, x => x.ClinicalDataTrialSet.TrialClinicalDataSetCriteriaList.Any(t => t.TrialReadingCriterionId == inDto.TrialReadingCriterionId)) - .Select(x => new GetReadingClinicalDataListOutDto() + }); + } + else + { + resultQuery = _readingClinicalDataRepository.Where(x => x.SubjectId == inDto.SubjectId) + .WhereIf(inDto.ReadingClinicalDataId != null, x => x.Id == inDto.ReadingClinicalDataId) + .WhereIf(inDto.ClinicalDataTrialSetId != null, x => x.ClinicalDataTrialSetId == inDto.ClinicalDataTrialSetId) + .WhereIf(inDto.SelectIsSign, x => x.IsSign == true) + .Where(x => x.ReadingId == inDto.ReadingId) + .WhereIf(inDto.TrialReadingCriterionId != null, x => x.ClinicalDataTrialSet.TrialClinicalDataSetCriteriaList.Any(t => t.TrialReadingCriterionId == inDto.TrialReadingCriterionId)) + .Select(x => new GetReadingClinicalDataListOutDto() + { + ClinicalDataLevel = x.ClinicalDataTrialSet.ClinicalDataLevel, + SubjectId = x.SubjectId, + ReadingId = x.ReadingId, + ClinicalDataSetEnName = x.ClinicalDataTrialSet.ClinicalDataSetEnName, + ClinicalDataSetName = x.ClinicalDataTrialSet.ClinicalDataSetName.LanguageName(x.ClinicalDataTrialSet.ClinicalDataSetEnName, _userInfo.IsEn_Us), + ClinicalDataTrialSetId = x.ClinicalDataTrialSetId, + IsSign = x.IsSign, + ClinicalUploadType = x.ClinicalDataTrialSet.ClinicalUploadType, + CriterionEnumList = x.ClinicalDataTrialSet.CriterionEnumList, + TrialClinicalDataSetCriteriaList = x.ClinicalDataTrialSet.TrialClinicalDataSetCriteriaList, + Id = x.Id, + UploadRole = x.ClinicalDataTrialSet.UploadRole, + IsCRCUpload = x.ClinicalDataTrialSet.UploadRole == UploadRole.CRC, + IsBlind = x.IsBlind, + IsComplete = x.IsComplete, + FileCount = x.FileCount, + ReadingClinicalDataState = x.ReadingClinicalDataState, + FileList = x.ReadingClinicalDataPDFList.Select(y => new GetFileDto() { - ClinicalDataLevel = x.ClinicalDataTrialSet.ClinicalDataLevel, - SubjectId = x.SubjectId, - ReadingId = x.ReadingId, - ClinicalDataSetEnName = x.ClinicalDataTrialSet.ClinicalDataSetEnName, - ClinicalDataSetName = x.ClinicalDataTrialSet.ClinicalDataSetName.LanguageName(x.ClinicalDataTrialSet.ClinicalDataSetEnName, _userInfo.IsEn_Us), - ClinicalDataTrialSetId = x.ClinicalDataTrialSetId, - IsSign = x.IsSign, - ClinicalUploadType = x.ClinicalDataTrialSet.ClinicalUploadType, - CriterionEnumList = x.ClinicalDataTrialSet.CriterionEnumList, - TrialClinicalDataSetCriteriaList = x.ClinicalDataTrialSet.TrialClinicalDataSetCriteriaList, - Id = x.Id, - UploadRole = x.ClinicalDataTrialSet.UploadRole, - IsCRCUpload = x.ClinicalDataTrialSet.UploadRole == UploadRole.CRC, - IsBlind = x.IsBlind, - IsComplete = x.IsComplete, - FileCount = x.FileCount, - ReadingClinicalDataState = x.ReadingClinicalDataState, - FileList = x.ReadingClinicalDataPDFList.Select(y => new GetFileDto() - { - Id = y.Id, - FileName = y.FileName, - Path = y.Path, - CreateTime = y.CreateTime, - }).ToList(), + Id = y.Id, + FileName = y.FileName, + Path = y.Path, + CreateTime = y.CreateTime, + }).ToList(), - }); + }); + } + + + var result = new List(); if (!inDto.IsOnlyGetCRCReadModule) From 9f32b92af3d60c37a0be547d127e6fd23d415183 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Fri, 26 Jul 2024 15:26:28 +0800 Subject: [PATCH 120/251] =?UTF-8?q?=E9=82=AE=E4=BB=B6=E4=B8=8A=E7=BA=BF?= =?UTF-8?q?=E5=88=B0=E7=B3=BB=E7=BB=9F=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../IRaCIS.Core.Application.xml | 2 +- .../Common/DTO/EmailNoticeConfigViewModel.cs | 2 + .../Service/Common/MailService.cs | 545 ++++++++---------- .../SiteSurvey/TrialSiteSurveyService.cs | 42 +- .../Common/EmailScenarioEnum.cs | 43 +- 5 files changed, 289 insertions(+), 345 deletions(-) diff --git a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml index 1525d317b..add5bef1a 100644 --- a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml +++ b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml @@ -13403,7 +13403,7 @@ - 发送验证码 + Reviewer简历录入 发送验证码 diff --git a/IRaCIS.Core.Application/Service/Common/DTO/EmailNoticeConfigViewModel.cs b/IRaCIS.Core.Application/Service/Common/DTO/EmailNoticeConfigViewModel.cs index 211be32dc..edb1cfc5a 100644 --- a/IRaCIS.Core.Application/Service/Common/DTO/EmailNoticeConfigViewModel.cs +++ b/IRaCIS.Core.Application/Service/Common/DTO/EmailNoticeConfigViewModel.cs @@ -128,6 +128,8 @@ namespace IRaCIS.Core.Application.Contracts public List ToUserTypeList { get; set; } public List CopyUserTypeList { get; set; } + public bool IsSystemLevel { get; set; } = false; + } diff --git a/IRaCIS.Core.Application/Service/Common/MailService.cs b/IRaCIS.Core.Application/Service/Common/MailService.cs index 588761284..7850b7e38 100644 --- a/IRaCIS.Core.Application/Service/Common/MailService.cs +++ b/IRaCIS.Core.Application/Service/Common/MailService.cs @@ -9,6 +9,15 @@ using IRaCIS.Application.Contracts; using Microsoft.Extensions.Options; using Medallion.Threading; using System.Text.RegularExpressions; +using IRaCIS.Core.Infrastructure; +using DocumentFormat.OpenXml.Spreadsheet; +using IRaCIS.Core.Application.Service.Reading.Dto; +using NPOI.SS.Formula.Functions; +using Microsoft.AspNetCore.Mvc.ViewFeatures; +using IRaCIS.Core.Domain.Models; +using DocumentFormat.OpenXml.Office2013.Excel; +using IRaCIS.Core.Application.Contracts; +using DocumentFormat.OpenXml.Vml; namespace IRaCIS.Application.Services { @@ -19,7 +28,7 @@ namespace IRaCIS.Application.Services Task SendEmailVerification(string emailAddress, int verificationCode); - Task SiteSurveyRejectEmail(MimeMessage messageToSend); + Task SiteSurveyRejectEmail(MimeMessage messageToSend, TrialSiteSurvey trialSiteSurvey, string routeUrl, User? user = null); Task SenMFAVerifyEmail(Guid userId, string userName, string emailAddress, int verificationCode, UserMFAType mfaType = UserMFAType.Login); @@ -40,7 +49,7 @@ namespace IRaCIS.Application.Services } - public class MailVerificationService : BaseService, IMailVerificationService + public class MailVerificationService : BaseService, IMailVerificationService { private readonly IRepository _verificationCodeRepository; @@ -59,15 +68,16 @@ namespace IRaCIS.Application.Services private readonly SystemEmailSendConfig _systemEmailConfig; + private readonly IRepository _emailNoticeConfigrepository; - - public MailVerificationService(IRepository verificationCodeRepository, + public MailVerificationService(IRepository verificationCodeRepository, IRepository systemBasicDatarepository, IRepository userRepository, ITokenService tokenService, IRepository trialRepository, IRepository userTypeRepository, IRepository doctorTypeRepository, + IRepository emailNoticeConfigRepository, IOptionsMonitor systemEmailConfig, IDistributedLockProvider distributedLockProvider) { _systemEmailConfig = systemEmailConfig.CurrentValue; @@ -80,16 +90,73 @@ namespace IRaCIS.Application.Services _userTypeRepository = userTypeRepository; _doctorTypeRepository = doctorTypeRepository; _distributedLockProvider = distributedLockProvider; - + _emailNoticeConfigrepository = emailNoticeConfigRepository; } + private async Task GetEmailSubejctAndHtmlInfoAndBuildAsync(EmailBusinessScenario scenario, MimeMessage messageToSend, + Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr)> emailFunc) + { + var configInfo = await _emailNoticeConfigrepository.Where(t => t.BusinessScenarioEnum == scenario).FirstOrDefaultAsync(); + + if (configInfo == null) + { + throw new BusinessValidationFailedException("系统未找到当前场景邮件配置信息,请联系运维人员核查"); + } + + + var (topicStr, htmlBodyStr) = _userInfo.IsEn_Us ? (configInfo.EmailTopic, configInfo.EmailHtmlContent) : (configInfo.EmailTopicCN, configInfo.EmailHtmlContentCN); + + try + { + //每个场景修改主题 和body的逻辑不一样 + (topicStr, htmlBodyStr) = emailFunc((topicStr, htmlBodyStr)); + } + catch (Exception ex) + { + + throw new BusinessValidationFailedException("邮件模板内容有误,填充内容出现问题,请联系运维人员核查"); + } + + + messageToSend.Subject = topicStr; + + var builder = new BodyBuilder(); + + builder.HtmlBody = htmlBodyStr; + + messageToSend.Body = builder.ToMessageBody(); + + return messageToSend; + } + + + private EventHandler GetEmailSuccessHandle(Guid userId, int verificationCode, string email = "") + { + EventHandler sucessHandle = (sender, args) => + { + // args.Response + var code = verificationCode.ToString(); + _ = _verificationCodeRepository.AddAsync(new VerificationCode() + { + CodeType = VerifyType.Email, + HasSend = true, + Code = code, + UserId = userId, + EmailOrPhone = email, + ExpirationTime = DateTime.Now.AddMinutes(3) + }).Result; + _ = _verificationCodeRepository.SaveChangesAsync().Result; + + }; + + return sucessHandle; + } private string ReplaceCompanyName(string needDealtxt) { - var str= needDealtxt.Replace("{company}", _userInfo.IsEn_Us ? _systemEmailConfig.CompanyName : _systemEmailConfig.CompanyNameCN) + var str = needDealtxt.Replace("{company}", _userInfo.IsEn_Us ? _systemEmailConfig.CompanyName : _systemEmailConfig.CompanyNameCN) .Replace("{company abbreviation}", _userInfo.IsEn_Us ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN); - return str; } @@ -101,120 +168,68 @@ namespace IRaCIS.Application.Services messageToSend.From.Add(new MailboxAddress(_systemEmailConfig.FromName, _systemEmailConfig.FromEmail)); //收件地址 messageToSend.To.Add(new MailboxAddress(userName, emailAddress)); - //主题 - //---[来自{0}] 关于MFA邮箱验证的提醒 - messageToSend.Subject = _localizer[mfaType == UserMFAType.Login? "Mail_EmailMFALoginTopic":"Mail_EmailMFAUnlockTopic", _userInfo.IsEn_Us ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN]; + //主题---[来自{0}] 关于MFA邮箱验证的提醒 - var builder = new BodyBuilder(); + var companyName = _userInfo.IsEn_Us ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN; - - var pathToFile = _hostEnvironment.WebRootPath - + Path.DirectorySeparatorChar.ToString() - + "EmailTemplate" - + Path.DirectorySeparatorChar.ToString() - //+ "UserOptCommon.html"; - + (_userInfo.IsEn_Us ? "UserOptCommon_US.html" : "UserOptCommon.html"); - - using (StreamReader SourceReader = System.IO.File.OpenText(pathToFile)) + Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr)> emailConfigFunc = input => { - var templateInfo = SourceReader.ReadToEnd(); + var topicStr = string.Format(input.topicStr, companyName); - - builder.HtmlBody = string.Format(ReplaceCompanyName(templateInfo), + var htmlBodyStr = string.Format(ReplaceCompanyName(input.htmlBodyStr), userName, - _localizer[mfaType == UserMFAType.Login ? "Mail_EmailMFALoginEmail": "Mail_EmailMFAUnlockEmail"], + _localizer[mfaType == UserMFAType.Login ? "Mail_EmailMFALoginEmail" : "Mail_EmailMFAUnlockEmail"], verificationCode ); - } - - - messageToSend.Body = builder.ToMessageBody(); - - - - EventHandler sucessHandle = (sender, args) => - { - // args.Response - var code = verificationCode.ToString(); - _ = _verificationCodeRepository.AddAsync(new VerificationCode() - { - CodeType = 0, - HasSend = true, - Code = code, - UserId = userId, - ExpirationTime = DateTime.Now.AddMinutes(3) - }).Result; - _ = _verificationCodeRepository.SaveChangesAsync().Result; + return (topicStr, htmlBodyStr); }; + messageToSend = await GetEmailSubejctAndHtmlInfoAndBuildAsync(mfaType == UserMFAType.Login ? EmailBusinessScenario.MFALogin : EmailBusinessScenario.MFAUnlock, messageToSend, emailConfigFunc); + + + var sucessHandle = GetEmailSuccessHandle(userId, verificationCode); + + await SendEmailHelper.SendEmailAsync(messageToSend, _systemEmailConfig, sucessHandle); } - //重置邮箱 + //用户重置邮箱 public async Task SendMailEditEmail(Guid userId, string userName, string emailAddress, int verificationCode) { - - var messageToSend = new MimeMessage(); //发件地址 messageToSend.From.Add(new MailboxAddress(_systemEmailConfig.FromName, _systemEmailConfig.FromEmail)); //收件地址 messageToSend.To.Add(new MailboxAddress(userName, emailAddress)); //主题 - //---[来自展影IRC] 关于重置邮箱的提醒 - messageToSend.Subject = _localizer["Mail_EmailResetReminder", _userInfo.IsEn_Us ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN]; + //---[来自展影IRC] 关于重置邮箱的提醒 - var builder = new BodyBuilder(); + var companyName = _userInfo.IsEn_Us ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN; - - var pathToFile = _hostEnvironment.WebRootPath - + Path.DirectorySeparatorChar.ToString() - + "EmailTemplate" - + Path.DirectorySeparatorChar.ToString() - //+ "UserOptCommon.html"; - +(_userInfo.IsEn_Us ? "UserOptCommon_US.html" : "UserOptCommon.html"); - - using (StreamReader SourceReader = System.IO.File.OpenText(pathToFile)) + Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr)> emailConfigFunc = input => { - var templateInfo = SourceReader.ReadToEnd(); + var topicStr = string.Format(input.topicStr, companyName); - - builder.HtmlBody = string.Format(ReplaceCompanyName(templateInfo), + var htmlBodyStr = string.Format(ReplaceCompanyName(input.htmlBodyStr), userName, - //---尊敬的 - //_localizer["Mail_Dear", userName], - //---您正在进行邮箱重置操作 + //---您正在进行邮箱重置操作 _localizer["Mail_ResettingEmail"], verificationCode ); - } + + return (topicStr, htmlBodyStr); + }; - messageToSend.Body = builder.ToMessageBody(); + messageToSend = await GetEmailSubejctAndHtmlInfoAndBuildAsync(EmailBusinessScenario.UserResetEmail, messageToSend, emailConfigFunc); - - EventHandler sucessHandle = (sender, args) => - { - // args.Response - var code = verificationCode.ToString(); - _ = _verificationCodeRepository.AddAsync(new VerificationCode() - { - CodeType = 0, - HasSend = true, - Code = code, - UserId = userId, - ExpirationTime = DateTime.Now.AddMinutes(3) - }).Result; - _ = _verificationCodeRepository.SaveChangesAsync().Result; - - }; - + var sucessHandle = GetEmailSuccessHandle(userId, verificationCode); await SendEmailHelper.SendEmailAsync(messageToSend, _systemEmailConfig, sucessHandle); @@ -231,61 +246,37 @@ namespace IRaCIS.Application.Services messageToSend.From.Add(new MailboxAddress(_systemEmailConfig.FromName, _systemEmailConfig.FromEmail)); //收件地址 messageToSend.To.Add(new MailboxAddress(String.Empty, emailAddress)); - //主题 - //---[来自展影IRC] 关于重置密码的提醒 - messageToSend.Subject = _localizer["Mail_IRCResettingPassword", _userInfo.IsEn_Us ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN]; + var companyName = _userInfo.IsEn_Us ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN; - var builder = new BodyBuilder(); - - var pathToFile = _hostEnvironment.WebRootPath - + Path.DirectorySeparatorChar.ToString() - + "EmailTemplate" - + Path.DirectorySeparatorChar.ToString() - //+ "UserOptCommon.html"; - + (_userInfo.IsEn_Us ? "UserOptCommon_US.html" : "UserOptCommon.html"); - - using (StreamReader SourceReader = System.IO.File.OpenText(pathToFile)) + Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr)> emailConfigFunc = input => { - var templateInfo = SourceReader.ReadToEnd(); + var topicStr = string.Format(input.topicStr, companyName); + var htmlBodyStr = string.Format(ReplaceCompanyName(input.htmlBodyStr), - builder.HtmlBody = string.Format(ReplaceCompanyName(templateInfo), - "", + "", //---您正在进行邮箱重置密码操作 _localizer["Mail_ResettingPassword"], verificationCode ); - } + + return (topicStr, htmlBodyStr); + }; + messageToSend = await GetEmailSubejctAndHtmlInfoAndBuildAsync(EmailBusinessScenario.UnloginUseEmailResetPassword, messageToSend, emailConfigFunc); - messageToSend.Body = builder.ToMessageBody(); - - - EventHandler sucessHandle = (sender, args) => - { - var code = verificationCode.ToString(); - _ = _verificationCodeRepository.AddAsync(new VerificationCode() - { - CodeType = Core.Domain.Share.VerifyType.Email, - HasSend = true, - Code = code, - UserId = Guid.Empty,//此时不知道用户 - EmailOrPhone = emailAddress, - ExpirationTime = DateTime.Now.AddMinutes(3) - }).Result; - _ = _verificationCodeRepository.SaveChangesAsync().Result; - }; - + ////此时不知道用户 + var sucessHandle = GetEmailSuccessHandle(Guid.Empty, verificationCode); await SendEmailHelper.SendEmailAsync(messageToSend, _systemEmailConfig, sucessHandle); } /// - /// 发送验证码 + /// Reviewer简历录入 发送验证码 /// /// /// @@ -293,61 +284,37 @@ namespace IRaCIS.Application.Services public async Task SendEmailVerification(string emailAddress, int verificationCode) { - var messageToSend = new MimeMessage(); //发件地址 messageToSend.From.Add(new MailboxAddress(_systemEmailConfig.FromName, _systemEmailConfig.FromEmail)); //收件地址 messageToSend.To.Add(new MailboxAddress(String.Empty, emailAddress)); //主题 - //---[来自展影IRC]的提醒 - messageToSend.Subject = _localizer["Mail_ImagingIRCReminder", _userInfo.IsEn_Us ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN]; + //---[来自展影IRC]的提醒 + var companyName = _userInfo.IsEn_Us ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN; - - - var builder = new BodyBuilder(); - - var pathToFile = _hostEnvironment.WebRootPath - + Path.DirectorySeparatorChar.ToString() - + "EmailTemplate" - + Path.DirectorySeparatorChar.ToString() - + (_userInfo.IsEn_Us ? "UserOptCommon_US.html": "UserOptCommon.html" ); - - using (StreamReader SourceReader = System.IO.File.OpenText(pathToFile)) + Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr)> emailConfigFunc = input => { - var templateInfo = SourceReader.ReadToEnd(); + var topicStr = string.Format(input.topicStr, companyName); + var htmlBodyStr = string.Format(ReplaceCompanyName(input.htmlBodyStr), - builder.HtmlBody = string.Format(ReplaceCompanyName(templateInfo), - "Sir or Madam", + "Sir or Madam", //---您正在参与展影医疗IRC项目 - _localizer["Mail_IRCProject", _userInfo.IsEn_Us ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN], + _localizer["Mail_IRCProject", companyName], verificationCode ); - } - messageToSend.Body = builder.ToMessageBody(); - - - - EventHandler sucessHandle = (sender, args) => - { - // args.Response - var code = verificationCode.ToString(); - _ = _verificationCodeRepository.AddAsync(new VerificationCode() - { - CodeType = VerifyType.Email, - HasSend = true, - Code = code, - UserId = Guid.Empty,//此时不知道用户 - EmailOrPhone = emailAddress, - ExpirationTime = DateTime.Now.AddMinutes(3) - }).Result; - _ = _verificationCodeRepository.SaveChangesAsync().Result; + return (topicStr, htmlBodyStr); }; + messageToSend = await GetEmailSubejctAndHtmlInfoAndBuildAsync(EmailBusinessScenario.UnloginUseEmailResetPassword, messageToSend, emailConfigFunc); + + //此时不知道用户 + var sucessHandle = GetEmailSuccessHandle(Guid.Empty, verificationCode, emailAddress); + await SendEmailHelper.SendEmailAsync(messageToSend, _systemEmailConfig, sucessHandle); @@ -359,7 +326,6 @@ namespace IRaCIS.Application.Services public async Task AnolymousSendEmail(string researchProgramNo, string emailAddress, int verificationCode) { - var messageToSend = new MimeMessage(); //发件地址 messageToSend.From.Add(new MailboxAddress(_systemEmailConfig.FromName, _systemEmailConfig.FromEmail)); @@ -367,67 +333,74 @@ namespace IRaCIS.Application.Services messageToSend.To.Add(new MailboxAddress(String.Empty, emailAddress)); //主题 //$"[来自展影IRC] [{researchProgramNo}] 关于中心调研的提醒"; - messageToSend.Subject = _localizer["Mail_ProjectParticipationReminder", _userInfo.IsEn_Us ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN, researchProgramNo]; + var companyName = _userInfo.IsEn_Us ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN; - - - var builder = new BodyBuilder(); - - var pathToFile = _hostEnvironment.WebRootPath - + Path.DirectorySeparatorChar.ToString() - + "EmailTemplate" - + Path.DirectorySeparatorChar.ToString() - //+ "UserOptCommon.html"; - + (_userInfo.IsEn_Us ? "UserOptCommon_US.html" : "UserOptCommon.html"); - - using (StreamReader SourceReader = System.IO.File.OpenText(pathToFile)) + Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr)> emailConfigFunc = input => { - var templateInfo = SourceReader.ReadToEnd(); + var topicStr = string.Format(input.topicStr, companyName, researchProgramNo); + var htmlBodyStr = string.Format(ReplaceCompanyName(input.htmlBodyStr), - builder.HtmlBody = string.Format(ReplaceCompanyName(templateInfo), "Sir or Madam", //---您正在参与展影医疗IRC项目中心调研工作 - _localizer["Mail_CenterResearchReminder", _userInfo.IsEn_Us ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN], + _localizer["Mail_CenterResearchReminder", companyName], verificationCode ); - } - messageToSend.Body = builder.ToMessageBody(); - - - - EventHandler sucessHandle = (sender, args) => - { - // args.Response - var code = verificationCode.ToString(); - _ = _verificationCodeRepository.AddAsync(new VerificationCode() - { - CodeType = VerifyType.Email, - HasSend = true, - Code = code, - UserId = Guid.Empty,//此时不知道用户 - EmailOrPhone = emailAddress, - ExpirationTime = DateTime.Now.AddMinutes(3) - }).Result; - _ = _verificationCodeRepository.SaveChangesAsync().Result; + return (topicStr, htmlBodyStr); }; + messageToSend = await GetEmailSubejctAndHtmlInfoAndBuildAsync(EmailBusinessScenario.SiteSurveyLogin, messageToSend, emailConfigFunc); - await SendEmailHelper.SendEmailAsync(messageToSend, _systemEmailConfig,sucessHandle); + //此时不知道用户 + var sucessHandle = GetEmailSuccessHandle(Guid.Empty, verificationCode); + await SendEmailHelper.SendEmailAsync(messageToSend, _systemEmailConfig, sucessHandle); + } - public async Task SiteSurveyRejectEmail(MimeMessage messageToSend) + public async Task SiteSurveyRejectEmail(MimeMessage messageToSend, TrialSiteSurvey trialSiteSurvey, string routeUrl, User? user) { - + //发件地址 messageToSend.From.Add(new MailboxAddress(_systemEmailConfig.FromName, _systemEmailConfig.FromEmail)); + var trialInfo = await _repository.FirstOrDefaultAsync(t => t.Id == trialSiteSurvey.TrialId); + + var siteInfo = await _repository.FirstOrDefaultAsync(t => t.TrialId == trialSiteSurvey.TrialId && t.Id == trialSiteSurvey.TrialSiteId, true); + + + var companyName = _userInfo.IsEn_Us ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN; + + + Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr)> emailConfigFunc = input => + { + var topicStr = string.Format(input.topicStr, companyName, trialInfo.ResearchProgramNo); + + var htmlBodyStr = string.Format(ReplaceCompanyName(input.htmlBodyStr), + + (user == null ? trialSiteSurvey.UserName : user.LastName + "/ " + user.FirstName), + trialInfo.TrialCode, + trialInfo.ResearchProgramNo, + trialInfo.ExperimentName, + siteInfo.TrialSiteCode, + siteInfo.TrialSiteAliasName, + trialSiteSurvey.LatestBackReason, + routeUrl, + (trialSiteSurvey.State == TrialSiteSurveyEnum.ToSubmit ? "inline - block" : "none") + ); + + return (topicStr, htmlBodyStr); + }; + + + messageToSend = await GetEmailSubejctAndHtmlInfoAndBuildAsync(EmailBusinessScenario.SiteSurveyReject, messageToSend, emailConfigFunc); + + await SendEmailHelper.SendEmailAsync(messageToSend, _systemEmailConfig); @@ -446,49 +419,42 @@ namespace IRaCIS.Application.Services //收件地址 messageToSend.To.Add(new MailboxAddress(sysUserInfo.FullName, sysUserInfo.EMail)); //主题 - //---[来自展影IRC] 关于创建账户的提醒 - messageToSend.Subject = _localizer["Mail_AccountCreationReminder", _userInfo.IsEn_Us ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN]; + //---[来自展影IRC] 关于创建账户的提醒 - - var builder = new BodyBuilder(); - - var pathToFile = _hostEnvironment.WebRootPath - + Path.DirectorySeparatorChar.ToString() - + "EmailTemplate" - + Path.DirectorySeparatorChar.ToString() - //+ "AdminAddUser.html"; - + (_userInfo.IsEn_Us ? "AdminAddUser_US.html" : "AdminAddUser.html"); - var token = _tokenService.GetToken(IRaCISClaims.Create(_mapper.Map(sysUserInfo))); await _userRepository.BatchUpdateNoTrackingAsync(t => t.Id == sysUserInfo.Id, u => new User() { EmailToken = token }); - routeUrl = routeUrl + "?UserId=" + sysUserInfo.Id + "&Email=" + sysUserInfo.EMail + "&UserName=" + sysUserInfo.UserName + "&UserType=" + sysUserInfo.UserTypeRole.UserTypeShortName + "&lang=" + (_userInfo.IsEn_Us?"en":"zh") + "&access_token=" + token; + routeUrl = routeUrl + "?UserId=" + sysUserInfo.Id + "&Email=" + sysUserInfo.EMail + "&UserName=" + sysUserInfo.UserName + "&UserType=" + sysUserInfo.UserTypeRole.UserTypeShortName + "&lang=" + (_userInfo.IsEn_Us ? "en" : "zh") + "&access_token=" + token; var domain = baseUrl.Substring(0, baseUrl.IndexOf("/login")); var redirectUrl = $"{domain}/api/User/UserRedirect?url={System.Web.HttpUtility.UrlEncode(routeUrl)}"; - using (StreamReader SourceReader = System.IO.File.OpenText(pathToFile)) + + var companyName = _userInfo.IsEn_Us ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN; + + Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr)> emailConfigFunc = input => { - var templateInfo = SourceReader.ReadToEnd(); + var topicStr = string.Format(input.topicStr, companyName); + var htmlBodyStr = string.Format(ReplaceCompanyName(input.htmlBodyStr), - builder.HtmlBody = string.Format(ReplaceCompanyName(templateInfo), - sysUserInfo.FullName, + sysUserInfo.FullName, sysUserInfo.UserName, sysUserInfo.UserTypeRole.UserTypeShortName, redirectUrl ); - } + + return (topicStr, htmlBodyStr); + }; - - messageToSend.Body = builder.ToMessageBody(); + messageToSend = await GetEmailSubejctAndHtmlInfoAndBuildAsync(EmailBusinessScenario.SysCreateUser, messageToSend, emailConfigFunc); - await SendEmailHelper.SendEmailAsync(messageToSend,_systemEmailConfig); + await SendEmailHelper.SendEmailAsync(messageToSend, _systemEmailConfig); } //管理员重置密码发送邮件 @@ -502,38 +468,27 @@ namespace IRaCIS.Application.Services //收件地址 messageToSend.To.Add(new MailboxAddress(sysUserInfo.FullName, sysUserInfo.EMail)); //主题 - //---[来自展影IRC] 关于重置账户密码的提醒 - messageToSend.Subject = _localizer["Mail_AccountPasswordResetReminder", _userInfo.IsEn_Us ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN]; + //---[来自展影IRC] 关于重置账户密码的提醒 + var companyName = _userInfo.IsEn_Us ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN; - - var builder = new BodyBuilder(); - - var pathToFile = _hostEnvironment.WebRootPath - + Path.DirectorySeparatorChar.ToString() - + "EmailTemplate" - + Path.DirectorySeparatorChar.ToString() - //+ "AdminResetUser.html"; - + (_userInfo.IsEn_Us ? "AdminResetUser_US.html" : "AdminResetUser.html"); - - - using (StreamReader SourceReader = System.IO.File.OpenText(pathToFile)) + Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr)> emailConfigFunc = input => { - var templateInfo = SourceReader.ReadToEnd(); + var topicStr = string.Format(input.topicStr, companyName); + var htmlBodyStr = string.Format(ReplaceCompanyName(input.htmlBodyStr), - builder.HtmlBody = string.Format(ReplaceCompanyName(templateInfo), - sysUserInfo.FullName, + sysUserInfo.FullName, sysUserInfo.UserName, sysUserInfo.UserTypeRole.UserTypeShortName, pwdNotMd5 ); - } + + return (topicStr, htmlBodyStr); + }; - - messageToSend.Body = builder.ToMessageBody(); - + messageToSend = await GetEmailSubejctAndHtmlInfoAndBuildAsync(EmailBusinessScenario.SysResetPassword, messageToSend, emailConfigFunc); await SendEmailHelper.SendEmailAsync(messageToSend, _systemEmailConfig); } @@ -553,11 +508,6 @@ namespace IRaCIS.Application.Services messageToSend.To.Add(new MailboxAddress(sysUserInfo.FullName, sysUserInfo.EMail)); //主题 // $"[来自展影IRC] [{trialInfo.ResearchProgramNo}]邀请信"; - messageToSend.Subject = _localizer["Mail_InvitationEmail", _userInfo.IsEn_Us ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN, trialInfo.ResearchProgramNo]; - - - - var builder = new BodyBuilder(); var token = _tokenService.GetToken(IRaCISClaims.Create(_mapper.Map(sysUserInfo))); @@ -567,24 +517,21 @@ namespace IRaCIS.Application.Services await _userRepository.BatchUpdateNoTrackingAsync(t => t.Id == sysUserInfo.Id, u => new User() { EmailToken = token }); } + var routeUrl = rootUrl + "?UserId=" + sysUserInfo.Id + "&Email=" + sysUserInfo.EMail + "&UserName=" + sysUserInfo.UserName + "&UserType=" + sysUserInfo.UserTypeRole.UserTypeShortName + "&lang=" + (_userInfo.IsEn_Us ? "en" : "zh") + "&access_token=" + token; - var pathToFile = _hostEnvironment.WebRootPath - + Path.DirectorySeparatorChar.ToString() - + "EmailTemplate" - + Path.DirectorySeparatorChar.ToString() - + (sysUserInfo.IsFirstAdd ? (_userInfo.IsEn_Us ? "TrialUserFirstJoin_US.html" : "TrialUserFirstJoin.html") : (_userInfo.IsEn_Us ? "TrialUserExistJoin_US.html" : "TrialUserExistJoin.html")); + var domain = baseUrl.Substring(0, baseUrl.IndexOf("/login")); - using (StreamReader SourceReader = System.IO.File.OpenText(pathToFile)) + var redirectUrl = $"{domain}/api/User/UserRedirect?url={System.Web.HttpUtility.UrlEncode(routeUrl)}"; + + + var companyName = _userInfo.IsEn_Us ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN; + + Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr)> emailConfigFunc = input => { - var templateInfo = SourceReader.ReadToEnd(); + var topicStr = string.Format(input.topicStr, companyName, trialInfo.ResearchProgramNo); - var routeUrl = rootUrl + "?UserId=" + sysUserInfo.Id + "&Email=" + sysUserInfo.EMail + "&UserName=" + sysUserInfo.UserName + "&UserType=" + sysUserInfo.UserTypeRole.UserTypeShortName + "&lang=" + (_userInfo.IsEn_Us ? "en" : "zh") + "&access_token=" + token; + var htmlBodyStr = string.Format(ReplaceCompanyName(input.htmlBodyStr), - var domain = baseUrl.Substring(0, baseUrl.IndexOf("/login")); - - var redirectUrl = $"{domain}/api/User/UserRedirect?url={System.Web.HttpUtility.UrlEncode(routeUrl)}"; - - builder.HtmlBody = string.Format(ReplaceCompanyName(templateInfo), sysUserInfo.FullName, trialInfo.ExperimentName, trialInfo.ResearchProgramNo, @@ -593,11 +540,15 @@ namespace IRaCIS.Application.Services sysUserInfo.UserTypeRole.UserTypeShortName, sysUserInfo.IsFirstAdd ? redirectUrl : baseUrl ); - } - messageToSend.Body = builder.ToMessageBody(); + return (topicStr, htmlBodyStr); + }; - await SendEmailHelper.SendEmailAsync(messageToSend, _systemEmailConfig,null); + + messageToSend = await GetEmailSubejctAndHtmlInfoAndBuildAsync(sysUserInfo.IsFirstAdd ? EmailBusinessScenario.SiteUseOrExternalUserFirstrJoinTrial : EmailBusinessScenario.SiteUserOrExternalUserExistJoinTrial, messageToSend, emailConfigFunc); + + + await SendEmailHelper.SendEmailAsync(messageToSend, _systemEmailConfig); } @@ -617,10 +568,6 @@ namespace IRaCIS.Application.Services messageToSend.To.Add(new MailboxAddress(String.Empty, sysUserInfo.EMail)); //主题 // $"[来自展影IRC] [{trialInfo.ResearchProgramNo}]邀请信"; - messageToSend.Subject = _localizer["Mail_InvitationEmail", _userInfo.IsEn_Us ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN,trialInfo.ResearchProgramNo]; - - - var builder = new BodyBuilder(); @@ -630,23 +577,21 @@ namespace IRaCIS.Application.Services await _userRepository.BatchUpdateNoTrackingAsync(t => t.Id == sysUserInfo.Id, u => new User() { EmailToken = token }); } - var pathToFile = _hostEnvironment.WebRootPath - + Path.DirectorySeparatorChar.ToString() - + "EmailTemplate" - + Path.DirectorySeparatorChar.ToString() - + (sysUserInfo.IsFirstAdd ? (_userInfo.IsEn_Us ? "TrialUserFirstJoin_US.html" : "TrialUserFirstJoin.html") : (_userInfo.IsEn_Us ? "TrialUserExistJoin_US.html" : "TrialUserExistJoin.html") ); + var domain = baseUrl.Substring(0, baseUrl.IndexOf("/login")); - using (StreamReader SourceReader = System.IO.File.OpenText(pathToFile)) + var routeUrl = rootUrl + "?UserId=" + sysUserInfo.Id + "&Email=" + sysUserInfo.EMail + "&UserName=" + sysUserInfo.UserName + "&UserType=" + sysUserInfo.UserTypeRole.UserTypeShortName + "&lang=" + (_userInfo.IsEn_Us ? "en" : "zh") + "&access_token=" + token; + + var redirectUrl = $"{domain}/api/User/UserRedirect?url={System.Web.HttpUtility.UrlEncode(routeUrl)}"; + + + var companyName = _userInfo.IsEn_Us ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN; + + Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr)> emailConfigFunc = input => { - var templateInfo = SourceReader.ReadToEnd(); + var topicStr = string.Format(input.topicStr, companyName, trialInfo.ResearchProgramNo); - var domain = baseUrl.Substring(0, baseUrl.IndexOf("/login")); + var htmlBodyStr = string.Format(ReplaceCompanyName(input.htmlBodyStr), - var routeUrl = rootUrl + "?UserId=" + sysUserInfo.Id + "&Email=" + sysUserInfo.EMail + "&UserName=" + sysUserInfo.UserName + "&UserType=" + sysUserInfo.UserTypeRole.UserTypeShortName + "&lang=" + (_userInfo.IsEn_Us ? "en" : "zh") + "&access_token=" + token; - - var redirectUrl = $"{domain}/api/User/UserRedirect?url={System.Web.HttpUtility.UrlEncode(routeUrl)}"; - - builder.HtmlBody = string.Format(ReplaceCompanyName(templateInfo), sysUserInfo.FullName, trialInfo.ExperimentName, trialInfo.ResearchProgramNo, @@ -655,11 +600,12 @@ namespace IRaCIS.Application.Services sysUserInfo.UserTypeRole.UserTypeShortName, sysUserInfo.IsFirstAdd ? redirectUrl : baseUrl ); - } + + return (topicStr, htmlBodyStr); + }; - - messageToSend.Body = builder.ToMessageBody(); + messageToSend = await GetEmailSubejctAndHtmlInfoAndBuildAsync(sysUserInfo.IsFirstAdd ? EmailBusinessScenario.SiteUseOrExternalUserFirstrJoinTrial : EmailBusinessScenario.SiteUserOrExternalUserExistJoinTrial, messageToSend, emailConfigFunc); await SendEmailHelper.SendEmailAsync(messageToSend, _systemEmailConfig, null); @@ -730,13 +676,8 @@ namespace IRaCIS.Application.Services messageToSend.From.Add(new MailboxAddress(_systemEmailConfig.FromName, _systemEmailConfig.FromEmail)); //收件地址 messageToSend.To.Add(new MailboxAddress(doctor.FullName, doctor.EMail)); - //主题 - // $"[来自展影IRC] [{trialInfo.ResearchProgramNo}]邀请信"; - messageToSend.Subject = _localizer["Mail_InvitationEmail", _userInfo.IsEn_Us ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN, trialInfo.ResearchProgramNo]; - var builder = new BodyBuilder(); - var basicInfo = IRaCISClaims.Create(_mapper.Map(sysUserInfo)); @@ -751,25 +692,25 @@ namespace IRaCIS.Application.Services await _userRepository.BatchUpdateNoTrackingAsync(t => t.Id == sysUserInfo.Id, u => new User() { EmailToken = token }); } + var routeUrl = rootUrl + "?UserId=" + sysUserInfo.Id + "&Email=" + sysUserInfo.EMail + "&UserName=" + sysUserInfo.UserName + "&UserType=" + userType.UserTypeShortName + "&lang=" + (_userInfo.IsEn_Us ? "en" : "zh") + "&access_token=" + token; - var pathToFile = _hostEnvironment.WebRootPath - + Path.DirectorySeparatorChar.ToString() - + "EmailTemplate" - + Path.DirectorySeparatorChar.ToString() - + (sysUserInfo.IsFirstAdd ? (_userInfo.IsEn_Us ? "TrialDoctorFirstJoin_US.html" : "TrialDoctorFirstJoin.html") : (_userInfo.IsEn_Us ? "TrialDoctorExistJoin_US.html" : "TrialDoctorExistJoin.html") ); + var domain = baseUrl.Substring(0, baseUrl.IndexOf("/login")); - using (StreamReader SourceReader = System.IO.File.OpenText(pathToFile)) + var redirectUrl = $"{domain}/api/User/UserRedirect?url={System.Web.HttpUtility.UrlEncode(routeUrl)}"; + + //主题 + // $"[来自展影IRC] [{trialInfo.ResearchProgramNo}]邀请信"; + + + var companyName = _userInfo.IsEn_Us ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN; + + Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr)> emailConfigFunc = input => { - var templateInfo = SourceReader.ReadToEnd(); + var topicStr = string.Format(input.topicStr, companyName, trialInfo.ResearchProgramNo); - var routeUrl = rootUrl + "?UserId=" + sysUserInfo.Id + "&Email=" + sysUserInfo.EMail + "&UserName=" + sysUserInfo.UserName + "&UserType=" + userType.UserTypeShortName + "&lang=" + (_userInfo.IsEn_Us ? "en" : "zh") + "&access_token=" + token; + var htmlBodyStr = string.Format(ReplaceCompanyName(input.htmlBodyStr), - var domain = baseUrl.Substring(0, baseUrl.IndexOf("/login")); - - var redirectUrl = $"{domain}/api/User/UserRedirect?url={System.Web.HttpUtility.UrlEncode(routeUrl)}"; - - builder.HtmlBody = string.Format(ReplaceCompanyName(templateInfo), - sysUserInfo.FullName, + sysUserInfo.FullName, trialInfo.ExperimentName, trialInfo.ResearchProgramNo, trialInfo.TrialCode, @@ -777,9 +718,13 @@ namespace IRaCIS.Application.Services userType.UserTypeShortName, sysUserInfo.IsFirstAdd ? redirectUrl : baseUrl ); - } - messageToSend.Body = builder.ToMessageBody(); + return (topicStr, htmlBodyStr); + }; + + + messageToSend = await GetEmailSubejctAndHtmlInfoAndBuildAsync(sysUserInfo.IsFirstAdd ? EmailBusinessScenario.DoctorUserFirstJoinTrial : EmailBusinessScenario.DoctorUserExistJoinTrial, messageToSend, emailConfigFunc); + await SendEmailHelper.SendEmailAsync(messageToSend, _systemEmailConfig, null); diff --git a/IRaCIS.Core.Application/Service/SiteSurvey/TrialSiteSurveyService.cs b/IRaCIS.Core.Application/Service/SiteSurvey/TrialSiteSurveyService.cs index 957bdba54..9ff013fac 100644 --- a/IRaCIS.Core.Application/Service/SiteSurvey/TrialSiteSurveyService.cs +++ b/IRaCIS.Core.Application/Service/SiteSurvey/TrialSiteSurveyService.cs @@ -611,48 +611,8 @@ namespace IRaCIS.Core.Application.Contracts } - var builder = new BodyBuilder(); - var trialInfo = await _repository.FirstOrDefaultAsync(t => t.Id == trialSiteSubmitBackCommand.TrialId); - - var siteInfo = await _trialSiteRepository.FirstOrDefaultAsync(t => t.TrialId == trialSiteSubmitBackCommand.TrialId && t.Id == survey.TrialSiteId, true); - - - //主题 - // $"[来自展影IRC] [{trialInfo.ResearchProgramNo}] 关于中心调研审批的提醒"; - messageToSend.Subject = _localizer["TrialSiteSurvey_IRCNotification", _userInfo.IsEn_Us ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN, trialInfo.ResearchProgramNo]; - - var pathToFile = _hostEnvironment.WebRootPath - + Path.DirectorySeparatorChar.ToString() - + "EmailTemplate" - + Path.DirectorySeparatorChar.ToString() - + (_userInfo.IsEn_Us ? "TrialSiteSurveyReject_US.html" : "TrialSiteSurveyReject.html"); - - - using (StreamReader SourceReader = System.IO.File.OpenText(pathToFile)) - { - var templateInfo = SourceReader.ReadToEnd(); - - templateInfo = templateInfo.Replace("{company}", _userInfo.IsEn_Us ? _systemEmailConfig.CompanyName : _systemEmailConfig.CompanyNameCN) - .Replace("{company abbreviation}", _userInfo.IsEn_Us ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN); - - builder.HtmlBody = string.Format(templateInfo, - (user == null ? survey.UserName : user.LastName + "/ " + user.FirstName), - trialInfo.TrialCode, - trialInfo.ResearchProgramNo, - trialInfo.ExperimentName, - siteInfo.TrialSiteCode, - siteInfo.TrialSiteAliasName, - survey.LatestBackReason, - trialSiteSubmitBackCommand.RouteUrl, - (survey.State == TrialSiteSurveyEnum.ToSubmit ? "inline - block" : "none") - - ); - } - messageToSend.Body = builder.ToMessageBody(); - - - await _IMailVerificationService.SiteSurveyRejectEmail(messageToSend); + await _IMailVerificationService.SiteSurveyRejectEmail(messageToSend, survey , trialSiteSubmitBackCommand.RouteUrl, user); await _trialSiteSurveyRepository.SaveChangesAsync(); diff --git a/IRaCIS.Core.Domain.Share/Common/EmailScenarioEnum.cs b/IRaCIS.Core.Domain.Share/Common/EmailScenarioEnum.cs index 1d4ecdf1a..ee22efd38 100644 --- a/IRaCIS.Core.Domain.Share/Common/EmailScenarioEnum.cs +++ b/IRaCIS.Core.Domain.Share/Common/EmailScenarioEnum.cs @@ -37,19 +37,56 @@ namespace IRaCIS.Core.Domain.Share public enum EmailBusinessScenario { None=-1, + EnrollConfirmed = 1, PDConfirmed = 2, - Trial=3, + //Trial=3, - Reviewer=4, + //Reviewer=4, QCTask = 5, QCQuestion = 6, - ImageQuestion = 7 + ImageQuestion = 7, + + + + MFALogin = 10, + + MFAUnlock = 11, + + + //医生简历信息录入入口登录 + ReviewerLogin=12, + + + + UserResetEmail = 13, + + + SiteSurveyLogin = 14, + + SiteUseOrExternalUserFirstrJoinTrial = 15, + + SiteUserOrExternalUserExistJoinTrial = 16, + + SiteSurveyReject=17, + + DoctorUserFirstJoinTrial=19, + + DoctorUserExistJoinTrial=20, + + + SysCreateUser = 21, + + SysResetPassword = 22, + + //不登陆通过邮箱重置密码 + UnloginUseEmailResetPassword = 23, + } From 5175c857ec03ab49d2afb2777e245da310f1ca35 Mon Sep 17 00:00:00 2001 From: he <109787524@qq.com> Date: Mon, 29 Jul 2024 10:43:24 +0800 Subject: [PATCH 121/251] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E6=8F=90=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Service/ImageAndDoc/DTO/DicomSeriesModel.cs | 2 ++ .../Reading/ClinicalData/ReadingClinicalDataService.cs | 4 ++-- .../Service/Reading/Dto/ReadingImageTaskViewModel.cs | 2 ++ .../Service/Visit/SubjectVisitService.cs | 2 ++ .../Reading/ReadingFormAnswer/ReadingCustomTag.cs | 6 ++++-- 5 files changed, 12 insertions(+), 4 deletions(-) diff --git a/IRaCIS.Core.Application/Service/ImageAndDoc/DTO/DicomSeriesModel.cs b/IRaCIS.Core.Application/Service/ImageAndDoc/DTO/DicomSeriesModel.cs index ceca4a370..c95598753 100644 --- a/IRaCIS.Core.Application/Service/ImageAndDoc/DTO/DicomSeriesModel.cs +++ b/IRaCIS.Core.Application/Service/ImageAndDoc/DTO/DicomSeriesModel.cs @@ -64,6 +64,8 @@ namespace IRaCIS.Core.Application.Contracts.Dicom.DTO public Guid? StudyId { get; set; } public Guid? InstanceId { get; set; } + + public int? NumberOfFrames { get; set; } } public class InstanceBasicInfo { diff --git a/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs b/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs index 620580abd..8670bd215 100644 --- a/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs +++ b/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs @@ -718,7 +718,7 @@ namespace IRaCIS.Application.Services {ClinicalLevel.ImageRead,2 }, {ClinicalLevel.OncologyRead,3 }, {ClinicalLevel.Subject,4 }, - {ClinicalLevel.Study,5 }, + {ClinicalLevel.Study,5 }, }; result = result.OrderBy(x => keys[x.ClinicalDataLevel]).ToList(); @@ -1021,7 +1021,7 @@ namespace IRaCIS.Application.Services } #endregion - + #region 阅片临床数据PDF diff --git a/IRaCIS.Core.Application/Service/Reading/Dto/ReadingImageTaskViewModel.cs b/IRaCIS.Core.Application/Service/Reading/Dto/ReadingImageTaskViewModel.cs index 2829ee398..688df02f5 100644 --- a/IRaCIS.Core.Application/Service/Reading/Dto/ReadingImageTaskViewModel.cs +++ b/IRaCIS.Core.Application/Service/Reading/Dto/ReadingImageTaskViewModel.cs @@ -511,6 +511,8 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto /// CreateUserId /// public Guid CreateUserId { get; set; } + + public int? NumberOfFrames { get; set; } } public class GetManualListInDto diff --git a/IRaCIS.Core.Application/Service/Visit/SubjectVisitService.cs b/IRaCIS.Core.Application/Service/Visit/SubjectVisitService.cs index 5d435d1e2..3f8ab4aec 100644 --- a/IRaCIS.Core.Application/Service/Visit/SubjectVisitService.cs +++ b/IRaCIS.Core.Application/Service/Visit/SubjectVisitService.cs @@ -584,6 +584,7 @@ namespace IRaCIS.Core.Application.Services SeriesId = x.SeriesId, StudyId = x.StudyId, InstanceId = x.InstanceId, + NumberOfFrames=x.NumberOfFrames, }).ToListAsync(); @@ -595,6 +596,7 @@ namespace IRaCIS.Core.Application.Services SeriesId = x.SeriesId, StudyId = x.StudyId, InstanceId = x.InstanceId, + NumberOfFrames = x.NumberOfFrames, }).ToListAsync(); rowInfoList.AddRange(customoList); diff --git a/IRaCIS.Core.Domain/Reading/ReadingFormAnswer/ReadingCustomTag.cs b/IRaCIS.Core.Domain/Reading/ReadingFormAnswer/ReadingCustomTag.cs index 1409e8f3f..88f59ce88 100644 --- a/IRaCIS.Core.Domain/Reading/ReadingFormAnswer/ReadingCustomTag.cs +++ b/IRaCIS.Core.Domain/Reading/ReadingFormAnswer/ReadingCustomTag.cs @@ -49,8 +49,10 @@ namespace IRaCIS.Core.Domain.Models /// CreateUserId /// public Guid CreateUserId { get; set; } - - } + + public int? NumberOfFrames { get; set; } + + } } From 73e9e3239a342dfdba53c7554b68de285a21ec77 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Mon, 29 Jul 2024 11:47:32 +0800 Subject: [PATCH 122/251] =?UTF-8?q?=E4=BF=AE=E6=94=B9us=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.API/appsettings.US_Uat_IRC.json | 36 ++++++++------------- 1 file changed, 13 insertions(+), 23 deletions(-) diff --git a/IRaCIS.Core.API/appsettings.US_Uat_IRC.json b/IRaCIS.Core.API/appsettings.US_Uat_IRC.json index 87b6305f1..8697adda1 100644 --- a/IRaCIS.Core.API/appsettings.US_Uat_IRC.json +++ b/IRaCIS.Core.API/appsettings.US_Uat_IRC.json @@ -10,33 +10,21 @@ "RemoteNew": "Server=us-mssql-service,1433;Database=US_Uat_IRC;User ID=sa;Password=xc@123456;TrustServerCertificate=true", "Hangfire": "Server=us-mssql-service,1433;Database=US_Uat_IRC_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true" - //"RemoteNew": "Server=44.218.11.19,1435;Database=Prod_US_IRC;User ID=sa;Password=xc@123456;TrustServerCertificate=true", - //"Hangfire": "Server=44.218.11.19,1435;Database=Prod_US_IRC_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true" + //"RemoteNew": "Server=3.226.182.187,1435;Database=US_Uat_IRC;User ID=sa;Password=xc@123456;TrustServerCertificate=true", + //"Hangfire": "Server=3.226.182.187,1435;Database=US_Uat_IRC_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true" }, "ObjectStoreService": { - "ObjectStoreUse": "MinIO", - - "AliyunOSS": { - "regionId": "cn-shanghai", - "internalEndpoint": "https://oss-cn-shanghai-internal.aliyuncs.com", - "endPoint": "https://oss-cn-shanghai.aliyuncs.com", - "accessKeyId": "LTAI5tKvzs7ed3UfSpNk3xwQ", - "accessKeySecret": "zTIceGEShlZDGnLrCFfIGFE7TXVRio", - "bucketName": "zy-irc-test-store", - "roleArn": "acs:ram::1899121822495495:role/oss-upload", - "viewEndpoint": "https://zy-irc-test-store.oss-cn-shanghai.aliyuncs.com", - "region": "oss-cn-shanghai" - }, + "ObjectStoreUse": "AWS", "MinIO": { - //"endPoint": "hir-oss.us.extimaging.com", + //"endPoint": "hir-minio.uat.elevateimaging.ai", //"port": "443", //"useSSL": true, - //"viewEndpoint": "https://hir-oss.us.extimaging.com/hir-us", + //"viewEndpoint": "https://hir-minio.uat.elevateimaging.ai/uat-irc-us", - "endPoint": "44.218.11.19", + "endPoint": "3.226.182.187", "port": "9001", "useSSL": false, "viewEndpoint": "http://44.218.11.19:9001/uat-irc-us", @@ -50,10 +38,10 @@ "AWS": { "endPoint": "s3.us-east-1.amazonaws.com", "useSSL": true, - "accessKey": "AKIAZQ3DRSOHFPJJ6FEU", - "secretKey": "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", - "bucketName": "ei-irc-test-store", - "viewEndpoint": "https://ei-irc-test-store.s3.amazonaws.com/" + "accessKey": "AKIAW3MEAFJXUO6XYFYN", + "secretKey": "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", + "bucketName": "ei-med-s3-lili-uat-store", + "viewEndpoint": "https://ei-med-s3-lili-uat-store.s3.amazonaws.com/" } }, "BasicSystemConfig": { @@ -73,7 +61,9 @@ "ContinuousReadingTimeMin": 120, - "ReadingRestTimeMin": 10 + "ReadingRestTimeMin": 10, + + "OpenLoginMFA": true }, "SystemEmailSendConfig": { From 6c9c8ee5dc0a05d12163c385e6cf232a142a5ac3 Mon Sep 17 00:00:00 2001 From: he <109787524@qq.com> Date: Mon, 29 Jul 2024 14:00:40 +0800 Subject: [PATCH 123/251] =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Service/Reading/Dto/ReadingClinicalDataDto.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/IRaCIS.Core.Application/Service/Reading/Dto/ReadingClinicalDataDto.cs b/IRaCIS.Core.Application/Service/Reading/Dto/ReadingClinicalDataDto.cs index 6f2d364bb..4b665a371 100644 --- a/IRaCIS.Core.Application/Service/Reading/Dto/ReadingClinicalDataDto.cs +++ b/IRaCIS.Core.Application/Service/Reading/Dto/ReadingClinicalDataDto.cs @@ -190,10 +190,10 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto /// public int Size { get; set; } = 0; - /// - /// 文件类型 - /// - public string Type { get; set; } + /// + /// 文件类型 + /// + public string Type { get; set; } = string.Empty; } From 55bb70179c8082af602cbf6cc6fdbf4133ffcc4d Mon Sep 17 00:00:00 2001 From: he <109787524@qq.com> Date: Mon, 29 Jul 2024 14:19:03 +0800 Subject: [PATCH 124/251] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Service/Reading/ClinicalData/ReadingClinicalDataService.cs | 3 ++- .../Service/Reading/Dto/ReadingClinicalDataDto.cs | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs b/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs index 8670bd215..180d71815 100644 --- a/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs +++ b/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs @@ -759,7 +759,8 @@ namespace IRaCIS.Application.Services GetClinicalType=inDto.GetClinicalType, SubjectId=inDto.SubjectId, TrialId=inDto.TrialId, - ReadingId=inDto.ReadingId, + SelectIsSign=false, + ReadingId =inDto.ReadingId, TrialReadingCriterionId = inDto.TrialReadingCriterionId, }); var readingIds = result.Select(x => x.ReadingId).ToList(); diff --git a/IRaCIS.Core.Application/Service/Reading/Dto/ReadingClinicalDataDto.cs b/IRaCIS.Core.Application/Service/Reading/Dto/ReadingClinicalDataDto.cs index 4b665a371..59e9b85d1 100644 --- a/IRaCIS.Core.Application/Service/Reading/Dto/ReadingClinicalDataDto.cs +++ b/IRaCIS.Core.Application/Service/Reading/Dto/ReadingClinicalDataDto.cs @@ -233,7 +233,8 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto /// 只查询已经签名的临床数据 /// public bool SelectIsSign { get; set; } = true; - } + + } /// /// 获取访视列表 From 4f5d89732de27cb9ae0c24dae222d184166fb923 Mon Sep 17 00:00:00 2001 From: he <109787524@qq.com> Date: Mon, 29 Jul 2024 15:13:15 +0800 Subject: [PATCH 125/251] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E6=8F=90=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ReadingClinicalDataService.cs | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs b/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs index 180d71815..1ac7b3b8d 100644 --- a/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs +++ b/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs @@ -413,6 +413,55 @@ namespace IRaCIS.Application.Services return ResponseOutput.Result(result); } + /// + /// 一致性分析的临床数据 + /// + /// + /// + //public async Task ReadClinicalDataSign(ReadingClinicalDataSignIndto inDto) + //{ + + + // var data = await _readingClinicalDataRepository.FirstOrDefaultAsync(t => t.Id == inDto.ReadingClinicalDataId); + + // data.IsBlind = inDto.IsBlind; + // data.IsComplete = inDto.IsComplete; + // data.IsSign = true; + // data.ReadingClinicalDataState = ReadingClinicalDataStatus.HaveSigned; + + + + // var result = await _readingClinicalDataRepository.SaveChangesAsync(); + + + // var readingId = await _readingClinicalDataRepository.Where(x => x.Id == inDto.ReadingClinicalDataId).Select(x => x.ReadingId).FirstOrDefaultAsync(); + + + + // //如果先生成了任务,再签名subject级别 PM 临床数据,那么会导致其他标准的任务签名状态无法得到维护 + + // if (await _repository.AnyAsync(t => t.Id == data.ClinicalDataTrialSetId && t.UploadRole == UploadRole.PM && t.ClinicalDataLevel == ClinicalLevel.Subject)) + // { + // var needDealTrialReadingCriterionIdList = _repository.Where(t => t.Id == data.ClinicalDataTrialSetId) + // .SelectMany(t => t.TrialClinicalDataSetCriteriaList) + // .Select(u => u.TrialReadingCriterionId).Distinct().ToList(); + + // foreach (var trialReadingCriterionId in needDealTrialReadingCriterionIdList) + // { + // await DealVisiTaskClinicalDataSignedAsync(data.TrialId, data.SubjectId, data.ReadingId, data.IsVisit, trialReadingCriterionId); + // } + // } + // else + // { + // await DealVisiTaskClinicalDataSignedAsync(data.TrialId, data.SubjectId, data.ReadingId, data.IsVisit, inDto.TrialReadingCriterionId); + + // } + + + + // return ResponseOutput.Result(result); + //} + //处理 任务 临床数据是否签名 public async Task DealVisiTaskClinicalDataSignedAsync(Guid trialId, Guid subjectId, Guid readingId, bool isVisit, Guid trialReadingCritrialId) { From 3b92aaf61c583d8ea487322b06eaf68d163f287d Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Mon, 29 Jul 2024 16:24:34 +0800 Subject: [PATCH 126/251] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=9B=BD=E9=99=85?= =?UTF-8?q?=E5=8C=96=20=E5=92=8C=20scp=20=E7=BC=A9=E7=95=A5=E5=9B=BE?= =?UTF-8?q?=E6=97=A5=E5=BF=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRC.Core.SCP/Service/CStoreSCPService.cs | 4 + .../BackGroundJob/IRaCISCHangfireJob.cs | 89 +------------------ .../Helper/InternationalizationHelper.cs | 58 ++++++++---- 3 files changed, 47 insertions(+), 104 deletions(-) diff --git a/IRC.Core.SCP/Service/CStoreSCPService.cs b/IRC.Core.SCP/Service/CStoreSCPService.cs index 97c2b636c..eb369a966 100644 --- a/IRC.Core.SCP/Service/CStoreSCPService.cs +++ b/IRC.Core.SCP/Service/CStoreSCPService.cs @@ -331,6 +331,10 @@ namespace IRaCIS.Core.SCP.Service } } + else + { + Log.Logger.Information($"ImageResizePath:{series.ImageResizePath} and series is null:{series == null} "); + } await _seriesRepository.SaveChangesAsync(); } diff --git a/IRaCIS.Core.Application/BackGroundJob/IRaCISCHangfireJob.cs b/IRaCIS.Core.Application/BackGroundJob/IRaCISCHangfireJob.cs index f135121b6..514df5174 100644 --- a/IRaCIS.Core.Application/BackGroundJob/IRaCISCHangfireJob.cs +++ b/IRaCIS.Core.Application/BackGroundJob/IRaCISCHangfireJob.cs @@ -25,8 +25,6 @@ namespace IRaCIS.Application.Services.BackGroundJob { public static string JsonFileFolder = Path.Combine(AppContext.BaseDirectory, StaticData.Folder.Resources); - public static FileSystemWatcher FileSystemWatcher_US { get; set; } - public static FileSystemWatcher FileSystemWatcher_CN { get; set; } private readonly IRepository _trialRepository; private readonly IEasyCachingProvider _provider; private readonly ILogger _logger; @@ -62,7 +60,7 @@ namespace IRaCIS.Application.Services.BackGroundJob //初始化 - await InitInternationlizationDataAndWatchJsonFileAsync(); + await InternationalizationHelper.InitInternationlizationDataAndWatchJsonFileAsync(_internationalizationRepository); //创建邮件定时任务 await InitSysAndTrialCronJobAsync(); @@ -96,93 +94,8 @@ namespace IRaCIS.Application.Services.BackGroundJob } - #region 国际化 初始化 - public async Task InitInternationlizationDataAndWatchJsonFileAsync() - { - //查询数据库的数据 - var toJsonList = await _internationalizationRepository.Where(t => t.InternationalizationType == 1).Select(t => new - { - t.Code, - t.Value, - t.ValueCN - }).ToListAsync(); - - //组织成json 文件 - - var usJsonPath = Path.Combine(JsonFileFolder, StaticData.En_US_Json); - var cnJsonPath = Path.Combine(JsonFileFolder, StaticData.Zh_CN_Json); - - - //本地静态文件国际化需要 - foreach (var tojsonItem in toJsonList) - { - StaticData.En_US_Dic[tojsonItem.Code] = tojsonItem.Value; - StaticData.Zh_CN_Dic[tojsonItem.Code] = tojsonItem.ValueCN; - } - - File.WriteAllText(usJsonPath, JsonConvert.SerializeObject(StaticData.En_US_Dic)); - File.WriteAllText(cnJsonPath, JsonConvert.SerializeObject(StaticData.Zh_CN_Dic)); - - - //监测Json文件变更 实时刷新数据 - - if (!File.Exists(usJsonPath)|| !File.Exists(cnJsonPath)) - { - throw new BusinessValidationFailedException(StaticData.International("IRaCISCHangfireJob_FileNotFound")); - } - - FileSystemWatcher_US = new FileSystemWatcher - { - Path = Path.GetDirectoryName(usJsonPath)!, - NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.Size, - Filter = Path.GetFileName(usJsonPath), - EnableRaisingEvents = true, - - }; - // 添加文件更改事件的处理程序 - FileSystemWatcher_US.Changed += (sender, e) => LoadJsonFile(StaticData.Folder.Resources+"\\"+ StaticData.En_US_Json); - - - FileSystemWatcher_CN = new FileSystemWatcher - { - Path = Path.GetDirectoryName(cnJsonPath)!, - NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.Size, - Filter = Path.GetFileName(cnJsonPath), - EnableRaisingEvents = true, - - }; - FileSystemWatcher_CN.Changed += (sender, e) => LoadJsonFile(StaticData.Folder.Resources + "\\" + StaticData.Zh_CN_Json); - - } - - - - - private void LoadJsonFile(string filePath) - { - Console.WriteLine("刷新json内存数据"); - IConfigurationBuilder builder = new ConfigurationBuilder().AddJsonFile(filePath,false,false); - - IConfigurationRoot enConfiguration = builder.Build(); - - foreach (IConfigurationSection section in enConfiguration.GetChildren()) - { - if (filePath.Contains(StaticData.En_US_Json)) - { - StaticData.En_US_Dic[section.Key] = section.Value; - - } - else - { - StaticData.Zh_CN_Dic[section.Key] = section.Value; - } - } - } - - #endregion - public async Task InitSysAndTrialCronJobAsync() { //var deleteJobIdList = await _trialEmailNoticeConfigRepository.Where(t => t.Trial.TrialStatusStr != StaticData.TrialState.TrialOngoing && t.EmailCron != string.Empty && t.IsAutoSend) diff --git a/IRaCIS.Core.Application/Helper/InternationalizationHelper.cs b/IRaCIS.Core.Application/Helper/InternationalizationHelper.cs index 5d3bfb633..11159c5cd 100644 --- a/IRaCIS.Core.Application/Helper/InternationalizationHelper.cs +++ b/IRaCIS.Core.Application/Helper/InternationalizationHelper.cs @@ -18,6 +18,9 @@ namespace IRaCIS.Core.Application.Helper { public static string JsonFileFolder = Path.Combine(AppContext.BaseDirectory, StaticData.Folder.Resources); + public static FileSystemWatcher FileSystemWatcher_US { get; set; } + public static FileSystemWatcher FileSystemWatcher_CN { get; set; } + private static void VerifyFolder() { if (!Directory.Exists(JsonFileFolder) || @@ -107,10 +110,11 @@ namespace IRaCIS.Core.Application.Helper } - public static async Task InitInternationlizationDataAndWatchJsonFileAsync(IRepository _repository) + + public static async Task InitInternationlizationDataAndWatchJsonFileAsync(IRepository _internationalizationRepository) { //查询数据库的数据 - var toJsonList = await _repository.Where(t => t.InternationalizationType == 1).Select(t => new + var toJsonList = await _internationalizationRepository.Where(t => t.InternationalizationType == 1).Select(t => new { t.Code, t.Value, @@ -136,29 +140,45 @@ namespace IRaCIS.Core.Application.Helper //监测Json文件变更 实时刷新数据 - WatchJsonFile(usJsonPath); - WatchJsonFile(cnJsonPath); - - } - - public static void WatchJsonFile(string filePath) - { - if (!File.Exists(filePath)) + if (!File.Exists(usJsonPath) || !File.Exists(cnJsonPath)) { - throw new BusinessValidationFailedException("国际化Json文件不存在"); + throw new BusinessValidationFailedException(StaticData.International("IRaCISCHangfireJob_FileNotFound")); } - FileSystemWatcher watcher = new FileSystemWatcher(Path.GetDirectoryName(filePath), Path.GetFileName(filePath)); - watcher.Changed += (sender, e) => LoadJsonFile(filePath); - watcher.EnableRaisingEvents = true; + + // //监测Json文件变更 实时刷新数据 + + + FileSystemWatcher_US = new FileSystemWatcher + { + Path = Path.GetDirectoryName(usJsonPath)!, + NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.Size, + Filter = Path.GetFileName(usJsonPath), + EnableRaisingEvents = true, + + }; + // 添加文件更改事件的处理程序 + FileSystemWatcher_US.Changed += (sender, e) => LoadJsonFile(StaticData.Folder.Resources + "\\" + StaticData.En_US_Json); + + + FileSystemWatcher_CN = new FileSystemWatcher + { + Path = Path.GetDirectoryName(cnJsonPath)!, + NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.Size, + Filter = Path.GetFileName(cnJsonPath), + EnableRaisingEvents = true, + + }; + FileSystemWatcher_CN.Changed += (sender, e) => LoadJsonFile(StaticData.Folder.Resources + "\\" + StaticData.Zh_CN_Json); } + private static void LoadJsonFile(string filePath) { - - IConfigurationBuilder builder = new ConfigurationBuilder().AddJsonFile(filePath); + Console.WriteLine("刷新json内存数据"); + IConfigurationBuilder builder = new ConfigurationBuilder().AddJsonFile(filePath, false, false); IConfigurationRoot enConfiguration = builder.Build(); @@ -175,5 +195,11 @@ namespace IRaCIS.Core.Application.Helper } } } + + + + + + } } From 942f3adfe0ee54d2c483a47f2e8fcb4f7ac2d8c7 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Mon, 29 Jul 2024 16:33:00 +0800 Subject: [PATCH 127/251] =?UTF-8?q?=E4=BF=AE=E6=94=B9scp=20=E4=B8=8A?= =?UTF-8?q?=E4=BC=A0bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRC.Core.SCP/Service/CStoreSCPService.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/IRC.Core.SCP/Service/CStoreSCPService.cs b/IRC.Core.SCP/Service/CStoreSCPService.cs index eb369a966..fa73a773b 100644 --- a/IRC.Core.SCP/Service/CStoreSCPService.cs +++ b/IRC.Core.SCP/Service/CStoreSCPService.cs @@ -256,8 +256,9 @@ namespace IRaCIS.Core.SCP.Service string seriesInstanceUid = request.Dataset.GetString(DicomTag.SeriesInstanceUID); string sopInstanceUid = request.Dataset.GetString(DicomTag.SOPInstanceUID); - Guid seriesId = IdentifierHelper.CreateGuid(studyInstanceUid, seriesInstanceUid); - Guid instanceId = IdentifierHelper.CreateGuid(studyInstanceUid, seriesInstanceUid, sopInstanceUid); + //Guid studyId = IdentifierHelper.CreateGuid(studyInstanceUid, trialId.ToString()); + Guid seriesId = IdentifierHelper.CreateGuid(studyInstanceUid, seriesInstanceUid, _trialId.ToString()); + Guid instanceId = IdentifierHelper.CreateGuid(studyInstanceUid, seriesInstanceUid, sopInstanceUid, _trialId.ToString()); var ossService = _serviceProvider.GetService(); From 8c94e17c1495c78a57a6adaf6813fd40ede923f9 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Mon, 29 Jul 2024 16:33:35 +0800 Subject: [PATCH 128/251] =?UTF-8?q?=E5=88=A0=E9=99=A4=E6=8F=90=E7=A4=BA?= =?UTF-8?q?=E8=AF=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRC.Core.SCP/Service/CStoreSCPService.cs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/IRC.Core.SCP/Service/CStoreSCPService.cs b/IRC.Core.SCP/Service/CStoreSCPService.cs index fa73a773b..539e24b36 100644 --- a/IRC.Core.SCP/Service/CStoreSCPService.cs +++ b/IRC.Core.SCP/Service/CStoreSCPService.cs @@ -332,10 +332,7 @@ namespace IRaCIS.Core.SCP.Service } } - else - { - Log.Logger.Information($"ImageResizePath:{series.ImageResizePath} and series is null:{series == null} "); - } + await _seriesRepository.SaveChangesAsync(); } From 633507d4cdae54f6d8020f9fc408278cae2883d8 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Mon, 29 Jul 2024 17:59:01 +0800 Subject: [PATCH 129/251] =?UTF-8?q?k8s=20=20docker=20=E6=8C=82=E8=BD=BD?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E6=96=87=E4=BB=B6=E7=83=AD=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E9=97=AE=E9=A2=98=E8=A7=A3=E5=86=B3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.API/IRaCIS.Core.API.csproj | 1 + IRaCIS.Core.API/Progranm.cs | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/IRaCIS.Core.API/IRaCIS.Core.API.csproj b/IRaCIS.Core.API/IRaCIS.Core.API.csproj index a434c6d2b..8bdddbe5f 100644 --- a/IRaCIS.Core.API/IRaCIS.Core.API.csproj +++ b/IRaCIS.Core.API/IRaCIS.Core.API.csproj @@ -64,6 +64,7 @@ + true diff --git a/IRaCIS.Core.API/Progranm.cs b/IRaCIS.Core.API/Progranm.cs index 885b11f66..50cb855b4 100644 --- a/IRaCIS.Core.API/Progranm.cs +++ b/IRaCIS.Core.API/Progranm.cs @@ -76,8 +76,8 @@ if (urlsIndex > -1) NewId.SetProcessIdProvider(new CurrentProcessIdProvider()); -builder.Configuration.AddJsonFile("appsettings.json", false, true) - .AddJsonFile($"appsettings.{enviromentName}.json", false, true); +builder.Configuration.AddJsonFile(ConfigMapFileProvider.FromRelativePath(""), "appsettings.json", false, true) + .AddJsonFile(ConfigMapFileProvider.FromRelativePath(""), $"appsettings.{enviromentName}.json", false, true); builder.Host .UseServiceProviderFactory(new AutofacServiceProviderFactory()) From fd9af4760674d83d482ba301512e6fa1b54e72da Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Tue, 30 Jul 2024 09:51:48 +0800 Subject: [PATCH 130/251] =?UTF-8?q?=E9=AA=8C=E8=AF=81=E7=A0=81=E4=BF=AE?= =?UTF-8?q?=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.Application/Service/Common/MailService.cs | 8 ++++---- .../Service/Management/UserService.cs | 11 ++++++++++- .../Service/SiteSurvey/TrialSiteSurveyService.cs | 7 +++++++ 3 files changed, 21 insertions(+), 5 deletions(-) diff --git a/IRaCIS.Core.Application/Service/Common/MailService.cs b/IRaCIS.Core.Application/Service/Common/MailService.cs index 7850b7e38..e2da0075e 100644 --- a/IRaCIS.Core.Application/Service/Common/MailService.cs +++ b/IRaCIS.Core.Application/Service/Common/MailService.cs @@ -190,7 +190,7 @@ namespace IRaCIS.Application.Services messageToSend = await GetEmailSubejctAndHtmlInfoAndBuildAsync(mfaType == UserMFAType.Login ? EmailBusinessScenario.MFALogin : EmailBusinessScenario.MFAUnlock, messageToSend, emailConfigFunc); - var sucessHandle = GetEmailSuccessHandle(userId, verificationCode); + var sucessHandle = GetEmailSuccessHandle(userId, verificationCode, emailAddress); await SendEmailHelper.SendEmailAsync(messageToSend, _systemEmailConfig, sucessHandle); @@ -229,7 +229,7 @@ namespace IRaCIS.Application.Services messageToSend = await GetEmailSubejctAndHtmlInfoAndBuildAsync(EmailBusinessScenario.UserResetEmail, messageToSend, emailConfigFunc); - var sucessHandle = GetEmailSuccessHandle(userId, verificationCode); + var sucessHandle = GetEmailSuccessHandle(userId, verificationCode, emailAddress); await SendEmailHelper.SendEmailAsync(messageToSend, _systemEmailConfig, sucessHandle); @@ -269,7 +269,7 @@ namespace IRaCIS.Application.Services messageToSend = await GetEmailSubejctAndHtmlInfoAndBuildAsync(EmailBusinessScenario.UnloginUseEmailResetPassword, messageToSend, emailConfigFunc); ////此时不知道用户 - var sucessHandle = GetEmailSuccessHandle(Guid.Empty, verificationCode); + var sucessHandle = GetEmailSuccessHandle(Guid.Empty, verificationCode, emailAddress); await SendEmailHelper.SendEmailAsync(messageToSend, _systemEmailConfig, sucessHandle); @@ -355,7 +355,7 @@ namespace IRaCIS.Application.Services messageToSend = await GetEmailSubejctAndHtmlInfoAndBuildAsync(EmailBusinessScenario.SiteSurveyLogin, messageToSend, emailConfigFunc); //此时不知道用户 - var sucessHandle = GetEmailSuccessHandle(Guid.Empty, verificationCode); + var sucessHandle = GetEmailSuccessHandle(Guid.Empty, verificationCode, emailAddress); await SendEmailHelper.SendEmailAsync(messageToSend, _systemEmailConfig, sucessHandle); diff --git a/IRaCIS.Core.Application/Service/Management/UserService.cs b/IRaCIS.Core.Application/Service/Management/UserService.cs index 151b5c907..f103313cf 100644 --- a/IRaCIS.Core.Application/Service/Management/UserService.cs +++ b/IRaCIS.Core.Application/Service/Management/UserService.cs @@ -208,6 +208,11 @@ namespace IRaCIS.Application.Services return ResponseOutput.NotOk(_localizer["User_VerificationCodeExpired"]); } + else if (verificationRecord.EmailOrPhone.Trim() != newEmail.Trim()) + { + //发送验证嘛的和提交的邮箱不一致 + return ResponseOutput.NotOk(_localizer["User_VerificationEmailNotSameWithBefore"]); + } else //验证码正确 并且 没有超时 { @@ -684,7 +689,7 @@ namespace IRaCIS.Application.Services [AllowAnonymous] public async Task VerifyMFACodeAsync(Guid userId, string Code) { - var verificationRecord = await _repository.GetQueryable().OrderByDescending(x => x.ExpirationTime).Where(t => t.UserId == userId && t.Code == Code && t.CodeType == VerifyType.Email).FirstOrDefaultAsync(); + var verificationRecord = await _verificationCodeRepository.Where(t => t.UserId == userId && t.Code == Code && t.CodeType == VerifyType.Email).OrderByDescending(x => x.ExpirationTime).FirstOrDefaultAsync(); VerifyEmialGetDoctorInfoOutDto result = new VerifyEmialGetDoctorInfoOutDto(); //检查数据库是否存在该验证码 @@ -707,6 +712,10 @@ namespace IRaCIS.Application.Services } else //验证码正确 并且 没有超时 { + + + //删除验证码历史记录 + await _verificationCodeRepository.BatchDeleteNoTrackingAsync(t => t.Id == verificationRecord.Id); await _userLogRepository.AddAsync(new UserLog() { IP = _userInfo.IP, LoginUserId = userId, OptUserId = userId, OptType = UserOptType.MFALogin }, true); } diff --git a/IRaCIS.Core.Application/Service/SiteSurvey/TrialSiteSurveyService.cs b/IRaCIS.Core.Application/Service/SiteSurvey/TrialSiteSurveyService.cs index 9ff013fac..2665746ff 100644 --- a/IRaCIS.Core.Application/Service/SiteSurvey/TrialSiteSurveyService.cs +++ b/IRaCIS.Core.Application/Service/SiteSurvey/TrialSiteSurveyService.cs @@ -117,6 +117,10 @@ namespace IRaCIS.Core.Application.Contracts } else //验证码正确 并且 没有超时 { + + //删除验证码历史记录 + await _repository.BatchDeleteAsync(t => t.Id == verificationRecord.Id); + var dockerInfo = await _repository.Where(t => t.EMail == inDto.EmailOrPhone || t.Phone == inDto.EmailOrPhone).FirstOrDefaultAsync(); if (dockerInfo != null) @@ -192,6 +196,9 @@ namespace IRaCIS.Core.Application.Contracts } else { + //删除验证码历史记录 + await _repository.BatchDeleteAsync(t => t.Id == verifyRecord.Id); + //验证码正确 不处理 } From e36dd04d3e4f21a8a834257c9975d7a8b2a9e2fc Mon Sep 17 00:00:00 2001 From: he <109787524@qq.com> Date: Tue, 30 Jul 2024 11:19:17 +0800 Subject: [PATCH 131/251] =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Service/ImageAndDoc/DTO/DicomSeriesModel.cs | 4 ++++ IRaCIS.Core.Application/Service/Visit/SubjectVisitService.cs | 3 ++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/IRaCIS.Core.Application/Service/ImageAndDoc/DTO/DicomSeriesModel.cs b/IRaCIS.Core.Application/Service/ImageAndDoc/DTO/DicomSeriesModel.cs index c95598753..155bc42ad 100644 --- a/IRaCIS.Core.Application/Service/ImageAndDoc/DTO/DicomSeriesModel.cs +++ b/IRaCIS.Core.Application/Service/ImageAndDoc/DTO/DicomSeriesModel.cs @@ -79,6 +79,10 @@ namespace IRaCIS.Core.Application.Contracts.Dicom.DTO public int InstanceNumber { get; set; } + public Guid? StudyId { get; set; } + + public Guid? SeriesId { get; set; } + [JsonIgnore] public int ShowOrder { get; set; } [JsonIgnore] diff --git a/IRaCIS.Core.Application/Service/Visit/SubjectVisitService.cs b/IRaCIS.Core.Application/Service/Visit/SubjectVisitService.cs index 3f8ab4aec..26020ecf5 100644 --- a/IRaCIS.Core.Application/Service/Visit/SubjectVisitService.cs +++ b/IRaCIS.Core.Application/Service/Visit/SubjectVisitService.cs @@ -637,7 +637,8 @@ namespace IRaCIS.Core.Application.Services HtmlPath = k.HtmlPath, Path = k.Path, InstanceNumber = k.InstanceNumber, - + StudyId = k.StudyId, + SeriesId = k.SeriesId, }).ToListAsync(); item.InstanceInfoList.ForEach(x => From ee4b4a62acf35677592449c48a66f25e66f3f53b Mon Sep 17 00:00:00 2001 From: he <109787524@qq.com> Date: Tue, 30 Jul 2024 11:30:16 +0800 Subject: [PATCH 132/251] =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Service/ImageAndDoc/DTO/DicomSeriesModel.cs | 4 ---- IRaCIS.Core.Application/Service/Visit/SubjectVisitService.cs | 2 -- 2 files changed, 6 deletions(-) diff --git a/IRaCIS.Core.Application/Service/ImageAndDoc/DTO/DicomSeriesModel.cs b/IRaCIS.Core.Application/Service/ImageAndDoc/DTO/DicomSeriesModel.cs index 155bc42ad..c95598753 100644 --- a/IRaCIS.Core.Application/Service/ImageAndDoc/DTO/DicomSeriesModel.cs +++ b/IRaCIS.Core.Application/Service/ImageAndDoc/DTO/DicomSeriesModel.cs @@ -79,10 +79,6 @@ namespace IRaCIS.Core.Application.Contracts.Dicom.DTO public int InstanceNumber { get; set; } - public Guid? StudyId { get; set; } - - public Guid? SeriesId { get; set; } - [JsonIgnore] public int ShowOrder { get; set; } [JsonIgnore] diff --git a/IRaCIS.Core.Application/Service/Visit/SubjectVisitService.cs b/IRaCIS.Core.Application/Service/Visit/SubjectVisitService.cs index 26020ecf5..c997b8cec 100644 --- a/IRaCIS.Core.Application/Service/Visit/SubjectVisitService.cs +++ b/IRaCIS.Core.Application/Service/Visit/SubjectVisitService.cs @@ -637,8 +637,6 @@ namespace IRaCIS.Core.Application.Services HtmlPath = k.HtmlPath, Path = k.Path, InstanceNumber = k.InstanceNumber, - StudyId = k.StudyId, - SeriesId = k.SeriesId, }).ToListAsync(); item.InstanceInfoList.ForEach(x => From f9fc79d3aa32b843c60a372c1cc9bb4ec255c1bd Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Tue, 30 Jul 2024 11:50:33 +0800 Subject: [PATCH 133/251] =?UTF-8?q?=E7=94=A8=E6=88=B7=E5=8F=8D=E9=A6=88?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3=E5=88=9D=E6=AD=A5=E5=AE=8C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Management/DTO/UserFeedBackViewModel.cs | 97 +++++++++++++++++++ .../Interface/IUserFeedBackService.cs | 24 +++++ .../Service/Management/UserFeedBackService.cs | 89 +++++++++++++++++ .../Service/Management/_MapConfig.cs | 12 +++ IRaCIS.Core.Domain/Management/UserFeedBack.cs | 77 +++++++++++++++ .../Context/IRaCISDBContext.cs | 2 + IRaCIS.Core.Test/DbHelper.ttinclude | 2 +- 7 files changed, 302 insertions(+), 1 deletion(-) create mode 100644 IRaCIS.Core.Application/Service/Management/DTO/UserFeedBackViewModel.cs create mode 100644 IRaCIS.Core.Application/Service/Management/Interface/IUserFeedBackService.cs create mode 100644 IRaCIS.Core.Application/Service/Management/UserFeedBackService.cs create mode 100644 IRaCIS.Core.Domain/Management/UserFeedBack.cs diff --git a/IRaCIS.Core.Application/Service/Management/DTO/UserFeedBackViewModel.cs b/IRaCIS.Core.Application/Service/Management/DTO/UserFeedBackViewModel.cs new file mode 100644 index 000000000..5635af438 --- /dev/null +++ b/IRaCIS.Core.Application/Service/Management/DTO/UserFeedBackViewModel.cs @@ -0,0 +1,97 @@ +//-------------------------------------------------------------------- +// 此代码由T4模板自动生成 byzhouhang 20210918 +// 生成时间 2024-07-30 10:39:12 +// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。 +//-------------------------------------------------------------------- +using System; +using IRaCIS.Core.Domain.Share; +using System.Collections.Generic; +using Newtonsoft.Json; +using System.ComponentModel.DataAnnotations; +namespace IRaCIS.Core.Application.ViewModel +{ + /// UserFeedBackView 列表视图模型 + public class UserFeedBackView : UserFeedBackAddOrEdit + { + public string TrialCode { get; set; } + + public string ExperimentName { get; set; } + + public string SubjectCode { get; set; } + + public string TrialSiteCode { get; set; } + + public string SubjectVisitName { get; set; } + + + public string FeedBackUserName { get; set; } + + public string FeedBackFullName { get; set; } + + + public DateTime CreateTime { get; set; } + public DateTime UpdateTime { get; set; } + + public UserTypeEnum UserTypeEnum { get; set; } + } + + ///UserFeedBackQuery 列表查询参数模型 + public class UserFeedBackQuery : PageInput + { + + public string? TrialKeyInfo { get; set; } + + public string? SubejctAndVisitKeyInfo { get; set; } + + public UserTypeEnum? UserTypeEnum { get; set; } + + public string FeedBackKeyInfo { get; set; } + + public string? QuestionDescription { get; set; } + + public int? QuestionType { get; set; } + + public int? State { get; set; } + + public string? TrialSiteCode { get; set; } + + public DateTime? BeginCreatime { get; set; } + + public DateTime? EndCreatime { get; set; } + + + + } + + /// UserFeedBackAddOrEdit 列表查询参数模型 + public class UserFeedBackAddOrEdit + { + public Guid? Id { get; set; } + public Guid? SubjectId { get; set; } + public Guid? SubjectVisitId { get; set; } + public int QuestionType { get; set; } + public string QuestionDescription { get; set; } + + public int State { get; set; } + public Guid? TrialSiteId { get; set; } + + [NotDefault] + public Guid TrialId { get; set; } + + public List ScreenshotList { get; set; } + + [JsonIgnore] + public string ScreenshotListStr { get; set; } + } + + + public class BatchUpdateCommand + { + public List IdList { get; set; } + + public int State { get; set; } + } + +} + + diff --git a/IRaCIS.Core.Application/Service/Management/Interface/IUserFeedBackService.cs b/IRaCIS.Core.Application/Service/Management/Interface/IUserFeedBackService.cs new file mode 100644 index 000000000..6fa7976a3 --- /dev/null +++ b/IRaCIS.Core.Application/Service/Management/Interface/IUserFeedBackService.cs @@ -0,0 +1,24 @@ +//-------------------------------------------------------------------- +// 此代码由T4模板自动生成 byzhouhang 20210918 +// 生成时间 2024-07-30 10:39:05 +// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。 +//-------------------------------------------------------------------- + +using IRaCIS.Core.Application.ViewModel; +namespace IRaCIS.Core.Application.Interfaces +{ + /// + /// IUserFeedBackService + /// + public interface IUserFeedBackService + { + + Task> GetUserFeedBackList(UserFeedBackQuery inQuery); + + Task AddOrUpdateUserFeedBack(UserFeedBackAddOrEdit addOrEditUserFeedBack); + + Task DeleteUserFeedBack(Guid userFeedBackId); + + + } +} diff --git a/IRaCIS.Core.Application/Service/Management/UserFeedBackService.cs b/IRaCIS.Core.Application/Service/Management/UserFeedBackService.cs new file mode 100644 index 000000000..e21a818fe --- /dev/null +++ b/IRaCIS.Core.Application/Service/Management/UserFeedBackService.cs @@ -0,0 +1,89 @@ +//-------------------------------------------------------------------- +// 此代码由T4模板自动生成 byzhouhang 20210918 +// 生成时间 2024-07-30 10:39:09 +// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。 +//-------------------------------------------------------------------- + +using IRaCIS.Core.Domain.Models; +using Microsoft.AspNetCore.Mvc; +using IRaCIS.Core.Application.Interfaces; +using IRaCIS.Core.Application.ViewModel; +using Newtonsoft.Json; +namespace IRaCIS.Core.Application.Service +{ + /// + /// UserFeedBackService + /// + [ApiExplorerSettings(GroupName = "Management")] + public class UserFeedBackService : BaseService, IUserFeedBackService + { + + private readonly IRepository _userFeedBackRepository; + + public UserFeedBackService(IRepository userFeedBackRepository) + { + _userFeedBackRepository = userFeedBackRepository; + } + + [HttpPost] + public async Task> GetUserFeedBackList(UserFeedBackQuery inQuery) + { + + var userFeedBackQueryable = _userFeedBackRepository + .WhereIf(inQuery.State != null, t => t.State == inQuery.State) + .WhereIf(inQuery.QuestionType != null, t => t.QuestionType == inQuery.QuestionType) + .WhereIf(inQuery.BeginCreatime != null, t => t.CreateTime >= inQuery.BeginCreatime) + + .WhereIf(inQuery.EndCreatime != null, t => t.CreateTime == inQuery.EndCreatime) + .WhereIf(inQuery.UserTypeEnum != null, t => t.CreateUser.UserTypeEnum == inQuery.UserTypeEnum) + .WhereIf(!string.IsNullOrEmpty(inQuery.QuestionDescription), t => t.QuestionDescription.Contains(inQuery.QuestionDescription) ) + .WhereIf(!string.IsNullOrEmpty(inQuery.TrialKeyInfo), t => t.Trial.ExperimentName.Contains(inQuery.TrialKeyInfo) || t.Trial.TrialCode.Contains(inQuery.TrialKeyInfo)) + .WhereIf(!string.IsNullOrEmpty(inQuery.SubejctAndVisitKeyInfo), t => t.Subject.Code.Contains(inQuery.SubejctAndVisitKeyInfo) || t.SubjectVisit.VisitName.Contains(inQuery.SubejctAndVisitKeyInfo)) + .WhereIf(!string.IsNullOrEmpty(inQuery.TrialSiteCode), t => t.TrialSite.TrialSiteCode.Contains(inQuery.TrialSiteCode) ) + + .ProjectTo(_mapper.ConfigurationProvider); + + var pageList = await userFeedBackQueryable + + .ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, string.IsNullOrWhiteSpace(inQuery.SortField) ? nameof(UserFeedBackView.Id) : inQuery.SortField, + inQuery.Asc); + + return pageList; + } + + + public async Task AddOrUpdateUserFeedBack(UserFeedBackAddOrEdit addOrEditUserFeedBack) + { + addOrEditUserFeedBack.ScreenshotListStr = JsonConvert.SerializeObject(addOrEditUserFeedBack.ScreenshotList); + + + var entity = await _userFeedBackRepository.InsertOrUpdateAsync(addOrEditUserFeedBack, true); + + return ResponseOutput.Ok(entity.Id.ToString()); + + } + + /// + /// 批量更新状态 + /// + /// + /// + [HttpPut] + public async Task BatchUpdateFeedBackState(BatchUpdateCommand batchUpdateCommand) + { + await _userFeedBackRepository.BatchUpdateNoTrackingAsync(t => batchUpdateCommand.IdList.Contains(t.Id), u => new UserFeedBack() { State = batchUpdateCommand.State }); + + return ResponseOutput.Ok(); + } + + + [HttpDelete("{userFeedBackId:guid}")] + public async Task DeleteUserFeedBack(Guid userFeedBackId) + { + var success = await _userFeedBackRepository.DeleteFromQueryAsync(t => t.Id == userFeedBackId, true); + return ResponseOutput.Ok(); + } + + + } +} diff --git a/IRaCIS.Core.Application/Service/Management/_MapConfig.cs b/IRaCIS.Core.Application/Service/Management/_MapConfig.cs index 744c906a8..5619e7127 100644 --- a/IRaCIS.Core.Application/Service/Management/_MapConfig.cs +++ b/IRaCIS.Core.Application/Service/Management/_MapConfig.cs @@ -125,6 +125,18 @@ namespace IRaCIS.Core.Application.Service .ForMember(d => d.OptUserName, c => c.MapFrom(t => t.OptUser.UserName)) .ForMember(d => d.OptUserTypeEnum, c => c.MapFrom(t => t.OptUser.UserTypeEnum)) ; + + + CreateMap() + .ForMember(d => d.ExperimentName, c => c.MapFrom(t => t.Trial.ExperimentName)) + .ForMember(d => d.TrialCode, c => c.MapFrom(t => t.Trial.TrialCode)) + .ForMember(d => d.SubjectCode, c => c.MapFrom(t => t.Subject.Code)) + .ForMember(d => d.TrialSiteCode, c => c.MapFrom(t => t.TrialSite.TrialSiteCode)) + .ForMember(d => d.SubjectVisitName, c => c.MapFrom(t => t.SubjectVisit.VisitName)) + .ForMember(d => d.FeedBackUserName, c => c.MapFrom(t => t.CreateUser.UserName)) + .ForMember(d => d.FeedBackFullName, c => c.MapFrom(t => t.CreateUser.FullName)) + .ForMember(d => d.UserTypeEnum, c => c.MapFrom(t => t.CreateUser.UserTypeEnum)); + CreateMap().ReverseMap(); } } diff --git a/IRaCIS.Core.Domain/Management/UserFeedBack.cs b/IRaCIS.Core.Domain/Management/UserFeedBack.cs new file mode 100644 index 000000000..d9ec5f7bb --- /dev/null +++ b/IRaCIS.Core.Domain/Management/UserFeedBack.cs @@ -0,0 +1,77 @@ + +//-------------------------------------------------------------------- +// 此代码由T4模板自动生成 byzhouhang 20210918 +// 生成时间 2024-07-30 10:39:01 +// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。 +using System; +using IRaCIS.Core.Domain.Share; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; +using System.Collections.Generic; +namespace IRaCIS.Core.Domain.Models +{ + /// + ///UserFeedBack + /// + [Table("UserFeedBack")] + public class UserFeedBack : Entity, IAuditUpdate, IAuditAdd + { + [JsonIgnore] + public Trial Trial { get; set; } + [JsonIgnore] + public Subject Subject { get; set; } + [JsonIgnore] + public SubjectVisit SubjectVisit { get; set; } + [JsonIgnore] + public TrialSite TrialSite { get; set; } + [JsonIgnore] + public User CreateUser { get; set; } + + public Guid? SubjectId { get; set; } + + + public Guid? SubjectVisitId { get; set; } + + + public int QuestionType { get; set; } + + public string QuestionDescription { get; set; } + + + public Guid CreateUserId { get; set; } + + + public DateTime CreateTime { get; set; } + + + public Guid UpdateUserId { get; set; } + + + public DateTime UpdateTime { get; set; } + + + public int State { get; set; } + + + public Guid? TrialSiteId { get; set; } + + + public Guid TrialId { get; set; } + + public string ScreenshotListStr { get; set; } + + // + [NotMapped] + public List ScreenshotList => JsonConvert.DeserializeObject>(ScreenshotListStr); + + + + //public class ScreenshotInfo + //{ + // public string Path { get; set; } + + // public string Name { get; set; } + //} + + } + } diff --git a/IRaCIS.Core.Infra.EFCore/Context/IRaCISDBContext.cs b/IRaCIS.Core.Infra.EFCore/Context/IRaCISDBContext.cs index f4dcffdd9..f81edd5f5 100644 --- a/IRaCIS.Core.Infra.EFCore/Context/IRaCISDBContext.cs +++ b/IRaCIS.Core.Infra.EFCore/Context/IRaCISDBContext.cs @@ -495,6 +495,8 @@ namespace IRaCIS.Core.Infra.EFCore public virtual DbSet SCPImageUpload { get; set; } + public virtual DbSet UserFeedBack { get; set; } + public override async Task SaveChangesAsync(CancellationToken cancellationToken = new CancellationToken()) { diff --git a/IRaCIS.Core.Test/DbHelper.ttinclude b/IRaCIS.Core.Test/DbHelper.ttinclude index 8790fcb50..d33e52c37 100644 --- a/IRaCIS.Core.Test/DbHelper.ttinclude +++ b/IRaCIS.Core.Test/DbHelper.ttinclude @@ -4,7 +4,7 @@ public static readonly string ConnectionString = "Server=106.14.89.110,1435;Database=Test_IRC;User ID=sa;Password=xc@123456;TrustServerCertificate=true"; public static readonly string DbDatabase = "Test_IRC"; //表名称用字符串,拼接 - public static readonly string TableName = "TrialSiteDicomAE"; + public static readonly string TableName = "UserFeedBack"; //具体文件里面 例如service 可以配置是否分页 } #> From e9a90a4c3a54fb0aba3cc9b9a10513d9b1df9978 Mon Sep 17 00:00:00 2001 From: he <109787524@qq.com> Date: Tue, 30 Jul 2024 14:15:50 +0800 Subject: [PATCH 134/251] =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Service/ImageAndDoc/DTO/DicomSeriesModel.cs | 4 ++++ IRaCIS.Core.Application/Service/Visit/SubjectVisitService.cs | 2 ++ 2 files changed, 6 insertions(+) diff --git a/IRaCIS.Core.Application/Service/ImageAndDoc/DTO/DicomSeriesModel.cs b/IRaCIS.Core.Application/Service/ImageAndDoc/DTO/DicomSeriesModel.cs index c95598753..155bc42ad 100644 --- a/IRaCIS.Core.Application/Service/ImageAndDoc/DTO/DicomSeriesModel.cs +++ b/IRaCIS.Core.Application/Service/ImageAndDoc/DTO/DicomSeriesModel.cs @@ -79,6 +79,10 @@ namespace IRaCIS.Core.Application.Contracts.Dicom.DTO public int InstanceNumber { get; set; } + public Guid? StudyId { get; set; } + + public Guid? SeriesId { get; set; } + [JsonIgnore] public int ShowOrder { get; set; } [JsonIgnore] diff --git a/IRaCIS.Core.Application/Service/Visit/SubjectVisitService.cs b/IRaCIS.Core.Application/Service/Visit/SubjectVisitService.cs index c997b8cec..071d8bf8b 100644 --- a/IRaCIS.Core.Application/Service/Visit/SubjectVisitService.cs +++ b/IRaCIS.Core.Application/Service/Visit/SubjectVisitService.cs @@ -637,6 +637,8 @@ namespace IRaCIS.Core.Application.Services HtmlPath = k.HtmlPath, Path = k.Path, InstanceNumber = k.InstanceNumber, + StudyId= k.StudyId, + SeriesId= k.SeriesId, }).ToListAsync(); item.InstanceInfoList.ForEach(x => From 8b05c01e423001bb858266e7ead172d0301fcf86 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Tue, 30 Jul 2024 15:12:11 +0800 Subject: [PATCH 135/251] =?UTF-8?q?=E9=80=9A=E8=BF=87=E9=85=8D=E7=BD=AEapi?= =?UTF-8?q?=20=E6=8E=A5=E5=8F=A3=EF=BC=8C=E8=87=AA=E5=8A=A8=E5=B0=86Result?= =?UTF-8?q?=20=E8=BF=9B=E8=A1=8C=E5=8A=A0=E5=AF=86=E8=BF=94=E5=9B=9E?= =?UTF-8?q?=EF=BC=8C=E5=90=8C=E6=97=B6code=E8=BF=94=E5=9B=9E12=E6=A0=87?= =?UTF-8?q?=E6=B3=A8=20=E7=9B=AE=E5=89=8D=E4=BD=BF=E7=94=A8base64?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.API/Progranm.cs | 11 +-- IRaCIS.Core.API/appsettings.json | 7 ++ .../BusinessFilter/EncreptApiResultFilter.cs | 71 +++++++++++++++++++ .../BusinessFilter/UnifiedApiResultFilter.cs | 16 +---- IRaCIS.Core.Domain/_Config/_AppSettings.cs | 26 ++++--- .../_IRaCIS/Output/ApiResponseCodeEnum.cs | 4 +- .../_IRaCIS/Output/IResponseOutput.cs | 2 +- .../_IRaCIS/Output/ResponseOutput.cs | 2 +- 8 files changed, 109 insertions(+), 30 deletions(-) create mode 100644 IRaCIS.Core.Application/BusinessFilter/EncreptApiResultFilter.cs diff --git a/IRaCIS.Core.API/Progranm.cs b/IRaCIS.Core.API/Progranm.cs index 50cb855b4..40ffb2743 100644 --- a/IRaCIS.Core.API/Progranm.cs +++ b/IRaCIS.Core.API/Progranm.cs @@ -28,6 +28,7 @@ using FellowOakDicom.Network; using IRaCIS.Core.Application.Service.ImageAndDoc; using IP2Region.Net.Abstractions; using IP2Region.Net.XDB; +using IRaCIS.Core.Application.BusinessFilter; #region 获取环境变量 @@ -104,11 +105,9 @@ builder.Services.AddControllers(options => options.Filters.Add(); options.Filters.Add(); options.Filters.Add(); + options.Filters.Add(10); + options.Filters.Add(); - if (_configuration.GetSection("BasicSystemConfig").GetValue("OpenLoginLimit")) - { - options.Filters.Add(); - } }) .AddNewtonsoftJsonSetup(builder.Services); // NewtonsoftJson 序列化 处理 @@ -117,6 +116,8 @@ builder.Services.AddOptions().Configure(_configuration.Ge builder.Services.AddOptions().Configure(_configuration.GetSection("BasicSystemConfig")); builder.Services.AddOptions().Configure(_configuration.GetSection("AliyunOSS")); builder.Services.AddOptions().Configure(_configuration.GetSection("ObjectStoreService")); +builder.Services.AddOptions().Configure(_configuration.GetSection("EncrypteResponseConfig")); + //动态WebApi + UnifiedApiResultFilter 省掉控制器代码 @@ -297,7 +298,7 @@ try - var server = DicomServerFactory.Create(11112,userState: app.Services); + var server = DicomServerFactory.Create(11112, userState: app.Services); app.Run(); diff --git a/IRaCIS.Core.API/appsettings.json b/IRaCIS.Core.API/appsettings.json index b6d0f4125..59dd671c2 100644 --- a/IRaCIS.Core.API/appsettings.json +++ b/IRaCIS.Core.API/appsettings.json @@ -92,5 +92,12 @@ "DefaultPassword": "123456", "DefaultInternalOrganizationName": "ExtImaging", "ImageShareExpireDays": 10 + }, + + "EncrypteResponseConfig": { + "IsEnable": true, + "ApiPathList": [ + "/test/get" + ] } } \ No newline at end of file diff --git a/IRaCIS.Core.Application/BusinessFilter/EncreptApiResultFilter.cs b/IRaCIS.Core.Application/BusinessFilter/EncreptApiResultFilter.cs new file mode 100644 index 000000000..fd58ae885 --- /dev/null +++ b/IRaCIS.Core.Application/BusinessFilter/EncreptApiResultFilter.cs @@ -0,0 +1,71 @@ +using IRaCIS.Core.Domain.Share; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.Filters; +using Microsoft.Extensions.Options; +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace IRaCIS.Core.Application.BusinessFilter +{ + public class EncreptApiResultFilter : IAsyncResultFilter + { + + private readonly IOptionsMonitor _encreptResponseMonitor; + + public EncreptApiResultFilter(IOptionsMonitor encreptResponseMonitor) + { + _encreptResponseMonitor = encreptResponseMonitor; + } + + public async Task OnResultExecutionAsync(ResultExecutingContext context, ResultExecutionDelegate next) + { + + if(_encreptResponseMonitor.CurrentValue.IsEnable) + { + + if (context.Result is ObjectResult objectResult) + { + var statusCode = objectResult.StatusCode ?? context.HttpContext.Response.StatusCode; + + var objectValue = objectResult.Value; + + + if (objectValue is IResponseOutput) + { + var responseOutput = objectValue as IResponseOutput; + + var path = context.HttpContext?.Request.Path.Value?.ToLower(); + + + if(!string.IsNullOrEmpty(path) && path.Length>5 && _encreptResponseMonitor.CurrentValue.ApiPathList.Contains(path.ToLower())) + { + + if(responseOutput.IsSuccess) + { + responseOutput.Code = ApiResponseCodeEnum.ResultEncrepted; + responseOutput.Data = JsonConvert.SerializeObject(Convert.ToBase64String(Encoding.UTF8.GetBytes(responseOutput.Data.ToString()))); + + objectResult.Value = responseOutput; + } + + } + + } + + + + } + } + + + + + await next.Invoke(); + + } + } +} diff --git a/IRaCIS.Core.Application/BusinessFilter/UnifiedApiResultFilter.cs b/IRaCIS.Core.Application/BusinessFilter/UnifiedApiResultFilter.cs index a41c659b1..9e5fdf591 100644 --- a/IRaCIS.Core.Application/BusinessFilter/UnifiedApiResultFilter.cs +++ b/IRaCIS.Core.Application/BusinessFilter/UnifiedApiResultFilter.cs @@ -8,8 +8,9 @@ namespace IRaCIS.Application.Services.BusinessFilter /// 统一返回前端数据包装,之前在控制器包装,现在修改为动态Api 在ResultFilter这里包装,减少重复冗余代码 /// by zhouhang 2021.09.12 周末 /// - public class UnifiedApiResultFilter : Attribute, IAsyncResultFilter - { + public class UnifiedApiResultFilter : Attribute, IAsyncResultFilter + { + /// /// 异步版本 /// @@ -26,15 +27,6 @@ namespace IRaCIS.Application.Services.BusinessFilter //是200 并且没有包装 那么包装结果 if (statusCode == 200 && !(objectResult.Value is IResponseOutput)) { - //if (objectResult.Value == null) - //{ - // var apiResponse = ResponseOutput.DBNotExist(); - - // objectResult.Value = apiResponse; - // objectResult.DeclaredType = apiResponse.GetType(); - //} - //else - //{ var type = objectResult.Value?.GetType(); @@ -64,8 +56,6 @@ namespace IRaCIS.Application.Services.BusinessFilter objectResult.DeclaredType = apiResponse.GetType(); } - - //} } //如果不是200 是IResponseOutput 不处理 diff --git a/IRaCIS.Core.Domain/_Config/_AppSettings.cs b/IRaCIS.Core.Domain/_Config/_AppSettings.cs index 80aed90e8..a4833050b 100644 --- a/IRaCIS.Core.Domain/_Config/_AppSettings.cs +++ b/IRaCIS.Core.Domain/_Config/_AppSettings.cs @@ -1,6 +1,7 @@ using IRaCIS.Core.Domain.Models; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration.Json; +using System.Collections.Generic; namespace IRaCIS.Core.Domain.Share { @@ -19,7 +20,7 @@ namespace IRaCIS.Core.Domain.Share public int LoginMaxFailCount { get; set; } - public int LoginFailLockMinutes { get; set; } + public int LoginFailLockMinutes { get; set; } public int AutoLoginOutMinutes { get; set; } @@ -39,9 +40,9 @@ namespace IRaCIS.Core.Domain.Share public class SystemEmailSendConfig { - public int Port { get; set; } + public int Port { get; set; } - public string Host { get; set; } + public string Host { get; set; } public string FromEmail { get; set; } @@ -66,6 +67,13 @@ namespace IRaCIS.Core.Domain.Share } + public class EncreptResponseOption + { + public bool IsEnable { get; set; } + + public List ApiPathList { get; set; } + } + /// /// 项目基础配置规则 @@ -89,7 +97,7 @@ namespace IRaCIS.Core.Domain.Share public static string SystemSiteCodePrefix { get; set; } - public static string BlindTaskPrefix { get; set; } + public static string BlindTaskPrefix { get; set; } /// /// 用户默认密码 @@ -104,7 +112,7 @@ namespace IRaCIS.Core.Domain.Share { Path = "appsettings.json", ReloadOnChange = true - }) + }) .Build(); DoctorCodePrefix = configuration.GetSection("IRaCISBasicConfig").GetValue("DoctorCodePrefix"); @@ -112,7 +120,7 @@ namespace IRaCIS.Core.Domain.Share QCChallengeCodePrefix = configuration.GetSection("IRaCISBasicConfig").GetValue("QCChallengeCodePrefix"); NoneDicomStudyCodePrefix = configuration.GetSection("IRaCISBasicConfig").GetValue("NoneDicomStudyCodePrefix"); DicomStudyCodePrefix = configuration.GetSection("IRaCISBasicConfig").GetValue("DicomStudyCodePrefix"); - DefaultPassword= configuration.GetSection("IRaCISBasicConfig").GetValue("DefaultPassword"); + DefaultPassword = configuration.GetSection("IRaCISBasicConfig").GetValue("DefaultPassword"); SystemSiteCodePrefix = configuration.GetSection("IRaCISBasicConfig").GetValue("SystemSiteCodePrefix"); DefaultInternalOrganizationName = configuration.GetSection("IRaCISBasicConfig").GetValue("DefaultInternalOrganizationName"); @@ -125,7 +133,7 @@ namespace IRaCIS.Core.Domain.Share //获取实体编码字符串 - public static string GetCodeStr(int codeInt ,string typeStr) + public static string GetCodeStr(int codeInt, string typeStr) { switch (typeStr) { @@ -139,7 +147,7 @@ namespace IRaCIS.Core.Domain.Share case nameof(QCChallenge): - return QCChallengeCodePrefix+ codeInt.ToString("D5"); + return QCChallengeCodePrefix + codeInt.ToString("D5"); case nameof(NoneDicomStudy): @@ -164,5 +172,5 @@ namespace IRaCIS.Core.Domain.Share } - + } \ No newline at end of file diff --git a/IRaCIS.Core.Infrastructure/_IRaCIS/Output/ApiResponseCodeEnum.cs b/IRaCIS.Core.Infrastructure/_IRaCIS/Output/ApiResponseCodeEnum.cs index 459ea65fb..a2d88b1c8 100644 --- a/IRaCIS.Core.Infrastructure/_IRaCIS/Output/ApiResponseCodeEnum.cs +++ b/IRaCIS.Core.Infrastructure/_IRaCIS/Output/ApiResponseCodeEnum.cs @@ -54,7 +54,9 @@ namespace IRaCIS.Core.Infrastructure.Extention NoToken = 10, //带了Token,但是没有相应权限(该用户类型不能做) - HaveTokenNotAccess = 11 + HaveTokenNotAccess = 11, + + ResultEncrepted=12 } diff --git a/IRaCIS.Core.Infrastructure/_IRaCIS/Output/IResponseOutput.cs b/IRaCIS.Core.Infrastructure/_IRaCIS/Output/IResponseOutput.cs index 9c713a8a0..13b15698a 100644 --- a/IRaCIS.Core.Infrastructure/_IRaCIS/Output/IResponseOutput.cs +++ b/IRaCIS.Core.Infrastructure/_IRaCIS/Output/IResponseOutput.cs @@ -27,7 +27,7 @@ /// /// 返回数据 /// - T Data { get; } + T Data { get; set; } } //public interface IResponseOutput : IResponseOutput diff --git a/IRaCIS.Core.Infrastructure/_IRaCIS/Output/ResponseOutput.cs b/IRaCIS.Core.Infrastructure/_IRaCIS/Output/ResponseOutput.cs index af255eeb2..74325db91 100644 --- a/IRaCIS.Core.Infrastructure/_IRaCIS/Output/ResponseOutput.cs +++ b/IRaCIS.Core.Infrastructure/_IRaCIS/Output/ResponseOutput.cs @@ -25,7 +25,7 @@ namespace IRaCIS.Core.Infrastructure.Extention /// 数据 兼顾以前 Json序列化的时候返回属性名为“Result” /// [JsonProperty("Result")] - public T Data { get; private set; } + public T Data { get; set; } [JsonProperty("OtherInfo")] From d602238f829d23f3ba5ea775e691c57dd2779a09 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Tue, 30 Jul 2024 16:03:35 +0800 Subject: [PATCH 136/251] =?UTF-8?q?hangfire=20=E4=BB=BB=E5=8A=A1=E8=B0=83?= =?UTF-8?q?=E5=BA=A6=E9=9A=90=E6=82=A3=E6=8E=92=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.API/IRaCIS.Core.API.csproj | 1 + .../_ServiceExtensions/hangfireSetup.cs | 35 ++++++++++++------- 2 files changed, 24 insertions(+), 12 deletions(-) diff --git a/IRaCIS.Core.API/IRaCIS.Core.API.csproj b/IRaCIS.Core.API/IRaCIS.Core.API.csproj index 8bdddbe5f..5a7be3fe9 100644 --- a/IRaCIS.Core.API/IRaCIS.Core.API.csproj +++ b/IRaCIS.Core.API/IRaCIS.Core.API.csproj @@ -71,6 +71,7 @@ + diff --git a/IRaCIS.Core.API/_ServiceExtensions/hangfireSetup.cs b/IRaCIS.Core.API/_ServiceExtensions/hangfireSetup.cs index 00b718e2c..e2dc37494 100644 --- a/IRaCIS.Core.API/_ServiceExtensions/hangfireSetup.cs +++ b/IRaCIS.Core.API/_ServiceExtensions/hangfireSetup.cs @@ -3,6 +3,7 @@ using Hangfire.SqlServer; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using System; +using System.Runtime.InteropServices; namespace IRaCIS.Core.API { @@ -14,19 +15,29 @@ namespace IRaCIS.Core.API services.AddHangfire(hangFireConfig => { - - //hangFireConfig.UseInMemoryStorage(); - - //指定存储介质 - hangFireConfig.UseSqlServerStorage(hangFireConnStr, new SqlServerStorageOptions() + //本地window 调试 使用内存,服务器部署使用数据库,防止服务器任务调度到本地 + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { - SchemaName = "dbo", - CommandBatchMaxTimeout = TimeSpan.FromMinutes(5), - SlidingInvisibilityTimeout = TimeSpan.FromMinutes(5), - QueuePollInterval = TimeSpan.Zero, - UseRecommendedIsolationLevel = true, - DisableGlobalLocks = true - }); + hangFireConfig.UseInMemoryStorage(); + + } + else + { + //指定存储介质 + hangFireConfig.UseSqlServerStorage(hangFireConnStr, new SqlServerStorageOptions() + { + SchemaName = "dbo", + CommandBatchMaxTimeout = TimeSpan.FromMinutes(5), + SlidingInvisibilityTimeout = TimeSpan.FromMinutes(5), + QueuePollInterval = TimeSpan.Zero, + UseRecommendedIsolationLevel = true, + DisableGlobalLocks = true + }); + } + + + + //hangFireConfig.UseTagsWithSql(); //nuget引入Hangfire.Tags.SqlServer //.UseHangfireHttpJob(); From a2ca3a82459fdb649ee0c00d84caeddd41ab07ec Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Wed, 31 Jul 2024 09:25:54 +0800 Subject: [PATCH 137/251] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E9=82=AE=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.Application/Service/Common/MailService.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/IRaCIS.Core.Application/Service/Common/MailService.cs b/IRaCIS.Core.Application/Service/Common/MailService.cs index e2da0075e..e34361d6f 100644 --- a/IRaCIS.Core.Application/Service/Common/MailService.cs +++ b/IRaCIS.Core.Application/Service/Common/MailService.cs @@ -256,7 +256,7 @@ namespace IRaCIS.Application.Services var htmlBodyStr = string.Format(ReplaceCompanyName(input.htmlBodyStr), - "", + "Sir/Madam", //---您正在进行邮箱重置密码操作 _localizer["Mail_ResettingPassword"], verificationCode @@ -300,7 +300,7 @@ namespace IRaCIS.Application.Services var htmlBodyStr = string.Format(ReplaceCompanyName(input.htmlBodyStr), - "Sir or Madam", + "Sir/Madam", //---您正在参与展影医疗IRC项目 _localizer["Mail_IRCProject", companyName], verificationCode @@ -342,7 +342,7 @@ namespace IRaCIS.Application.Services var htmlBodyStr = string.Format(ReplaceCompanyName(input.htmlBodyStr), - "Sir or Madam", + "Sir/Madam", //---您正在参与展影医疗IRC项目中心调研工作 _localizer["Mail_CenterResearchReminder", companyName], verificationCode From 48cba9499511ff9b1ec875f3ea35f2fa9892d7b1 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Wed, 31 Jul 2024 09:35:33 +0800 Subject: [PATCH 138/251] =?UTF-8?q?=E9=82=AE=E4=BB=B6=E7=A7=B0=E5=91=BC?= =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.Application/Service/Common/MailService.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/IRaCIS.Core.Application/Service/Common/MailService.cs b/IRaCIS.Core.Application/Service/Common/MailService.cs index 7850b7e38..190d0446a 100644 --- a/IRaCIS.Core.Application/Service/Common/MailService.cs +++ b/IRaCIS.Core.Application/Service/Common/MailService.cs @@ -256,7 +256,7 @@ namespace IRaCIS.Application.Services var htmlBodyStr = string.Format(ReplaceCompanyName(input.htmlBodyStr), - "", + "Sir/Madam", //---您正在进行邮箱重置密码操作 _localizer["Mail_ResettingPassword"], verificationCode @@ -300,7 +300,7 @@ namespace IRaCIS.Application.Services var htmlBodyStr = string.Format(ReplaceCompanyName(input.htmlBodyStr), - "Sir or Madam", + "Sir/Madam", //---您正在参与展影医疗IRC项目 _localizer["Mail_IRCProject", companyName], verificationCode @@ -342,7 +342,7 @@ namespace IRaCIS.Application.Services var htmlBodyStr = string.Format(ReplaceCompanyName(input.htmlBodyStr), - "Sir or Madam", + "Sir/Madam", //---您正在参与展影医疗IRC项目中心调研工作 _localizer["Mail_CenterResearchReminder", companyName], verificationCode From 52b60338c341bd441d1ec685f5eaac045d1697f7 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Wed, 31 Jul 2024 10:01:48 +0800 Subject: [PATCH 139/251] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E9=9A=90=E8=97=8F?= =?UTF-8?q?=E9=82=AE=E7=AE=B1=E7=9A=84=E7=AE=97=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Controllers/ExtraController.cs | 21 ++------- .../Helper/EmailMaskHelper.cs | 44 +++++++++++++++++++ .../Service/Management/UserService.cs | 4 +- IRaCIS.Core.Application/TestService.cs | 7 ++- 4 files changed, 55 insertions(+), 21 deletions(-) create mode 100644 IRaCIS.Core.Application/Helper/EmailMaskHelper.cs diff --git a/IRaCIS.Core.API/Controllers/ExtraController.cs b/IRaCIS.Core.API/Controllers/ExtraController.cs index 97804aa3e..95fba4ab5 100644 --- a/IRaCIS.Core.API/Controllers/ExtraController.cs +++ b/IRaCIS.Core.API/Controllers/ExtraController.cs @@ -32,6 +32,7 @@ using IRaCIS.Core.Application.Contracts; using LoginReturnDTO = IRaCIS.Application.Contracts.LoginReturnDTO; using DocumentFormat.OpenXml.Spreadsheet; using AutoMapper.QueryableExtensions; +using NetTopologySuite.Algorithm; namespace IRaCIS.Api.Controllers { @@ -108,7 +109,7 @@ namespace IRaCIS.Api.Controllers { //MFA 邮箱验证 前端传递用户Id 和MFACode - if (loginUser.UserId != null && _verifyConfig.CurrentValue.OpenLoginMFA) + if (loginUser.UserId != null && _verifyConfig.CurrentValue.OpenLoginMFA) { Guid userId = (Guid)loginUser.UserId; @@ -226,23 +227,7 @@ namespace IRaCIS.Api.Controllers var email = returnModel.Data.BasicInfo.EMail; - #region 隐藏Email - // 找到 "@" 符号的位置 - int atIndex = email.IndexOf('@'); - - // 替换 "@" 符号前的中间两位为星号 - string visiblePart = email.Substring(0, atIndex); - - int startIndex = (visiblePart.Length - 2) / 2; - - // 替换中间两位字符为星号 - string hiddenPartBeforeAt = visiblePart.Substring(0, startIndex) + "**" + visiblePart.Substring(startIndex + 2); - - string afterAt = email.Substring(atIndex + 1); - - // 组合隐藏和可见部分 - string hiddenEmail = hiddenPartBeforeAt + "@" + afterAt; - #endregion + var hiddenEmail = EmailMaskHelper.MaskEmail(email); returnModel.Data.BasicInfo.EMail = hiddenEmail; diff --git a/IRaCIS.Core.Application/Helper/EmailMaskHelper.cs b/IRaCIS.Core.Application/Helper/EmailMaskHelper.cs new file mode 100644 index 000000000..027c74523 --- /dev/null +++ b/IRaCIS.Core.Application/Helper/EmailMaskHelper.cs @@ -0,0 +1,44 @@ +using NPOI.SS.Formula.Functions; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace IRaCIS.Core.Application.Helper +{ + public static class EmailMaskHelper + { + + //显示位数:3分之2的位数,向上取整 + //取哪几个个值:最后一位和前面几位 + //其他:3个***。 + //比如:hlj23@126.com + //为:hlj***3@126.com + + //he@126.com + //为:h*** e@126.com + + public static string MaskEmail(string email) + { + + // 找到 "@" 符号的位置 + int atIndex = email.IndexOf('@'); + + string visiblePartBefore = email.Substring(0, atIndex); + + string afterAt = email.Substring(atIndex + 1); + + int visibleLength = (int)Math.Ceiling((double)visiblePartBefore.Length * 2 / 3); + + // 替换中间两位字符为星号 + string hiddenPartBeforeAt = visiblePartBefore.Substring(0, visibleLength - 1) + "***" + visiblePartBefore.Last(); + + + // 组合隐藏和可见部分 + string hiddenEmail = hiddenPartBeforeAt + "@" + afterAt; + + return hiddenEmail; + } + } +} diff --git a/IRaCIS.Core.Application/Service/Management/UserService.cs b/IRaCIS.Core.Application/Service/Management/UserService.cs index f103313cf..7aab3e7b6 100644 --- a/IRaCIS.Core.Application/Service/Management/UserService.cs +++ b/IRaCIS.Core.Application/Service/Management/UserService.cs @@ -18,6 +18,7 @@ using LoginReturnDTO = IRaCIS.Application.Contracts.LoginReturnDTO; using IRaCIS.Core.Application.Auth; using BeetleX.Redis.Commands; using IRaCIS.Core.Domain.Models; +using IRaCIS.Core.Application.Helper; namespace IRaCIS.Application.Services { @@ -676,7 +677,8 @@ namespace IRaCIS.Application.Services await _mailVerificationService.SenMFAVerifyEmail(userId, userInfo.FullName, userInfo.EMail, verificationCode, (UserMFAType)mfaType); - return ResponseOutput.Ok(); + var hiddenEmail = EmailMaskHelper.MaskEmail(userInfo.EMail); + return ResponseOutput.Ok(hiddenEmail); } /// diff --git a/IRaCIS.Core.Application/TestService.cs b/IRaCIS.Core.Application/TestService.cs index f00d2ac7a..08fbc3a60 100644 --- a/IRaCIS.Core.Application/TestService.cs +++ b/IRaCIS.Core.Application/TestService.cs @@ -261,9 +261,12 @@ namespace IRaCIS.Application.Services [AllowAnonymous] - public async Task testwwwww([FromServices] IWebHostEnvironment env) + public async Task testEmail([FromServices] IWebHostEnvironment env ,string email) { - await Task.CompletedTask; + + var hiddenEmail = EmailMaskHelper.MaskEmail(email); + + return hiddenEmail; } From 63c225fb9b69ba2005e499a9129bdb7f84e36ad3 Mon Sep 17 00:00:00 2001 From: he <109787524@qq.com> Date: Wed, 31 Jul 2024 10:40:40 +0800 Subject: [PATCH 140/251] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Allocation/VisitTaskHelpeService.cs | 2 +- .../ReadingClinicalDataService.cs | 51 ++++++++++++++++++- 2 files changed, 51 insertions(+), 2 deletions(-) diff --git a/IRaCIS.Core.Application/Service/Allocation/VisitTaskHelpeService.cs b/IRaCIS.Core.Application/Service/Allocation/VisitTaskHelpeService.cs index 8c7eec7c7..4a3627320 100644 --- a/IRaCIS.Core.Application/Service/Allocation/VisitTaskHelpeService.cs +++ b/IRaCIS.Core.Application/Service/Allocation/VisitTaskHelpeService.cs @@ -1425,7 +1425,7 @@ namespace IRaCIS.Core.Application.Service var taskState = exsitPDF ? TaskState.NotEffect : TaskState.Effect; - var clinicalDataList = _readingClinicalDataRepository.Where(t => t.SubjectId == subjectId).Include(t => t.ReadingClinicalDataPDFList).Include(t=>t.ClinicalDataTrialSet).ToList(); + var clinicalDataList = _readingClinicalDataRepository.Where(t => t.SubjectId == subjectId&&t.ClinicalDataTrialSet.ClinicalUploadType == ClinicalUploadType.PDF).Include(t => t.ReadingClinicalDataPDFList).Include(t=>t.ClinicalDataTrialSet).ToList(); foreach (var clinicalData in clinicalDataList) { diff --git a/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs b/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs index 1ac7b3b8d..5d89812c9 100644 --- a/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs +++ b/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs @@ -1071,7 +1071,56 @@ namespace IRaCIS.Application.Services } #endregion - + + + #region 一致性分析 + /// + /// 获取阅片临床数据列表 + /// + /// + /// + [HttpPost] + public async Task<(List, object)> GetConsistencyAnalysisReadingClinicalDataList(GetReadingClinicalDataListIndto inDto) + { + + + + + var isBaseLine = await _subjectVisitRepository.AnyAsync(x => x.Id == inDto.ReadingId && x.IsBaseLine); + + + var result = await this.GetClinicalDataList(new GetReadingOrTaskClinicalDataListInDto() + { + ClinicalDataTrialSetId = inDto.ClinicalDataTrialSetId, + GetClinicalType = inDto.GetClinicalType, + SubjectId = inDto.SubjectId, + TrialId = inDto.TrialId, + SelectIsSign = false, + ReadingId = inDto.ReadingId, + TrialReadingCriterionId = inDto.TrialReadingCriterionId, + }); + var readingIds = result.Select(x => x.ReadingId).ToList(); + + var previousHistoryList = await _previousHistoryRepository.Where(x => readingIds.Contains(x.SubjectVisitId)).ProjectTo(_mapper.ConfigurationProvider).ToListAsync(); + var previousOtherList = await _previousOtherRepository.Where(x => readingIds.Contains(x.SubjectVisitId)).ProjectTo(_mapper.ConfigurationProvider).ToListAsync(); + var previousSurgeryList = await _previousSurgeryRepository.Where(x => readingIds.Contains(x.SubjectVisitId)).ProjectTo(_mapper.ConfigurationProvider).ToListAsync(); + foreach (var item in result) + { + item.ClinicalTableData = new ClinicalDataTable() + { + PreviousHistoryList = previousHistoryList.Where(x => x.ClinicalDataTrialSetId == item.ClinicalDataTrialSetId).ToList(), + PreviousOtherList = previousOtherList.Where(x => x.ClinicalDataTrialSetId == item.ClinicalDataTrialSetId).ToList(), + PreviousSurgeryList = previousSurgeryList.Where(x => x.ClinicalDataTrialSetId == item.ClinicalDataTrialSetId).ToList(), + }; + + } + + return (result, new + { + IsCanAddClinicalData = false, + }); + } + #endregion #region 阅片临床数据PDF From 81aa7fb8ef6fbdb869b0551af84f822c6e3b63d0 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Wed, 31 Jul 2024 13:42:49 +0800 Subject: [PATCH 141/251] =?UTF-8?q?=E4=B8=8A=E4=BC=A0=E5=86=8D=E6=AC=A1?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=88=A4=E6=96=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Service/ImageAndDoc/StudyService.cs | 24 +++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/IRaCIS.Core.Application/Service/ImageAndDoc/StudyService.cs b/IRaCIS.Core.Application/Service/ImageAndDoc/StudyService.cs index 5bf595a63..e3bac406e 100644 --- a/IRaCIS.Core.Application/Service/ImageAndDoc/StudyService.cs +++ b/IRaCIS.Core.Application/Service/ImageAndDoc/StudyService.cs @@ -145,6 +145,22 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })] public async Task AddOrUpdateArchiveStudy(NewArchiveStudyCommand incommand) { + + var @uploadLock = _distributedLockProvider.CreateLock($"UploadDicom"); + + using (await @uploadLock.AcquireAsync()) + { + if (_provider.Exists($"StudyUid_{incommand.TrialId}_{incommand.Study.StudyInstanceUid}")) + { + //---当前已有人正在上传和归档该检查! + return ResponseOutput.NotOk(StaticData.International("UploadDownLoad_ArchiveInProgress")); + } + else + { + _provider.Set($"StudyUid_{incommand.TrialId}_{incommand.Study.StudyInstanceUid}", _userInfo.Id, TimeSpan.FromSeconds(30)); + } + } + var modalitys = string.Empty; try @@ -191,7 +207,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc study.SubjectVisitId = incommand.SubjectVisitId; //如果因为意外情况,连续点击两次,导致第一次插入了,第二次进来也会插入,在此判断一下 - var findStudy = await _dicomstudyRepository.FirstOrDefaultAsync(t => t.Id == study.Id); + var findStudy = await _dicomstudyRepository.FirstOrDefaultAsync(t => t.Id == study.Id); if (findStudy != null) { @@ -372,7 +388,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc VisitNum = t.SubjectVisit.VisitNum, IsDicom = true, - IsFromPACS=t.IsFromPACS, + IsFromPACS = t.IsFromPACS, SubjectCode = t.Subject.Code, @@ -422,7 +438,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc VisitNum = t.SubjectVisit.VisitNum, IsDicom = false, - IsFromPACS=false, + IsFromPACS = false, SubjectCode = t.Subject.Code, @@ -543,7 +559,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc path = (await _dicomInstanceRepository.Where(s => s.StudyId == studyId).Select(t => t.Path).FirstOrDefaultAsync()).IfNullThrowException(); - + using (var sw = ImageHelper.RenderPreviewJpeg(path)) { From ca41fac53d38c18e56aeb1421cfe80c158f9a0a6 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Wed, 31 Jul 2024 13:44:50 +0800 Subject: [PATCH 142/251] =?UTF-8?q?=E6=9C=89=E9=97=AE=E9=A2=98=EF=BC=8C?= =?UTF-8?q?=E6=92=A4=E5=9B=9E=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Service/ImageAndDoc/StudyService.cs | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/IRaCIS.Core.Application/Service/ImageAndDoc/StudyService.cs b/IRaCIS.Core.Application/Service/ImageAndDoc/StudyService.cs index e3bac406e..13a2857bb 100644 --- a/IRaCIS.Core.Application/Service/ImageAndDoc/StudyService.cs +++ b/IRaCIS.Core.Application/Service/ImageAndDoc/StudyService.cs @@ -146,20 +146,20 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc public async Task AddOrUpdateArchiveStudy(NewArchiveStudyCommand incommand) { - var @uploadLock = _distributedLockProvider.CreateLock($"UploadDicom"); + //var @uploadLock = _distributedLockProvider.CreateLock($"UploadDicom"); - using (await @uploadLock.AcquireAsync()) - { - if (_provider.Exists($"StudyUid_{incommand.TrialId}_{incommand.Study.StudyInstanceUid}")) - { - //---当前已有人正在上传和归档该检查! - return ResponseOutput.NotOk(StaticData.International("UploadDownLoad_ArchiveInProgress")); - } - else - { - _provider.Set($"StudyUid_{incommand.TrialId}_{incommand.Study.StudyInstanceUid}", _userInfo.Id, TimeSpan.FromSeconds(30)); - } - } + //using (await @uploadLock.AcquireAsync()) + //{ + // if (_provider.Exists($"StudyUid_{incommand.TrialId}_{incommand.Study.StudyInstanceUid}")) + // { + // //---当前已有人正在上传和归档该检查! + // return ResponseOutput.NotOk(StaticData.International("UploadDownLoad_ArchiveInProgress")); + // } + // else + // { + // _provider.Set($"StudyUid_{incommand.TrialId}_{incommand.Study.StudyInstanceUid}", _userInfo.Id, TimeSpan.FromSeconds(30)); + // } + //} var modalitys = string.Empty; From d3f7c199c7b917768fe9943573dbe6fac76bbfb0 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Wed, 31 Jul 2024 14:05:38 +0800 Subject: [PATCH 143/251] =?UTF-8?q?=E9=98=B2=E6=AD=A2=E5=89=8D=E7=AB=AF?= =?UTF-8?q?=E9=87=8D=E5=A4=8D=E4=B8=8A=E4=BC=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Service/ImageAndDoc/StudyService.cs | 28 ++++++++++--------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/IRaCIS.Core.Application/Service/ImageAndDoc/StudyService.cs b/IRaCIS.Core.Application/Service/ImageAndDoc/StudyService.cs index 13a2857bb..dbed0f7c8 100644 --- a/IRaCIS.Core.Application/Service/ImageAndDoc/StudyService.cs +++ b/IRaCIS.Core.Application/Service/ImageAndDoc/StudyService.cs @@ -146,20 +146,21 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc public async Task AddOrUpdateArchiveStudy(NewArchiveStudyCommand incommand) { - //var @uploadLock = _distributedLockProvider.CreateLock($"UploadDicom"); + var @uploadLock = _distributedLockProvider.CreateLock($"UploadDicom"); - //using (await @uploadLock.AcquireAsync()) - //{ - // if (_provider.Exists($"StudyUid_{incommand.TrialId}_{incommand.Study.StudyInstanceUid}")) - // { - // //---当前已有人正在上传和归档该检查! - // return ResponseOutput.NotOk(StaticData.International("UploadDownLoad_ArchiveInProgress")); - // } - // else - // { - // _provider.Set($"StudyUid_{incommand.TrialId}_{incommand.Study.StudyInstanceUid}", _userInfo.Id, TimeSpan.FromSeconds(30)); - // } - //} + using (await @uploadLock.AcquireAsync()) + { + if (_provider.Exists($"{incommand.TrialId}_{incommand.Study.StudyInstanceUid}")) + { + //---当前已有人正在上传和归档该检查! + return ResponseOutput.NotOk(StaticData.International("UploadDownLoad_ArchiveInProgress")); + } + else + { + //在事务未完成前 防止前端重复提交 + _provider.Set($"{incommand.TrialId}_{incommand.Study.StudyInstanceUid}", _userInfo.Id, TimeSpan.FromMinutes(3)); + } + } var modalitys = string.Empty; @@ -355,6 +356,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc finally { _provider.Remove($"StudyUid_{incommand.TrialId}_{incommand.Study.StudyInstanceUid}"); + _provider.Remove($"{incommand.TrialId}_{incommand.Study.StudyInstanceUid}"); } From aae243e36e331b9da3a7927b2280491e3c09a1d6 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Wed, 31 Jul 2024 15:08:28 +0800 Subject: [PATCH 144/251] =?UTF-8?q?=E9=A1=B9=E7=9B=AEdicom=20ae=20=20?= =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Service/TrialSiteUser/TrialDicomAEService.cs | 10 +++++++++- .../Service/Visit/DTO/PatientViewModel.cs | 2 ++ .../Service/Visit/PatientService.cs | 2 +- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/IRaCIS.Core.Application/Service/TrialSiteUser/TrialDicomAEService.cs b/IRaCIS.Core.Application/Service/TrialSiteUser/TrialDicomAEService.cs index 7c24b56c9..58d71629b 100644 --- a/IRaCIS.Core.Application/Service/TrialSiteUser/TrialDicomAEService.cs +++ b/IRaCIS.Core.Application/Service/TrialSiteUser/TrialDicomAEService.cs @@ -76,6 +76,14 @@ namespace IRaCIS.Core.Application.Service VerifyMsg = _localizer["TrialDicomAE_RepeatIPAndPort"] }; + var verifyExp2 = new EntityVerifyExp() + { + VerifyExp = u => u.IP == addOrEditDicomAE.CalledAE , + + //"AE名称不能与其他项目相同" + VerifyMsg = _localizer["TrialDicomAE_RepeatCalledAE"] + }; + //var verifyExp2 = new EntityVerifyExp() //{ // VerifyExp = u => u.TrialId == addOrEditDicomAE.TrialId, @@ -90,7 +98,7 @@ namespace IRaCIS.Core.Application.Service if (addOrEditDicomAE.IsPACSConnect) { // 在此处拷贝automapper 映射 - var entity = await _dicomAERepository.InsertOrUpdateAsync(addOrEditDicomAE, true, verifyExp1); + var entity = await _dicomAERepository.InsertOrUpdateAsync(addOrEditDicomAE, true, verifyExp1, verifyExp2); return ResponseOutput.Ok(entity.Id.ToString()); } diff --git a/IRaCIS.Core.Application/Service/Visit/DTO/PatientViewModel.cs b/IRaCIS.Core.Application/Service/Visit/DTO/PatientViewModel.cs index 178dc34b8..05d8d3fcc 100644 --- a/IRaCIS.Core.Application/Service/Visit/DTO/PatientViewModel.cs +++ b/IRaCIS.Core.Application/Service/Visit/DTO/PatientViewModel.cs @@ -954,6 +954,8 @@ namespace IRaCIS.Application.Contracts public class SCPImageUploadQuery : PageInput { + [NotDefault] + public Guid TrialId { get; set; } public string TrialSiteKeyInfo { get; set; } public string? CallingAE { get; set; } diff --git a/IRaCIS.Core.Application/Service/Visit/PatientService.cs b/IRaCIS.Core.Application/Service/Visit/PatientService.cs index da2f95207..1d98ce922 100644 --- a/IRaCIS.Core.Application/Service/Visit/PatientService.cs +++ b/IRaCIS.Core.Application/Service/Visit/PatientService.cs @@ -75,7 +75,7 @@ namespace IRaCIS.Application.Services [HttpPost] public async Task>> GetSCPImageUploadList(SCPImageUploadQuery inQuery) { - var query = _repository.Where() + var query = _repository.Where(t=>t.TrialId==inQuery.TrialId) .WhereIf(!string.IsNullOrWhiteSpace(inQuery.CalledAE), t => t.CalledAE.Contains(inQuery.CalledAE)) .WhereIf(!string.IsNullOrWhiteSpace(inQuery.CallingAEIP), t => t.CallingAEIP.Contains(inQuery.CallingAEIP)) .WhereIf(!string.IsNullOrWhiteSpace(inQuery.CallingAE), t => t.CallingAE.Contains(inQuery.CallingAE)) From de01da975e26c4d529e14670701807493a2fdf53 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Wed, 31 Jul 2024 15:13:00 +0800 Subject: [PATCH 145/251] =?UTF-8?q?CalledAE=20=E5=90=8D=E5=AD=97=E9=94=99?= =?UTF-8?q?=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Service/TrialSiteUser/TrialDicomAEService.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/IRaCIS.Core.Application/Service/TrialSiteUser/TrialDicomAEService.cs b/IRaCIS.Core.Application/Service/TrialSiteUser/TrialDicomAEService.cs index 58d71629b..b0e1be07c 100644 --- a/IRaCIS.Core.Application/Service/TrialSiteUser/TrialDicomAEService.cs +++ b/IRaCIS.Core.Application/Service/TrialSiteUser/TrialDicomAEService.cs @@ -78,7 +78,7 @@ namespace IRaCIS.Core.Application.Service var verifyExp2 = new EntityVerifyExp() { - VerifyExp = u => u.IP == addOrEditDicomAE.CalledAE , + VerifyExp = u => u.CalledAE == addOrEditDicomAE.CalledAE , //"AE名称不能与其他项目相同" VerifyMsg = _localizer["TrialDicomAE_RepeatCalledAE"] From cdbe74f1d94e259df9097536b00e9de8f7fbc638 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Wed, 31 Jul 2024 15:51:38 +0800 Subject: [PATCH 146/251] =?UTF-8?q?=E6=A0=B9=E6=8D=AE=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=E8=AE=BE=E7=BD=AE=E7=94=A8=E6=88=B7=E7=9A=84=E6=9C=BA=E6=9E=84?= =?UTF-8?q?=E5=90=8D=E7=A7=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.Application/Service/Management/UserService.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/IRaCIS.Core.Application/Service/Management/UserService.cs b/IRaCIS.Core.Application/Service/Management/UserService.cs index 7aab3e7b6..a719dbab3 100644 --- a/IRaCIS.Core.Application/Service/Management/UserService.cs +++ b/IRaCIS.Core.Application/Service/Management/UserService.cs @@ -560,7 +560,9 @@ namespace IRaCIS.Application.Services if (saveItem.IsZhiZhun) { - saveItem.OrganizationName = AppSettings.DefaultInternalOrganizationName; + var organizationName = _userInfo.IsEn_Us ? _systemEmailConfig.OrganizationName : _systemEmailConfig.OrganizationNameCN; + + saveItem.OrganizationName = organizationName; } From 7f5a3bffd1b300fc1b2373c48462adf70b8e4932 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Wed, 31 Jul 2024 16:11:55 +0800 Subject: [PATCH 147/251] =?UTF-8?q?=E5=AE=8C=E6=88=90=E6=9C=BA=E6=9E=84?= =?UTF-8?q?=E5=90=8D=E7=A7=B0=E9=BB=98=E8=AE=A4=E5=80=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.API/appsettings.json | 1 - IRaCIS.Core.Domain/_Config/_AppSettings.cs | 2 -- 2 files changed, 3 deletions(-) diff --git a/IRaCIS.Core.API/appsettings.json b/IRaCIS.Core.API/appsettings.json index 59dd671c2..8fa44ed41 100644 --- a/IRaCIS.Core.API/appsettings.json +++ b/IRaCIS.Core.API/appsettings.json @@ -90,7 +90,6 @@ "DicomStudyCodePrefix": "ST", "SystemSiteCodePrefix": "S", "DefaultPassword": "123456", - "DefaultInternalOrganizationName": "ExtImaging", "ImageShareExpireDays": 10 }, diff --git a/IRaCIS.Core.Domain/_Config/_AppSettings.cs b/IRaCIS.Core.Domain/_Config/_AppSettings.cs index a4833050b..b4c890257 100644 --- a/IRaCIS.Core.Domain/_Config/_AppSettings.cs +++ b/IRaCIS.Core.Domain/_Config/_AppSettings.cs @@ -90,7 +90,6 @@ namespace IRaCIS.Core.Domain.Share public static string NoneDicomStudyCodePrefix { get; set; } - public static string DefaultInternalOrganizationName { get; set; } public static int ImageShareExpireDays { get; set; } = 7; @@ -123,7 +122,6 @@ namespace IRaCIS.Core.Domain.Share DefaultPassword = configuration.GetSection("IRaCISBasicConfig").GetValue("DefaultPassword"); SystemSiteCodePrefix = configuration.GetSection("IRaCISBasicConfig").GetValue("SystemSiteCodePrefix"); - DefaultInternalOrganizationName = configuration.GetSection("IRaCISBasicConfig").GetValue("DefaultInternalOrganizationName"); ImageShareExpireDays = configuration.GetSection("IRaCISBasicConfig").GetValue("ImageShareExpireDays"); From cd2ebe700b1f307a73349ab29156b26a28db503c Mon Sep 17 00:00:00 2001 From: he <109787524@qq.com> Date: Wed, 31 Jul 2024 16:49:23 +0800 Subject: [PATCH 148/251] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ReadingClinicalDataService.cs | 99 +++++++++++++------ 1 file changed, 69 insertions(+), 30 deletions(-) diff --git a/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs b/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs index 5d89812c9..54c3a82c4 100644 --- a/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs +++ b/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs @@ -11,6 +11,7 @@ using IRaCIS.Core.Infrastructure; using System.Linq.Dynamic.Core; using Microsoft.Extensions.Logging; using IRaCIS.Core.Infrastructure.Extention; +using System.Linq; namespace IRaCIS.Application.Services { @@ -854,40 +855,78 @@ namespace IRaCIS.Application.Services // 一致性分析 if (isSelfAnalysis) { + // 一致性分析的 resultQuery = _readingConsistentClinicalDataRepository.Where(x => x.SubjectId == inDto.SubjectId) - .WhereIf(inDto.ReadingClinicalDataId != null, x => x.Id == inDto.ReadingClinicalDataId) + .WhereIf(inDto.ReadingClinicalDataId != null, x => x.Id == inDto.ReadingClinicalDataId) .WhereIf(inDto.ClinicalDataTrialSetId != null, x => x.ClinicalDataTrialSetId == inDto.ClinicalDataTrialSetId) - .WhereIf(inDto.SelectIsSign, x => x.IsSign == true) - .Where(x => x.ReadingId == inDto.ReadingId) - .WhereIf(inDto.TrialReadingCriterionId != null, x => x.ClinicalDataTrialSet.TrialClinicalDataSetCriteriaList.Any(t => t.TrialReadingCriterionId == inDto.TrialReadingCriterionId)) - .Select(x => new GetReadingClinicalDataListOutDto() - { - ClinicalDataLevel = x.ClinicalDataTrialSet.ClinicalDataLevel, - SubjectId = x.SubjectId, - ReadingId = x.ReadingId, - ClinicalDataSetEnName = x.ClinicalDataTrialSet.ClinicalDataSetEnName, - ClinicalDataSetName = x.ClinicalDataTrialSet.ClinicalDataSetName.LanguageName(x.ClinicalDataTrialSet.ClinicalDataSetEnName, _userInfo.IsEn_Us), - ClinicalDataTrialSetId = x.ClinicalDataTrialSetId, - IsSign = x.IsSign, - ClinicalUploadType = x.ClinicalDataTrialSet.ClinicalUploadType, - CriterionEnumList = x.ClinicalDataTrialSet.CriterionEnumList, - TrialClinicalDataSetCriteriaList = x.ClinicalDataTrialSet.TrialClinicalDataSetCriteriaList, - Id = x.Id, - UploadRole = x.ClinicalDataTrialSet.UploadRole, - IsCRCUpload = x.ClinicalDataTrialSet.UploadRole == UploadRole.CRC, - IsBlind = x.IsBlind, - IsComplete = x.IsComplete, - FileCount = x.FileCount, - ReadingClinicalDataState = x.ReadingClinicalDataState, - FileList = x.ReadingClinicalDataPDFList.Select(y => new GetFileDto() + .WhereIf(inDto.SelectIsSign, x => x.IsSign == true) + .Where(x => x.ReadingId == inDto.ReadingId) + .WhereIf(inDto.TrialReadingCriterionId != null, x => x.ClinicalDataTrialSet.TrialClinicalDataSetCriteriaList.Any(t => t.TrialReadingCriterionId == inDto.TrialReadingCriterionId)) + .Select(x => new GetReadingClinicalDataListOutDto() { - Id = y.Id, - FileName = y.FileName, - Path = y.Path, - CreateTime = y.CreateTime, - }).ToList(), + ClinicalDataLevel = x.ClinicalDataTrialSet.ClinicalDataLevel, + SubjectId = x.SubjectId, + ReadingId = x.ReadingId, + ClinicalDataSetEnName = x.ClinicalDataTrialSet.ClinicalDataSetEnName, + ClinicalDataSetName = x.ClinicalDataTrialSet.ClinicalDataSetName.LanguageName(x.ClinicalDataTrialSet.ClinicalDataSetEnName, _userInfo.IsEn_Us), + ClinicalDataTrialSetId = x.ClinicalDataTrialSetId, + IsSign = x.IsSign, + ClinicalUploadType = x.ClinicalDataTrialSet.ClinicalUploadType, + CriterionEnumList = x.ClinicalDataTrialSet.CriterionEnumList, + TrialClinicalDataSetCriteriaList = x.ClinicalDataTrialSet.TrialClinicalDataSetCriteriaList, + Id = x.Id, + UploadRole = x.ClinicalDataTrialSet.UploadRole, + IsCRCUpload = x.ClinicalDataTrialSet.UploadRole == UploadRole.CRC, + IsBlind = x.IsBlind, + IsComplete = x.IsComplete, + FileCount = x.FileCount, + ReadingClinicalDataState = x.ReadingClinicalDataState, + FileList = x.ReadingClinicalDataPDFList.Select(y => new GetFileDto() + { + Id = y.Id, + FileName = y.FileName, + Path = y.Path, + CreateTime = y.CreateTime, + }).ToList(), + }); - }); + // 原来的非PDF + var otherQuesy = _readingClinicalDataRepository.Where(x => x.SubjectId == inDto.SubjectId) + .WhereIf(inDto.ReadingClinicalDataId != null, x => x.Id == inDto.ReadingClinicalDataId) + .WhereIf(inDto.ClinicalDataTrialSetId != null, x => x.ClinicalDataTrialSetId == inDto.ClinicalDataTrialSetId) + .WhereIf(inDto.SelectIsSign, x => x.IsSign == true) + .Where(x => x.ReadingId == inDto.ReadingId) + .WhereIf(inDto.TrialReadingCriterionId != null, x => x.ClinicalDataTrialSet.TrialClinicalDataSetCriteriaList.Any(t => t.TrialReadingCriterionId == inDto.TrialReadingCriterionId)) + .Where(x => x.ClinicalDataTrialSet.ClinicalUploadType != ClinicalUploadType.PDF) + .Select(x => new GetReadingClinicalDataListOutDto() + { + ClinicalDataLevel = x.ClinicalDataTrialSet.ClinicalDataLevel, + SubjectId = x.SubjectId, + ReadingId = x.ReadingId, + ClinicalDataSetEnName = x.ClinicalDataTrialSet.ClinicalDataSetEnName, + ClinicalDataSetName = x.ClinicalDataTrialSet.ClinicalDataSetName.LanguageName(x.ClinicalDataTrialSet.ClinicalDataSetEnName, _userInfo.IsEn_Us), + ClinicalDataTrialSetId = x.ClinicalDataTrialSetId, + IsSign = x.IsSign, + ClinicalUploadType = x.ClinicalDataTrialSet.ClinicalUploadType, + CriterionEnumList = x.ClinicalDataTrialSet.CriterionEnumList, + TrialClinicalDataSetCriteriaList = x.ClinicalDataTrialSet.TrialClinicalDataSetCriteriaList, + Id = x.Id, + UploadRole = x.ClinicalDataTrialSet.UploadRole, + IsCRCUpload = x.ClinicalDataTrialSet.UploadRole == UploadRole.CRC, + IsBlind = x.IsBlind, + IsComplete = x.IsComplete, + FileCount = x.FileCount, + ReadingClinicalDataState = x.ReadingClinicalDataState, + FileList = x.ReadingClinicalDataPDFList.Select(y => new GetFileDto() + { + Id = y.Id, + FileName = y.FileName, + Path = y.Path, + CreateTime = y.CreateTime, + }).ToList(), + }); + + resultQuery = resultQuery.Union(otherQuesy); } else { From 3ab411578ef87d5121dbd516df1a5fb54ed74133 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Wed, 31 Jul 2024 17:35:03 +0800 Subject: [PATCH 149/251] =?UTF-8?q?=E6=97=A5=E5=BF=97=E5=86=99=E5=85=A5?= =?UTF-8?q?=E5=88=B0=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRC.Core.SCP/Program.cs | 45 ++++++++++++++++++++++++----------------- 1 file changed, 26 insertions(+), 19 deletions(-) diff --git a/IRC.Core.SCP/Program.cs b/IRC.Core.SCP/Program.cs index 5ad53894d..89bdd08c1 100644 --- a/IRC.Core.SCP/Program.cs +++ b/IRC.Core.SCP/Program.cs @@ -159,25 +159,31 @@ app.MapControllers(); #region 日志 +//Log.Logger = new LoggerConfiguration() +// .MinimumLevel.Information() +// .MinimumLevel.Override("Microsoft", LogEventLevel.Information) +// // Filter out ASP.NET Core infrastructre logs that are Information and below 日志太多了 一个请求 记录好几条 +// .MinimumLevel.Override("Microsoft.AspNetCore", LogEventLevel.Warning) +// .MinimumLevel.Override("Hangfire", LogEventLevel.Warning) +// .MinimumLevel.Override("System.Net.Http.HttpClient.HttpReports", LogEventLevel.Warning) +// .Enrich.WithClientIp() + +// .Enrich.FromLogContext() + +// //控制台 方便调试 问题 我们显示记录日志 时 获取上下文的ip 和用户名 用户类型 +// .WriteTo.Console(restrictedToMinimumLevel: LogEventLevel.Warning, +// outputTemplate: "[{Timestamp:HH:mm:ss} {Level:u3}] {SourceContext:l} || {Message} || {Exception} ||end {NewLine}") + +// .WriteTo.File($"{AppContext.BaseDirectory}Serilogs/.log", rollingInterval: RollingInterval.Day, +// outputTemplate: "[{Timestamp:HH:mm:ss} {Level:u3}] {SourceContext:l} || {Message} || {Exception} ||end {NewLine}") +// .CreateLogger(); + Log.Logger = new LoggerConfiguration() - .MinimumLevel.Information() - .MinimumLevel.Override("Microsoft", LogEventLevel.Information) - // Filter out ASP.NET Core infrastructre logs that are Information and below 日志太多了 一个请求 记录好几条 - .MinimumLevel.Override("Microsoft.AspNetCore", LogEventLevel.Warning) - .MinimumLevel.Override("Hangfire", LogEventLevel.Warning) - .MinimumLevel.Override("System.Net.Http.HttpClient.HttpReports", LogEventLevel.Warning) - .Enrich.WithClientIp() - - .Enrich.FromLogContext() - - //控制台 方便调试 问题 我们显示记录日志 时 获取上下文的ip 和用户名 用户类型 - .WriteTo.Console(restrictedToMinimumLevel: LogEventLevel.Warning, - outputTemplate: "[{Timestamp:HH:mm:ss} {Level:u3}] {SourceContext:l} || {Message} || {Exception} ||end {NewLine}") - - .WriteTo.File($"{AppContext.BaseDirectory}Serilogs/.log", rollingInterval: RollingInterval.Day, - outputTemplate: "[{Timestamp:HH:mm:ss} {Level:u3}] {SourceContext:l} || {Message} || {Exception} ||end {NewLine}") - .CreateLogger(); - + //.MinimumLevel.Information() + //.MinimumLevel.Override("Microsoft", LogEventLevel.Warning) + .WriteTo.Console() + .WriteTo.File($"{AppContext.BaseDirectory}Serilogs/.log", rollingInterval: RollingInterval.Day) + .CreateLogger(); #endregion @@ -201,8 +207,9 @@ else #endregion +var logger = app.Services.GetService(); -var server = DicomServerFactory.Create(_configuration.GetSection("DicomSCPServiceConfig").GetValue("ServerPort"), userState: app.Services); +var server = DicomServerFactory.Create(_configuration.GetSection("DicomSCPServiceConfig").GetValue("ServerPort"), userState: app.Services,logger: logger); app.Run(); From 0e631e6f292e03600bd57f6122358959647e3989 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Wed, 31 Jul 2024 17:36:46 +0800 Subject: [PATCH 150/251] =?UTF-8?q?=E4=BC=A0=E9=80=92logger?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRC.Core.SCP/Program.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/IRC.Core.SCP/Program.cs b/IRC.Core.SCP/Program.cs index 89bdd08c1..792d63c26 100644 --- a/IRC.Core.SCP/Program.cs +++ b/IRC.Core.SCP/Program.cs @@ -207,7 +207,7 @@ else #endregion -var logger = app.Services.GetService(); +var logger = app.Services.GetService>(); var server = DicomServerFactory.Create(_configuration.GetSection("DicomSCPServiceConfig").GetValue("ServerPort"), userState: app.Services,logger: logger); From 9fa24a35efbcc28490d7b757b5c52daac06df655 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Wed, 31 Jul 2024 17:42:40 +0800 Subject: [PATCH 151/251] =?UTF-8?q?=E8=AE=B0=E5=BD=95=E4=BC=A0=E8=BE=93?= =?UTF-8?q?=E6=97=A5=E5=BF=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRC.Core.SCP/Program.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/IRC.Core.SCP/Program.cs b/IRC.Core.SCP/Program.cs index 792d63c26..dfa4bb17e 100644 --- a/IRC.Core.SCP/Program.cs +++ b/IRC.Core.SCP/Program.cs @@ -180,7 +180,7 @@ app.MapControllers(); Log.Logger = new LoggerConfiguration() //.MinimumLevel.Information() - //.MinimumLevel.Override("Microsoft", LogEventLevel.Warning) + .MinimumLevel.Override("Microsoft", LogEventLevel.Warning) .WriteTo.Console() .WriteTo.File($"{AppContext.BaseDirectory}Serilogs/.log", rollingInterval: RollingInterval.Day) .CreateLogger(); From e3ee1a42fb83c600eb340c2062d89f58dc05a9ca Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Thu, 1 Aug 2024 10:12:09 +0800 Subject: [PATCH 152/251] =?UTF-8?q?=E4=BF=AE=E6=94=B9dicom=20=E8=8E=B7?= =?UTF-8?q?=E5=8F=96tag=E5=80=BC=20patientId=E4=B8=BA=E7=A9=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRC.Core.SCP/Service/DicomArchiveService.cs | 2 +- IRC.Core.SCP/Service/OSSService.cs | 47 +++++--- IRC.Core.SCP/appsettings.Prod_IRC_SCP.json | 1 + IRC.Core.SCP/appsettings.Test_IRC_SCP.json | 1 + IRC.Core.SCP/appsettings.Uat_IRC_SCP.json | 1 + IRaCIS.Core.Application/Helper/OSSService.cs | 105 ++++++++++-------- .../IRaCIS.Core.Application.xml | 40 +++++++ 7 files changed, 132 insertions(+), 65 deletions(-) diff --git a/IRC.Core.SCP/Service/DicomArchiveService.cs b/IRC.Core.SCP/Service/DicomArchiveService.cs index 8632cd4e8..ee456af4a 100644 --- a/IRC.Core.SCP/Service/DicomArchiveService.cs +++ b/IRC.Core.SCP/Service/DicomArchiveService.cs @@ -57,7 +57,7 @@ namespace IRaCIS.Core.SCP.Service string seriesInstanceUid = dataset.GetString(DicomTag.SeriesInstanceUID); string sopInstanceUid = dataset.GetString(DicomTag.SOPInstanceUID); - string patientIdStr = dataset.GetString(DicomTag.PatientID); + string patientIdStr = dataset.GetSingleValueOrDefault(DicomTag.PatientID,string.Empty); //Guid patientId= IdentifierHelper.CreateGuid(patientIdStr); Guid studyId = IdentifierHelper.CreateGuid(studyInstanceUid,trialId.ToString()); diff --git a/IRC.Core.SCP/Service/OSSService.cs b/IRC.Core.SCP/Service/OSSService.cs index cfbe4b3f8..eb34ec64f 100644 --- a/IRC.Core.SCP/Service/OSSService.cs +++ b/IRC.Core.SCP/Service/OSSService.cs @@ -13,6 +13,7 @@ using System.Linq; using System.Security.AccessControl; using System.Text; using System.Threading.Tasks; +using System.Runtime.InteropServices; namespace IRaCIS.Core.SCP { @@ -37,6 +38,9 @@ namespace IRaCIS.Core.SCP public string regionId { get; set; } public string accessKeyId { get; set; } public string accessKeySecret { get; set; } + + public string internalEndpoint { get; set; } + public string endPoint { get; set; } public string bucketName { get; set; } @@ -93,7 +97,7 @@ namespace IRaCIS.Core.SCP public interface IOSSService { - public Task UploadToOSSAsync(Stream fileStream, string oosFolderPath, string fileRealName,bool isFileNameAddGuid=true); + public Task UploadToOSSAsync(Stream fileStream, string oosFolderPath, string fileRealName, bool isFileNameAddGuid = true); public Task UploadToOSSAsync(string localFilePath, string oosFolderPath, bool isFileNameAddGuid = true); public Task DownLoadFromOSSAsync(string ossRelativePath, string localFilePath); @@ -121,12 +125,12 @@ namespace IRaCIS.Core.SCP /// /// /// + /// /// public async Task UploadToOSSAsync(Stream fileStream, string oosFolderPath, string fileRealName, bool isFileNameAddGuid = true) { - - - var ossRelativePath = isFileNameAddGuid? $"{oosFolderPath}/{Guid.NewGuid()}_{fileRealName}": $"{oosFolderPath}/{fileRealName}"; + var ossRelativePath = isFileNameAddGuid ? $"{oosFolderPath}/{Guid.NewGuid()}_{fileRealName}" : $"{oosFolderPath}/{fileRealName}"; + //var ossRelativePath = $"{oosFolderPath}/{Guid.NewGuid()}_{fileRealName}"; //var ossRelativePath = oosFolderPath + "/" + fileRealName; try @@ -144,7 +148,7 @@ namespace IRaCIS.Core.SCP { var aliConfig = ObjectStoreServiceOptions.AliyunOSS; - var _ossClient = new OssClient(aliConfig.endPoint, aliConfig.accessKeyId, aliConfig.accessKeySecret); + var _ossClient = new OssClient(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? aliConfig.endPoint : aliConfig.internalEndpoint, aliConfig.accessKeyId, aliConfig.accessKeySecret); @@ -195,7 +199,7 @@ namespace IRaCIS.Core.SCP catch (Exception ex) { - throw new BusinessValidationFailedException($"上传发生异常:{ex.Message}"); ; + throw new BusinessValidationFailedException($"上传发生异常:{ex.Message}"); } @@ -218,7 +222,8 @@ namespace IRaCIS.Core.SCP { var localFileName = Path.GetFileName(localFilePath); - var ossRelativePath = isFileNameAddGuid? $"{oosFolderPath}/{Guid.NewGuid()}_{localFileName}" : $"{oosFolderPath}/{localFileName}"; + var ossRelativePath = isFileNameAddGuid ? $"{oosFolderPath}/{Guid.NewGuid()}_{localFileName}" : $"{oosFolderPath}/{localFileName}"; + //var ossRelativePath = oosFolderPath + "/" + localFileName; @@ -227,7 +232,7 @@ namespace IRaCIS.Core.SCP { var aliConfig = ObjectStoreServiceOptions.AliyunOSS; - var _ossClient = new OssClient(aliConfig.endPoint, aliConfig.accessKeyId, aliConfig.accessKeySecret); + var _ossClient = new OssClient(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? aliConfig.endPoint : aliConfig.internalEndpoint, aliConfig.accessKeyId, aliConfig.accessKeySecret); // 上传文件 var result = _ossClient.PutObject(aliConfig.bucketName, ossRelativePath, localFilePath); @@ -273,6 +278,7 @@ namespace IRaCIS.Core.SCP } + public async Task DownLoadFromOSSAsync(string ossRelativePath, string localFilePath) { @@ -285,7 +291,7 @@ namespace IRaCIS.Core.SCP { var aliConfig = ObjectStoreServiceOptions.AliyunOSS; - var _ossClient = new OssClient(aliConfig.endPoint, aliConfig.accessKeyId, aliConfig.accessKeySecret); + var _ossClient = new OssClient(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? aliConfig.endPoint : aliConfig.internalEndpoint, aliConfig.accessKeyId, aliConfig.accessKeySecret); // 上传文件 var result = _ossClient.GetObject(aliConfig.bucketName, ossRelativePath); @@ -346,7 +352,7 @@ namespace IRaCIS.Core.SCP } - public async Task GetSignedUrl(string ossRelativePath) + public async Task GetSignedUrl(string ossRelativePath) { ossRelativePath = ossRelativePath.TrimStart('/'); try @@ -357,7 +363,7 @@ namespace IRaCIS.Core.SCP { var aliConfig = ObjectStoreServiceOptions.AliyunOSS; - var _ossClient = new OssClient(aliConfig.endPoint, aliConfig.accessKeyId, aliConfig.accessKeySecret); + var _ossClient = new OssClient(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? aliConfig.endPoint : aliConfig.internalEndpoint, aliConfig.accessKeyId, aliConfig.accessKeySecret); // 生成签名URL。 var req = new GeneratePresignedUriRequest(aliConfig.bucketName, ossRelativePath, SignHttpMethod.Get) @@ -378,10 +384,6 @@ namespace IRaCIS.Core.SCP .WithCredentials(minIOConfig.accessKey, minIOConfig.secretKey).WithSSL(minIOConfig.useSSL) .Build(); - //var reqParams = new Dictionary(StringComparer.Ordinal) - // { - // { "response-content-type", "application/json" } - // }; var args = new PresignedGetObjectArgs() .WithBucket(minIOConfig.bucketName) @@ -407,7 +409,19 @@ namespace IRaCIS.Core.SCP .WithCredentials(minIOConfig.accessKey, minIOConfig.secretKey).WithSSL(minIOConfig.useSSL) .Build(); - return string.Empty; + var args = new PresignedGetObjectArgs() + .WithBucket(minIOConfig.bucketName) + .WithObject(ossRelativePath) + .WithExpiry(3600); + + var presignedUrl = await minioClient.PresignedGetObjectAsync(args); + + Uri uri = new Uri(presignedUrl); + + string relativePath = uri.PathAndQuery; + + + return relativePath; } else { @@ -424,4 +438,5 @@ namespace IRaCIS.Core.SCP } + } diff --git a/IRC.Core.SCP/appsettings.Prod_IRC_SCP.json b/IRC.Core.SCP/appsettings.Prod_IRC_SCP.json index 32ee00af6..6def61882 100644 --- a/IRC.Core.SCP/appsettings.Prod_IRC_SCP.json +++ b/IRC.Core.SCP/appsettings.Prod_IRC_SCP.json @@ -10,6 +10,7 @@ "ObjectStoreUse": "AliyunOSS", "AliyunOSS": { "regionId": "cn-shanghai", + "internalEndpoint": "https://oss-cn-shanghai-internal.aliyuncs.com", "endpoint": "https://oss-cn-shanghai.aliyuncs.com", "accessKeyId": "LTAI5tKvzs7ed3UfSpNk3xwQ", "accessKeySecret": "zTIceGEShlZDGnLrCFfIGFE7TXVRio", diff --git a/IRC.Core.SCP/appsettings.Test_IRC_SCP.json b/IRC.Core.SCP/appsettings.Test_IRC_SCP.json index aa6c2223b..4122b7ecf 100644 --- a/IRC.Core.SCP/appsettings.Test_IRC_SCP.json +++ b/IRC.Core.SCP/appsettings.Test_IRC_SCP.json @@ -10,6 +10,7 @@ "ObjectStoreUse": "AliyunOSS", "AliyunOSS": { "regionId": "cn-shanghai", + "internalEndpoint": "https://oss-cn-shanghai-internal.aliyuncs.com", "endPoint": "https://oss-cn-shanghai.aliyuncs.com", "accessKeyId": "LTAI5tKvzs7ed3UfSpNk3xwQ", "accessKeySecret": "zTIceGEShlZDGnLrCFfIGFE7TXVRio", diff --git a/IRC.Core.SCP/appsettings.Uat_IRC_SCP.json b/IRC.Core.SCP/appsettings.Uat_IRC_SCP.json index f50eedf66..9079082c4 100644 --- a/IRC.Core.SCP/appsettings.Uat_IRC_SCP.json +++ b/IRC.Core.SCP/appsettings.Uat_IRC_SCP.json @@ -10,6 +10,7 @@ "ObjectStoreUse": "MinIO", "AliyunOSS": { "regionId": "cn-shanghai", + "internalEndpoint": "https://oss-cn-shanghai-internal.aliyuncs.com", "endpoint": "https://oss-cn-shanghai.aliyuncs.com", "accessKeyId": "LTAI5tKvzs7ed3UfSpNk3xwQ", "accessKeySecret": "zTIceGEShlZDGnLrCFfIGFE7TXVRio", diff --git a/IRaCIS.Core.Application/Helper/OSSService.cs b/IRaCIS.Core.Application/Helper/OSSService.cs index 175367992..a50c92da3 100644 --- a/IRaCIS.Core.Application/Helper/OSSService.cs +++ b/IRaCIS.Core.Application/Helper/OSSService.cs @@ -1,11 +1,9 @@ using Aliyun.OSS; -using IRaCIS.Core.Application.Contracts; using IRaCIS.Core.Infrastructure; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Options; using Minio.DataModel.Args; using Minio; -using NPOI.HPSF; using SharpCompress.Common; using System; using System.Collections.Generic; @@ -15,6 +13,7 @@ using System.Linq; using System.Security.AccessControl; using System.Text; using System.Threading.Tasks; +using System.Runtime.InteropServices; namespace IRaCIS.Core.Application.Helper { @@ -134,66 +133,76 @@ namespace IRaCIS.Core.Application.Helper //var ossRelativePath = $"{oosFolderPath}/{Guid.NewGuid()}_{fileRealName}"; //var ossRelativePath = oosFolderPath + "/" + fileRealName; - using (var memoryStream = new MemoryStream()) + try { - fileStream.Seek(0, SeekOrigin.Begin); - - fileStream.CopyTo(memoryStream); - - memoryStream.Seek(0, SeekOrigin.Begin); - - - if (ObjectStoreServiceOptions.ObjectStoreUse == "AliyunOSS") + using (var memoryStream = new MemoryStream()) { - var aliConfig = ObjectStoreServiceOptions.AliyunOSS; + fileStream.Seek(0, SeekOrigin.Begin); - var _ossClient = new OssClient(aliConfig.internalEndpoint, aliConfig.accessKeyId, aliConfig.accessKeySecret); + fileStream.CopyTo(memoryStream); + + memoryStream.Seek(0, SeekOrigin.Begin); + + + if (ObjectStoreServiceOptions.ObjectStoreUse == "AliyunOSS") + { + var aliConfig = ObjectStoreServiceOptions.AliyunOSS; + + var _ossClient = new OssClient(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? aliConfig.endPoint : aliConfig.internalEndpoint, aliConfig.accessKeyId, aliConfig.accessKeySecret); - // 上传文件 - var result = _ossClient.PutObject(aliConfig.bucketName, ossRelativePath, memoryStream); + // 上传文件 + var result = _ossClient.PutObject(aliConfig.bucketName, ossRelativePath, memoryStream); - } - else if (ObjectStoreServiceOptions.ObjectStoreUse == "MinIO") - { - var minIOConfig = ObjectStoreServiceOptions.MinIO; + } + else if (ObjectStoreServiceOptions.ObjectStoreUse == "MinIO") + { + var minIOConfig = ObjectStoreServiceOptions.MinIO; - var minioClient = new MinioClient().WithEndpoint($"{minIOConfig.endPoint}:{minIOConfig.port}") - .WithCredentials(minIOConfig.accessKey, minIOConfig.secretKey).WithSSL(minIOConfig.useSSL) - .Build(); + var minioClient = new MinioClient().WithEndpoint($"{minIOConfig.endPoint}:{minIOConfig.port}") + .WithCredentials(minIOConfig.accessKey, minIOConfig.secretKey).WithSSL(minIOConfig.useSSL) + .Build(); - var putObjectArgs = new PutObjectArgs() - .WithBucket(minIOConfig.bucketName) - .WithObject(ossRelativePath) - .WithStreamData(memoryStream) - .WithObjectSize(memoryStream.Length); + var putObjectArgs = new PutObjectArgs() + .WithBucket(minIOConfig.bucketName) + .WithObject(ossRelativePath) + .WithStreamData(memoryStream) + .WithObjectSize(memoryStream.Length); - await minioClient.PutObjectAsync(putObjectArgs); - } - else if (ObjectStoreServiceOptions.ObjectStoreUse == "AWS") - { - var minIOConfig = ObjectStoreServiceOptions.AWS; + await minioClient.PutObjectAsync(putObjectArgs); + } + else if (ObjectStoreServiceOptions.ObjectStoreUse == "AWS") + { + var minIOConfig = ObjectStoreServiceOptions.AWS; - var minioClient = new MinioClient().WithEndpoint($"{minIOConfig.endPoint}") - .WithCredentials(minIOConfig.accessKey, minIOConfig.secretKey).WithSSL(minIOConfig.useSSL) - .Build(); + var minioClient = new MinioClient().WithEndpoint($"{minIOConfig.endPoint}") + .WithCredentials(minIOConfig.accessKey, minIOConfig.secretKey).WithSSL(minIOConfig.useSSL) + .Build(); - var putObjectArgs = new PutObjectArgs() - .WithBucket(minIOConfig.bucketName) - .WithObject(ossRelativePath) - .WithStreamData(memoryStream) - .WithObjectSize(memoryStream.Length); + var putObjectArgs = new PutObjectArgs() + .WithBucket(minIOConfig.bucketName) + .WithObject(ossRelativePath) + .WithStreamData(memoryStream) + .WithObjectSize(memoryStream.Length); - await minioClient.PutObjectAsync(putObjectArgs); - } - else - { - throw new BusinessValidationFailedException("未定义的存储介质类型"); + await minioClient.PutObjectAsync(putObjectArgs); + } + else + { + throw new BusinessValidationFailedException("未定义的存储介质类型"); + } } } + catch (Exception ex) + { + + throw new BusinessValidationFailedException($"上传发生异常:{ex.Message}"); + } + + return "/" + ossRelativePath; @@ -223,7 +232,7 @@ namespace IRaCIS.Core.Application.Helper { var aliConfig = ObjectStoreServiceOptions.AliyunOSS; - var _ossClient = new OssClient(aliConfig.internalEndpoint, aliConfig.accessKeyId, aliConfig.accessKeySecret); + var _ossClient = new OssClient(RuntimeInformation.IsOSPlatform(OSPlatform.Windows)? aliConfig.endPoint: aliConfig.internalEndpoint, aliConfig.accessKeyId, aliConfig.accessKeySecret); // 上传文件 var result = _ossClient.PutObject(aliConfig.bucketName, ossRelativePath, localFilePath); @@ -282,7 +291,7 @@ namespace IRaCIS.Core.Application.Helper { var aliConfig = ObjectStoreServiceOptions.AliyunOSS; - var _ossClient = new OssClient(aliConfig.internalEndpoint, aliConfig.accessKeyId, aliConfig.accessKeySecret); + var _ossClient = new OssClient(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? aliConfig.endPoint : aliConfig.internalEndpoint, aliConfig.accessKeyId, aliConfig.accessKeySecret); // 上传文件 var result = _ossClient.GetObject(aliConfig.bucketName, ossRelativePath); @@ -354,7 +363,7 @@ namespace IRaCIS.Core.Application.Helper { var aliConfig = ObjectStoreServiceOptions.AliyunOSS; - var _ossClient = new OssClient(aliConfig.internalEndpoint, aliConfig.accessKeyId, aliConfig.accessKeySecret); + var _ossClient = new OssClient(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? aliConfig.endPoint : aliConfig.internalEndpoint, aliConfig.accessKeyId, aliConfig.accessKeySecret); // 生成签名URL。 var req = new GeneratePresignedUriRequest(aliConfig.bucketName, ossRelativePath, SignHttpMethod.Get) diff --git a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml index add5bef1a..fa33a1f82 100644 --- a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml +++ b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml @@ -1293,6 +1293,18 @@ 获取登陆用户的系统通知列表 只是过滤了用户类型 和已经发布的 + + + UserFeedBackService + + + + + 批量更新状态 + + + + 验证CRC 是否已提交 已提交 就不允许进行任何操作,如果是IQC 那么还验证是否是当前任务领取人 @@ -10244,6 +10256,15 @@ SystemNoticeAddOrEdit 列表查询参数模型 + + UserFeedBackView 列表视图模型 + + + UserFeedBackQuery 列表查询参数模型 + + + UserFeedBackAddOrEdit 列表查询参数模型 + UserLogView 列表视图模型 @@ -11101,6 +11122,11 @@ ISystemNoticeService + + + IUserFeedBackService + + IUserLogService @@ -14075,6 +14101,13 @@ 影像阅片临床数据签名 + + + 一致性分析的临床数据 + + + + 获取下拉菜单 @@ -14096,6 +14129,13 @@ + + + 获取阅片临床数据列表 + + + + 获取单个阅片临床数据的所有文件 From ee43a5dc9da8b34eff1d3f609cf525fdd16923a5 Mon Sep 17 00:00:00 2001 From: he <109787524@qq.com> Date: Thu, 1 Aug 2024 10:35:57 +0800 Subject: [PATCH 153/251] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ReadingClinicalDataService.cs | 194 ++++++++++++------ .../Reading/Dto/ReadingClinicalDataDto.cs | 24 ++- 2 files changed, 148 insertions(+), 70 deletions(-) diff --git a/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs b/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs index 54c3a82c4..61082c802 100644 --- a/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs +++ b/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs @@ -38,6 +38,7 @@ namespace IRaCIS.Application.Services private readonly IRepository _subjectRepository; private readonly IRepository _readModuleRepository; private readonly IRepository _readingClinicalDataPDFRepository; + private readonly IRepository _readingConsistentClinicalDataPDFRepository; public ReadingClinicalDataService(IRepository readingClinicalDataRepository, IRepository readingConsistentClinicalDataRepository, @@ -56,6 +57,7 @@ namespace IRaCIS.Application.Services IRepository readModuleRepository, IRepository readingClinicalDataPDFRepository, + IRepository readingConsistentClinicalDataPDFRepository, IRepository visitTaskRepository) { this._readingClinicalDataRepository = readingClinicalDataRepository; @@ -73,6 +75,7 @@ namespace IRaCIS.Application.Services this._subjectRepository = subjectRepository; this._readModuleRepository = readModuleRepository; this._readingClinicalDataPDFRepository = readingClinicalDataPDFRepository; + this._readingConsistentClinicalDataPDFRepository = readingConsistentClinicalDataPDFRepository; this._visitTaskRepository = visitTaskRepository; } @@ -91,9 +94,6 @@ namespace IRaCIS.Application.Services .WhereIf(indto.Id != null, x => x.Id != indto.Id) .Where(x => x.ClinicalDataTrialSetId == indto.ClinicalDataTrialSetId && x.ReadingId == indto.ReadingId && x.StudyId == indto.StudyId); - - - if (await existsQuery.AnyAsync()) { //---存在同类型的临床数据,操作失败 @@ -845,7 +845,7 @@ namespace IRaCIS.Application.Services { var visitTask = await _visitTaskRepository.FirstOrDefaultAsync(x => x.Id == inDto.VisitTaskId); inDto.ReadingId = visitTask.SouceReadModuleId ?? visitTask.SourceSubjectVisitId; - + inDto.TrialReadingCriterionId = visitTask.TrialReadingCriterionId; if (visitTask.IsAnalysisCreate && visitTask.IsSelfAnalysis == true) { @@ -890,43 +890,48 @@ namespace IRaCIS.Application.Services }).ToList(), }); - // 原来的非PDF - var otherQuesy = _readingClinicalDataRepository.Where(x => x.SubjectId == inDto.SubjectId) - .WhereIf(inDto.ReadingClinicalDataId != null, x => x.Id == inDto.ReadingClinicalDataId) - .WhereIf(inDto.ClinicalDataTrialSetId != null, x => x.ClinicalDataTrialSetId == inDto.ClinicalDataTrialSetId) - .WhereIf(inDto.SelectIsSign, x => x.IsSign == true) - .Where(x => x.ReadingId == inDto.ReadingId) - .WhereIf(inDto.TrialReadingCriterionId != null, x => x.ClinicalDataTrialSet.TrialClinicalDataSetCriteriaList.Any(t => t.TrialReadingCriterionId == inDto.TrialReadingCriterionId)) - .Where(x => x.ClinicalDataTrialSet.ClinicalUploadType != ClinicalUploadType.PDF) - .Select(x => new GetReadingClinicalDataListOutDto() + // 是否获取所有一致性分析的数据 + if(!inDto.IsGetAllConsistencyAnalysis) { - ClinicalDataLevel = x.ClinicalDataTrialSet.ClinicalDataLevel, - SubjectId = x.SubjectId, - ReadingId = x.ReadingId, - ClinicalDataSetEnName = x.ClinicalDataTrialSet.ClinicalDataSetEnName, - ClinicalDataSetName = x.ClinicalDataTrialSet.ClinicalDataSetName.LanguageName(x.ClinicalDataTrialSet.ClinicalDataSetEnName, _userInfo.IsEn_Us), - ClinicalDataTrialSetId = x.ClinicalDataTrialSetId, - IsSign = x.IsSign, - ClinicalUploadType = x.ClinicalDataTrialSet.ClinicalUploadType, - CriterionEnumList = x.ClinicalDataTrialSet.CriterionEnumList, - TrialClinicalDataSetCriteriaList = x.ClinicalDataTrialSet.TrialClinicalDataSetCriteriaList, - Id = x.Id, - UploadRole = x.ClinicalDataTrialSet.UploadRole, - IsCRCUpload = x.ClinicalDataTrialSet.UploadRole == UploadRole.CRC, - IsBlind = x.IsBlind, - IsComplete = x.IsComplete, - FileCount = x.FileCount, - ReadingClinicalDataState = x.ReadingClinicalDataState, - FileList = x.ReadingClinicalDataPDFList.Select(y => new GetFileDto() - { - Id = y.Id, - FileName = y.FileName, - Path = y.Path, - CreateTime = y.CreateTime, - }).ToList(), + // 原来的非PDF + var otherQuesy = _readingClinicalDataRepository.Where(x => x.SubjectId == inDto.SubjectId) + .WhereIf(inDto.ReadingClinicalDataId != null, x => x.Id == inDto.ReadingClinicalDataId) + .WhereIf(inDto.ClinicalDataTrialSetId != null, x => x.ClinicalDataTrialSetId == inDto.ClinicalDataTrialSetId) + .WhereIf(inDto.SelectIsSign, x => x.IsSign == true) + .Where(x => x.ReadingId == inDto.ReadingId) + .WhereIf(inDto.TrialReadingCriterionId != null, x => x.ClinicalDataTrialSet.TrialClinicalDataSetCriteriaList.Any(t => t.TrialReadingCriterionId == inDto.TrialReadingCriterionId)) + .Where(x => x.ClinicalDataTrialSet.ClinicalUploadType != ClinicalUploadType.PDF) + .Select(x => new GetReadingClinicalDataListOutDto() + { + ClinicalDataLevel = x.ClinicalDataTrialSet.ClinicalDataLevel, + SubjectId = x.SubjectId, + ReadingId = x.ReadingId, + ClinicalDataSetEnName = x.ClinicalDataTrialSet.ClinicalDataSetEnName, + ClinicalDataSetName = x.ClinicalDataTrialSet.ClinicalDataSetName.LanguageName(x.ClinicalDataTrialSet.ClinicalDataSetEnName, _userInfo.IsEn_Us), + ClinicalDataTrialSetId = x.ClinicalDataTrialSetId, + IsSign = x.IsSign, + ClinicalUploadType = x.ClinicalDataTrialSet.ClinicalUploadType, + CriterionEnumList = x.ClinicalDataTrialSet.CriterionEnumList, + TrialClinicalDataSetCriteriaList = x.ClinicalDataTrialSet.TrialClinicalDataSetCriteriaList, + Id = x.Id, + UploadRole = x.ClinicalDataTrialSet.UploadRole, + IsCRCUpload = x.ClinicalDataTrialSet.UploadRole == UploadRole.CRC, + IsBlind = x.IsBlind, + IsComplete = x.IsComplete, + FileCount = x.FileCount, + ReadingClinicalDataState = x.ReadingClinicalDataState, + FileList = x.ReadingClinicalDataPDFList.Select(y => new GetFileDto() + { + Id = y.Id, + FileName = y.FileName, + Path = y.Path, + CreateTime = y.CreateTime, + }).ToList(), }); - resultQuery = resultQuery.Union(otherQuesy); + resultQuery = resultQuery.Union(otherQuesy); + } + } else { @@ -1112,52 +1117,109 @@ namespace IRaCIS.Application.Services #endregion - #region 一致性分析 + #region 一致性分析临床数据 /// - /// 获取阅片临床数据列表 + /// 获取阅片临床数据列表 (在任务列表) /// /// /// [HttpPost] - public async Task<(List, object)> GetConsistencyAnalysisReadingClinicalDataList(GetReadingClinicalDataListIndto inDto) + public async Task> GetConsistencyAnalysisReadingClinicalDataList(GetConsistencyAnalysisReadingClinicalDataListInDto inDto) { - - - - - var isBaseLine = await _subjectVisitRepository.AnyAsync(x => x.Id == inDto.ReadingId && x.IsBaseLine); - - var result = await this.GetClinicalDataList(new GetReadingOrTaskClinicalDataListInDto() { - ClinicalDataTrialSetId = inDto.ClinicalDataTrialSetId, - GetClinicalType = inDto.GetClinicalType, SubjectId = inDto.SubjectId, TrialId = inDto.TrialId, SelectIsSign = false, - ReadingId = inDto.ReadingId, - TrialReadingCriterionId = inDto.TrialReadingCriterionId, + IsGetAllConsistencyAnalysis = false, }); - var readingIds = result.Select(x => x.ReadingId).ToList(); + + return result; + } - var previousHistoryList = await _previousHistoryRepository.Where(x => readingIds.Contains(x.SubjectVisitId)).ProjectTo(_mapper.ConfigurationProvider).ToListAsync(); - var previousOtherList = await _previousOtherRepository.Where(x => readingIds.Contains(x.SubjectVisitId)).ProjectTo(_mapper.ConfigurationProvider).ToListAsync(); - var previousSurgeryList = await _previousSurgeryRepository.Where(x => readingIds.Contains(x.SubjectVisitId)).ProjectTo(_mapper.ConfigurationProvider).ToListAsync(); - foreach (var item in result) + + + /// + /// 新增或修改一致性分析临床数据 + /// + /// + /// + [HttpPost] + public async Task AddOrUpdateConsistencyAnalysisReadingClinicalData(AddOrUpdateReadingClinicalDataDto indto) + { + var existsQuery = _readingClinicalDataRepository + .WhereIf(indto.Id != null, x => x.Id != indto.Id) + .Where(x => x.ClinicalDataTrialSetId == indto.ClinicalDataTrialSetId && x.ReadingId == indto.ReadingId && x.StudyId == indto.StudyId); + + if (await existsQuery.AnyAsync()) { - item.ClinicalTableData = new ClinicalDataTable() + //---存在同类型的临床数据,操作失败 + return ResponseOutput.NotOk(_localizer["ReadingClinicalData_DupTypeFail"]); + } + var clinicalDataTrialSet = (await _clinicalDataTrialSetRepository.Where(x => x.Id == indto.ClinicalDataTrialSetId).FirstOrDefaultAsync()).IfNullThrowException(); + + //subject 或者访视级别的 都是在访视传 + indto.IsVisit = clinicalDataTrialSet.ClinicalDataLevel == ClinicalLevel.Subject || clinicalDataTrialSet.ClinicalDataLevel == ClinicalLevel.SubjectVisit; + + if (indto.Id == null) + { + var entity = _mapper.Map(indto); + entity.ReadingClinicalDataPDFList = indto.AddFileList.Select(x => new ReadingClinicalDataPDF() { - PreviousHistoryList = previousHistoryList.Where(x => x.ClinicalDataTrialSetId == item.ClinicalDataTrialSetId).ToList(), - PreviousOtherList = previousOtherList.Where(x => x.ClinicalDataTrialSetId == item.ClinicalDataTrialSetId).ToList(), - PreviousSurgeryList = previousSurgeryList.Where(x => x.ClinicalDataTrialSetId == item.ClinicalDataTrialSetId).ToList(), - }; + FileName = x.FileName, + Path = x.Path, + Size = x.Size, + Type = x.Type, + }).ToList(); + + entity.ReadingClinicalDataState = ReadingClinicalDataStatus.HaveUploaded; + entity.IsBlind = null; + entity.IsComplete = null; + entity.FileCount = entity.ReadingClinicalDataPDFList.Count; + await _readingClinicalDataRepository.AddAsync(entity, true); + var success = await _readingClinicalDataRepository.SaveChangesAsync(); + return ResponseOutput.Ok(entity.Id); + } + else + { + var entity = (await _readingClinicalDataRepository.Where(t => t.Id == indto.Id, true).FirstOrDefaultAsync()).IfNullThrowException(); + await _readingClinicalDataPDFRepository.BatchDeleteNoTrackingAsync(x => indto.DeleteFileIds.Contains(x.Id)); + + var addFileList = indto.AddFileList.Select(x => new ReadingClinicalDataPDF() + { + + FileName = x.FileName, + Path = x.Path, + Size = x.Size, + Type = x.Type, + ReadingClinicalDataId = entity.Id, + }).ToList(); + + + + _mapper.Map(indto, entity); + + //上传 或者删除了文件 核查状态需要重新确认 + + if (indto.AddFileList.Count > 0 || indto.AddFileList.Count > 0) + { + entity.IsComplete = null; + entity.IsBlind = null; + } + + await _readingClinicalDataPDFRepository.AddRangeAsync(addFileList); + + await _readingClinicalDataPDFRepository.SaveChangesAsync(); + + var fileCount = await _readingClinicalDataPDFRepository.Where(t => t.ReadingClinicalDataId == indto.Id).CountAsync(); + entity.ReadingClinicalDataState = ReadingClinicalDataStatus.HaveUploaded; + entity.IsSign = false; + entity.FileCount = fileCount; + var success = await _readingClinicalDataRepository.SaveChangesAsync(); + return ResponseOutput.Ok(entity.Id); } - return (result, new - { - IsCanAddClinicalData = false, - }); } #endregion diff --git a/IRaCIS.Core.Application/Service/Reading/Dto/ReadingClinicalDataDto.cs b/IRaCIS.Core.Application/Service/Reading/Dto/ReadingClinicalDataDto.cs index 59e9b85d1..8bbf13388 100644 --- a/IRaCIS.Core.Application/Service/Reading/Dto/ReadingClinicalDataDto.cs +++ b/IRaCIS.Core.Application/Service/Reading/Dto/ReadingClinicalDataDto.cs @@ -234,12 +234,28 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto /// public bool SelectIsSign { get; set; } = true; + /// + /// 是否查询所有的一致性分析临床数据 (为否只查询PDF) + /// + public bool IsGetAllConsistencyAnalysis { get; set; } = true; + } - /// - /// 获取访视列表 - /// - public class GetReadingClinicalDataListIndto + public class GetConsistencyAnalysisReadingClinicalDataListInDto + { + [NotDefault] + public Guid SubjectId { get; set; } + [NotDefault] + public Guid VisitTaskId { get; set; } + + [NotDefault] + public Guid TrialId { get; set; } + } + + /// + /// 获取访视列表 + /// + public class GetReadingClinicalDataListIndto { [NotDefault] public Guid SubjectId { get; set; } From 13acd950adbe2799a1d424c4a62f728c7d1de453 Mon Sep 17 00:00:00 2001 From: he <109787524@qq.com> Date: Thu, 1 Aug 2024 10:39:21 +0800 Subject: [PATCH 154/251] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ReadingClinicalDataService.cs | 26 +++++++++---------- .../Service/Reading/_MapConfig.cs | 1 + 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs b/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs index 61082c802..458d15cbd 100644 --- a/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs +++ b/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs @@ -1147,7 +1147,7 @@ namespace IRaCIS.Application.Services [HttpPost] public async Task AddOrUpdateConsistencyAnalysisReadingClinicalData(AddOrUpdateReadingClinicalDataDto indto) { - var existsQuery = _readingClinicalDataRepository + var existsQuery = _readingConsistentClinicalDataRepository .WhereIf(indto.Id != null, x => x.Id != indto.Id) .Where(x => x.ClinicalDataTrialSetId == indto.ClinicalDataTrialSetId && x.ReadingId == indto.ReadingId && x.StudyId == indto.StudyId); @@ -1163,8 +1163,8 @@ namespace IRaCIS.Application.Services if (indto.Id == null) { - var entity = _mapper.Map(indto); - entity.ReadingClinicalDataPDFList = indto.AddFileList.Select(x => new ReadingClinicalDataPDF() + var entity = _mapper.Map(indto); + entity.ReadingClinicalDataPDFList = indto.AddFileList.Select(x => new ReadingConsistentClinicalDataPDF() { FileName = x.FileName, Path = x.Path, @@ -1176,23 +1176,23 @@ namespace IRaCIS.Application.Services entity.IsBlind = null; entity.IsComplete = null; entity.FileCount = entity.ReadingClinicalDataPDFList.Count; - await _readingClinicalDataRepository.AddAsync(entity, true); - var success = await _readingClinicalDataRepository.SaveChangesAsync(); + await _readingConsistentClinicalDataRepository.AddAsync(entity, true); + var success = await _readingConsistentClinicalDataRepository.SaveChangesAsync(); return ResponseOutput.Ok(entity.Id); } else { - var entity = (await _readingClinicalDataRepository.Where(t => t.Id == indto.Id, true).FirstOrDefaultAsync()).IfNullThrowException(); - await _readingClinicalDataPDFRepository.BatchDeleteNoTrackingAsync(x => indto.DeleteFileIds.Contains(x.Id)); + var entity = (await _readingConsistentClinicalDataRepository.Where(t => t.Id == indto.Id, true).FirstOrDefaultAsync()).IfNullThrowException(); + await _readingConsistentClinicalDataPDFRepository.BatchDeleteNoTrackingAsync(x => indto.DeleteFileIds.Contains(x.Id)); - var addFileList = indto.AddFileList.Select(x => new ReadingClinicalDataPDF() + var addFileList = indto.AddFileList.Select(x => new ReadingConsistentClinicalDataPDF() { FileName = x.FileName, Path = x.Path, Size = x.Size, Type = x.Type, - ReadingClinicalDataId = entity.Id, + ReadingConsistentClinicalDataId = entity.Id, }).ToList(); @@ -1207,15 +1207,15 @@ namespace IRaCIS.Application.Services entity.IsBlind = null; } - await _readingClinicalDataPDFRepository.AddRangeAsync(addFileList); + await _readingConsistentClinicalDataPDFRepository.AddRangeAsync(addFileList); - await _readingClinicalDataPDFRepository.SaveChangesAsync(); + await _readingConsistentClinicalDataPDFRepository.SaveChangesAsync(); - var fileCount = await _readingClinicalDataPDFRepository.Where(t => t.ReadingClinicalDataId == indto.Id).CountAsync(); + var fileCount = await _readingConsistentClinicalDataPDFRepository.Where(t => t.ReadingConsistentClinicalDataId == indto.Id).CountAsync(); entity.ReadingClinicalDataState = ReadingClinicalDataStatus.HaveUploaded; entity.IsSign = false; entity.FileCount = fileCount; - var success = await _readingClinicalDataRepository.SaveChangesAsync(); + var success = await _readingConsistentClinicalDataRepository.SaveChangesAsync(); return ResponseOutput.Ok(entity.Id); } diff --git a/IRaCIS.Core.Application/Service/Reading/_MapConfig.cs b/IRaCIS.Core.Application/Service/Reading/_MapConfig.cs index e2a260e9f..fe279c652 100644 --- a/IRaCIS.Core.Application/Service/Reading/_MapConfig.cs +++ b/IRaCIS.Core.Application/Service/Reading/_MapConfig.cs @@ -118,6 +118,7 @@ namespace IRaCIS.Core.Application.Service //.ForMember(d => d.SiteNames, u => u.MapFrom(s => s.ReadingPeriodSites.SelectMany(x => x.Site.SiteName).ToList())); CreateMap().ReverseMap(); + CreateMap().ReverseMap(); CreateMap().ReverseMap(); From b8e0c74d451e52ff48342febb110f45b40026fa1 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Thu, 1 Aug 2024 10:50:11 +0800 Subject: [PATCH 155/251] =?UTF-8?q?=E7=94=A8=E6=88=B7=E5=8F=8D=E9=A6=88?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=AD=97=E6=AE=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Management/DTO/UserFeedBackViewModel.cs | 10 ++++ .../Service/Management/UserFeedBackService.cs | 60 +++++++++++++++++-- IRaCIS.Core.Domain/Management/UserFeedBack.cs | 6 ++ 3 files changed, 71 insertions(+), 5 deletions(-) diff --git a/IRaCIS.Core.Application/Service/Management/DTO/UserFeedBackViewModel.cs b/IRaCIS.Core.Application/Service/Management/DTO/UserFeedBackViewModel.cs index 5635af438..b3c1098b2 100644 --- a/IRaCIS.Core.Application/Service/Management/DTO/UserFeedBackViewModel.cs +++ b/IRaCIS.Core.Application/Service/Management/DTO/UserFeedBackViewModel.cs @@ -35,6 +35,14 @@ namespace IRaCIS.Core.Application.ViewModel public UserTypeEnum UserTypeEnum { get; set; } } + + public class GetUserFeedBackQuery + { + public Guid? Id { get; set; } + + public Guid? VisitTaskId { get; set; } + } + ///UserFeedBackQuery 列表查询参数模型 public class UserFeedBackQuery : PageInput { @@ -78,6 +86,8 @@ namespace IRaCIS.Core.Application.ViewModel [NotDefault] public Guid TrialId { get; set; } + public Guid? VisitTaskId { get; set; } + public List ScreenshotList { get; set; } [JsonIgnore] diff --git a/IRaCIS.Core.Application/Service/Management/UserFeedBackService.cs b/IRaCIS.Core.Application/Service/Management/UserFeedBackService.cs index e21a818fe..f24fd97c7 100644 --- a/IRaCIS.Core.Application/Service/Management/UserFeedBackService.cs +++ b/IRaCIS.Core.Application/Service/Management/UserFeedBackService.cs @@ -9,6 +9,8 @@ using Microsoft.AspNetCore.Mvc; using IRaCIS.Core.Application.Interfaces; using IRaCIS.Core.Application.ViewModel; using Newtonsoft.Json; +using IRaCIS.Core.Domain.Share; +using IRaCIS.Core.Infrastructure; namespace IRaCIS.Core.Application.Service { /// @@ -29,33 +31,81 @@ namespace IRaCIS.Core.Application.Service public async Task> GetUserFeedBackList(UserFeedBackQuery inQuery) { + var isCRCOrIR = _userInfo.UserTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.CRA || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.IndependentReviewer; + var userFeedBackQueryable = _userFeedBackRepository + .WhereIf(isCRCOrIR, t => t.CreateUserId == _userInfo.Id) .WhereIf(inQuery.State != null, t => t.State == inQuery.State) .WhereIf(inQuery.QuestionType != null, t => t.QuestionType == inQuery.QuestionType) .WhereIf(inQuery.BeginCreatime != null, t => t.CreateTime >= inQuery.BeginCreatime) - + .WhereIf(inQuery.EndCreatime != null, t => t.CreateTime == inQuery.EndCreatime) .WhereIf(inQuery.UserTypeEnum != null, t => t.CreateUser.UserTypeEnum == inQuery.UserTypeEnum) - .WhereIf(!string.IsNullOrEmpty(inQuery.QuestionDescription), t => t.QuestionDescription.Contains(inQuery.QuestionDescription) ) + .WhereIf(!string.IsNullOrEmpty(inQuery.QuestionDescription), t => t.QuestionDescription.Contains(inQuery.QuestionDescription)) .WhereIf(!string.IsNullOrEmpty(inQuery.TrialKeyInfo), t => t.Trial.ExperimentName.Contains(inQuery.TrialKeyInfo) || t.Trial.TrialCode.Contains(inQuery.TrialKeyInfo)) .WhereIf(!string.IsNullOrEmpty(inQuery.SubejctAndVisitKeyInfo), t => t.Subject.Code.Contains(inQuery.SubejctAndVisitKeyInfo) || t.SubjectVisit.VisitName.Contains(inQuery.SubejctAndVisitKeyInfo)) - .WhereIf(!string.IsNullOrEmpty(inQuery.TrialSiteCode), t => t.TrialSite.TrialSiteCode.Contains(inQuery.TrialSiteCode) ) - + .WhereIf(!string.IsNullOrEmpty(inQuery.TrialSiteCode), t => t.TrialSite.TrialSiteCode.Contains(inQuery.TrialSiteCode)) + .ProjectTo(_mapper.ConfigurationProvider); var pageList = await userFeedBackQueryable - + .ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, string.IsNullOrWhiteSpace(inQuery.SortField) ? nameof(UserFeedBackView.Id) : inQuery.SortField, inQuery.Asc); return pageList; } + [HttpPost] + public async Task GetUserFeedBackInfo(GetUserFeedBackQuery inQuery) + { + if (inQuery.Id == null && inQuery.VisitTaskId == null) + { + throw new BusinessValidationFailedException("Id 或者VisitTaskId 必传一个"); + } + + var result = _userFeedBackRepository.WhereIf(inQuery.Id == null, t => t.VisitTaskId == inQuery.VisitTaskId) + .WhereIf(inQuery.VisitTaskId == null, t => t.Id == inQuery.Id).ProjectTo(_mapper.ConfigurationProvider).FirstOrDefaultAsync(); + + return ResponseOutput.Ok(result); + } + public async Task AddOrUpdateUserFeedBack(UserFeedBackAddOrEdit addOrEditUserFeedBack) { addOrEditUserFeedBack.ScreenshotListStr = JsonConvert.SerializeObject(addOrEditUserFeedBack.ScreenshotList); + if (addOrEditUserFeedBack.VisitTaskId != null) + { + var info = await _repository.Where(t => t.Id == addOrEditUserFeedBack.VisitTaskId).Select(t => new { t.SubjectId, t.SourceSubjectVisitId, t.Subject.TrialSiteId }).FirstOrDefaultAsync(); + + if (info != null) + { + addOrEditUserFeedBack.SubjectId = info.SubjectId; + addOrEditUserFeedBack.TrialSiteId = info.TrialSiteId; + addOrEditUserFeedBack.SubjectVisitId = info.SourceSubjectVisitId; + } + } + + else if (addOrEditUserFeedBack.SubjectVisitId != null) + { + var info = await _repository.Where(t => t.Id == addOrEditUserFeedBack.SubjectVisitId).Select(t => new { t.TrialSiteId, t.SubjectId }).FirstOrDefaultAsync(); + + if (info != null) + { + addOrEditUserFeedBack.TrialSiteId = info.TrialSiteId; + addOrEditUserFeedBack.SubjectId = info.SubjectId; + } + } + else if (addOrEditUserFeedBack.SubjectId != null) + { + var info = await _repository.Where(t => t.Id == addOrEditUserFeedBack.SubjectId).Select(t => new { t.TrialSiteId }).FirstOrDefaultAsync(); + + if (info != null) + { + addOrEditUserFeedBack.TrialSiteId = info.TrialSiteId; + } + } var entity = await _userFeedBackRepository.InsertOrUpdateAsync(addOrEditUserFeedBack, true); diff --git a/IRaCIS.Core.Domain/Management/UserFeedBack.cs b/IRaCIS.Core.Domain/Management/UserFeedBack.cs index d9ec5f7bb..999a4c04e 100644 --- a/IRaCIS.Core.Domain/Management/UserFeedBack.cs +++ b/IRaCIS.Core.Domain/Management/UserFeedBack.cs @@ -27,6 +27,12 @@ namespace IRaCIS.Core.Domain.Models [JsonIgnore] public User CreateUser { get; set; } + [JsonIgnore] + + public VisitTask VisitTask { get; set; } + + public Guid? VisitTaskId { get; set; } + public Guid? SubjectId { get; set; } From a6b8db30c3b020e4ceaed577657786034d158fb0 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Thu, 1 Aug 2024 11:48:24 +0800 Subject: [PATCH 156/251] =?UTF-8?q?scp=20=E4=BC=A0=E8=BE=93=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=E5=A4=87=E6=B3=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRC.Core.SCP/Service/CStoreSCPService.cs | 26 ++++++++++++------------ 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/IRC.Core.SCP/Service/CStoreSCPService.cs b/IRC.Core.SCP/Service/CStoreSCPService.cs index 539e24b36..6cfb381ad 100644 --- a/IRC.Core.SCP/Service/CStoreSCPService.cs +++ b/IRC.Core.SCP/Service/CStoreSCPService.cs @@ -58,21 +58,21 @@ namespace IRaCIS.Core.SCP.Service private static readonly DicomTransferSyntax[] _acceptedImageTransferSyntaxes = new DicomTransferSyntax[] { - // Lossless - DicomTransferSyntax.JPEGLSLossless, - DicomTransferSyntax.JPEG2000Lossless, - DicomTransferSyntax.JPEGProcess14SV1, - DicomTransferSyntax.JPEGProcess14, - DicomTransferSyntax.RLELossless, + // Lossless + DicomTransferSyntax.JPEGLSLossless, //1.2.840.10008.1.2.4.80 + DicomTransferSyntax.JPEG2000Lossless, //1.2.840.10008.1.2.4.90 + DicomTransferSyntax.JPEGProcess14SV1, //1.2.840.10008.1.2.4.70 + DicomTransferSyntax.JPEGProcess14, //1.2.840.10008.1.2.4.57 JPEG Lossless, Non-Hierarchical (Process 14) + DicomTransferSyntax.RLELossless, //1.2.840.10008.1.2.5 // Lossy - DicomTransferSyntax.JPEGLSNearLossless, - DicomTransferSyntax.JPEG2000Lossy, - DicomTransferSyntax.JPEGProcess1, - DicomTransferSyntax.JPEGProcess2_4, + DicomTransferSyntax.JPEGLSNearLossless,//1.2.840.10008.1.2.4.81" + DicomTransferSyntax.JPEG2000Lossy, //1.2.840.10008.1.2.4.91 + DicomTransferSyntax.JPEGProcess1, //1.2.840.10008.1.2.4.50 + DicomTransferSyntax.JPEGProcess2_4, //1.2.840.10008.1.2.4.51 // Uncompressed - DicomTransferSyntax.ExplicitVRLittleEndian, - DicomTransferSyntax.ExplicitVRBigEndian, - DicomTransferSyntax.ImplicitVRLittleEndian + DicomTransferSyntax.ExplicitVRLittleEndian, //1.2.840.10008.1.2.1 + DicomTransferSyntax.ExplicitVRBigEndian, //1.2.840.10008.1.2.2 + DicomTransferSyntax.ImplicitVRLittleEndian //1.2.840.10008.1.2 }; From 3e5d0b650dbb2c7db0c37bcb7e42efab1c2d29ca Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Thu, 1 Aug 2024 13:17:23 +0800 Subject: [PATCH 157/251] =?UTF-8?q?=E6=88=AA=E5=9B=BE=E7=BB=99=E9=BB=98?= =?UTF-8?q?=E8=AE=A4=E5=80=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Service/Management/DTO/UserFeedBackViewModel.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/IRaCIS.Core.Application/Service/Management/DTO/UserFeedBackViewModel.cs b/IRaCIS.Core.Application/Service/Management/DTO/UserFeedBackViewModel.cs index b3c1098b2..cb375a0db 100644 --- a/IRaCIS.Core.Application/Service/Management/DTO/UserFeedBackViewModel.cs +++ b/IRaCIS.Core.Application/Service/Management/DTO/UserFeedBackViewModel.cs @@ -91,7 +91,7 @@ namespace IRaCIS.Core.Application.ViewModel public List ScreenshotList { get; set; } [JsonIgnore] - public string ScreenshotListStr { get; set; } + public string ScreenshotListStr { get; set; } = string.Empty; } From 7069a17d8ee0404220f8e1e750c92180ad420cd6 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Thu, 1 Aug 2024 13:31:53 +0800 Subject: [PATCH 158/251] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=8F=82=E6=95=B0?= =?UTF-8?q?=E5=BF=85=E4=BC=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../IRaCIS.Core.Application.xml | 16 ++++++++++++++-- .../Management/DTO/UserFeedBackViewModel.cs | 2 +- .../Service/Management/UserFeedBackService.cs | 5 +---- 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml index fa33a1f82..a79b6199f 100644 --- a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml +++ b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml @@ -5303,6 +5303,11 @@ 只查询已经签名的临床数据 + + + 是否查询所有的一致性分析临床数据 (为否只查询PDF) + + 获取访视列表 @@ -14129,13 +14134,20 @@ - + - 获取阅片临床数据列表 + 获取阅片临床数据列表 (在任务列表) + + + 新增或修改一致性分析临床数据 + + + + 获取单个阅片临床数据的所有文件 diff --git a/IRaCIS.Core.Application/Service/Management/DTO/UserFeedBackViewModel.cs b/IRaCIS.Core.Application/Service/Management/DTO/UserFeedBackViewModel.cs index cb375a0db..14a6fcd70 100644 --- a/IRaCIS.Core.Application/Service/Management/DTO/UserFeedBackViewModel.cs +++ b/IRaCIS.Core.Application/Service/Management/DTO/UserFeedBackViewModel.cs @@ -53,7 +53,7 @@ namespace IRaCIS.Core.Application.ViewModel public UserTypeEnum? UserTypeEnum { get; set; } - public string FeedBackKeyInfo { get; set; } + public string? FeedBackKeyInfo { get; set; } public string? QuestionDescription { get; set; } diff --git a/IRaCIS.Core.Application/Service/Management/UserFeedBackService.cs b/IRaCIS.Core.Application/Service/Management/UserFeedBackService.cs index f24fd97c7..2f06b3fd0 100644 --- a/IRaCIS.Core.Application/Service/Management/UserFeedBackService.cs +++ b/IRaCIS.Core.Application/Service/Management/UserFeedBackService.cs @@ -48,10 +48,7 @@ namespace IRaCIS.Core.Application.Service .ProjectTo(_mapper.ConfigurationProvider); - var pageList = await userFeedBackQueryable - - .ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, string.IsNullOrWhiteSpace(inQuery.SortField) ? nameof(UserFeedBackView.Id) : inQuery.SortField, - inQuery.Asc); + var pageList = await userFeedBackQueryable.ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, string.IsNullOrWhiteSpace(inQuery.SortField) ? nameof(UserFeedBackView.Id) : inQuery.SortField,inQuery.Asc); return pageList; } From 9cd4e272c728a99cab9f3d56be6b46c3940b6e36 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Thu, 1 Aug 2024 13:36:46 +0800 Subject: [PATCH 159/251] =?UTF-8?q?=E9=81=97=E6=BC=8Fawait?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Service/Management/UserFeedBackService.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/IRaCIS.Core.Application/Service/Management/UserFeedBackService.cs b/IRaCIS.Core.Application/Service/Management/UserFeedBackService.cs index 2f06b3fd0..a9217b6a5 100644 --- a/IRaCIS.Core.Application/Service/Management/UserFeedBackService.cs +++ b/IRaCIS.Core.Application/Service/Management/UserFeedBackService.cs @@ -61,7 +61,7 @@ namespace IRaCIS.Core.Application.Service throw new BusinessValidationFailedException("Id 或者VisitTaskId 必传一个"); } - var result = _userFeedBackRepository.WhereIf(inQuery.Id == null, t => t.VisitTaskId == inQuery.VisitTaskId) + var result = await _userFeedBackRepository.WhereIf(inQuery.Id == null, t => t.VisitTaskId == inQuery.VisitTaskId) .WhereIf(inQuery.VisitTaskId == null, t => t.Id == inQuery.Id).ProjectTo(_mapper.ConfigurationProvider).FirstOrDefaultAsync(); return ResponseOutput.Ok(result); From 3561df75743188f47374a79abad3837e0ebf5df3 Mon Sep 17 00:00:00 2001 From: he <109787524@qq.com> Date: Thu, 1 Aug 2024 16:12:48 +0800 Subject: [PATCH 160/251] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ReadingClinicalDataService.cs | 56 ++++++++++++++++++- .../Reading/Dto/ReadingClinicalDataDto.cs | 24 +++++++- IRaCIS.Core.Domain/Allocation/VisitTask.cs | 7 ++- 3 files changed, 83 insertions(+), 4 deletions(-) diff --git a/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs b/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs index 458d15cbd..9a620aaed 100644 --- a/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs +++ b/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs @@ -12,6 +12,8 @@ using System.Linq.Dynamic.Core; using Microsoft.Extensions.Logging; using IRaCIS.Core.Infrastructure.Extention; using System.Linq; +using BeetleX.Redis.Commands; +using NPOI.SS.Formula.Functions; namespace IRaCIS.Application.Services { @@ -1124,7 +1126,7 @@ namespace IRaCIS.Application.Services /// /// [HttpPost] - public async Task> GetConsistencyAnalysisReadingClinicalDataList(GetConsistencyAnalysisReadingClinicalDataListInDto inDto) + public async Task<(List, object)> GetConsistencyAnalysisReadingClinicalDataList(GetConsistencyAnalysisReadingClinicalDataListInDto inDto) { var result = await this.GetClinicalDataList(new GetReadingOrTaskClinicalDataListInDto() { @@ -1134,7 +1136,7 @@ namespace IRaCIS.Application.Services IsGetAllConsistencyAnalysis = false, }); - return result; + return (result,true); } @@ -1221,6 +1223,56 @@ namespace IRaCIS.Application.Services } } + + + /// + /// 一致性分析临床数据签名 + /// + /// + /// + [HttpPost] + public async Task SignConsistencyAnalysisReadingClinicalData(SignConsistencyAnalysisReadingClinicalDataInDto inDto) + { + var pdfCount = await _readingConsistentClinicalDataPDFRepository.Where(x => x.ReadingConsistentClinicalDataId == inDto.ConsistentClinicalDataId).CountAsync(); + if (pdfCount == 0) + { + return ResponseOutput.NotOk(_localizer["ReadingClinicalData_NoHavePDF"]); + } + await _readingConsistentClinicalDataRepository.UpdatePartialFromQueryAsync(x => x.Id == inDto.ConsistentClinicalDataId, x => new ReadingConsistentClinicalData() + { + IsSign = true, + IsBlind = inDto.IsBlind, + IsComplete = inDto.IsComplete + }); + await _readingClinicalDataPDFRepository.SaveChangesAsync(); + return ResponseOutput.Ok(pdfCount); + } + + /// + /// 一致性分析临床数据签名完设置任务为有效 + /// + /// + /// + [HttpPost] + public async Task SetTaskValid(SetTaskValidInDto inDto) + { + var visittask = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).FirstNotNullAsync(); + var readingId = visittask.SouceReadModuleId==null? visittask.SourceSubjectVisitId: visittask.SouceReadModuleId; + + if (await _readingConsistentClinicalDataRepository.AnyAsync(x => x.ReadingId == readingId && x.IsSign == false)) + { + return ResponseOutput.NotOk(_localizer["ReadingClinicalData_HaveUnsignedClinicalData"]); + } + + await _visitTaskRepository.UpdatePartialFromQueryAsync(x => x.Id == inDto.VisitTaskId, x => new VisitTask() + { + + TaskState = TaskState.Effect + }); + await _visitTaskRepository.SaveChangesAsync(); + return ResponseOutput.Ok(); + + } #endregion #region 阅片临床数据PDF diff --git a/IRaCIS.Core.Application/Service/Reading/Dto/ReadingClinicalDataDto.cs b/IRaCIS.Core.Application/Service/Reading/Dto/ReadingClinicalDataDto.cs index 8bbf13388..edf51866c 100644 --- a/IRaCIS.Core.Application/Service/Reading/Dto/ReadingClinicalDataDto.cs +++ b/IRaCIS.Core.Application/Service/Reading/Dto/ReadingClinicalDataDto.cs @@ -9,8 +9,30 @@ using System.Threading.Tasks; namespace IRaCIS.Core.Application.Service.Reading.Dto { + public class SetTaskValidInDto + { + public Guid VisitTaskId { get; set; } + } - public class AddOrUpdateReadingClinicalDataDto + + public class SignConsistencyAnalysisReadingClinicalDataInDto + { + public Guid ConsistentClinicalDataId { get; set; } + + /// + /// 是否盲化 + /// + public bool? IsBlind { get; set; } + + /// + /// 是否完整 + /// + public bool? IsComplete { get; set; } + + } + + + public class AddOrUpdateReadingClinicalDataDto { public Guid? Id { get; set; } diff --git a/IRaCIS.Core.Domain/Allocation/VisitTask.cs b/IRaCIS.Core.Domain/Allocation/VisitTask.cs index f1eb0a159..77516f056 100644 --- a/IRaCIS.Core.Domain/Allocation/VisitTask.cs +++ b/IRaCIS.Core.Domain/Allocation/VisitTask.cs @@ -368,9 +368,14 @@ namespace IRaCIS.Core.Domain.Models public bool IsNeedClinicalDataSign { get; set; } + /// + /// 临床数据是否签名 + /// public bool IsClinicalDataSign { get; set; } - //前序任务需要签名 但是未签名 + /// + /// 前序任务需要签名 但是未签名 + /// public bool IsFrontTaskNeedSignButNotSign { get; set; } [JsonIgnore] From 7c5f3323de95b5bee769fdfbc6cf97a13e016792 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Thu, 1 Aug 2024 16:57:25 +0800 Subject: [PATCH 161/251] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E4=B8=8B=E8=BD=BD?= =?UTF-8?q?=E4=BF=A1=E6=81=AF=E7=9A=84=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ImageAndDoc/DTO/UnionStudyViewDodel.cs | 14 ++ .../ImageAndDoc/DownloadAndUploadService.cs | 142 +++++++++++++++--- 2 files changed, 135 insertions(+), 21 deletions(-) diff --git a/IRaCIS.Core.Application/Service/ImageAndDoc/DTO/UnionStudyViewDodel.cs b/IRaCIS.Core.Application/Service/ImageAndDoc/DTO/UnionStudyViewDodel.cs index 6be7f1de5..24982f635 100644 --- a/IRaCIS.Core.Application/Service/ImageAndDoc/DTO/UnionStudyViewDodel.cs +++ b/IRaCIS.Core.Application/Service/ImageAndDoc/DTO/UnionStudyViewDodel.cs @@ -214,6 +214,20 @@ namespace IRaCIS.Core.Application.Contracts public int FileCount { get; set; } } + + public class SubejctZipInfoQuery + { + public Guid? SubejctId { get; set; } + + public string? SubjectCode { get; set; } + + + public Guid? SubejectVisitId { get; set; } + + public Guid? TrialReadingCriterionId { get; set; } + + } + public class TaskArchiveStudyCommand { [NotDefault] diff --git a/IRaCIS.Core.Application/Service/ImageAndDoc/DownloadAndUploadService.cs b/IRaCIS.Core.Application/Service/ImageAndDoc/DownloadAndUploadService.cs index 9f71bad89..acf4c3dd5 100644 --- a/IRaCIS.Core.Application/Service/ImageAndDoc/DownloadAndUploadService.cs +++ b/IRaCIS.Core.Application/Service/ImageAndDoc/DownloadAndUploadService.cs @@ -4,6 +4,7 @@ using IRaCIS.Core.Application.Contracts; using IRaCIS.Core.Application.Filter; using IRaCIS.Core.Application.Helper; using IRaCIS.Core.Application.Service.ImageAndDoc.DTO; +using IRaCIS.Core.Domain.Models; using IRaCIS.Core.Domain.Share; using IRaCIS.Core.Infrastructure; using IRaCIS.Core.Infrastructure.Extention; @@ -11,6 +12,7 @@ using MassTransit; using MathNet.Numerics; using Medallion.Threading; using Microsoft.AspNetCore.Mvc; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion.Internal; using Newtonsoft.Json; using System; using System.Collections.Generic; @@ -536,36 +538,134 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc - public async Task GetSubejectVisitPathInfo(Guid subjectVisitId) + /// + /// 受试者级别所有的影像 + /// 访视级别的影响 传递subjectVisitId + /// 标准Id是可选的 不同标准有些检查可能有过滤 + /// + /// + /// + /// + public async Task GetSubejectOrVisitZipInfo([FromServices] IRepository _subjectRepository, SubejctZipInfoQuery inQuery) { - var query = from sv in _subjectVisitRepository.Where(t => t.Id == subjectVisitId) + var isImageFilter = false; - select new - { - SubjectCode = sv.Subject.Code, - VisitName = sv.VisitName, - StudyList = sv.StudyList.Select(u => new + var criterionModalitys = string.Empty; + + if (inQuery.TrialReadingCriterionId != null) + { + var criterionInfo = await _repository.Where(t => t.Id == inQuery.TrialReadingCriterionId).Select(t => new { t.IsImageFilter, t.CriterionModalitys }).FirstOrDefaultAsync(); + + if (criterionInfo != null) + { + isImageFilter = criterionInfo.IsImageFilter; + criterionModalitys = criterionInfo.CriterionModalitys; + } + + } + + if (inQuery.SubejectVisitId != null) + { + var query = from sv in _subjectVisitRepository.Where(t => t.Id == inQuery.SubejectVisitId) + + + select new { - u.PatientId, - u.StudyTime, - u.StudyCode, - - SeriesList = u.SeriesList.Select(z => new + SubjectCode = sv.Subject.Code, + VisitName = sv.VisitName, + StudyList = sv.StudyList.AsQueryable().WhereIf(isImageFilter, t => ("|" + criterionModalitys + "|").Contains("|" + t.ModalityForEdit + "|")) + .Select(u => new { - z.Modality, + u.PatientId, + u.StudyTime, + u.StudyCode, - InstancePathList = z.DicomInstanceList.Select(k => new + SeriesList = u.SeriesList.Select(z => new { - k.Path + z.Modality, + + InstancePathList = z.DicomInstanceList.Select(k => new + { + k.Path + }) + }) + + }), + + NoneDicomStudyList = sv.NoneDicomStudyList.AsQueryable().WhereIf(isImageFilter, t => ("|" + criterionModalitys + "|").Contains("|" + t.Modality + "|")) + .Select(nd => new + { + nd.Modality, + nd.StudyCode, + nd.ImageDate, + + FileList = nd.NoneDicomFileList.Select(file => new + { + file.FileName, + file.Path, + file.FileType }) }) + }; - }) - }; + var result = query.ToList(); + + return ResponseOutput.Ok(result); + } + else if (inQuery.SubejctId != null) + { + var query = from sv in _subjectRepository.Where(t => t.Id == inQuery.SubejctId).SelectMany(t=>t.SubjectVisitList) + + + select new + { + SubjectCode = sv.Subject.Code, + VisitName = sv.VisitName, + StudyList = sv.StudyList.AsQueryable().WhereIf(isImageFilter, t => ("|" + criterionModalitys + "|").Contains("|" + t.ModalityForEdit + "|")) + .Select(u => new + { + u.PatientId, + u.StudyTime, + u.StudyCode, + + SeriesList = u.SeriesList.Select(z => new + { + z.Modality, + + InstancePathList = z.DicomInstanceList.Select(k => new + { + k.Path + }) + }) + + }), + + NoneDicomStudyList = sv.NoneDicomStudyList.AsQueryable().WhereIf(isImageFilter, t => ("|" + criterionModalitys + "|").Contains("|" + t.Modality + "|")) + .Select(nd => new + { + nd.Modality, + nd.StudyCode, + nd.ImageDate, + + FileList = nd.NoneDicomFileList.Select(file => new + { + file.FileName, + file.Path, + file.FileType + }) + }) + }; + + var result = query.ToList(); + + return ResponseOutput.Ok(result); + } + else + { + return ResponseOutput.NotOk("不允许 subjectId subjectId 都不传递"); + } - var info = query.FirstOrDefault(); - return ResponseOutput.Ok(info); } /// @@ -765,9 +865,9 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc foreach (var file in noneDicomStudy.FileList) { string destinationPath = Path.Combine(studyNoneDicomFolderPath, Path.GetFileName(file.FileName)); - + //下载到当前目录 - await _oSSService.DownLoadFromOSSAsync(HttpUtility.UrlDecode(file.Path) , destinationPath); + await _oSSService.DownLoadFromOSSAsync(HttpUtility.UrlDecode(file.Path), destinationPath); } } From 62f37a4bb4f79b743e57b8634a473f9ad19cb5a0 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Thu, 1 Aug 2024 17:05:28 +0800 Subject: [PATCH 162/251] =?UTF-8?q?crc=20=E9=87=8D=E4=BC=A0=E5=85=81?= =?UTF-8?q?=E8=AE=B8=E4=BF=AE=E6=94=B9=E9=83=A8=E4=BD=8D=E7=BC=96=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.Application/Service/QC/QCOperationService.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/IRaCIS.Core.Application/Service/QC/QCOperationService.cs b/IRaCIS.Core.Application/Service/QC/QCOperationService.cs index d67743443..dd8f0f34c 100644 --- a/IRaCIS.Core.Application/Service/QC/QCOperationService.cs +++ b/IRaCIS.Core.Application/Service/QC/QCOperationService.cs @@ -707,7 +707,7 @@ namespace IRaCIS.Core.Application.Image.QA } else { - if (await _subjectVisitRepository.AnyAsync(t => t.Id == updateModalityCommand.SubjectVisitId && t.SubmitState == SubmitStateEnum.Submitted)) + if (await _subjectVisitRepository.AnyAsync(t => t.Id == updateModalityCommand.SubjectVisitId && t.SubmitState == SubmitStateEnum.Submitted && !t.QCChallengeList.Any(c=>c.ReuploadEnum==QCChanllengeReuploadEnum.CRCRequestReupload)) ) { //---提交之后,不允许修改! throw new BusinessValidationFailedException(_localizer["QCOperation_NoModifyAfterSubmit"]); From 63c6c2f67b0f639831d360b964a575ee15f29900 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Thu, 1 Aug 2024 17:22:10 +0800 Subject: [PATCH 163/251] =?UTF-8?q?QCAgreeUpload=20=20=E6=89=8D=E5=85=81?= =?UTF-8?q?=E8=AE=B8=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.Application/Service/QC/QCOperationService.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/IRaCIS.Core.Application/Service/QC/QCOperationService.cs b/IRaCIS.Core.Application/Service/QC/QCOperationService.cs index dd8f0f34c..3bccf5c80 100644 --- a/IRaCIS.Core.Application/Service/QC/QCOperationService.cs +++ b/IRaCIS.Core.Application/Service/QC/QCOperationService.cs @@ -707,7 +707,7 @@ namespace IRaCIS.Core.Application.Image.QA } else { - if (await _subjectVisitRepository.AnyAsync(t => t.Id == updateModalityCommand.SubjectVisitId && t.SubmitState == SubmitStateEnum.Submitted && !t.QCChallengeList.Any(c=>c.ReuploadEnum==QCChanllengeReuploadEnum.CRCRequestReupload)) ) + if (await _subjectVisitRepository.AnyAsync(t => t.Id == updateModalityCommand.SubjectVisitId && t.SubmitState == SubmitStateEnum.Submitted && !t.QCChallengeList.Any(c=>c.ReuploadEnum==QCChanllengeReuploadEnum.QCAgreeUpload)) ) { //---提交之后,不允许修改! throw new BusinessValidationFailedException(_localizer["QCOperation_NoModifyAfterSubmit"]); From eb1dcc9f0a33184e166f2a6784aab36e675df149 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Fri, 2 Aug 2024 09:54:31 +0800 Subject: [PATCH 164/251] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=8F=8D=E9=A6=88?= =?UTF-8?q?=E5=AD=97=E6=AE=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.API/_ServiceExtensions/EFSetup.cs | 2 +- .../Service/Allocation/DTO/VisitTaskViewModel.cs | 2 ++ IRaCIS.Core.Application/Service/Allocation/_MapConfig.cs | 2 +- IRaCIS.Core.Domain/Allocation/VisitTask.cs | 3 +++ 4 files changed, 7 insertions(+), 2 deletions(-) diff --git a/IRaCIS.Core.API/_ServiceExtensions/EFSetup.cs b/IRaCIS.Core.API/_ServiceExtensions/EFSetup.cs index 1f4ca4079..7c54848c6 100644 --- a/IRaCIS.Core.API/_ServiceExtensions/EFSetup.cs +++ b/IRaCIS.Core.API/_ServiceExtensions/EFSetup.cs @@ -18,7 +18,7 @@ namespace IRaCIS.Core.API //这个注入没有成功--注入是没问题的,构造函数也只是支持参数就好,错在注入的地方不能写DbContext //Web程序中通过重用池中DbContext实例可提高高并发场景下的吞吐量, 这在概念上类似于ADO.NET Provider原生的连接池操作方式,具有节省DbContext实例化成本的优点 - services.AddDbContext(options => + services.AddDbContextPool(options => { options.UseSqlServer(configuration.GetSection("ConnectionStrings:RemoteNew").Value, contextOptionsBuilder => contextOptionsBuilder.EnableRetryOnFailure()); diff --git a/IRaCIS.Core.Application/Service/Allocation/DTO/VisitTaskViewModel.cs b/IRaCIS.Core.Application/Service/Allocation/DTO/VisitTaskViewModel.cs index 27bcb5d88..302351e3d 100644 --- a/IRaCIS.Core.Application/Service/Allocation/DTO/VisitTaskViewModel.cs +++ b/IRaCIS.Core.Application/Service/Allocation/DTO/VisitTaskViewModel.cs @@ -201,6 +201,8 @@ namespace IRaCIS.Core.Application.ViewModel public Guid? SourceSubjectVisitId { get; set; } public Guid? SouceReadModuleId { get; set; } + + public bool IsHaveFeedBack { get; set; } //public bool IsAfterConvertedTask { get; set; } } diff --git a/IRaCIS.Core.Application/Service/Allocation/_MapConfig.cs b/IRaCIS.Core.Application/Service/Allocation/_MapConfig.cs index 510ee9b8b..649ca5ba6 100644 --- a/IRaCIS.Core.Application/Service/Allocation/_MapConfig.cs +++ b/IRaCIS.Core.Application/Service/Allocation/_MapConfig.cs @@ -145,7 +145,7 @@ namespace IRaCIS.Core.Application.Service .ForMember(o => o.HistoryReadingDoctorUserList, t => t.MapFrom(u => u.JudgeVisitList)); CreateMap().IncludeBase() - + .ForMember(o => o.IsHaveFeedBack, t => t.MapFrom(u => u.UserFeedBackList.Any())) ; CreateMap().IncludeBase() diff --git a/IRaCIS.Core.Domain/Allocation/VisitTask.cs b/IRaCIS.Core.Domain/Allocation/VisitTask.cs index 77516f056..5a45dd3c4 100644 --- a/IRaCIS.Core.Domain/Allocation/VisitTask.cs +++ b/IRaCIS.Core.Domain/Allocation/VisitTask.cs @@ -436,5 +436,8 @@ namespace IRaCIS.Core.Domain.Models public int ImageStudyState { get; set; } + [JsonIgnore] + public List UserFeedBackList { get; set; } + } } From c98db93ecbe009918adb268ef97d4afd5728c1fa Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Fri, 2 Aug 2024 10:30:33 +0800 Subject: [PATCH 165/251] =?UTF-8?q?=E4=B8=80=E8=87=B4=E6=80=A7=E5=88=86?= =?UTF-8?q?=E6=9E=90=20=E5=85=A8=E5=B1=80=E4=BB=BB=E5=8A=A1=20SouceReadMod?= =?UTF-8?q?uleId=20=20=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Allocation/TaskConsistentRuleService.cs | 53 +++++++++++-------- 1 file changed, 32 insertions(+), 21 deletions(-) diff --git a/IRaCIS.Core.Application/Service/Allocation/TaskConsistentRuleService.cs b/IRaCIS.Core.Application/Service/Allocation/TaskConsistentRuleService.cs index 0941f9d25..579c1e766 100644 --- a/IRaCIS.Core.Application/Service/Allocation/TaskConsistentRuleService.cs +++ b/IRaCIS.Core.Application/Service/Allocation/TaskConsistentRuleService.cs @@ -88,7 +88,7 @@ namespace IRaCIS.Core.Application.Service /// /// [HttpPost] - public async Task>> GetAnalysisTaskList(VisitTaskQuery queryVisitTask ) + public async Task>> GetAnalysisTaskList(VisitTaskQuery queryVisitTask) { var visitTaskQueryable = _visitTaskRepository.Where(t => t.TrialId == queryVisitTask.TrialId) .Where(t => t.IsAnalysisCreate) @@ -107,7 +107,7 @@ namespace IRaCIS.Core.Application.Service .WhereIf(queryVisitTask.ArmEnum != null, t => t.ArmEnum == queryVisitTask.ArmEnum) .WhereIf(!string.IsNullOrEmpty(queryVisitTask.TrialSiteCode), t => /*(t.BlindTrialSiteCode.Contains(queryVisitTask.TrialSiteCode!) && t.IsAnalysisCreate) ||*/ (t.Subject.TrialSite.TrialSiteCode.Contains(queryVisitTask.TrialSiteCode!) /*&& t.IsAnalysisCreate == false*/)) .WhereIf(!string.IsNullOrEmpty(queryVisitTask.TaskName), t => t.TaskName.Contains(queryVisitTask.TaskName) || t.TaskBlindName.Contains(queryVisitTask.TaskName)) - .WhereIf(!string.IsNullOrEmpty(queryVisitTask.SubjectCode), t => ((t.Subject.Code.Contains(queryVisitTask.SubjectCode)||t.Subject.MedicalNo.Contains(queryVisitTask.SubjectCode)) && t.IsAnalysisCreate == false) || (t.BlindSubjectCode.Contains(queryVisitTask.SubjectCode) && t.IsAnalysisCreate)) + .WhereIf(!string.IsNullOrEmpty(queryVisitTask.SubjectCode), t => ((t.Subject.Code.Contains(queryVisitTask.SubjectCode) || t.Subject.MedicalNo.Contains(queryVisitTask.SubjectCode)) && t.IsAnalysisCreate == false) || (t.BlindSubjectCode.Contains(queryVisitTask.SubjectCode) && t.IsAnalysisCreate)) .WhereIf(queryVisitTask.BeginAllocateDate != null, t => t.AllocateTime >= queryVisitTask.BeginAllocateDate) .WhereIf(queryVisitTask.EndAllocateDate != null, t => t.AllocateTime <= queryVisitTask.EndAllocateDate) .WhereIf(queryVisitTask.BeginSignTime != null, t => t.SignTime >= queryVisitTask.BeginSignTime) @@ -118,7 +118,7 @@ namespace IRaCIS.Core.Application.Service var pageList = await visitTaskQueryable.ToPagedListAsync(queryVisitTask.PageIndex, queryVisitTask.PageSize, queryVisitTask.SortField, queryVisitTask.Asc, string.IsNullOrWhiteSpace(queryVisitTask.SortField), defalutSortArray); - var trialTaskConfig = _repository.Where(t => t.Id == queryVisitTask.TrialId).Select(t => new { IsHaveDoubleReadCriterion=t.TrialReadingCriterionList.Any(t=>t.IsSigned && t.IsConfirm && t.ReadingType==ReadingMethod.Double), t.VitrualSiteCode }).FirstOrDefault(); + var trialTaskConfig = _repository.Where(t => t.Id == queryVisitTask.TrialId).Select(t => new { IsHaveDoubleReadCriterion = t.TrialReadingCriterionList.Any(t => t.IsSigned && t.IsConfirm && t.ReadingType == ReadingMethod.Double), t.VitrualSiteCode }).FirstOrDefault(); return ResponseOutput.Ok(pageList, trialTaskConfig); } @@ -154,7 +154,7 @@ namespace IRaCIS.Core.Application.Service { - var filterObj = await _taskConsistentRuleRepository.Where(t => t.Id == inCommand.TaskConsistentRuleId).Include(t=>t.TrialReadingCriterion).FirstOrDefaultAsync(); + var filterObj = await _taskConsistentRuleRepository.Where(t => t.Id == inCommand.TaskConsistentRuleId).Include(t => t.TrialReadingCriterion).FirstOrDefaultAsync(); var doctorUserId = inCommand.DoctorUserId; var trialReadingCriterionId = filterObj.TrialReadingCriterionId; @@ -169,7 +169,7 @@ namespace IRaCIS.Core.Application.Service throw new BusinessValidationFailedException(_localizer["TaskConsistent_NotAllowedGenerate"]); } - if (subjectList.Count<2 * filterObj.PlanSubjectCount) + if (subjectList.Count < 2 * filterObj.PlanSubjectCount) { throw new BusinessValidationFailedException(_localizer["TaskConsistent_NotAllowedGenerate1"]); } @@ -254,6 +254,17 @@ namespace IRaCIS.Core.Application.Service TaskBlindName = lastTask.TaskBlindName + "_Global", TrialReadingCriterionId = trialReadingCriterionId, }; + + var afterGlobal = _visitTaskRepository.Where(t => t.SubjectId == lastTask.SubjectId && t.TrialReadingCriterionId == trialReadingCriterionId && t.TaskState == TaskState.Effect && t.ReadingCategory == ReadingCategory.Global && t.VisitTaskNum > lastTask.VisitTaskNum).ProjectTo(_mapper.ConfigurationProvider).FirstOrDefault(); + + if (afterGlobal == null) + { + throw new BusinessValidationFailedException("联系后台排查数据,没找到后续全局"); + } + else + { + existGlobal.SouceReadModuleId = afterGlobal.SouceReadModuleId; + } } @@ -294,7 +305,7 @@ namespace IRaCIS.Core.Application.Service /// /// [HttpPost] - public async Task> > GetGroupConsistentRuleSubjectList(GroupConsistentQuery inQuery) + public async Task>> GetGroupConsistentRuleSubjectList(GroupConsistentQuery inQuery) { var trialId = inQuery.TrialId; @@ -304,7 +315,7 @@ namespace IRaCIS.Core.Application.Service if (filterObj == null) { object tt = null; - return ResponseOutput.Ok(new PageOutput(), new { Rule = tt, IsAllowAutoAllocate = false }) ; + return ResponseOutput.Ok(new PageOutput(), new { Rule = tt, IsAllowAutoAllocate = false }); } var query = await GetGroupConsistentQueryAsync(filterObj); @@ -316,9 +327,9 @@ namespace IRaCIS.Core.Application.Service var list = await GetGroupConsistentRuleMatchSubjectIdListAsync(new GroupConsistentSimpleQuery() { TrialId = inQuery.TrialId, TrialReadingCriterionId = inQuery.TrialReadingCriterionId }); - var isAllowAutoAllocate = !list.Any(t => t.IsHaveGeneratedTask) && list.Count() > 2*(rule?.PlanSubjectCount??0); + var isAllowAutoAllocate = !list.Any(t => t.IsHaveGeneratedTask) && list.Count() > 2 * (rule?.PlanSubjectCount ?? 0); - return ResponseOutput.Ok(pagedList, new {Rule=rule, IsAllowAutoAllocate = isAllowAutoAllocate }); + return ResponseOutput.Ok(pagedList, new { Rule = rule, IsAllowAutoAllocate = isAllowAutoAllocate }); } @@ -336,11 +347,11 @@ namespace IRaCIS.Core.Application.Service { var trialId = inCommand.TrialId; - var filterObj = await _taskConsistentRuleRepository.Where(t => t.TrialId == trialId && t.TrialReadingCriterionId == inCommand.TrialReadingCriterionId && t.IsSelfAnalysis == false).Include(t=>t.TrialReadingCriterion).FirstNotNullAsync(); + var filterObj = await _taskConsistentRuleRepository.Where(t => t.TrialId == trialId && t.TrialReadingCriterionId == inCommand.TrialReadingCriterionId && t.IsSelfAnalysis == false).Include(t => t.TrialReadingCriterion).FirstNotNullAsync(); var trialReadingCriterionId = filterObj.TrialReadingCriterionId; - + //随机分配 if (inCommand.IsAutoAllocateGenerateTask) @@ -353,12 +364,12 @@ namespace IRaCIS.Core.Application.Service throw new BusinessValidationFailedException(_localizer["TaskConsistent_NotAllowedGenerate"]); } - if (subjectSelectList.Count< 2 * filterObj.PlanSubjectCount) + if (subjectSelectList.Count < 2 * filterObj.PlanSubjectCount) { throw new BusinessValidationFailedException(_localizer["TaskConsistent_NotAllowedGenerate1"]); } - inCommand.SubejctIdList = subjectSelectList.Select(t => t.SubjectId).ToList().GetRandomCountList(filterObj.PlanSubjectCount) ; + inCommand.SubejctIdList = subjectSelectList.Select(t => t.SubjectId).ToList().GetRandomCountList(filterObj.PlanSubjectCount); } @@ -573,7 +584,7 @@ namespace IRaCIS.Core.Application.Service var subjectQuery = _subjectRepository.Where(t => t.TrialId == trialId && t.SubjectVisitTaskList.AsQueryable().Where(visitTaskFilter).Count() >= filterObj.PlanVisitCount) .WhereIf(filterObj.IsHaveReadingPeriod == true, u => u.SubjectVisitTaskList.AsQueryable().Where(comonTaskFilter) - .Where(t => t.ReadingCategory == ReadingCategory.Visit || t.ReadingCategory == ReadingCategory.Global).Any(t => t.ReadingCategory == ReadingCategory.Global && t.VisitTaskNum>filterObj.PlanVisitCount-1)) + .Where(t => t.ReadingCategory == ReadingCategory.Visit || t.ReadingCategory == ReadingCategory.Global).Any(t => t.ReadingCategory == ReadingCategory.Global && t.VisitTaskNum > filterObj.PlanVisitCount - 1)) ; @@ -684,7 +695,7 @@ namespace IRaCIS.Core.Application.Service t.SubjectVisitTaskList.AsQueryable().Where(visitTaskFilter).GroupBy(t => new { t.SubjectId, t.VisitTaskNum }).Where(g => g.Count() == 2).Count() >= filterObj.PlanVisitCount ) //.WhereIf(filterObj.IsHaveReadingPeriod == true, u => u.SubjectVisitTaskList.AsQueryable().Where(comonTaskFilter).Where(t => t.ReadingCategory == ReadingCategory.Visit || t.ReadingCategory == ReadingCategory.Global).OrderBy(t => t.VisitTaskNum).Take(filterObj.PlanVisitCount * 2 + 2).Any(t => t.ReadingCategory == ReadingCategory.Global)) - .WhereIf(filterObj.IsHaveReadingPeriod == true, u => u.SubjectVisitTaskList.AsQueryable().Where(comonTaskFilter).Where(t => t.ReadingCategory == ReadingCategory.Global && t.VisitTaskNum> filterObj.PlanVisitCount - 1).Select(t => t.DoctorUserId).Distinct().Count() == 2) + .WhereIf(filterObj.IsHaveReadingPeriod == true, u => u.SubjectVisitTaskList.AsQueryable().Where(comonTaskFilter).Where(t => t.ReadingCategory == ReadingCategory.Global && t.VisitTaskNum > filterObj.PlanVisitCount - 1).Select(t => t.DoctorUserId).Distinct().Count() == 2) ; @@ -804,14 +815,14 @@ namespace IRaCIS.Core.Application.Service //全局要>计划访视数量后面 t.SubjectVisitTaskList.AsQueryable().Where(comonTaskFilter) .Where(t => t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId && t.SignTime!.Value.AddDays(taskConsistentRule.IntervalWeeks * 7) < appDateTimeNow && t.DoctorUserId == user.Id) - .Where(t => t.ReadingCategory == ReadingCategory.Visit || t.ReadingCategory == ReadingCategory.Global).Any(t => t.ReadingCategory == ReadingCategory.Global && t.VisitTaskNum>taskConsistentRule.PlanVisitCount-1) + .Where(t => t.ReadingCategory == ReadingCategory.Visit || t.ReadingCategory == ReadingCategory.Global).Any(t => t.ReadingCategory == ReadingCategory.Global && t.VisitTaskNum > taskConsistentRule.PlanVisitCount - 1) && t.SubjectVisitTaskList.AsQueryable().Where(visitTaskFilter) .Where(t => t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId && t.SignTime!.Value.AddDays(taskConsistentRule.IntervalWeeks * 7) < appDateTimeNow && t.DoctorUserId == user.Id) - .Count()>= taskConsistentRule.PlanVisitCount + .Count() >= taskConsistentRule.PlanVisitCount ) - + .Count(), @@ -841,9 +852,9 @@ namespace IRaCIS.Core.Application.Service //var taskConsistentRuleQueryable = _taskConsistentRuleRepository.Where(t => t.TrialId == inQuery.TrialId) // .ProjectTo(_mapper.ConfigurationProvider); - var list= await taskConsistentRuleQueryable.ToListAsync(); + var list = await taskConsistentRuleQueryable.ToListAsync(); - var rule= await _taskConsistentRuleRepository.Where(t => t.TrialId == inQuery.TrialId && t.IsSelfAnalysis == true && t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId).ProjectTo(_mapper.ConfigurationProvider).FirstOrDefaultAsync(); + var rule = await _taskConsistentRuleRepository.Where(t => t.TrialId == inQuery.TrialId && t.IsSelfAnalysis == true && t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId).ProjectTo(_mapper.ConfigurationProvider).FirstOrDefaultAsync(); return ResponseOutput.Ok(list, rule); } @@ -880,7 +891,7 @@ namespace IRaCIS.Core.Application.Service public async Task> GetUpdateVirtualSiteCodeList(Guid trialId) { - var list = await _trialVirtualSiteCodeUpdateRepository.Where(t => t.TrialId == trialId).Select(t => new UpdateTrialSiteCodeCommandView() { TrialId = trialId, VirtualSiteCode = t.VirturalSiteCode, Creatime = t.CreateTime }).OrderByDescending(t=>t.Creatime).ToListAsync(); + var list = await _trialVirtualSiteCodeUpdateRepository.Where(t => t.TrialId == trialId).Select(t => new UpdateTrialSiteCodeCommandView() { TrialId = trialId, VirtualSiteCode = t.VirturalSiteCode, Creatime = t.CreateTime }).OrderByDescending(t => t.Creatime).ToListAsync(); return list; } From fa9c9de12cc6197dc28595ce56ce392113cbea6c Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Fri, 2 Aug 2024 11:27:51 +0800 Subject: [PATCH 166/251] =?UTF-8?q?=E8=B4=A8=E6=8E=A7=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E5=AD=97=E6=AE=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../IRaCIS.Core.Application.xml | 34 +++++++++++++++++++ .../Service/QC/DTO/QCListViewModel.cs | 16 +++++++-- .../Service/QC/QCListService.cs | 12 +++++-- 3 files changed, 57 insertions(+), 5 deletions(-) diff --git a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml index a79b6199f..970833ba3 100644 --- a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml +++ b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml @@ -885,6 +885,16 @@ + + + 受试者级别所有的影像 + 访视级别的影响 传递subjectVisitId + 标准Id是可选的 不同标准有些检查可能有过滤 + + + + + 后台任务调用,前端忽略该接口 @@ -5178,6 +5188,16 @@ 是否是正在转化 + + + 是否盲化 + + + + + 是否完整 + + 项目ID @@ -14148,6 +14168,20 @@ + + + 一致性分析临床数据签名 + + + + + + + 一致性分析临床数据签名完设置任务为有效 + + + + 获取单个阅片临床数据的所有文件 diff --git a/IRaCIS.Core.Application/Service/QC/DTO/QCListViewModel.cs b/IRaCIS.Core.Application/Service/QC/DTO/QCListViewModel.cs index 2db5966a6..588085be1 100644 --- a/IRaCIS.Core.Application/Service/QC/DTO/QCListViewModel.cs +++ b/IRaCIS.Core.Application/Service/QC/DTO/QCListViewModel.cs @@ -62,6 +62,10 @@ namespace IRaCIS.Core.Application.Contracts //public string VisitPlanInfo { get; set; } = String.Empty; public Guid? HandleUserId { get; set; } + + public DateTime? BeginAuditTime { get; set; } + + public DateTime? EndAuditTime { get; set; } } public class GetNextIQCQualityInDto @@ -1110,6 +1114,9 @@ namespace IRaCIS.Core.Application.Contracts public bool IsHaveUploadFailed { get; set; } + + + } public class GetNextCRCChallengeInDto @@ -1415,8 +1422,7 @@ namespace IRaCIS.Core.Application.Contracts public string ReviewAuditUserName { get; set; } = String.Empty; - public DateTime? ReviewAuditTime { get; set; } - public DateTime? PreliminaryAuditTime { get; set; } + public bool IsEnrollmentConfirm { get; set; } = false; public DateTime? SubjectFirstGiveMedicineTime { get; set; } @@ -1491,6 +1497,12 @@ namespace IRaCIS.Core.Application.Contracts public PackState PackState { get; set; } //public Guid? ClinicalDataSignUserId { get; set; } + + public DateTime? ReviewAuditTime { get; set; } + public DateTime? PreliminaryAuditTime { get; set; } + + + public DateTime? AuditTime => QCProcessEnum == TrialQCProcess.SingleAudit ? PreliminaryAuditTime : (QCProcessEnum == TrialQCProcess.DoubleAudit ? ReviewAuditTime : null); } diff --git a/IRaCIS.Core.Application/Service/QC/QCListService.cs b/IRaCIS.Core.Application/Service/QC/QCListService.cs index 4ec4e93bf..cf6324aa6 100644 --- a/IRaCIS.Core.Application/Service/QC/QCListService.cs +++ b/IRaCIS.Core.Application/Service/QC/QCListService.cs @@ -235,7 +235,7 @@ namespace IRaCIS.Core.Application.Image.QA PageSize = 1, }); - return result.Item1.CurrentPageData.Count > 0 ? result.Item1.CurrentPageData[0] : null; + return result.Data.CurrentPageData.Count > 0 ? result.Data.CurrentPageData[0] : null; } /// @@ -244,7 +244,7 @@ namespace IRaCIS.Core.Application.Image.QA /// /// [HttpPost] - public async Task<(PageOutput, TrialSubjectAndSVConfig)> GetQCVisitList(QCVisitSearchDTO visitSearchDTO) + public async Task>> GetQCVisitList(QCVisitSearchDTO visitSearchDTO) { var svExpression = QCCommon.GetSubjectVisitFilter(visitSearchDTO.VisitPlanArray); @@ -266,6 +266,12 @@ namespace IRaCIS.Core.Application.Image.QA || t.QCChallengeDialogList.Any(t => t.CreateUserId == visitSearchDTO.HandleUserId)) .WhereIf(visitSearchDTO.IsUrgent != null, t => t.IsUrgent == visitSearchDTO.IsUrgent) .Where(t => t.SubmitState != SubmitStateEnum.None) + .WhereIf(visitSearchDTO.BeginAuditTime != null, t => t.Trial.QCProcessEnum==TrialQCProcess.SingleAudit? t.PreliminaryAuditTime>= visitSearchDTO.BeginAuditTime: + (t.Trial.QCProcessEnum == TrialQCProcess.DoubleAudit?t.ReviewAuditTime>= visitSearchDTO.BeginAuditTime:true)) + + .WhereIf(visitSearchDTO.EndAuditTime != null, t => t.Trial.QCProcessEnum == TrialQCProcess.SingleAudit ? t.ReviewAuditTime <= visitSearchDTO.EndAuditTime : + (t.Trial.QCProcessEnum == TrialQCProcess.DoubleAudit ? t.ReviewAuditTime <= visitSearchDTO.EndAuditTime : true)) + //.WhereIf(visitSearchDTO.SubmitState != null, t => t.SubmitState == visitSearchDTO.SubmitState) //.WhereIf(visitSearchDTO.ChallengeState != null, t => t.ChallengeState == visitSearchDTO.ChallengeState) .ProjectTo(_mapper.ConfigurationProvider); @@ -279,7 +285,7 @@ namespace IRaCIS.Core.Application.Image.QA var config = await _repository.Where(t => t.Id == visitSearchDTO.TrialId).ProjectTo(_mapper.ConfigurationProvider).FirstOrDefaultAsync().IfNullThrowException(); - return (pageList, config); + return ResponseOutput.Ok (pageList, config); } From 9b4e29a812828e279626df39bd24330b34f7433d Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Fri, 2 Aug 2024 11:28:58 +0800 Subject: [PATCH 167/251] x --- IRaCIS.Core.API/_ServiceExtensions/EFSetup.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/IRaCIS.Core.API/_ServiceExtensions/EFSetup.cs b/IRaCIS.Core.API/_ServiceExtensions/EFSetup.cs index 7c54848c6..1f4ca4079 100644 --- a/IRaCIS.Core.API/_ServiceExtensions/EFSetup.cs +++ b/IRaCIS.Core.API/_ServiceExtensions/EFSetup.cs @@ -18,7 +18,7 @@ namespace IRaCIS.Core.API //这个注入没有成功--注入是没问题的,构造函数也只是支持参数就好,错在注入的地方不能写DbContext //Web程序中通过重用池中DbContext实例可提高高并发场景下的吞吐量, 这在概念上类似于ADO.NET Provider原生的连接池操作方式,具有节省DbContext实例化成本的优点 - services.AddDbContextPool(options => + services.AddDbContext(options => { options.UseSqlServer(configuration.GetSection("ConnectionStrings:RemoteNew").Value, contextOptionsBuilder => contextOptionsBuilder.EnableRetryOnFailure()); From cb53dbefcf15c72fd2b21fb271e282d2ee46fb4b Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Fri, 2 Aug 2024 11:48:09 +0800 Subject: [PATCH 168/251] =?UTF-8?q?CRC=20=E4=B8=8A=E4=BC=A0=E5=AF=BC?= =?UTF-8?q?=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.Application/Service/QC/DTO/QCListViewModel.cs | 7 +++++++ IRaCIS.Core.Application/Service/QC/_MapConfig.cs | 1 + 2 files changed, 8 insertions(+) diff --git a/IRaCIS.Core.Application/Service/QC/DTO/QCListViewModel.cs b/IRaCIS.Core.Application/Service/QC/DTO/QCListViewModel.cs index 588085be1..3a4ba042c 100644 --- a/IRaCIS.Core.Application/Service/QC/DTO/QCListViewModel.cs +++ b/IRaCIS.Core.Application/Service/QC/DTO/QCListViewModel.cs @@ -191,6 +191,13 @@ namespace IRaCIS.Core.Application.Contracts public string SubmitUserName { get; set; } + + public TrialQCProcess QCProcessEnum { get; set; } + + public DateTime? ReviewAuditTime { get; set; } + public DateTime? PreliminaryAuditTime { get; set; } + + public DateTime? AuditTime => QCProcessEnum == TrialQCProcess.SingleAudit ? PreliminaryAuditTime : (QCProcessEnum == TrialQCProcess.DoubleAudit ? ReviewAuditTime : null); } diff --git a/IRaCIS.Core.Application/Service/QC/_MapConfig.cs b/IRaCIS.Core.Application/Service/QC/_MapConfig.cs index 2110ce0bd..b5c088c66 100644 --- a/IRaCIS.Core.Application/Service/QC/_MapConfig.cs +++ b/IRaCIS.Core.Application/Service/QC/_MapConfig.cs @@ -22,6 +22,7 @@ namespace IRaCIS.Core.Application.Service CreateMap(); CreateMap() .ForMember(d => d.TrialSiteCode, u => u.MapFrom(s => s.TrialSite.TrialSiteCode)) + .ForMember(d => d.QCProcessEnum, u => u.MapFrom(s => s.Trial.QCProcessEnum)) .ForMember(d => d.SubjectCode, u => u.MapFrom(s => s.Subject.Code)) .ForMember(d => d.SubmitUserName, u => u.MapFrom(s => s.SubmitUser.FullName)) From 826f8a670db483dab6fd01f93b78a57dea5d3d06 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Fri, 2 Aug 2024 13:25:44 +0800 Subject: [PATCH 169/251] =?UTF-8?q?=E9=82=AE=E4=BB=B6=E6=A8=A1=E6=9D=BF?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.Application/Service/Common/MailService.cs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/IRaCIS.Core.Application/Service/Common/MailService.cs b/IRaCIS.Core.Application/Service/Common/MailService.cs index e34361d6f..fab8dd58f 100644 --- a/IRaCIS.Core.Application/Service/Common/MailService.cs +++ b/IRaCIS.Core.Application/Service/Common/MailService.cs @@ -177,9 +177,7 @@ namespace IRaCIS.Application.Services var topicStr = string.Format(input.topicStr, companyName); var htmlBodyStr = string.Format(ReplaceCompanyName(input.htmlBodyStr), - userName, - _localizer[mfaType == UserMFAType.Login ? "Mail_EmailMFALoginEmail" : "Mail_EmailMFAUnlockEmail"], verificationCode ); @@ -218,7 +216,6 @@ namespace IRaCIS.Application.Services userName, //---您正在进行邮箱重置操作 - _localizer["Mail_ResettingEmail"], verificationCode ); @@ -258,7 +255,6 @@ namespace IRaCIS.Application.Services "Sir/Madam", //---您正在进行邮箱重置密码操作 - _localizer["Mail_ResettingPassword"], verificationCode ); @@ -302,7 +298,7 @@ namespace IRaCIS.Application.Services "Sir/Madam", //---您正在参与展影医疗IRC项目 - _localizer["Mail_IRCProject", companyName], + companyName, verificationCode ); @@ -344,7 +340,7 @@ namespace IRaCIS.Application.Services "Sir/Madam", //---您正在参与展影医疗IRC项目中心调研工作 - _localizer["Mail_CenterResearchReminder", companyName], + companyName, verificationCode ); From 99eef312022a4d341c93d285970ffb422d82ddf4 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Fri, 2 Aug 2024 13:31:57 +0800 Subject: [PATCH 170/251] =?UTF-8?q?=E7=94=A8=E6=88=B7=E5=8F=8D=E9=A6=88?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=95=B0=E5=AD=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Service/TrialSiteUser/DTO/TrialViewModel.cs | 1 + IRaCIS.Core.Application/Service/TrialSiteUser/_MapConfig.cs | 3 +++ IRaCIS.Core.Domain/Trial/Trial.cs | 4 ++-- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/IRaCIS.Core.Application/Service/TrialSiteUser/DTO/TrialViewModel.cs b/IRaCIS.Core.Application/Service/TrialSiteUser/DTO/TrialViewModel.cs index a25cf7e19..93469cbcf 100644 --- a/IRaCIS.Core.Application/Service/TrialSiteUser/DTO/TrialViewModel.cs +++ b/IRaCIS.Core.Application/Service/TrialSiteUser/DTO/TrialViewModel.cs @@ -159,6 +159,7 @@ namespace IRaCIS.Application.Contracts //public int? StudyCount { get; set; } = 0; //public int? SiteCount { get; set; } = 0; + public int? UserFeedBackUnDealedCount { get; set; } } diff --git a/IRaCIS.Core.Application/Service/TrialSiteUser/_MapConfig.cs b/IRaCIS.Core.Application/Service/TrialSiteUser/_MapConfig.cs index 461523bfa..9a3326db6 100644 --- a/IRaCIS.Core.Application/Service/TrialSiteUser/_MapConfig.cs +++ b/IRaCIS.Core.Application/Service/TrialSiteUser/_MapConfig.cs @@ -77,6 +77,9 @@ namespace IRaCIS.Core.Application.Service .ForMember(d => d.ReviewMode, u => u.MapFrom(s => isEn_Us ? s.ReviewMode.Value : s.ReviewMode.ValueCN)) //.ForMember(d => d.ReviewType, u => u.MapFrom(s => s.ReviewType.Value)) .ForMember(d => d.IsLocked, u => u.MapFrom(s => s.WorkloadList.Any(u => u.DataFrom == (int)WorkLoadFromStatus.FinalConfirm))) + .ForMember(d => d.UserFeedBackUnDealedCount, u => u.MapFrom(s => s.UserFeedBackList.Count(t=>t.State==0))) + + //.ForMember(d => d.SiteCount, u => u.MapFrom(s => userTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator ? s.TrialSiteUserList.Count(k => k.UserId == userId) : s.TrialSiteList.Count())) //.ForMember(d => d.StudyCount, u => u.MapFrom(s => userTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator ? s.StudyList.Count(t => t.TrialSite.CRCUserList.Any(t => t.UserId == userId)) : s.StudyList.Count())) //.ForMember(d => d.SubjectCount, u => u.MapFrom(s => userTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator ? s.SubjectList.Count(t => t.TrialSite.CRCUserList.Any(t => t.UserId == userId)) : s.SubjectList.Count())) diff --git a/IRaCIS.Core.Domain/Trial/Trial.cs b/IRaCIS.Core.Domain/Trial/Trial.cs index 2160203ab..f2dc183c9 100644 --- a/IRaCIS.Core.Domain/Trial/Trial.cs +++ b/IRaCIS.Core.Domain/Trial/Trial.cs @@ -59,8 +59,8 @@ namespace IRaCIS.Core.Domain.Models public List TrialSiteUserList { get; set; } = new List(); [JsonIgnore] public List ReadModuleList { get; set; } = new List(); - - + [JsonIgnore] + public List UserFeedBackList { get; set; } = new List(); public Guid IndicationTypeId { get; set; } = Guid.Empty; public Guid? PhaseId { get; set; } = Guid.Empty; From 1875b56b3729ea5ea2b496cf3f90db8c8ed03e3a Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Fri, 2 Aug 2024 13:50:16 +0800 Subject: [PATCH 171/251] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E7=94=A8=E6=88=B7?= =?UTF-8?q?=E5=8F=8D=E9=A6=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.Application/Service/Allocation/_MapConfig.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/IRaCIS.Core.Application/Service/Allocation/_MapConfig.cs b/IRaCIS.Core.Application/Service/Allocation/_MapConfig.cs index 649ca5ba6..8ae10c42c 100644 --- a/IRaCIS.Core.Application/Service/Allocation/_MapConfig.cs +++ b/IRaCIS.Core.Application/Service/Allocation/_MapConfig.cs @@ -145,7 +145,7 @@ namespace IRaCIS.Core.Application.Service .ForMember(o => o.HistoryReadingDoctorUserList, t => t.MapFrom(u => u.JudgeVisitList)); CreateMap().IncludeBase() - .ForMember(o => o.IsHaveFeedBack, t => t.MapFrom(u => u.UserFeedBackList.Any())) + .ForMember(o => o.IsHaveFeedBack, t => t.MapFrom(u => u.UserFeedBackList.Any(t=>t.State==0))) ; CreateMap().IncludeBase() From 994a770fef4f4ced97f0f25fa60d192b73ffc3ac Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Fri, 2 Aug 2024 13:58:54 +0800 Subject: [PATCH 172/251] =?UTF-8?q?=E7=94=A8=E6=88=B7=E5=8F=8D=E9=A6=88?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E9=A1=B9=E7=9B=AE=E8=BF=87=E6=BB=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Service/Management/DTO/UserFeedBackViewModel.cs | 2 ++ .../Service/Management/UserFeedBackService.cs | 1 + 2 files changed, 3 insertions(+) diff --git a/IRaCIS.Core.Application/Service/Management/DTO/UserFeedBackViewModel.cs b/IRaCIS.Core.Application/Service/Management/DTO/UserFeedBackViewModel.cs index 14a6fcd70..51bc992bb 100644 --- a/IRaCIS.Core.Application/Service/Management/DTO/UserFeedBackViewModel.cs +++ b/IRaCIS.Core.Application/Service/Management/DTO/UserFeedBackViewModel.cs @@ -67,6 +67,8 @@ namespace IRaCIS.Core.Application.ViewModel public DateTime? EndCreatime { get; set; } + public Guid? TrialId { get; set; } + } diff --git a/IRaCIS.Core.Application/Service/Management/UserFeedBackService.cs b/IRaCIS.Core.Application/Service/Management/UserFeedBackService.cs index a9217b6a5..5a950602d 100644 --- a/IRaCIS.Core.Application/Service/Management/UserFeedBackService.cs +++ b/IRaCIS.Core.Application/Service/Management/UserFeedBackService.cs @@ -36,6 +36,7 @@ namespace IRaCIS.Core.Application.Service var userFeedBackQueryable = _userFeedBackRepository .WhereIf(isCRCOrIR, t => t.CreateUserId == _userInfo.Id) .WhereIf(inQuery.State != null, t => t.State == inQuery.State) + .WhereIf(inQuery.TrialId != null, t => t.TrialId == inQuery.TrialId) .WhereIf(inQuery.QuestionType != null, t => t.QuestionType == inQuery.QuestionType) .WhereIf(inQuery.BeginCreatime != null, t => t.CreateTime >= inQuery.BeginCreatime) From e1038c27f6e19706df3886b3efebe615f7b3230f Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Fri, 2 Aug 2024 15:41:29 +0800 Subject: [PATCH 173/251] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=AE=A1=E6=A0=B8?= =?UTF-8?q?=E6=97=B6=E9=97=B4=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.Application/Service/QC/QCListService.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/IRaCIS.Core.Application/Service/QC/QCListService.cs b/IRaCIS.Core.Application/Service/QC/QCListService.cs index cf6324aa6..dd1e1d662 100644 --- a/IRaCIS.Core.Application/Service/QC/QCListService.cs +++ b/IRaCIS.Core.Application/Service/QC/QCListService.cs @@ -269,7 +269,7 @@ namespace IRaCIS.Core.Application.Image.QA .WhereIf(visitSearchDTO.BeginAuditTime != null, t => t.Trial.QCProcessEnum==TrialQCProcess.SingleAudit? t.PreliminaryAuditTime>= visitSearchDTO.BeginAuditTime: (t.Trial.QCProcessEnum == TrialQCProcess.DoubleAudit?t.ReviewAuditTime>= visitSearchDTO.BeginAuditTime:true)) - .WhereIf(visitSearchDTO.EndAuditTime != null, t => t.Trial.QCProcessEnum == TrialQCProcess.SingleAudit ? t.ReviewAuditTime <= visitSearchDTO.EndAuditTime : + .WhereIf(visitSearchDTO.EndAuditTime != null, t => t.Trial.QCProcessEnum == TrialQCProcess.SingleAudit ? t.PreliminaryAuditTime <= visitSearchDTO.EndAuditTime : (t.Trial.QCProcessEnum == TrialQCProcess.DoubleAudit ? t.ReviewAuditTime <= visitSearchDTO.EndAuditTime : true)) //.WhereIf(visitSearchDTO.SubmitState != null, t => t.SubmitState == visitSearchDTO.SubmitState) From c353ae645b800cec432c285373daff543fa5af54 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Fri, 2 Aug 2024 17:03:23 +0800 Subject: [PATCH 174/251] =?UTF-8?q?dbcontext=20=E4=B8=8A=E4=B8=8B=E6=96=87?= =?UTF-8?q?=E6=B1=A0=EF=BC=8C=E6=8F=90=E9=AB=98=E6=80=A7=E8=83=BD=E6=B5=8B?= =?UTF-8?q?=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRC.Core.SCP/HostConfig/AutofacModuleSetup.cs | 4 +- IRC.Core.SCP/HostConfig/EFSetup.cs | 27 +++++++++--- .../_ServiceExtensions/AutofacModuleSetup.cs | 4 +- IRaCIS.Core.API/_ServiceExtensions/EFSetup.cs | 29 +++++++++++-- .../Context/IRaCISDBContext.cs | 41 +++++++++++-------- 5 files changed, 75 insertions(+), 30 deletions(-) diff --git a/IRC.Core.SCP/HostConfig/AutofacModuleSetup.cs b/IRC.Core.SCP/HostConfig/AutofacModuleSetup.cs index 6567c9735..629cf9636 100644 --- a/IRC.Core.SCP/HostConfig/AutofacModuleSetup.cs +++ b/IRC.Core.SCP/HostConfig/AutofacModuleSetup.cs @@ -45,8 +45,8 @@ namespace IRaCIS.Core.SCP .PropertiesAutowired().AsImplementedInterfaces(); - containerBuilder.RegisterType().As().SingleInstance(); - containerBuilder.RegisterType().As().InstancePerLifetimeScope(); + //containerBuilder.RegisterType().As().SingleInstance(); + //containerBuilder.RegisterType().As().InstancePerLifetimeScope(); diff --git a/IRC.Core.SCP/HostConfig/EFSetup.cs b/IRC.Core.SCP/HostConfig/EFSetup.cs index b53095cbd..77d9465c8 100644 --- a/IRC.Core.SCP/HostConfig/EFSetup.cs +++ b/IRC.Core.SCP/HostConfig/EFSetup.cs @@ -1,4 +1,6 @@ -using IRaCIS.Core.Infra.EFCore; +using EntityFramework.Exceptions.SqlServer; +using IRaCIS.Core.Domain.Share; +using IRaCIS.Core.Infra.EFCore; using Medallion.Threading; using Medallion.Threading.SqlServer; using Microsoft.EntityFrameworkCore; @@ -11,15 +13,25 @@ namespace IRaCIS.Core.SCP { public static void AddEFSetup( this IServiceCollection services, IConfiguration configuration) { - //services.AddScoped(); + services.AddHttpContextAccessor(); + services.AddScoped(); + //这个注入没有成功--注入是没问题的,构造函数也只是支持参数就好,错在注入的地方不能写DbContext //Web程序中通过重用池中DbContext实例可提高高并发场景下的吞吐量, 这在概念上类似于ADO.NET Provider原生的连接池操作方式,具有节省DbContext实例化成本的优点 - services.AddDbContext(options => + services.AddPooledDbContextFactory(options => { - options.UseSqlServer(configuration.GetSection("ConnectionStrings:RemoteNew").Value, + // 在控制台 + //public static readonly ILoggerFactory MyLoggerFactory = LoggerFactory.Create(builder => { builder.AddConsole(); }); + var logFactory = LoggerFactory.Create(builder => { builder.AddDebug(); }); + + options.UseSqlServer(configuration.GetSection("ConnectionStrings:RemoteNew").Value, contextOptionsBuilder => contextOptionsBuilder.EnableRetryOnFailure()); + options.UseLoggerFactory(logFactory); + + options.UseExceptionProcessor(); + options.EnableSensitiveDataLogging(); options.AddInterceptors(new QueryWithNoLockDbCommandInterceptor()); @@ -30,6 +42,12 @@ namespace IRaCIS.Core.SCP }); + // Register an additional context factory as a Scoped service, which gets a pooled context from the Singleton factory we registered above, + services.AddScoped(); + + // Finally, arrange for a context to get injected from our Scoped factory: + services.AddScoped(sp => sp.GetRequiredService().CreateDbContext()); + //注意区分 easy caching 也有 IDistributedLockProvider services.AddSingleton(sp => { @@ -38,7 +56,6 @@ namespace IRaCIS.Core.SCP return new SqlDistributedSynchronizationProvider(configuration.GetSection("ConnectionStrings:RemoteNew").Value); }); - //services.AddAssemblyTriggers(typeof(SubjectVisitImageDateTrigger).Assembly); } } } diff --git a/IRaCIS.Core.API/_ServiceExtensions/AutofacModuleSetup.cs b/IRaCIS.Core.API/_ServiceExtensions/AutofacModuleSetup.cs index 015405bf1..3806353b2 100644 --- a/IRaCIS.Core.API/_ServiceExtensions/AutofacModuleSetup.cs +++ b/IRaCIS.Core.API/_ServiceExtensions/AutofacModuleSetup.cs @@ -55,8 +55,8 @@ namespace IRaCIS.Core.API - containerBuilder.RegisterType().As().SingleInstance(); - containerBuilder.RegisterType().As().InstancePerLifetimeScope(); + //containerBuilder.RegisterType().As().SingleInstance(); + //containerBuilder.RegisterType().As().InstancePerLifetimeScope(); //注册hangfire任务 依赖注入 diff --git a/IRaCIS.Core.API/_ServiceExtensions/EFSetup.cs b/IRaCIS.Core.API/_ServiceExtensions/EFSetup.cs index 1f4ca4079..17aa20a19 100644 --- a/IRaCIS.Core.API/_ServiceExtensions/EFSetup.cs +++ b/IRaCIS.Core.API/_ServiceExtensions/EFSetup.cs @@ -1,11 +1,15 @@ -using Hangfire.SqlServer; +using Castle.Core.Logging; +using EntityFramework.Exceptions.SqlServer; +using Hangfire.SqlServer; using IRaCIS.Core.Application.Triggers; +using IRaCIS.Core.Domain.Share; using IRaCIS.Core.Infra.EFCore; using Medallion.Threading; using Medallion.Threading.SqlServer; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; using StackExchange.Redis; namespace IRaCIS.Core.API @@ -14,15 +18,28 @@ namespace IRaCIS.Core.API { public static void AddEFSetup( this IServiceCollection services, IConfiguration configuration) { - //services.AddScoped(); + + services.AddHttpContextAccessor(); + services.AddScoped(); + + // First, register a pooling context factory as a Singleton service, as usual: //这个注入没有成功--注入是没问题的,构造函数也只是支持参数就好,错在注入的地方不能写DbContext //Web程序中通过重用池中DbContext实例可提高高并发场景下的吞吐量, 这在概念上类似于ADO.NET Provider原生的连接池操作方式,具有节省DbContext实例化成本的优点 - services.AddDbContext(options => + services.AddPooledDbContextFactory(options => { + + // 在控制台 + //public static readonly ILoggerFactory MyLoggerFactory = LoggerFactory.Create(builder => { builder.AddConsole(); }); + var logFactory = LoggerFactory.Create(builder => { builder.AddDebug(); }); + options.UseSqlServer(configuration.GetSection("ConnectionStrings:RemoteNew").Value, contextOptionsBuilder => contextOptionsBuilder.EnableRetryOnFailure()); + options.UseLoggerFactory(logFactory); + + options.UseExceptionProcessor(); + options.EnableSensitiveDataLogging(); options.AddInterceptors(new QueryWithNoLockDbCommandInterceptor()); @@ -62,6 +79,12 @@ namespace IRaCIS.Core.API }); + // Register an additional context factory as a Scoped service, which gets a pooled context from the Singleton factory we registered above, + services.AddScoped(); + + // Finally, arrange for a context to get injected from our Scoped factory: + services.AddScoped(sp => sp.GetRequiredService().CreateDbContext()); + //注意区分 easy caching 也有 IDistributedLockProvider services.AddSingleton(sp => { diff --git a/IRaCIS.Core.Infra.EFCore/Context/IRaCISDBContext.cs b/IRaCIS.Core.Infra.EFCore/Context/IRaCISDBContext.cs index f81edd5f5..0644e35c3 100644 --- a/IRaCIS.Core.Infra.EFCore/Context/IRaCISDBContext.cs +++ b/IRaCIS.Core.Infra.EFCore/Context/IRaCISDBContext.cs @@ -24,33 +24,38 @@ using IRaCIS.Core.Infrastructure; namespace IRaCIS.Core.Infra.EFCore { + + public class IRaCISDBScopedFactory : IDbContextFactory + { + + private readonly IDbContextFactory _pooledFactory; + private readonly IUserInfo _userInfo; + + public IRaCISDBScopedFactory(IDbContextFactory pooledFactory,IUserInfo userInfo) + { + _pooledFactory = pooledFactory; + _userInfo = userInfo; + } + + public IRaCISDBContext CreateDbContext() + { + var context = _pooledFactory.CreateDbContext(); + context._userInfo = _userInfo; + return context; + } + } + public class IRaCISDBContext : DbContext { - public readonly IUserInfo _userInfo; + public IUserInfo _userInfo; public readonly ILogger _logger; - // 在控制台 - //public static readonly ILoggerFactory MyLoggerFactory = LoggerFactory.Create(builder => { builder.AddConsole(); }); - // 调试窗口 - public static readonly ILoggerFactory MyLoggerFactory = LoggerFactory.Create(builder => { builder.AddDebug(); }); - public IRaCISDBContext(DbContextOptions options, IUserInfo userInfo, ILogger logger + public IRaCISDBContext(DbContextOptions options, ILogger logger ) : base(options) { _logger= logger; - _userInfo = userInfo; - - } - - - //比数据库上下文构造函数先执行 不能构造函数注入的方式使用配置文件 - protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) - { - optionsBuilder.UseLoggerFactory(MyLoggerFactory); - - optionsBuilder.UseExceptionProcessor(); - } From 4eaf070243ee8f26492a0f81989776c2cd262268 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Fri, 2 Aug 2024 17:44:45 +0800 Subject: [PATCH 175/251] =?UTF-8?q?=E6=92=A4=E5=9B=9E=20dbcontext=20?= =?UTF-8?q?=E8=BF=9E=E6=8E=A5=E6=B1=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRC.Core.SCP/HostConfig/EFSetup.cs | 10 +++++----- IRaCIS.Core.API/_ServiceExtensions/EFSetup.cs | 8 ++++---- IRaCIS.Core.Infra.EFCore/Context/IRaCISDBContext.cs | 5 +++-- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/IRC.Core.SCP/HostConfig/EFSetup.cs b/IRC.Core.SCP/HostConfig/EFSetup.cs index 77d9465c8..921f293b9 100644 --- a/IRC.Core.SCP/HostConfig/EFSetup.cs +++ b/IRC.Core.SCP/HostConfig/EFSetup.cs @@ -19,7 +19,7 @@ namespace IRaCIS.Core.SCP //这个注入没有成功--注入是没问题的,构造函数也只是支持参数就好,错在注入的地方不能写DbContext //Web程序中通过重用池中DbContext实例可提高高并发场景下的吞吐量, 这在概念上类似于ADO.NET Provider原生的连接池操作方式,具有节省DbContext实例化成本的优点 - services.AddPooledDbContextFactory(options => + services.AddDbContext(options => { // 在控制台 //public static readonly ILoggerFactory MyLoggerFactory = LoggerFactory.Create(builder => { builder.AddConsole(); }); @@ -42,11 +42,11 @@ namespace IRaCIS.Core.SCP }); - // Register an additional context factory as a Scoped service, which gets a pooled context from the Singleton factory we registered above, - services.AddScoped(); + //// Register an additional context factory as a Scoped service, which gets a pooled context from the Singleton factory we registered above, + //services.AddScoped(); - // Finally, arrange for a context to get injected from our Scoped factory: - services.AddScoped(sp => sp.GetRequiredService().CreateDbContext()); + //// Finally, arrange for a context to get injected from our Scoped factory: + //services.AddScoped(sp => sp.GetRequiredService().CreateDbContext()); //注意区分 easy caching 也有 IDistributedLockProvider services.AddSingleton(sp => diff --git a/IRaCIS.Core.API/_ServiceExtensions/EFSetup.cs b/IRaCIS.Core.API/_ServiceExtensions/EFSetup.cs index 17aa20a19..820a2a67e 100644 --- a/IRaCIS.Core.API/_ServiceExtensions/EFSetup.cs +++ b/IRaCIS.Core.API/_ServiceExtensions/EFSetup.cs @@ -26,7 +26,7 @@ namespace IRaCIS.Core.API //这个注入没有成功--注入是没问题的,构造函数也只是支持参数就好,错在注入的地方不能写DbContext //Web程序中通过重用池中DbContext实例可提高高并发场景下的吞吐量, 这在概念上类似于ADO.NET Provider原生的连接池操作方式,具有节省DbContext实例化成本的优点 - services.AddPooledDbContextFactory(options => + services.AddDbContext(options => { // 在控制台 @@ -80,10 +80,10 @@ namespace IRaCIS.Core.API }); // Register an additional context factory as a Scoped service, which gets a pooled context from the Singleton factory we registered above, - services.AddScoped(); + //services.AddScoped(); - // Finally, arrange for a context to get injected from our Scoped factory: - services.AddScoped(sp => sp.GetRequiredService().CreateDbContext()); + //// Finally, arrange for a context to get injected from our Scoped factory: + //services.AddScoped(sp => sp.GetRequiredService().CreateDbContext()); //注意区分 easy caching 也有 IDistributedLockProvider services.AddSingleton(sp => diff --git a/IRaCIS.Core.Infra.EFCore/Context/IRaCISDBContext.cs b/IRaCIS.Core.Infra.EFCore/Context/IRaCISDBContext.cs index 0644e35c3..210224194 100644 --- a/IRaCIS.Core.Infra.EFCore/Context/IRaCISDBContext.cs +++ b/IRaCIS.Core.Infra.EFCore/Context/IRaCISDBContext.cs @@ -51,11 +51,12 @@ namespace IRaCIS.Core.Infra.EFCore public readonly ILogger _logger; - public IRaCISDBContext(DbContextOptions options, ILogger logger + public IRaCISDBContext(DbContextOptions options, IUserInfo userInfo, ILogger logger ) : base(options) { - _logger= logger; + _userInfo= userInfo; + _logger = logger; } From 9f5b8e985807732112304bc968f2523f7e54b701 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Mon, 5 Aug 2024 10:41:42 +0800 Subject: [PATCH 176/251] =?UTF-8?q?=E5=93=8D=E5=BA=94=E5=8E=8B=E7=BC=A9?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=8E=8B=E7=BC=A9=E7=BA=A7=E5=88=AB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRC.Core.SCP/HostConfig/EFSetup.cs | 2 +- .../ResponseCompressionSetup.cs | 14 ++++++- .../Context/IRaCISDBContext.cs | 40 ++++++++++--------- 3 files changed, 35 insertions(+), 21 deletions(-) diff --git a/IRC.Core.SCP/HostConfig/EFSetup.cs b/IRC.Core.SCP/HostConfig/EFSetup.cs index 921f293b9..00ee49222 100644 --- a/IRC.Core.SCP/HostConfig/EFSetup.cs +++ b/IRC.Core.SCP/HostConfig/EFSetup.cs @@ -19,7 +19,7 @@ namespace IRaCIS.Core.SCP //这个注入没有成功--注入是没问题的,构造函数也只是支持参数就好,错在注入的地方不能写DbContext //Web程序中通过重用池中DbContext实例可提高高并发场景下的吞吐量, 这在概念上类似于ADO.NET Provider原生的连接池操作方式,具有节省DbContext实例化成本的优点 - services.AddDbContext(options => + services.AddDbContextPool(options => { // 在控制台 //public static readonly ILoggerFactory MyLoggerFactory = LoggerFactory.Create(builder => { builder.AddConsole(); }); diff --git a/IRaCIS.Core.API/_ServiceExtensions/ResponseCompressionSetup.cs b/IRaCIS.Core.API/_ServiceExtensions/ResponseCompressionSetup.cs index 6037273da..5bc11b6cb 100644 --- a/IRaCIS.Core.API/_ServiceExtensions/ResponseCompressionSetup.cs +++ b/IRaCIS.Core.API/_ServiceExtensions/ResponseCompressionSetup.cs @@ -1,18 +1,30 @@ using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.ResponseCompression; using Microsoft.Extensions.DependencyInjection; +using System.IO.Compression; namespace IRaCIS.Core.API { - public static class ResponseCompressionSetup + public static class ResponseCompressionSetup { public static void AddResponseCompressionSetup(this IServiceCollection services) { services.AddResponseCompression(options => { + options.EnableForHttps = true; options.Providers.Add(); options.Providers.Add(); }); + + services.Configure(options => + { + options.Level = CompressionLevel.Optimal; + }); + + services.Configure(options => + { + options.Level = CompressionLevel.Optimal; + }); } } } diff --git a/IRaCIS.Core.Infra.EFCore/Context/IRaCISDBContext.cs b/IRaCIS.Core.Infra.EFCore/Context/IRaCISDBContext.cs index 210224194..44a2ad291 100644 --- a/IRaCIS.Core.Infra.EFCore/Context/IRaCISDBContext.cs +++ b/IRaCIS.Core.Infra.EFCore/Context/IRaCISDBContext.cs @@ -24,32 +24,34 @@ using IRaCIS.Core.Infrastructure; namespace IRaCIS.Core.Infra.EFCore { + /// + /// 报错,添加subject 报错,重复添加访视 + /// + //public class IRaCISDBScopedFactory : IDbContextFactory + //{ - public class IRaCISDBScopedFactory : IDbContextFactory - { + // private readonly IDbContextFactory _pooledFactory; + // private readonly IUserInfo _userInfo; - private readonly IDbContextFactory _pooledFactory; - private readonly IUserInfo _userInfo; + // public IRaCISDBScopedFactory(IDbContextFactory pooledFactory,IUserInfo userInfo) + // { + // _pooledFactory = pooledFactory; + // _userInfo = userInfo; + // } - public IRaCISDBScopedFactory(IDbContextFactory pooledFactory,IUserInfo userInfo) - { - _pooledFactory = pooledFactory; - _userInfo = userInfo; - } - - public IRaCISDBContext CreateDbContext() - { - var context = _pooledFactory.CreateDbContext(); - context._userInfo = _userInfo; - return context; - } - } + // public IRaCISDBContext CreateDbContext() + // { + // var context = _pooledFactory.CreateDbContext(); + // context._userInfo = _userInfo; + // return context; + // } + //} public class IRaCISDBContext : DbContext { - public IUserInfo _userInfo; + private IUserInfo _userInfo; - public readonly ILogger _logger; + private readonly ILogger _logger; public IRaCISDBContext(DbContextOptions options, IUserInfo userInfo, ILogger logger From 2d1325ca5216dcd3bccb28ea2dd755542aa3b554 Mon Sep 17 00:00:00 2001 From: he <109787524@qq.com> Date: Mon, 5 Aug 2024 13:32:13 +0800 Subject: [PATCH 177/251] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Service/Reading/ClinicalData/ReadingClinicalDataService.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs b/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs index 9a620aaed..d146af56b 100644 --- a/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs +++ b/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs @@ -1134,6 +1134,7 @@ namespace IRaCIS.Application.Services TrialId = inDto.TrialId, SelectIsSign = false, IsGetAllConsistencyAnalysis = false, + VisitTaskId=inDto.VisitTaskId, }); return (result,true); From 97a5eda8f8f410d7b2f06c701f6e2f0bfd433405 Mon Sep 17 00:00:00 2001 From: he <109787524@qq.com> Date: Mon, 5 Aug 2024 13:51:20 +0800 Subject: [PATCH 178/251] =?UTF-8?q?=E4=B8=80=E8=87=B4=E6=80=A7=E5=88=86?= =?UTF-8?q?=E6=9E=90=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Reading/ClinicalData/ReadingClinicalDataService.cs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs b/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs index d146af56b..cb6ef0f19 100644 --- a/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs +++ b/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs @@ -843,6 +843,7 @@ namespace IRaCIS.Application.Services var resultQuery = _readingClinicalDataRepository.Where(x=>1==1).Select(x=> new GetReadingClinicalDataListOutDto() { }); bool isSelfAnalysis = false; + var otherIsSelfAnalysisList=new List(); if (inDto.ReadingId == null) { var visitTask = await _visitTaskRepository.FirstOrDefaultAsync(x => x.Id == inDto.VisitTaskId); @@ -893,10 +894,10 @@ namespace IRaCIS.Application.Services }); // 是否获取所有一致性分析的数据 - if(!inDto.IsGetAllConsistencyAnalysis) + if(inDto.IsGetAllConsistencyAnalysis) { // 原来的非PDF - var otherQuesy = _readingClinicalDataRepository.Where(x => x.SubjectId == inDto.SubjectId) + otherIsSelfAnalysisList =await _readingClinicalDataRepository.Where(x => x.SubjectId == inDto.SubjectId) .WhereIf(inDto.ReadingClinicalDataId != null, x => x.Id == inDto.ReadingClinicalDataId) .WhereIf(inDto.ClinicalDataTrialSetId != null, x => x.ClinicalDataTrialSetId == inDto.ClinicalDataTrialSetId) .WhereIf(inDto.SelectIsSign, x => x.IsSign == true) @@ -929,9 +930,9 @@ namespace IRaCIS.Application.Services Path = y.Path, CreateTime = y.CreateTime, }).ToList(), - }); + }).ToListAsync(); - resultQuery = resultQuery.Union(otherQuesy); + } } @@ -980,6 +981,7 @@ namespace IRaCIS.Application.Services if (!inDto.IsOnlyGetCRCReadModule) { result = await resultQuery.ToListAsync(); + result.AddRange(otherIsSelfAnalysisList); } var readingIds = result.Select(x => x.ReadingId).ToList(); From 99ef28be99f72b36eea32a31b5f07f7df6161271 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Mon, 5 Aug 2024 14:41:30 +0800 Subject: [PATCH 179/251] =?UTF-8?q?=E5=8A=A0=E5=AF=86=E6=96=B9=E6=B3=95?= =?UTF-8?q?=E5=87=86=E5=A4=87=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.Application/Helper/RSAHelper.cs | 97 ++++++++++++++++ .../Service/Allocation/VisitTaskService.cs | 1 - .../Service/QC/QCListService.cs | 1 - .../Visit/DTO/ClinicalStudySubjects.cs | 1 - IRaCIS.Core.Application/TestService.cs | 104 ++++-------------- 5 files changed, 119 insertions(+), 85 deletions(-) create mode 100644 IRaCIS.Core.Application/Helper/RSAHelper.cs diff --git a/IRaCIS.Core.Application/Helper/RSAHelper.cs b/IRaCIS.Core.Application/Helper/RSAHelper.cs new file mode 100644 index 000000000..fb5309691 --- /dev/null +++ b/IRaCIS.Core.Application/Helper/RSAHelper.cs @@ -0,0 +1,97 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Encodings; +using Org.BouncyCastle.Crypto.Engines; +using Org.BouncyCastle.Crypto.Generators; +using Org.BouncyCastle.OpenSsl; +using Org.BouncyCastle.Security; + +namespace IRaCIS.Core.Application.Helper +{ + /// + /// https://www.cnblogs.com/NBDWDYS2214143926/p/13329231.html + /// + public class RSAHelper + { + + public static AsymmetricCipherKeyPair GenerateRSAKeyPair(int keySize) + { + var keyGenerationParameters = new KeyGenerationParameters(new SecureRandom(), keySize); + var keyPairGenerator = new RsaKeyPairGenerator(); + keyPairGenerator.Init(keyGenerationParameters); + return keyPairGenerator.GenerateKeyPair(); + } + + public static string ExportPublicKey(AsymmetricKeyParameter publicKey) + { + using (StringWriter sw = new StringWriter()) + { + PemWriter pw = new PemWriter(sw); + pw.WriteObject(publicKey); + pw.Writer.Flush(); + return sw.ToString(); + } + } + + public static string ExportPrivateKey(AsymmetricKeyParameter privateKey) + { + using (StringWriter sw = new StringWriter()) + { + PemWriter pw = new PemWriter(sw); + pw.WriteObject(privateKey); + pw.Writer.Flush(); + return sw.ToString(); + } + } + + /// + /// RSA解密 + /// + /// 私钥 + /// 待解密的字符串(Base64) + /// 解密后的字符串 + public static string Decrypt(string privateKey, string decryptstring) + { + using (TextReader reader = new StringReader(privateKey)) + { + dynamic key = new PemReader(reader).ReadObject(); + var rsaDecrypt = new Pkcs1Encoding(new RsaEngine()); + if (key is AsymmetricKeyParameter) + { + key = (AsymmetricKeyParameter)key; + } + else if (key is AsymmetricCipherKeyPair) + { + key = ((AsymmetricCipherKeyPair)key).Private; + } + rsaDecrypt.Init(false, key); //这里加密是true;解密是false + + byte[] entData = Convert.FromBase64String(decryptstring); + entData = rsaDecrypt.ProcessBlock(entData, 0, entData.Length); + return Encoding.UTF8.GetString(entData); + } + }/// + + /// 加密 + /// + /// 公钥 + /// 待加密的字符串 + /// 加密后的Base64 + public static string Encrypt(string publicKey, string encryptstring) + { + using (TextReader reader = new StringReader(publicKey)) + { + AsymmetricKeyParameter key = new PemReader(reader).ReadObject() as AsymmetricKeyParameter; + Pkcs1Encoding pkcs1 = new Pkcs1Encoding(new RsaEngine()); + pkcs1.Init(true, key);//加密是true;解密是false; + byte[] entData = Encoding.UTF8.GetBytes(encryptstring); + entData = pkcs1.ProcessBlock(entData, 0, entData.Length); + return Convert.ToBase64String(entData); + } + } + } +} diff --git a/IRaCIS.Core.Application/Service/Allocation/VisitTaskService.cs b/IRaCIS.Core.Application/Service/Allocation/VisitTaskService.cs index b030d49ec..efdd7ff84 100644 --- a/IRaCIS.Core.Application/Service/Allocation/VisitTaskService.cs +++ b/IRaCIS.Core.Application/Service/Allocation/VisitTaskService.cs @@ -19,7 +19,6 @@ using DocumentFormat.OpenXml.Office2010.Word; using System.Linq.Dynamic.Core; using System.Linq; using DocumentFormat.OpenXml.Bibliography; -using Org.BouncyCastle.Crypto; using IRaCIS.Core.Domain.Share.Reading; using MassTransit; using System.Reactive.Subjects; diff --git a/IRaCIS.Core.Application/Service/QC/QCListService.cs b/IRaCIS.Core.Application/Service/QC/QCListService.cs index dd1e1d662..bd065b33e 100644 --- a/IRaCIS.Core.Application/Service/QC/QCListService.cs +++ b/IRaCIS.Core.Application/Service/QC/QCListService.cs @@ -8,7 +8,6 @@ using IRaCIS.Application.Interfaces; using IRaCIS.Application.Contracts; using IRaCIS.Core.Application.ViewModel; using IRaCIS.Core.Application.Service.Reading.Dto; -using static Org.BouncyCastle.Math.EC.ECCurve; using IRaCIS.Core.Infrastructure; namespace IRaCIS.Core.Application.Image.QA diff --git a/IRaCIS.Core.Application/Service/Visit/DTO/ClinicalStudySubjects.cs b/IRaCIS.Core.Application/Service/Visit/DTO/ClinicalStudySubjects.cs index fc1155c32..bd0178751 100644 --- a/IRaCIS.Core.Application/Service/Visit/DTO/ClinicalStudySubjects.cs +++ b/IRaCIS.Core.Application/Service/Visit/DTO/ClinicalStudySubjects.cs @@ -2,7 +2,6 @@ using IRaCIS.Core.Infrastructure.Extention; using IRaCIS.Core.Domain.Share; using System.ComponentModel.DataAnnotations; -using Org.BouncyCastle.Bcpg.OpenPgp; namespace IRaCIS.Application.Contracts { diff --git a/IRaCIS.Core.Application/TestService.cs b/IRaCIS.Core.Application/TestService.cs index 08fbc3a60..b0dd183e8 100644 --- a/IRaCIS.Core.Application/TestService.cs +++ b/IRaCIS.Core.Application/TestService.cs @@ -1,7 +1,4 @@ using Aliyun.OSS; -using BeetleX; -using BeetleX.BNR; -using Castle.DynamicProxy.Generators.Emitters.SimpleAST; using IP2Region.Net.XDB; using IRaCIS.Application.Contracts; using IRaCIS.Core.Application.Contracts; @@ -21,14 +18,10 @@ using Microsoft.Extensions.Options; using MiniExcelLibs; using Minio; using Minio.DataModel.Args; -using NPOI.HPSF; -using NPOI.POIFS.Crypt; using SharpCompress.Common; using Spire.Doc; using System.Linq.Expressions; using System.Reflection.Metadata; -using System.Security.AccessControl; -using System.Security.Cryptography; using System.Text; using System.Text.RegularExpressions; @@ -177,83 +170,30 @@ namespace IRaCIS.Application.Services [UnitOfWork] public async Task Get() { + // Generate RSA keys + var keyPair = RSAHelper.GenerateRSAKeyPair(2048); - //Expression> visitTaskLambda = x => x.TrialId == Guid.Empty && x.SubjectId == Guid.Empty && x.TrialReadingCriterionId == Guid.Empty; + // Export the public and private keys to PEM format + string publicKey = RSAHelper.ExportPublicKey(keyPair.Public); + string privateKey = RSAHelper.ExportPrivateKey(keyPair.Private); - //var visitTaskIdQueryable = _visitTaskRepositoryy.Where(visitTaskLambda).Where(t => t.Subject.SubjectVisitTaskList.AsQueryable().Where(visitTaskLambda).Any(c => c.IsNeedClinicalDataSign == true && c.IsClinicalDataSign == false && c.VisitTaskNum < t.VisitTaskNum)).Select(t => t.Id); + Console.WriteLine("Public Key:"); + Console.WriteLine(publicKey); + Console.WriteLine("\nPrivate Key:"); + Console.WriteLine(privateKey); - //await _visitTaskRepositoryy.BatchUpdateNoTrackingAsync(t => visitTaskIdQueryable.Contains(t.Id), u => new VisitTask() - //{ - // IsFrontTaskNeedSignButNotSign = true - //}); + // Data to encrypt + string dataToEncrypt = "Hello, RSA!"; + Console.WriteLine("\nOriginal Data: " + dataToEncrypt); + // Encrypt the data + var encryptedData = RSAHelper.Encrypt( publicKey, dataToEncrypt); + Console.WriteLine("\nEncrypted Data: " + encryptedData); - //var a = ((Decimal)1.00).ToString().TrimEnd(new char[] { '.', '0' }); - //var b = ((Decimal)1.01).ToString().TrimEnd(new char[] { '.', '0' }); - //var c = ((Decimal)100).ToString().TrimEnd(new char[] { '.', '0' }); - //var subject1 = Guid.Parse("431D0C58-ABC5-4166-B9BC-08DA0E391693"); - //var subject2 = Guid.Parse("431D0C58-ABC5-4166-B9BC-08DA0E391694"); + // Decrypt the data + string decryptedData = RSAHelper.Decrypt( privateKey, encryptedData); + Console.WriteLine("\nDecrypted Data: " + decryptedData); - // var subjectList = new List() { Guid.Parse("431D0C58-ABC5-4166-B9BC-08DA0E391693") , - // Guid.Parse("431D0C58-ABC5-4166-B9BC-08DA0E391694") , - // Guid.Parse("431D0C58-ABC5-4166-B9BC-08DA0E391695") - // }; - - //string[] citys = new string[] { "广州", "深圳", "上海", "北京" }; - //foreach (var item in subjectList) - //{ - // Console.WriteLine(await BNRFactory.Default.Create($"[CN:{item}][N:[CN:{item}]/0000000]")); - //} - //foreach (var item in subjectList) - //{ - // Console.WriteLine(await BNRFactory.Default.Create($"[N:[CN:{item}]/0000000]")); - //} - - //foreach (var item in subjectList) - //{ - // Console.WriteLine(await BNRFactory.Default.Create($"[CN:{item}][redis:city/0000000]")); - //} - - //var needAddVisitList = await _repository.Where(t => t.TrialId == Guid.Empty).DistinctBy(t => t.VisitTaskNum).ToListAsync(); - - - //await _repository.BatchUpdateAsync(t => t.Id == Guid.Empty, u => new VisitTask() - //{ - // SuggesteFinishedTime = u.IsUrgent ? DateTime.Now.AddDays(2) : DateTime.Now.AddDays(7), - - // Code = u.Code + 1 - //}); - - //var query = from item1 in _repository.Where() - // join item2 in _repository.Where() on item1.ValueType equals item2.ValueType - // select new - // { - // item1.ValueType, - // dd = item2.ValueType - // }; - - //var list2 = query.ToList(); - - //await Task.CompletedTask; - - //var list = await _repository.Where(t => t.TrialId == Guid.Parse("40400000-3e2c-0016-239b-08da581f0e74")).ToListAsync(); - - ////await _repository.BatchDeleteAsync(t => t.TrialId == Guid.Parse("40400000-3e2c-0016-239b-08da581f0e74")); - - //await _repository.AddRangeAsync(list, true); - - //await _repository.SaveChangesAsync(); - - //await _repository.BatchUpdateAsync(t => t.TrialId == Guid.Parse("40400000-3e2c-0016-239b-08da581f0e74") && t.EntityName== "ClinicalDataTrialSet", t => new DataInspection() { CreateTime= DateTime.Now.AddMonths(-2) } ); - - //await _visitTaskRepositoryy.UpdatePartialFromQueryAsync( Guid.Parse("78360000-3E2C-0016-9B53-08DA6A002040"), c => new VisitTask() { UpdateTime = DateTime.Now }); - - //await _visitTaskRepositoryy.UpdatePartialFromQueryAsync( Guid.Parse("78360000-3E2C-0016-9B53-08DA6A002040"), c => new VisitTask() { UpdateTime = DateTime.Now.AddMinutes(1) }); - - //var a = _userInfo.IsTestUser; - - //var list1 = await _repository.Where().Select(t => t.TranslateValue(t.Value, t.ValueCN, true)).ToListAsync(); - //var list2 = await _repository.Where().Select(t => t.TranslateValue(t.Value, t.ValueCN, false)).ToListAsync(); return "测试自动发布--再次提交"; } @@ -273,15 +213,15 @@ namespace IRaCIS.Application.Services [AllowAnonymous] public async Task GetEnvironmentName([FromServices] IWebHostEnvironment env) { - var a = IdentifierHelper.CreateGuid("123456"); + //var a = IdentifierHelper.CreateGuid("123456"); - var k = MD5.Create().ComputeHash(Encoding.UTF8.GetBytes("123456")); + //var k = MD5.Create().ComputeHash(Encoding.UTF8.GetBytes("123456")); - var c = MD5Helper.Md5("123456"); + //var c = MD5Helper.Md5("123456"); - return new { env.EnvironmentName, EMailConfig = _systemEmailConfig.CurrentValue, BasicConfig = _basicConfig.CurrentValue }; + //return new { env.EnvironmentName, EMailConfig = _systemEmailConfig.CurrentValue, BasicConfig = _basicConfig.CurrentValue }; // Load a document. From 03c2a67fe4548e737710638e897ada54f56851ff Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Mon, 5 Aug 2024 14:55:13 +0800 Subject: [PATCH 180/251] =?UTF-8?q?=E4=B8=80=E8=87=B4=E6=80=A7=E5=88=86?= =?UTF-8?q?=E6=9E=90=E4=BB=BB=E5=8A=A1=E7=94=9F=E6=88=90bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Service/Allocation/VisitTaskHelpeService.cs | 7 ++++--- IRaCIS.Core.Domain/Image/DicomStudy.cs | 6 ++++-- .../EntityConfigration/StudyConfigration.cs | 9 ++++++++- 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/IRaCIS.Core.Application/Service/Allocation/VisitTaskHelpeService.cs b/IRaCIS.Core.Application/Service/Allocation/VisitTaskHelpeService.cs index 4a3627320..d739000b2 100644 --- a/IRaCIS.Core.Application/Service/Allocation/VisitTaskHelpeService.cs +++ b/IRaCIS.Core.Application/Service/Allocation/VisitTaskHelpeService.cs @@ -1425,7 +1425,7 @@ namespace IRaCIS.Core.Application.Service var taskState = exsitPDF ? TaskState.NotEffect : TaskState.Effect; - var clinicalDataList = _readingClinicalDataRepository.Where(t => t.SubjectId == subjectId&&t.ClinicalDataTrialSet.ClinicalUploadType == ClinicalUploadType.PDF).Include(t => t.ReadingClinicalDataPDFList).Include(t=>t.ClinicalDataTrialSet).ToList(); + var clinicalDataList = _readingClinicalDataRepository.Where(t => t.SubjectId == subjectId && t.ClinicalDataTrialSet.ClinicalUploadType == ClinicalUploadType.PDF).Include(t => t.ReadingClinicalDataPDFList).Include(t => t.ClinicalDataTrialSet).ToList(); foreach (var clinicalData in clinicalDataList) { @@ -1433,13 +1433,14 @@ namespace IRaCIS.Core.Application.Service var id = NewId.NextSequentialGuid(); consistnentClinicalData.Id = id; - if(consistnentClinicalData.ClinicalDataTrialSet.ClinicalUploadType == ClinicalUploadType.PDF) + if (consistnentClinicalData.ClinicalDataTrialSet.ClinicalUploadType == ClinicalUploadType.PDF) { consistnentClinicalData.IsSign = false; consistnentClinicalData.IsBlind = false; consistnentClinicalData.ReadingClinicalDataState = ReadingClinicalDataStatus.HaveUploaded; + consistnentClinicalData.ClinicalDataTrialSet = null; } - + var consistanClinicalDataPdfList = _mapper.Map>(clinicalData.ReadingClinicalDataPDFList); consistanClinicalDataPdfList.ForEach(t => { t.ReadingConsistentClinicalDataId = id; t.Id = Guid.Empty; }); diff --git a/IRaCIS.Core.Domain/Image/DicomStudy.cs b/IRaCIS.Core.Domain/Image/DicomStudy.cs index b0d6526b5..2fa295e25 100644 --- a/IRaCIS.Core.Domain/Image/DicomStudy.cs +++ b/IRaCIS.Core.Domain/Image/DicomStudy.cs @@ -89,10 +89,12 @@ namespace IRaCIS.Core.Domain.Models public List ReadingClinicalDataList { get; set; } + [JsonIgnore] + public List ReadingConsistentClinicalDataList { get; set; } - //软删除 - public bool IsDeleted { get; set; } + //软删除 + public bool IsDeleted { get; set; } public DateTime? DeletedTime { get; set; } diff --git a/IRaCIS.Core.Infra.EFCore/EntityConfigration/StudyConfigration.cs b/IRaCIS.Core.Infra.EFCore/EntityConfigration/StudyConfigration.cs index dfed9328a..c1b0133e8 100644 --- a/IRaCIS.Core.Infra.EFCore/EntityConfigration/StudyConfigration.cs +++ b/IRaCIS.Core.Infra.EFCore/EntityConfigration/StudyConfigration.cs @@ -19,6 +19,13 @@ namespace IRaCIS.Core.Infra.EFCore.EntityConfigration .HasForeignKey(s => new { s.StudyId }) .HasPrincipalKey(c => new { c.Id }); - } + + builder + .HasMany(s => s.ReadingConsistentClinicalDataList) + .WithOne(c => c.DicomStudy) + .HasForeignKey(s => new { s.StudyId }) + .HasPrincipalKey(c => new { c.Id }); + + } } } From 37c898ea0c5e711aa6fa468874df91a248e772b7 Mon Sep 17 00:00:00 2001 From: he <109787524@qq.com> Date: Mon, 5 Aug 2024 15:35:02 +0800 Subject: [PATCH 181/251] =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Reading/ClinicalData/ReadingClinicalDataService.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs b/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs index cb6ef0f19..3d90c7dce 100644 --- a/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs +++ b/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs @@ -733,10 +733,11 @@ namespace IRaCIS.Application.Services if (inDto.ReadingId == null) { var visitTask = await _visitTaskRepository.FirstOrDefaultAsync(x => x.Id == inDto.VisitTaskId); - inDto.ReadingId = visitTask.SouceReadModuleId ?? visitTask.SourceSubjectVisitId; + readingNameOrTaskBlindName = visitTask.TaskBlindName; } - + inDto.SelectIsSign = false; + var result = await GetClinicalDataList(inDto); if (readingNameOrTaskBlindName.IsNullOrEmpty()) { readingNameOrTaskBlindName = await _subjectVisitRepository.Where(x => x.Id == inDto.ReadingId).Select(x => x.VisitName).FirstOrDefaultAsync(); @@ -746,8 +747,7 @@ namespace IRaCIS.Application.Services } } - inDto.SelectIsSign = false; - var result = await GetClinicalDataList(inDto); + var readingIds = result.Select(x => x.ReadingId).ToList(); From 2217ae03536ada645eb16c9e56cde74e7fe61c1a Mon Sep 17 00:00:00 2001 From: he <109787524@qq.com> Date: Mon, 5 Aug 2024 15:41:39 +0800 Subject: [PATCH 182/251] =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Controllers/InspectionController.cs | 27 +++++++++++++++---- .../Interface/IReadingClinicalDataService.cs | 2 ++ 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/IRaCIS.Core.API/Controllers/InspectionController.cs b/IRaCIS.Core.API/Controllers/InspectionController.cs index e9deab588..bbeaf4e35 100644 --- a/IRaCIS.Core.API/Controllers/InspectionController.cs +++ b/IRaCIS.Core.API/Controllers/InspectionController.cs @@ -308,11 +308,28 @@ namespace IRaCIS.Core.API.Controllers } - /// - /// 提交结构化录入并签名 - /// - /// - /// + /// + /// PM签名一致性分析临床数据 + /// + /// + /// + [HttpPost, Route("Inspection/ReadingClinicalData/SignConsistencyAnalysisReadingClinicalData")] + [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })] + + [UnitOfWork] + public async Task SignConsistencyAnalysisReadingClinicalData(DataInspectionDto opt) + { + var singid = await _inspectionService.RecordSing(opt.SignInfo); + var result = await _readingClinicalDataService.SignConsistencyAnalysisReadingClinicalData(opt.Data); + await _inspectionService.CompletedSign(singid, result); + return result; + } + + /// + /// 提交结构化录入并签名 + /// + /// + /// [HttpPost, Route("Inspection/ClinicalAnswer/SubmitClinicalFormAndSign")] [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })] diff --git a/IRaCIS.Core.Application/Service/Reading/Interface/IReadingClinicalDataService.cs b/IRaCIS.Core.Application/Service/Reading/Interface/IReadingClinicalDataService.cs index 795bab0fc..521a9d843 100644 --- a/IRaCIS.Core.Application/Service/Reading/Interface/IReadingClinicalDataService.cs +++ b/IRaCIS.Core.Application/Service/Reading/Interface/IReadingClinicalDataService.cs @@ -29,5 +29,7 @@ namespace IRaCIS.Core.Application.Contracts Task DealVisiTaskClinicalDataSignedAsync(Guid trialId, Guid subjectId, Guid readingId, bool isVisit, Guid trialReadingCritrialId); + + Task SignConsistencyAnalysisReadingClinicalData(SignConsistencyAnalysisReadingClinicalDataInDto inDto); } } \ No newline at end of file From 36a63d76281db5e2e1bad7079d45244359e136b6 Mon Sep 17 00:00:00 2001 From: he <109787524@qq.com> Date: Mon, 5 Aug 2024 16:20:30 +0800 Subject: [PATCH 183/251] =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Reading/ClinicalData/ReadingClinicalDataService.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs b/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs index 3d90c7dce..611c72ab8 100644 --- a/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs +++ b/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs @@ -889,6 +889,8 @@ namespace IRaCIS.Application.Services Id = y.Id, FileName = y.FileName, Path = y.Path, + Size=y.Size, + Type=y.Type, CreateTime = y.CreateTime, }).ToList(), }); @@ -928,6 +930,8 @@ namespace IRaCIS.Application.Services Id = y.Id, FileName = y.FileName, Path = y.Path, + Size = y.Size, + Type = y.Type, CreateTime = y.CreateTime, }).ToList(), }).ToListAsync(); @@ -968,6 +972,8 @@ namespace IRaCIS.Application.Services Id = y.Id, FileName = y.FileName, Path = y.Path, + Size = y.Size, + Type = y.Type, CreateTime = y.CreateTime, }).ToList(), From a47e20ff74f0a07b336126f49437d66549224a37 Mon Sep 17 00:00:00 2001 From: he <109787524@qq.com> Date: Mon, 5 Aug 2024 16:54:59 +0800 Subject: [PATCH 184/251] =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Service/Reading/ClinicalData/ReadingClinicalDataService.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs b/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs index 611c72ab8..2277a72b8 100644 --- a/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs +++ b/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs @@ -1251,7 +1251,8 @@ namespace IRaCIS.Application.Services { IsSign = true, IsBlind = inDto.IsBlind, - IsComplete = inDto.IsComplete + IsComplete = inDto.IsComplete, + ReadingClinicalDataState= ReadingClinicalDataStatus.HaveSigned, }); await _readingClinicalDataPDFRepository.SaveChangesAsync(); return ResponseOutput.Ok(pdfCount); From 9cbfb2c7e4a37be61b47f475331bf6eec8c9b370 Mon Sep 17 00:00:00 2001 From: he <109787524@qq.com> Date: Mon, 5 Aug 2024 17:08:06 +0800 Subject: [PATCH 185/251] =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Service/Reading/ClinicalData/ReadingClinicalDataService.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs b/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs index 2277a72b8..b6d719184 100644 --- a/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs +++ b/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs @@ -878,7 +878,8 @@ namespace IRaCIS.Application.Services CriterionEnumList = x.ClinicalDataTrialSet.CriterionEnumList, TrialClinicalDataSetCriteriaList = x.ClinicalDataTrialSet.TrialClinicalDataSetCriteriaList, Id = x.Id, - UploadRole = x.ClinicalDataTrialSet.UploadRole, + // 这里现在都是PM上传的 + UploadRole = UploadRole.PM, IsCRCUpload = x.ClinicalDataTrialSet.UploadRole == UploadRole.CRC, IsBlind = x.IsBlind, IsComplete = x.IsComplete, From 75d162b353be4be4859481fab07749323cab03a5 Mon Sep 17 00:00:00 2001 From: he <109787524@qq.com> Date: Mon, 5 Aug 2024 17:08:39 +0800 Subject: [PATCH 186/251] =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Service/Reading/ClinicalData/ReadingClinicalDataService.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs b/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs index b6d719184..6ac1ad4f5 100644 --- a/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs +++ b/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs @@ -880,7 +880,7 @@ namespace IRaCIS.Application.Services Id = x.Id, // 这里现在都是PM上传的 UploadRole = UploadRole.PM, - IsCRCUpload = x.ClinicalDataTrialSet.UploadRole == UploadRole.CRC, + IsCRCUpload = false, IsBlind = x.IsBlind, IsComplete = x.IsComplete, FileCount = x.FileCount, From cda134e92c07d0d0b7a9da473ae52cd8d2bcff62 Mon Sep 17 00:00:00 2001 From: he <109787524@qq.com> Date: Mon, 5 Aug 2024 17:09:05 +0800 Subject: [PATCH 187/251] =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Service/Reading/ClinicalData/ReadingClinicalDataService.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs b/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs index 6ac1ad4f5..f33e41df5 100644 --- a/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs +++ b/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs @@ -878,7 +878,7 @@ namespace IRaCIS.Application.Services CriterionEnumList = x.ClinicalDataTrialSet.CriterionEnumList, TrialClinicalDataSetCriteriaList = x.ClinicalDataTrialSet.TrialClinicalDataSetCriteriaList, Id = x.Id, - // 这里现在都是PM上传的 + // 这里现在都是PM上传的 前端会判断是否可以上传 UploadRole = UploadRole.PM, IsCRCUpload = false, IsBlind = x.IsBlind, From ef63c19c931ceeb9178969b1636c9236ff7dedd4 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Mon, 5 Aug 2024 17:59:26 +0800 Subject: [PATCH 188/251] =?UTF-8?q?=E5=AE=8C=E6=88=90=E9=82=AE=E4=BB=B6?= =?UTF-8?q?=E5=9F=BA=E6=9C=AC=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Service/Common/MailService.cs | 139 ++++++++++++++++++ .../Management/DTO/UserFeedBackViewModel.cs | 3 +- IRaCIS.Core.Domain/Management/UserFeedBack.cs | 2 +- 3 files changed, 141 insertions(+), 3 deletions(-) diff --git a/IRaCIS.Core.Application/Service/Common/MailService.cs b/IRaCIS.Core.Application/Service/Common/MailService.cs index fab8dd58f..ef2839944 100644 --- a/IRaCIS.Core.Application/Service/Common/MailService.cs +++ b/IRaCIS.Core.Application/Service/Common/MailService.cs @@ -18,6 +18,9 @@ using IRaCIS.Core.Domain.Models; using DocumentFormat.OpenXml.Office2013.Excel; using IRaCIS.Core.Application.Contracts; using DocumentFormat.OpenXml.Vml; +using System.Net.Mail; +using IP2Region.Net.XDB; +using NPOI.SS.Formula.Eval; namespace IRaCIS.Application.Services { @@ -728,6 +731,142 @@ namespace IRaCIS.Application.Services } + //用户反馈邮件 + public async Task UserFeedBack(Guid feedBackId) + { + var feedBack = await _repository.Where(t => t.Id == feedBackId).Include(t => t.CreateUser).ThenInclude(t => t.UserTypeRole).FirstNotNullAsync(); + + var messageToSend = new MimeMessage(); + //发件地址 + messageToSend.From.Add(new MailboxAddress(_systemEmailConfig.FromName, _systemEmailConfig.FromEmail)); + + var isHaveTrialId = feedBack.TrialId != null; + + var companyName = _userInfo.IsEn_Us ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN; + + + var emailList = await _repository.Where(t => t.UserTypeEnum == UserTypeEnum.Admin || t.UserTypeEnum == UserTypeEnum.ZYSS || + (isHaveTrialId ? t.UserTrials.Any(t => t.User.UserTypeEnum == UserTypeEnum.ProjectManager && t.TrialId == feedBack.TrialId) : true)).Select(t => new { t.EMail, t.UserTypeEnum, t.FullName }).ToListAsync(); + + + //影像阅片反馈 pm + if (feedBack.VisitTaskId != null) + { + foreach (var email in emailList) + { + if (email.UserTypeEnum == UserTypeEnum.ProjectManager) + { + //收件地址 + messageToSend.To.Add(new MailboxAddress(email.FullName, email.EMail)); + } + } + + var userNames = string.Join(',', emailList.Where(email => email.UserTypeEnum == UserTypeEnum.ProjectManager).Select(t => t.FullName)); + + var emailType = await _repository.Where(t => t.Parent.Code == "Email_BusinessScenario" && t.ParentId != null && t.Code == ((int)EmailBusinessScenario.UserResetEmail).ToString()).Select(t => _userInfo.IsEn_Us ? t.Value : t.ValueCN).FirstOrDefaultAsync(); + + + var info = await _repository.Where(t => t.Id == feedBack.VisitTaskId).Select(t => new { t.Trial.ResearchProgramNo, t.Trial.TrialCode, SubejctCode = t.Subject.Code, t.SourceSubjectVisit.VisitName }).FirstNotNullAsync(); + + Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr)> emailConfigFunc = input => + { + var topicStr = string.Format(input.topicStr, info.SubejctCode, info.VisitName, info.ResearchProgramNo); + + var htmlBodyStr = string.Format(ReplaceCompanyName(input.htmlBodyStr), + userNames, + info.TrialCode, + info.SubejctCode, + info.VisitName, + feedBack.CreateUser.UserTypeRole.UserTypeShortName, + feedBack.CreateUser.FullName, + emailType, + feedBack.QuestionDescription, + _systemEmailConfig.SiteUrl + ); + + return (topicStr, htmlBodyStr); + }; + + + messageToSend = await GetEmailSubejctAndHtmlInfoAndBuildAsync(EmailBusinessScenario.UserResetEmail, messageToSend, emailConfigFunc); + + } + //项目相关的反馈 pm admin + else if (feedBack.TrialId != null) + { + foreach (var email in emailList) + { + if (email.UserTypeEnum == UserTypeEnum.ProjectManager || email.UserTypeEnum == UserTypeEnum.Admin) + { + //收件地址 + messageToSend.To.Add(new MailboxAddress(email.FullName, email.EMail)); + } + } + + var userNames = string.Join(',', emailList.Where(email => email.UserTypeEnum == UserTypeEnum.ProjectManager || email.UserTypeEnum == UserTypeEnum.Admin).Select(t => t.FullName)); + + var emailType = await _repository.Where(t => t.Parent.Code == "Email_BusinessScenario" && t.ParentId != null && t.Code == ((int)EmailBusinessScenario.UserResetEmail).ToString()).Select(t => _userInfo.IsEn_Us ? t.Value : t.ValueCN).FirstOrDefaultAsync(); + + + var info = await _repository.Where(t => t.Id == feedBack.TrialId).Select(t => new { t.ResearchProgramNo, t.TrialCode }).FirstNotNullAsync(); + + Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr)> emailConfigFunc = input => + { + var topicStr = string.Format(input.topicStr, info.ResearchProgramNo); + + var htmlBodyStr = string.Format(ReplaceCompanyName(input.htmlBodyStr), + userNames, + info.TrialCode, + feedBack.CreateUser.UserTypeRole.UserTypeShortName, + feedBack.CreateUser.FullName, + emailType, + feedBack.QuestionDescription, + _systemEmailConfig.SiteUrl + ); + + return (topicStr, htmlBodyStr); + }; + + + messageToSend = await GetEmailSubejctAndHtmlInfoAndBuildAsync(EmailBusinessScenario.UserResetEmail, messageToSend, emailConfigFunc); + + } + //项目无关的反馈 admin zyss + else + { + foreach (var email in emailList) + { + if (email.UserTypeEnum == UserTypeEnum.ZYSS || email.UserTypeEnum == UserTypeEnum.Admin) + { + //收件地址 + messageToSend.To.Add(new MailboxAddress(email.FullName, email.EMail)); + } + } + + var userNames = string.Join(',', emailList.Where(email => email.UserTypeEnum == UserTypeEnum.ZYSS || email.UserTypeEnum == UserTypeEnum.Admin).Select(t => t.FullName)); + + Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr)> emailConfigFunc = input => + { + var topicStr = string.Format(input.topicStr); + + var htmlBodyStr = string.Format(ReplaceCompanyName(input.htmlBodyStr), + userNames, + feedBack.CreateUser.UserTypeRole.UserTypeShortName, + feedBack.CreateUser.FullName, + feedBack.QuestionDescription, + _systemEmailConfig.SiteUrl + ); + + return (topicStr, htmlBodyStr); + }; + + + messageToSend = await GetEmailSubejctAndHtmlInfoAndBuildAsync(EmailBusinessScenario.UserResetEmail, messageToSend, emailConfigFunc); + } + + await SendEmailHelper.SendEmailAsync(messageToSend, _systemEmailConfig); + + } } } diff --git a/IRaCIS.Core.Application/Service/Management/DTO/UserFeedBackViewModel.cs b/IRaCIS.Core.Application/Service/Management/DTO/UserFeedBackViewModel.cs index 51bc992bb..a83c28ba2 100644 --- a/IRaCIS.Core.Application/Service/Management/DTO/UserFeedBackViewModel.cs +++ b/IRaCIS.Core.Application/Service/Management/DTO/UserFeedBackViewModel.cs @@ -85,8 +85,7 @@ namespace IRaCIS.Core.Application.ViewModel public int State { get; set; } public Guid? TrialSiteId { get; set; } - [NotDefault] - public Guid TrialId { get; set; } + public Guid? TrialId { get; set; } public Guid? VisitTaskId { get; set; } diff --git a/IRaCIS.Core.Domain/Management/UserFeedBack.cs b/IRaCIS.Core.Domain/Management/UserFeedBack.cs index 999a4c04e..a9674c176 100644 --- a/IRaCIS.Core.Domain/Management/UserFeedBack.cs +++ b/IRaCIS.Core.Domain/Management/UserFeedBack.cs @@ -62,7 +62,7 @@ namespace IRaCIS.Core.Domain.Models public Guid? TrialSiteId { get; set; } - public Guid TrialId { get; set; } + public Guid? TrialId { get; set; } public string ScreenshotListStr { get; set; } From e92ea3ea0c78cb4b2e2ae03aa44ba666eb64a240 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Tue, 6 Aug 2024 12:23:57 +0800 Subject: [PATCH 189/251] =?UTF-8?q?lili=20=E7=94=9F=E6=88=90=E4=BB=BB?= =?UTF-8?q?=E5=8A=A1bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Service/Allocation/VisitTaskHelpeService.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/IRaCIS.Core.Application/Service/Allocation/VisitTaskHelpeService.cs b/IRaCIS.Core.Application/Service/Allocation/VisitTaskHelpeService.cs index d739000b2..9bd628b3d 100644 --- a/IRaCIS.Core.Application/Service/Allocation/VisitTaskHelpeService.cs +++ b/IRaCIS.Core.Application/Service/Allocation/VisitTaskHelpeService.cs @@ -703,8 +703,8 @@ namespace IRaCIS.Core.Application.Service && t.TrialReadingCriterionId == trialReadingCriterionId && t.TaskState == TaskState.Effect /* && t.TaskAllocationState == TaskAllocationState.NotAllocate && t.DoctorUserId == null*/ && t.SourceSubjectVisitId == subjectVisit.Id).ToList(); - VisitTask? task1 = null; - VisitTask? task2 = null; + VisitTask? task1 = existCurrentVisitTaskList.FirstOrDefault(t => t.ArmEnum == Arm.DoubleReadingArm1); + VisitTask? task2 = existCurrentVisitTaskList.FirstOrDefault(t => t.ArmEnum == Arm.DoubleReadingArm2); if (!existCurrentVisitTaskList.Any(t => t.ArmEnum == Arm.DoubleReadingArm1)) @@ -736,6 +736,7 @@ namespace IRaCIS.Core.Application.Service }); } + if (!existCurrentVisitTaskList.Any(t => t.ArmEnum == Arm.DoubleReadingArm2)) { currentMaxCodeInt = currentMaxCodeInt + 1; From 7b78e4b399fb76e6841abd96faf839ec24f1ec67 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Tue, 6 Aug 2024 14:38:30 +0800 Subject: [PATCH 190/251] =?UTF-8?q?20240806=20=E5=AF=BC=E8=A1=A8=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Allocation/TaskMedicalReviewService.cs | 3 - .../Service/Allocation/VisitTaskService.cs | 54 +-- .../Service/Common/ExcelExportService.cs | 443 ++++++++++++------ .../Service/Document/TrialDocumentService.cs | 34 +- .../Service/ImageAndDoc/StudyService.cs | 26 +- .../Service/QC/DTO/QCListViewModel.cs | 93 +++- .../Service/QC/QCListService.cs | 154 +++--- .../Service/QC/_MapConfig.cs | 24 +- .../Service/Visit/SubjectService.cs | 22 +- IRaCIS.Core.Domain/_Config/_StaticData.cs | 4 + 10 files changed, 562 insertions(+), 295 deletions(-) diff --git a/IRaCIS.Core.Application/Service/Allocation/TaskMedicalReviewService.cs b/IRaCIS.Core.Application/Service/Allocation/TaskMedicalReviewService.cs index 10a9f59a4..b8e31ed21 100644 --- a/IRaCIS.Core.Application/Service/Allocation/TaskMedicalReviewService.cs +++ b/IRaCIS.Core.Application/Service/Allocation/TaskMedicalReviewService.cs @@ -56,9 +56,6 @@ namespace IRaCIS.Core.Application.Service var taskMedicalReviewQueryable = _taskMedicalReviewRepository.Where(t => t.VisitTask.TrialId == inQuery.TrialId) - //.WhereIf(inQuery.IsEffect == true, t => t.VisitTask.TaskState == TaskState.Effect || t.VisitTask.TaskState == TaskState.Freeze) - //.WhereIf(inQuery.IsEffect == false, t => t.VisitTask.TaskState == TaskState.Adbandon || t.VisitTask.TaskState == TaskState.HaveReturned) - .WhereIf(inQuery.TrialSiteId != null, t => t.VisitTask.Subject.TrialSiteId == inQuery.TrialSiteId) .WhereIf(inQuery.SubjectId != null, t => t.VisitTask.SubjectId == inQuery.SubjectId) .WhereIf(!string.IsNullOrEmpty(inQuery.SubjectCode), t => t.VisitTask.Subject.Code.Contains(inQuery.SubjectCode) || t.VisitTask.Subject.MedicalNo.Contains(inQuery.SubjectCode)) diff --git a/IRaCIS.Core.Application/Service/Allocation/VisitTaskService.cs b/IRaCIS.Core.Application/Service/Allocation/VisitTaskService.cs index efdd7ff84..4898ac25c 100644 --- a/IRaCIS.Core.Application/Service/Allocation/VisitTaskService.cs +++ b/IRaCIS.Core.Application/Service/Allocation/VisitTaskService.cs @@ -803,43 +803,43 @@ namespace IRaCIS.Core.Application.Service.Allocation /// /// PM 重阅追踪 /// - /// + /// /// [HttpPost] - public async Task> GetReReadingTaskList(VisitTaskQuery queryVisitTask) + public async Task> GetReReadingTaskList(VisitTaskQuery inQuery) { var visitTaskQueryable = _visitTaskReReadingRepository - .Where(t => t.OriginalReReadingTask.TrialId == queryVisitTask.TrialId /*&& t.OriginalReReadingTask.IsAnalysisCreate == false*/) - .WhereIf(queryVisitTask.RootReReadingTaskId != null, t => t.RootReReadingTaskId == queryVisitTask.RootReReadingTaskId || t.OriginalReReadingTaskId == queryVisitTask.RootReReadingTaskId) - .WhereIf(!string.IsNullOrEmpty(queryVisitTask.TaskCode), t => t.OriginalReReadingTask.TaskCode.Contains(queryVisitTask.TaskCode!) || t.RootReReadingTask.TaskCode.Contains(queryVisitTask.TaskCode!)) - .WhereIf(queryVisitTask.TrialSiteId != null, t => t.OriginalReReadingTask.Subject.TrialSiteId == queryVisitTask.TrialSiteId) - .WhereIf(queryVisitTask.TaskState != null, t => t.OriginalReReadingTask.TaskState == queryVisitTask.TaskState) - .WhereIf(queryVisitTask.ReReadingApplyState != null, t => t.OriginalReReadingTask.ReReadingApplyState == queryVisitTask.ReReadingApplyState) - .WhereIf(queryVisitTask.RequestReReadingType != null, t => t.RequestReReadingType == queryVisitTask.RequestReReadingType) - .WhereIf(queryVisitTask.SubjectId != null, t => t.OriginalReReadingTask.SubjectId == queryVisitTask.SubjectId) - .WhereIf(queryVisitTask.IsUrgent != null, t => t.OriginalReReadingTask.IsUrgent == queryVisitTask.IsUrgent) - .WhereIf(queryVisitTask.DoctorUserId != null, t => t.OriginalReReadingTask.DoctorUserId == queryVisitTask.DoctorUserId) - .WhereIf(queryVisitTask.ArmEnum != null, t => t.OriginalReReadingTask.ArmEnum == queryVisitTask.ArmEnum) - .WhereIf(queryVisitTask.ReadingTaskState != null, t => t.OriginalReReadingTask.ReadingTaskState == queryVisitTask.ReadingTaskState) - .WhereIf(queryVisitTask.TaskAllocationState != null, t => t.OriginalReReadingTask.TaskAllocationState == queryVisitTask.TaskAllocationState) - .WhereIf(queryVisitTask.TrialReadingCriterionId != null, t => t.OriginalReReadingTask.TrialReadingCriterionId == queryVisitTask.TrialReadingCriterionId) - .WhereIf(queryVisitTask.ReadingCategory != null, t => t.OriginalReReadingTask.ReadingCategory == queryVisitTask.ReadingCategory) + .Where(t => t.OriginalReReadingTask.TrialId == inQuery.TrialId /*&& t.OriginalReReadingTask.IsAnalysisCreate == false*/) + .WhereIf(inQuery.RootReReadingTaskId != null, t => t.RootReReadingTaskId == inQuery.RootReReadingTaskId || t.OriginalReReadingTaskId == inQuery.RootReReadingTaskId) + .WhereIf(!string.IsNullOrEmpty(inQuery.TaskCode), t => t.OriginalReReadingTask.TaskCode.Contains(inQuery.TaskCode!) || t.RootReReadingTask.TaskCode.Contains(inQuery.TaskCode!)) + .WhereIf(inQuery.TrialSiteId != null, t => t.OriginalReReadingTask.Subject.TrialSiteId == inQuery.TrialSiteId) + .WhereIf(inQuery.TaskState != null, t => t.OriginalReReadingTask.TaskState == inQuery.TaskState) + .WhereIf(inQuery.ReReadingApplyState != null, t => t.OriginalReReadingTask.ReReadingApplyState == inQuery.ReReadingApplyState) + .WhereIf(inQuery.RequestReReadingType != null, t => t.RequestReReadingType == inQuery.RequestReReadingType) + .WhereIf(inQuery.SubjectId != null, t => t.OriginalReReadingTask.SubjectId == inQuery.SubjectId) + .WhereIf(inQuery.IsUrgent != null, t => t.OriginalReReadingTask.IsUrgent == inQuery.IsUrgent) + .WhereIf(inQuery.DoctorUserId != null, t => t.OriginalReReadingTask.DoctorUserId == inQuery.DoctorUserId) + .WhereIf(inQuery.ArmEnum != null, t => t.OriginalReReadingTask.ArmEnum == inQuery.ArmEnum) + .WhereIf(inQuery.ReadingTaskState != null, t => t.OriginalReReadingTask.ReadingTaskState == inQuery.ReadingTaskState) + .WhereIf(inQuery.TaskAllocationState != null, t => t.OriginalReReadingTask.TaskAllocationState == inQuery.TaskAllocationState) + .WhereIf(inQuery.TrialReadingCriterionId != null, t => t.OriginalReReadingTask.TrialReadingCriterionId == inQuery.TrialReadingCriterionId) + .WhereIf(inQuery.ReadingCategory != null, t => t.OriginalReReadingTask.ReadingCategory == inQuery.ReadingCategory) - .WhereIf(!string.IsNullOrEmpty(queryVisitTask.RequestReReadingReason), t => t.RequestReReadingReason.Contains(queryVisitTask.RequestReReadingReason)) + .WhereIf(!string.IsNullOrEmpty(inQuery.RequestReReadingReason), t => t.RequestReReadingReason.Contains(inQuery.RequestReReadingReason)) - .WhereIf(queryVisitTask.RequestReReadingResultEnum != null, t => t.RequestReReadingResultEnum == queryVisitTask.RequestReReadingResultEnum) + .WhereIf(inQuery.RequestReReadingResultEnum != null, t => t.RequestReReadingResultEnum == inQuery.RequestReReadingResultEnum) - .WhereIf(!string.IsNullOrEmpty(queryVisitTask.TrialSiteCode), t => (t.OriginalReReadingTask.BlindTrialSiteCode.Contains(queryVisitTask.TrialSiteCode!) && t.OriginalReReadingTask.IsAnalysisCreate) || (t.OriginalReReadingTask.Subject.TrialSite.TrialSiteCode.Contains(queryVisitTask.TrialSiteCode!) && t.OriginalReReadingTask.IsAnalysisCreate == false)) - .WhereIf(!string.IsNullOrEmpty(queryVisitTask.TaskName), t => t.OriginalReReadingTask.TaskName.Contains(queryVisitTask.TaskName) || t.OriginalReReadingTask.TaskBlindName.Contains(queryVisitTask.TaskName)) - .WhereIf(!string.IsNullOrEmpty(queryVisitTask.SubjectCode), t => ((t.OriginalReReadingTask.Subject.Code.Contains(queryVisitTask.SubjectCode) || t.OriginalReReadingTask.Subject.MedicalNo.Contains(queryVisitTask.SubjectCode)) && t.OriginalReReadingTask.IsAnalysisCreate == false) || (t.OriginalReReadingTask.BlindSubjectCode.Contains(queryVisitTask.SubjectCode) && t.OriginalReReadingTask.IsAnalysisCreate)) - .WhereIf(queryVisitTask.BeginAllocateDate != null, t => t.OriginalReReadingTask.AllocateTime > queryVisitTask.BeginAllocateDate) - .WhereIf(queryVisitTask.EndAllocateDate != null, t => t.OriginalReReadingTask.AllocateTime < queryVisitTask.EndAllocateDate!.Value.AddDays(1)) + .WhereIf(!string.IsNullOrEmpty(inQuery.TrialSiteCode), t => (t.OriginalReReadingTask.BlindTrialSiteCode.Contains(inQuery.TrialSiteCode!) && t.OriginalReReadingTask.IsAnalysisCreate) || (t.OriginalReReadingTask.Subject.TrialSite.TrialSiteCode.Contains(inQuery.TrialSiteCode!) && t.OriginalReReadingTask.IsAnalysisCreate == false)) + .WhereIf(!string.IsNullOrEmpty(inQuery.TaskName), t => t.OriginalReReadingTask.TaskName.Contains(inQuery.TaskName) || t.OriginalReReadingTask.TaskBlindName.Contains(inQuery.TaskName)) + .WhereIf(!string.IsNullOrEmpty(inQuery.SubjectCode), t => ((t.OriginalReReadingTask.Subject.Code.Contains(inQuery.SubjectCode) || t.OriginalReReadingTask.Subject.MedicalNo.Contains(inQuery.SubjectCode)) && t.OriginalReReadingTask.IsAnalysisCreate == false) || (t.OriginalReReadingTask.BlindSubjectCode.Contains(inQuery.SubjectCode) && t.OriginalReReadingTask.IsAnalysisCreate)) + .WhereIf(inQuery.BeginAllocateDate != null, t => t.OriginalReReadingTask.AllocateTime > inQuery.BeginAllocateDate) + .WhereIf(inQuery.EndAllocateDate != null, t => t.OriginalReReadingTask.AllocateTime < inQuery.EndAllocateDate!.Value.AddDays(1)) - .WhereIf(queryVisitTask.BeginRequestReReadingTime != null, t => t.RequestReReadingTime >= queryVisitTask.BeginRequestReReadingTime) - .WhereIf(queryVisitTask.EndRequestReReadingTime != null, t => t.RequestReReadingTime <= queryVisitTask.EndRequestReReadingTime!.Value.AddDays(1)) + .WhereIf(inQuery.BeginRequestReReadingTime != null, t => t.RequestReReadingTime >= inQuery.BeginRequestReReadingTime) + .WhereIf(inQuery.EndRequestReReadingTime != null, t => t.RequestReReadingTime <= inQuery.EndRequestReReadingTime!.Value.AddDays(1)) .ProjectTo(_mapper.ConfigurationProvider); @@ -853,7 +853,7 @@ namespace IRaCIS.Core.Application.Service.Allocation - var pageList = await visitTaskQueryable.ToPagedListAsync(queryVisitTask.PageIndex, queryVisitTask.PageSize, queryVisitTask.SortField, queryVisitTask.Asc, string.IsNullOrWhiteSpace(queryVisitTask.SortField), defalutSortArray); + var pageList = await visitTaskQueryable.ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, inQuery.SortField, inQuery.Asc, string.IsNullOrWhiteSpace(inQuery.SortField), defalutSortArray); return pageList; } diff --git a/IRaCIS.Core.Application/Service/Common/ExcelExportService.cs b/IRaCIS.Core.Application/Service/Common/ExcelExportService.cs index 96ece98b1..d2616588e 100644 --- a/IRaCIS.Core.Application/Service/Common/ExcelExportService.cs +++ b/IRaCIS.Core.Application/Service/Common/ExcelExportService.cs @@ -51,8 +51,8 @@ namespace IRaCIS.Core.Application.Service.Common public async Task TrialUserListExport(TrialMaintenanceExportQuery param, [FromServices] IRepository _commonDocumentRepository, [FromServices] IDictionaryService _dictionaryService, - [FromServices] IRepository _trialRepository, - [FromServices] IRepository _trialUseRepository + [FromServices] IRepository _trialRepository, + [FromServices] IRepository _trialUseRepository ) { @@ -95,8 +95,8 @@ namespace IRaCIS.Core.Application.Service.Common public async Task TrialSiteUserListExport(SiteCRCExportQueryDTO param, [FromServices] IRepository _commonDocumentRepository, [FromServices] IDictionaryService _dictionaryService, - [FromServices] IRepository _trialRepository, - [FromServices] IRepository _trialSiteUserRepository + [FromServices] IRepository _trialRepository, + [FromServices] IRepository _trialSiteUserRepository ) { @@ -144,8 +144,8 @@ namespace IRaCIS.Core.Application.Service.Common [FromServices] IRepository _commonDocumentRepository, [FromServices] IRepository _trialSiteSurveyRepository, [FromServices] IRepository _trialSiteUserSurveyRepository, - [FromServices] IRepository _trialRepository, - [FromServices] IDictionaryService _dictionaryService + [FromServices] IRepository _trialRepository, + [FromServices] IDictionaryService _dictionaryService ) { @@ -189,9 +189,118 @@ namespace IRaCIS.Core.Application.Service.Common #region 导表查询 + /// + /// getDocumentConfirmList 培训记录导出 + /// + /// + /// + /// + /// + /// + /// + [HttpPost] + [AllowAnonymous] + public async Task PMTrainingRecordList_Export(DocumentTrialUnionQuery inQuery, + [FromServices] IRepository _commonDocumentRepository, + [FromServices] IDictionaryService _dictionaryService, + [FromServices] IRepository _subjectVisitRepository, + [FromServices] IRepository _trialRepository + ) + { + var trialInfo = (await _repository.Where(t => t.Id == inQuery.TrialId).Select(t => new { t.TrialFinishedTime, t.TrialStatusStr }).FirstNotNullAsync()); + + var trialDocQuery = from trialDocumentNeedConfirmedUserType in _repository.Where(t => t.TrialDocument.TrialId == inQuery.TrialId) + join trialUser in _repository.Where(t => t.TrialId == inQuery.TrialId) + .WhereIf(inQuery.UserId != null, t => t.UserId == inQuery.UserId) + .WhereIf(inQuery.UserTypeId != null, t => t.User.UserTypeId == inQuery.UserTypeId) + on trialDocumentNeedConfirmedUserType.NeedConfirmUserTypeId equals trialUser.User.UserTypeId + + join confirm in _repository.Where(t => t.TrialDocument.TrialId == inQuery.TrialId) on + new { trialUser.UserId, TrialDocumentId = trialDocumentNeedConfirmedUserType.TrialDocumentId } equals new { UserId = confirm.ConfirmUserId, confirm.TrialDocumentId } into cc + from confirm in cc.DefaultIfEmpty() + select new TrainingRecordExportDTO() + { + IsSystemDoc = false, + + Id = trialDocumentNeedConfirmedUserType.TrialDocument.Id, + CreateTime = trialDocumentNeedConfirmedUserType.TrialDocument.CreateTime, + IsDeleted = trialDocumentNeedConfirmedUserType.TrialDocument.IsDeleted, + //SignViewMinimumMinutes = trialDocumentNeedConfirmedUserType.TrialDocument.SignViewMinimumMinutes, + Name = trialDocumentNeedConfirmedUserType.TrialDocument.Name, + //Path = trialDocumentNeedConfirmedUserType.TrialDocument.Path, + FileTypeId = trialDocumentNeedConfirmedUserType.TrialDocument.FileTypeId, + FileType = _userInfo.IsEn_Us ? trialDocumentNeedConfirmedUserType.TrialDocument.FileType.Value : trialDocumentNeedConfirmedUserType.TrialDocument.FileType.ValueCN, + //UpdateTime = trialDocumentNeedConfirmedUserType.TrialDocument.UpdateTime, + //IsConfirmed= confirm.ConfirmTime!=null, + //ConfirmUserId = confirm.ConfirmUserId, + ConfirmTime = confirm.ConfirmTime, + RealName = trialUser.User.FullName, + UserName = trialUser.User.UserName, + UserTypeId = trialUser.User.UserTypeId, + UserTypeShortName = trialUser.User.UserTypeRole.UserTypeShortName, + + //FullFilePath = trialDocumentNeedConfirmedUserType.TrialDocument.Path + }; + + + + var systemDocQuery = from needConfirmEdUserType in _repository.WhereIf(trialInfo.TrialFinishedTime != null, u => u.SystemDocument.CreateTime < trialInfo.TrialFinishedTime) + + join trialUser in _repository.Where(t => t.TrialId == inQuery.TrialId) + .WhereIf(inQuery.UserId != null, t => t.UserId == inQuery.UserId) + on needConfirmEdUserType.NeedConfirmUserTypeId equals trialUser.User.UserTypeId + join confirm in _repository.GetQueryable() on new { ConfirmUserId = trialUser.UserId, SystemDocumentId = needConfirmEdUserType.SystemDocumentId } equals new { confirm.ConfirmUserId, confirm.SystemDocumentId } into cc + from confirm in cc.DefaultIfEmpty() + select new TrainingRecordExportDTO() + { + IsSystemDoc = true, + + Id = needConfirmEdUserType.SystemDocument.Id, + CreateTime = needConfirmEdUserType.SystemDocument.CreateTime, + IsDeleted = needConfirmEdUserType.SystemDocument.IsDeleted, + //SignViewMinimumMinutes = needConfirmEdUserType.SystemDocument.SignViewMinimumMinutes, + Name = needConfirmEdUserType.SystemDocument.Name, + //Path = needConfirmEdUserType.SystemDocument.Path, + FileType = _userInfo.IsEn_Us ? needConfirmEdUserType.SystemDocument.FileType.Value : needConfirmEdUserType.SystemDocument.FileType.ValueCN, + FileTypeId = needConfirmEdUserType.SystemDocument.FileTypeId, + //UpdateTime = needConfirmEdUserType.SystemDocument.UpdateTime, + //IsConfirmed = confirm.ConfirmTime != null, + + //ConfirmUserId = confirm.ConfirmUserId, + ConfirmTime = confirm.ConfirmTime, + RealName = trialUser.User.FullName, + UserName = trialUser.User.UserName, + UserTypeId = trialUser.User.UserTypeId, + UserTypeShortName = trialUser.User.UserTypeRole.UserTypeShortName, + + //FullFilePath = needConfirmEdUserType.SystemDocument.Path + }; + + var unionQuery = trialDocQuery.Union(systemDocQuery) + .WhereIf(!string.IsNullOrEmpty(inQuery.Name), t => t.Name.Contains(inQuery.Name)) + .WhereIf(inQuery.FileTypeId != null, t => t.FileTypeId == inQuery.FileTypeId) + .WhereIf(inQuery.IsConfirmed == true, t => t.ConfirmTime != null) + .WhereIf(inQuery.IsConfirmed == false, t => t.ConfirmTime == null) + .WhereIf(inQuery.IsDeleted != null, t => t.IsDeleted == inQuery.IsDeleted) + .WhereIf(inQuery.UserTypeId != null, t => t.UserTypeId == inQuery.UserTypeId); + + var list = await unionQuery.ToListAsync(); + + + var exportInfo = (await _trialRepository.Where(t => t.Id == inQuery.TrialId).IgnoreQueryFilters().ProjectTo(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException(); + + exportInfo.List = ExportExcelConverterDate.ConvertToClientTimeInObject(list, _userInfo.TimeZoneId); + exportInfo.IsEn_US = _userInfo.IsEn_Us; + exportInfo.ClientZoneId = _userInfo.TimeZoneId; + + + return await ExcelExportHelper.DataExportAsync(StaticData.Export.TrialTrainingRecordList_Export, exportInfo, $"{exportInfo.ResearchProgramNo}", _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(TrainingRecordExportDTO)); + + } + @@ -201,7 +310,7 @@ namespace IRaCIS.Core.Application.Service.Common /// /// 影像上传列表 只导出已上传状态的访视记录 /// - /// + /// /// /// /// @@ -209,7 +318,7 @@ namespace IRaCIS.Core.Application.Service.Common /// [HttpPost] [AllowAnonymous] - public async Task CRCVisitList_Export(CRCVisitSearchDTO visitSearchDTO, + public async Task CRCVisitList_Export(CRCVisitSearchDTO inQuery, [FromServices] IRepository _commonDocumentRepository, [FromServices] IDictionaryService _dictionaryService, [FromServices] IRepository _subjectVisitRepository, @@ -217,26 +326,26 @@ namespace IRaCIS.Core.Application.Service.Common ) { - var svExpression = QCCommon.GetSubjectVisitFilter(visitSearchDTO.VisitPlanArray); + var svExpression = QCCommon.GetSubjectVisitFilter(inQuery.VisitPlanArray); - var list = await _subjectVisitRepository.Where(x => x.TrialId == visitSearchDTO.TrialId) + var query = _subjectVisitRepository.Where(x => x.TrialId == inQuery.TrialId) .Where(t => t.Subject.FinalSubjectVisitId != null ? t.VisitNum <= t.Subject.FinalSubjectVisit.VisitNum : true) - .WhereIf(visitSearchDTO.TrialSiteId != null, t => t.TrialSiteId == visitSearchDTO.TrialSiteId) - .WhereIf(visitSearchDTO.SubjectId != null, t => t.Subject.Id == visitSearchDTO.SubjectId) - .WhereIf(!string.IsNullOrEmpty(visitSearchDTO.SubjectInfo), t => t.Subject.Code.Contains(visitSearchDTO.SubjectInfo)) + .WhereIf(inQuery.TrialSiteId != null, t => t.TrialSiteId == inQuery.TrialSiteId) + .WhereIf(inQuery.SubjectId != null, t => t.Subject.Id == inQuery.SubjectId) + .WhereIf(!string.IsNullOrEmpty(inQuery.SubjectInfo), t => t.Subject.Code.Contains(inQuery.SubjectInfo)) - .WhereIf(visitSearchDTO.VisitPlanArray != null && visitSearchDTO.VisitPlanArray?.Length > 0, svExpression) + .WhereIf(inQuery.VisitPlanArray != null && inQuery.VisitPlanArray?.Length > 0, svExpression) //.WhereIf(!string.IsNullOrEmpty(visitSearchDTO.VisitPlanInfo), visitSearchDTO.VisitPlanInfo.Contains('.') ? t => t.InPlan == false : t => t.VisitNum == decimal.Parse(visitSearchDTO.VisitPlanInfo)) - .WhereIf(visitSearchDTO.AuditStateArray != null && visitSearchDTO.AuditStateArray?.Length > 0, t => visitSearchDTO.AuditStateArray!.Contains(t.AuditState)) - .WhereIf(visitSearchDTO.SubmitState != null, t => t.SubmitState == visitSearchDTO.SubmitState) - .WhereIf(visitSearchDTO.ChallengeState != null, t => t.ChallengeState == visitSearchDTO.ChallengeState) - .WhereIf(visitSearchDTO.IsUrgent != null, t => t.IsUrgent == visitSearchDTO.IsUrgent) + .WhereIf(inQuery.AuditStateArray != null && inQuery.AuditStateArray?.Length > 0, t => inQuery.AuditStateArray!.Contains(t.AuditState)) + .WhereIf(inQuery.SubmitState != null, t => t.SubmitState == inQuery.SubmitState) + .WhereIf(inQuery.ChallengeState != null, t => t.ChallengeState == inQuery.ChallengeState) + .WhereIf(inQuery.IsUrgent != null, t => t.IsUrgent == inQuery.IsUrgent) .WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.CRA, t => t.TrialSite.CRCUserList.Any(t => t.UserId == _userInfo.Id)) - .ProjectTo(_mapper.ConfigurationProvider).ToListAsync(); + .ProjectTo(_mapper.ConfigurationProvider); - list = list.OrderBy(t => t.TrialSiteCode).ThenBy(t => t.SubjectCode).ThenBy(t => t.BlindName).ToList(); + var list = query.OrderBy(t => t.TrialSiteCode).ThenBy(t => t.SubjectCode).ThenBy(t => t.BlindName).ToList(); - var exportInfo = (await _trialRepository.Where(t => t.Id == visitSearchDTO.TrialId).IgnoreQueryFilters().ProjectTo(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException(); + var exportInfo = (await _trialRepository.Where(t => t.Id == inQuery.TrialId).IgnoreQueryFilters().ProjectTo(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException(); exportInfo.List = ExportExcelConverterDate.ConvertToClientTimeInObject(list, _userInfo.TimeZoneId); exportInfo.IsEn_US = _userInfo.IsEn_Us; @@ -247,20 +356,77 @@ namespace IRaCIS.Core.Application.Service.Common } + /// + /// 影像质控导出 + /// + /// + /// + /// + /// + /// + /// + [HttpPost] + [AllowAnonymous] + public async Task QCVisitList_Export(QCVisitSearchDTO inQuery, + [FromServices] IRepository _commonDocumentRepository, + [FromServices] IDictionaryService _dictionaryService, + [FromServices] IRepository _subjectVisitRepository, + [FromServices] IRepository _trialRepository + ) + { + var svExpression = QCCommon.GetSubjectVisitFilter(inQuery.VisitPlanArray); + var query = _subjectVisitRepository.Where(x => x.TrialId == inQuery.TrialId) + .WhereIf(inQuery.VisitId != null, t => t.Id == inQuery.VisitId) + .WhereIf(inQuery.CurrentActionUserId != null, t => t.CurrentActionUserId == inQuery.CurrentActionUserId) + .WhereIf(inQuery.ChallengeState != null, t => t.ChallengeState == inQuery.ChallengeState) + .WhereIf(inQuery.TrialSiteId != null, t => t.TrialSiteId == inQuery.TrialSiteId) + .WhereIf(inQuery.SubjectId != null, t => t.Subject.Id == inQuery.SubjectId) + .WhereIf(!string.IsNullOrEmpty(inQuery.SubjectInfo), t => /*t.Subject.FirstName.Contains(subjectInfo) || t.Subject.LastName.Contains(subjectInfo) ||*/ t.Subject.Code.Contains(inQuery.SubjectInfo)) + .WhereIf(inQuery.VisitPlanArray != null && inQuery.VisitPlanArray?.Length > 0, svExpression) + //.WhereIf(!string.IsNullOrEmpty(visitSearchDTO.VisitPlanInfo), visitSearchDTO.VisitPlanInfo.Contains('.') ? t => t.VisitNum.ToString().Contains(".") : t => t.VisitNum == decimal.Parse(visitSearchDTO.VisitPlanInfo)) + //.WhereIf(visitSearchDTO.AuditState != null, t => t.AuditState == visitSearchDTO.AuditState) + .WhereIf(inQuery.AuditStateArray != null && inQuery.AuditStateArray?.Length > 0, t => inQuery.AuditStateArray!.Contains(t.AuditState)) + .WhereIf(inQuery.HandleUserId != null, t => t.PreliminaryAuditUserId == inQuery.HandleUserId || t.CurrentActionUserId == inQuery.HandleUserId + || t.ReviewAuditUserId == inQuery.HandleUserId + || t.QCChallengeList.Any(t => t.CreateUserId == inQuery.HandleUserId) + || t.QCChallengeDialogList.Any(t => t.CreateUserId == inQuery.HandleUserId)) + .WhereIf(inQuery.IsUrgent != null, t => t.IsUrgent == inQuery.IsUrgent) + .Where(t => t.SubmitState != SubmitStateEnum.None) + .WhereIf(inQuery.BeginAuditTime != null, t => t.Trial.QCProcessEnum == TrialQCProcess.SingleAudit ? t.PreliminaryAuditTime >= inQuery.BeginAuditTime : + (t.Trial.QCProcessEnum == TrialQCProcess.DoubleAudit ? t.ReviewAuditTime >= inQuery.BeginAuditTime : true)) + + .WhereIf(inQuery.EndAuditTime != null, t => t.Trial.QCProcessEnum == TrialQCProcess.SingleAudit ? t.PreliminaryAuditTime <= inQuery.EndAuditTime : + (t.Trial.QCProcessEnum == TrialQCProcess.DoubleAudit ? t.ReviewAuditTime <= inQuery.EndAuditTime : true)) + + .ProjectTo(_mapper.ConfigurationProvider); + + + var list = query.ToList(); + + var exportInfo = (await _trialRepository.Where(t => t.Id == inQuery.TrialId).IgnoreQueryFilters().ProjectTo(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException(); + + exportInfo.List = ExportExcelConverterDate.ConvertToClientTimeInObject(list, _userInfo.TimeZoneId); + exportInfo.IsEn_US = _userInfo.IsEn_Us; + exportInfo.ClientZoneId = _userInfo.TimeZoneId; + + + return await ExcelExportHelper.DataExportAsync(StaticData.Export.TrialQCVisitImageList_Export, exportInfo, $"{exportInfo.ResearchProgramNo}", _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(CRCVisitExportDTO)); + + } /// /// 质疑列表 /// - /// + /// /// /// /// /// [HttpPost] [AllowAnonymous] - public async Task GetQCChallengeList_Export(ChallengeQuery challengeQuery, + public async Task GetQCChallengeList_Export(ChallengeQuery inQuery, [FromServices] IRepository _commonDocumentRepository, [FromServices] IDictionaryService _dictionaryService, [FromServices] IRepository _trialRepository @@ -268,26 +434,28 @@ namespace IRaCIS.Core.Application.Service.Common { - var svExpression = QCCommon.GetQCChallengeFilter(challengeQuery.VisitPlanArray); + var svExpression = QCCommon.GetQCChallengeFilter(inQuery.VisitPlanArray); - var list = await _repository.Where(x => x.TrialId == challengeQuery.TrialId) + var query = _repository.Where(x => x.TrialId == inQuery.TrialId) //.WhereIf(challengeQuery.ChallengeState != null, t => t.SubjectVisit.ChallengeState == challengeQuery.ChallengeState) - .WhereIf(challengeQuery.ReuploadEnum != null, t => t.ReuploadEnum == challengeQuery.ReuploadEnum) - .WhereIf(challengeQuery.IsClosed != null, t => t.IsClosed == challengeQuery.IsClosed) - .WhereIf(challengeQuery.TrialSiteId != null, t => t.SubjectVisit.TrialSiteId == challengeQuery.TrialSiteId) - .WhereIf(challengeQuery.SubjectId != null, t => t.SubjectVisit.SubjectId == challengeQuery.SubjectId) - .WhereIf(challengeQuery.CreateUserId != null, t => t.CreateUserId == challengeQuery.CreateUserId) - .WhereIf(!string.IsNullOrEmpty(challengeQuery.SubjectCode), t => t.SubjectVisit.Subject.Code.Contains(challengeQuery.SubjectCode)) - .WhereIf(challengeQuery.VisitPlanArray != null && challengeQuery.VisitPlanArray?.Length > 0, svExpression) - //.WhereIf(!string.IsNullOrEmpty(challengeQuery.VisitPlanInfo), challengeQuery.VisitPlanInfo.Contains('.') ? t => t.SubjectVisit.InPlan == false : t => t.SubjectVisit.VisitNum == decimal.Parse(challengeQuery.VisitPlanInfo)) - .WhereIf(challengeQuery.IsUrgent != null, t => t.SubjectVisit.IsUrgent == challengeQuery.IsUrgent) - .WhereIf(challengeQuery.IsOverTime != null && challengeQuery.IsOverTime == true, t => t.IsClosed ? t.ClosedTime > t.DeadlineTime : DateTime.Now > t.DeadlineTime) - .WhereIf(challengeQuery.IsOverTime != null && challengeQuery.IsOverTime == false, t => t.IsClosed ? t.ClosedTime < t.DeadlineTime : DateTime.Now < t.DeadlineTime) - .ProjectTo(_mapper.ConfigurationProvider).ToListAsync(); + .WhereIf(inQuery.ReuploadEnum != null, t => t.ReuploadEnum == inQuery.ReuploadEnum) + .WhereIf(inQuery.IsClosed != null, t => t.IsClosed == inQuery.IsClosed) + .WhereIf(inQuery.TrialSiteId != null, t => t.SubjectVisit.TrialSiteId == inQuery.TrialSiteId) + .WhereIf(inQuery.SubjectId != null, t => t.SubjectVisit.SubjectId == inQuery.SubjectId) + .WhereIf(inQuery.CreateUserId != null, t => t.CreateUserId == inQuery.CreateUserId) + .WhereIf(inQuery.SubjectCode != null, t => t.SubjectVisit.Subject.Code.Contains(inQuery.SubjectCode!)) + .WhereIf(inQuery.VisitPlanArray != null && inQuery.VisitPlanArray?.Length > 0, svExpression) + //.WhereIf(!string.IsNullOrEmpty(challengeQuery.VisitPlanInfo), challengeQuery.VisitPlanInfo.Contains('.') ? t => t.SubjectVisit.VisitNum.ToString().Contains(".") : t => t.SubjectVisit.VisitNum == decimal.Parse(challengeQuery.VisitPlanInfo)) + .WhereIf(inQuery.IsOverTime != null && inQuery.IsOverTime == true, t => t.IsClosed ? t.ClosedTime > t.DeadlineTime : DateTime.Now > t.DeadlineTime) + .WhereIf(inQuery.IsOverTime != null && inQuery.IsOverTime == false, t => t.IsClosed ? t.ClosedTime < t.DeadlineTime : DateTime.Now < t.DeadlineTime) + .WhereIf(inQuery.IsUrgent != null, t => t.SubjectVisit.IsUrgent == inQuery.IsUrgent) + .WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.CRA, t => t.SubjectVisit.TrialSite.CRCUserList.Any(t => t.UserId == _userInfo.Id)) - list = list.OrderBy(t => t.TrialSiteCode).ThenBy(t => t.SubjectCode).ThenBy(t => t.ChallengeCode).ToList(); + .ProjectTo(_mapper.ConfigurationProvider); - var exportInfo = (await _trialRepository.Where(t => t.Id == challengeQuery.TrialId).IgnoreQueryFilters().ProjectTo(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException(); + var list = query.OrderBy(t => t.TrialSiteCode).ThenBy(t => t.SubjectCode).ThenBy(t => t.ChallengeCode).ToList(); + + var exportInfo = (await _trialRepository.Where(t => t.Id == inQuery.TrialId).IgnoreQueryFilters().ProjectTo(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException(); exportInfo.List = ExportExcelConverterDate.ConvertToClientTimeInObject(list, _userInfo.TimeZoneId); exportInfo.IsEn_US = _userInfo.IsEn_Us; @@ -300,32 +468,37 @@ namespace IRaCIS.Core.Application.Service.Common /// /// 受试者信息导出表 /// - /// + /// /// + /// /// /// /// [HttpPost] - public async Task GetSubjectList_Export(SubjectQueryParam param, + public async Task GetSubjectList_Export(SubjectQueryParam inQuery, [FromServices] IRepository _commonDocumentRepository, + [FromServices] IRepository _subjectRepository, [FromServices] IDictionaryService _dictionaryService, [FromServices] IRepository _trialRepository) { - var list = await _repository.Where(u => u.TrialId == param.TrialId) - .WhereIf(!string.IsNullOrWhiteSpace(param.Code), t => t.Code.Contains(param.Code)) - .WhereIf(!string.IsNullOrWhiteSpace(param.Name), t => t.ShortName.Contains(param.Name)) - .WhereIf(!string.IsNullOrWhiteSpace(param.Sex), t => t.Sex.Contains(param.Sex)) - .WhereIf(param.Status != null, t => t.Status == param.Status) - .WhereIf(param.TrialSiteId != null, t => t.TrialSiteId == param.TrialSiteId) + var subjectQuery = _subjectRepository.Where(u => u.TrialId == inQuery.TrialId) + .WhereIf(!string.IsNullOrWhiteSpace(inQuery.Code), t => t.Code.Contains(inQuery.Code)) + .WhereIf(!string.IsNullOrWhiteSpace(inQuery.Name), t => t.ShortName.Contains(inQuery.Name)) + .WhereIf(!string.IsNullOrWhiteSpace(inQuery.Sex), t => t.Sex.Contains(inQuery.Sex)) + .WhereIf(inQuery.Status != null, t => t.Status == inQuery.Status) + + .WhereIf(inQuery.TrialSiteId != null, t => t.TrialSiteId == inQuery.TrialSiteId) // CRC 只负责他管理site的受试者 .WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.CRA, t => t.TrialSite.CRCUserList.Any(t => t.UserId == _userInfo.Id)) - .ProjectTo(_mapper.ConfigurationProvider).ToListAsync(); + .ProjectTo(_mapper.ConfigurationProvider) + .WhereIf(inQuery.IsMissingImages != null, t => t.IsMissingImages == inQuery.IsMissingImages) + .ProjectTo(_mapper.ConfigurationProvider); - list = list.OrderBy(t => t.TrialSiteCode).ThenBy(t => t.Code).ToList(); + var list = subjectQuery.OrderBy(t => t.TrialSiteCode).ThenBy(t => t.Code).ToList(); - var exportInfo = (await _trialRepository.Where(t => t.Id == param.TrialId).IgnoreQueryFilters().ProjectTo(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException(); + var exportInfo = (await _trialRepository.Where(t => t.Id == inQuery.TrialId).IgnoreQueryFilters().ProjectTo(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException(); exportInfo.List = ExportExcelConverterDate.ConvertToClientTimeInObject(list, _userInfo.TimeZoneId); exportInfo.IsEn_US = _userInfo.IsEn_Us; @@ -337,39 +510,6 @@ namespace IRaCIS.Core.Application.Service.Common - ///// - ///// 受试者 阅片期 进度表 导出 - ///// - ///// - ///// - ///// - ///// - //[HttpPost] - //public async Task GetSubjectReadingPeriod_Export(GetReadModuleDto dto, - // [FromServices] IRepository _commonDocumentRepository, - // [FromServices] IDictionaryService _dictionaryService, - // [FromServices] IRepository _trialRepository) - //{ - - - // var list = await _repository.Where(u => u.TrialId == dto.TrialId) - // .WhereIf(dto.SubjectId != null, x => x.Id == dto.SubjectId) - // .WhereIf(dto.TrialSiteCode != null && dto.TrialSiteCode != string.Empty, x => x.TrialSite.TrialSiteCode == dto.TrialSiteCode) - // .WhereIf(dto.SubjectCode != null && dto.SubjectCode != string.Empty, x => x.Code == dto.SubjectCode) - // //.WhereIf(dto.ReadingStatus != null, x => x.ReadingStatus == dto.ReadingStatus) - - // .ProjectTo(_mapper.ConfigurationProvider).ToListAsync(); - - - // list = list.OrderBy(t => t.TrialSiteCode).ThenBy(t => t.Code).ToList(); - - // var exportInfo = (await _trialRepository.Where(t => t.Id == dto.TrialId).IgnoreQueryFilters().ProjectTo(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException(); - - // exportInfo.List = list; - - // return await ExcelExportHelper.DataExportAsync(StaticData.Export.TrialSubjectList_Export, exportInfo, $"{exportInfo.ResearchProgramNo}", _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(SubjectExportDTO)); - //} - /// @@ -517,26 +657,31 @@ namespace IRaCIS.Core.Application.Service.Common /// /// 影像上传监控表 /// - /// + /// /// /// /// /// [HttpPost] - public async Task GetStudyUploadMonitor_Export(StudyQuery studyQuery, + public async Task GetStudyUploadMonitor_Export(StudyQuery inQuery, [FromServices] IRepository _commonDocumentRepository, [FromServices] IDictionaryService _dictionaryService, [FromServices] IRepository _trialRepository) { - var svExpression = QCCommon.GetStudyMonitorSubjectVisitFilter(studyQuery.VisitPlanArray); - var StudyMonitorQuery = _repository.Where(t => t.TrialId == studyQuery.TrialId) + var svExpression = QCCommon.GetStudyMonitorSubjectVisitFilter(inQuery.VisitPlanArray); + var StudyMonitorQuery = _repository.Where(t => t.TrialId == inQuery.TrialId, ignoreQueryFilters: true) .WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.CRA, t => t.Subject.TrialSite.CRCUserList.Any(t => t.UserId == _userInfo.Id)) - .WhereIf(studyQuery.VisitPlanArray != null && studyQuery.VisitPlanArray?.Length > 0, svExpression) - .WhereIf(!string.IsNullOrWhiteSpace(studyQuery.SubjectInfo), t => t.Subject.Code.Contains(studyQuery.SubjectInfo)) - .WhereIf(studyQuery.SubjectId != null, t => t.SubjectId == studyQuery.SubjectId) - .WhereIf(studyQuery.SubjectVisitId != null, t => t.SubjectId == studyQuery.SubjectVisitId) - .WhereIf(studyQuery.TrialSiteId != null, t => t.Subject.TrialSiteId == studyQuery.TrialSiteId) + //.WhereIf(!string.IsNullOrEmpty(studyQuery.VisitPlanInfo), studyQuery.VisitPlanInfo.Contains('.') ? t => t.SubjectVisit.VisitNum.ToString().Contains(".") : t => t.SubjectVisit.VisitNum == decimal.Parse(studyQuery.VisitPlanInfo)) + .WhereIf(inQuery.VisitPlanArray != null && inQuery.VisitPlanArray?.Length > 0, svExpression) + .WhereIf(!string.IsNullOrWhiteSpace(inQuery.SubjectInfo), t => t.Subject.Code.Contains(inQuery.SubjectInfo)) + .WhereIf(inQuery.SubjectId != null, t => t.SubjectId == inQuery.SubjectId) + .WhereIf(inQuery.SubjectVisitId != null, t => t.SubjectId == inQuery.SubjectVisitId) + .WhereIf(inQuery.TrialSiteId != null, t => t.Subject.TrialSiteId == inQuery.TrialSiteId) + .WhereIf(inQuery.IsDicom != null, t => t.IsDicom == inQuery.IsDicom) + .WhereIf(!string.IsNullOrWhiteSpace(inQuery.Uploader), t => t.Uploader.UserName.Contains(inQuery.Uploader)) + .WhereIf(inQuery.IsSuccess != null, t => t.IsSuccess == inQuery.IsSuccess) + .WhereIf(!string.IsNullOrWhiteSpace(inQuery.StudyCode), t => t.StudyCode.Contains(inQuery.StudyCode)) .Select(t => new UnionStudyMonitorExportDto() { TrialSiteCode = t.Subject.TrialSite.TrialSiteCode, @@ -575,7 +720,7 @@ namespace IRaCIS.Core.Application.Service.Common var list = await StudyMonitorQuery.ToListAsync(); - var exportInfo = (await _trialRepository.Where(t => t.Id == studyQuery.TrialId).IgnoreQueryFilters().ProjectTo(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException(); + var exportInfo = (await _trialRepository.Where(t => t.Id == inQuery.TrialId).IgnoreQueryFilters().ProjectTo(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException(); exportInfo.List = ExportExcelConverterDate.ConvertToClientTimeInObject(list, _userInfo.TimeZoneId); exportInfo.IsEn_US = _userInfo.IsEn_Us; @@ -715,34 +860,35 @@ namespace IRaCIS.Core.Application.Service.Common /// /// 一致性核查记录表 /// - /// + /// /// /// /// /// /// [HttpPost] - public async Task GetConsistencyVerificationList_Export(CheckQuery checkQuery, + public async Task GetConsistencyVerificationList_Export(CheckQuery inQuery, [FromServices] IRepository _commonDocumentRepository, [FromServices] IDictionaryService _dictionaryService, [FromServices] IRepository _trialRepository, [FromServices] IRepository _subjectVisitRepository) { - var svExpression = QCCommon.GetSubjectVisitFilter(checkQuery.VisitPlanArray); + var svExpression = QCCommon.GetSubjectVisitFilter(inQuery.VisitPlanArray); - var list = await _subjectVisitRepository.Where(x => x.TrialId == checkQuery.TrialId) + var query = _subjectVisitRepository.Where(x => x.TrialId == inQuery.TrialId) .Where(x => x.AuditState == AuditStateEnum.QCPassed) //一致性核查中的,或者还没一致性核查的 - .WhereIf(checkQuery.CheckState != null, t => t.CheckState == checkQuery.CheckState) - .WhereIf(checkQuery.TrialSiteId != null, t => t.TrialSiteId == checkQuery.TrialSiteId) - .WhereIf(!string.IsNullOrEmpty(checkQuery.SubjectInfo), t => t.Subject.Code.Contains(checkQuery.SubjectInfo)) - .WhereIf(checkQuery.VisitPlanArray != null && checkQuery.VisitPlanArray?.Length > 0, svExpression) + .WhereIf(inQuery.CheckState != null, t => t.CheckState == inQuery.CheckState) + .WhereIf(inQuery.TrialSiteId != null, t => t.TrialSiteId == inQuery.TrialSiteId) + .WhereIf(!string.IsNullOrEmpty(inQuery.SubjectInfo), t => t.Subject.Code.Contains(inQuery.SubjectInfo)) + .WhereIf(inQuery.VisitPlanArray != null && inQuery.VisitPlanArray?.Length > 0, svExpression) + //.WhereIf(!string.IsNullOrEmpty(checkQuery.VisitPlanInfo), checkQuery.VisitPlanInfo.Contains('.') ? t => t.InPlan == false : t => t.VisitNum == decimal.Parse(checkQuery.VisitPlanInfo)) .WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.CRA, t => t.TrialSite.CRCUserList.Any(t => t.UserId == _userInfo.Id))//CRC 过滤负责的site - .ProjectTo(_mapper.ConfigurationProvider).ToListAsync(); + .ProjectTo(_mapper.ConfigurationProvider); - list = list.OrderBy(t => t.TrialSiteCode).ThenBy(t => t.SubjectCode).ThenBy(t => t.VisitNum).ToList(); + var list = query.OrderBy(t => t.TrialSiteCode).ThenBy(t => t.SubjectCode).ThenBy(t => t.VisitNum).ToList(); - var exportInfo = (await _trialRepository.Where(t => t.Id == checkQuery.TrialId).IgnoreQueryFilters().ProjectTo(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException(); + var exportInfo = (await _trialRepository.Where(t => t.Id == inQuery.TrialId).IgnoreQueryFilters().ProjectTo(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException(); exportInfo.List = ExportExcelConverterDate.ConvertToClientTimeInObject(list, _userInfo.TimeZoneId); exportInfo.IsEn_US = _userInfo.IsEn_Us; @@ -810,44 +956,58 @@ namespace IRaCIS.Core.Application.Service.Common /// /// PM 重阅追踪 /// - /// + /// /// + /// /// /// /// [HttpPost] - public async Task GetReReadingTaskList_Export(VisitTaskQuery queryVisitTask, + public async Task GetReReadingTaskList_Export(VisitTaskQuery inQuery, [FromServices] IRepository _commonDocumentRepository, + [FromServices] IRepository _visitTaskReReadingRepository, [FromServices] IDictionaryService _dictionaryService, [FromServices] IRepository _trialRepository) { - var list = await _repository.Where(t => t.OriginalReReadingTask.TrialId == queryVisitTask.TrialId /*&& t.OriginalReReadingTask.IsAnalysisCreate == false*/) - .WhereIf(queryVisitTask.RootReReadingTaskId != null, t => t.RootReReadingTaskId == queryVisitTask.RootReReadingTaskId || t.OriginalReReadingTaskId == queryVisitTask.RootReReadingTaskId) - .WhereIf(!string.IsNullOrEmpty(queryVisitTask.TaskCode), t => t.OriginalReReadingTask.TaskCode.Contains(queryVisitTask.TaskCode!) || t.RootReReadingTask.TaskCode.Contains(queryVisitTask.TaskCode!)) - .WhereIf(queryVisitTask.TrialSiteId != null, t => t.OriginalReReadingTask.Subject.TrialSiteId == queryVisitTask.TrialSiteId) - .WhereIf(queryVisitTask.TaskState != null, t => t.OriginalReReadingTask.TaskState == queryVisitTask.TaskState) - .WhereIf(queryVisitTask.ReReadingApplyState != null, t => t.OriginalReReadingTask.ReReadingApplyState == queryVisitTask.ReReadingApplyState) - .WhereIf(queryVisitTask.SubjectId != null, t => t.OriginalReReadingTask.SubjectId == queryVisitTask.SubjectId) - .WhereIf(queryVisitTask.IsUrgent != null, t => t.OriginalReReadingTask.IsUrgent == queryVisitTask.IsUrgent) - .WhereIf(queryVisitTask.DoctorUserId != null, t => t.OriginalReReadingTask.DoctorUserId == queryVisitTask.DoctorUserId) - .WhereIf(queryVisitTask.ReadingTaskState != null, t => t.OriginalReReadingTask.ReadingTaskState == queryVisitTask.ReadingTaskState) - .WhereIf(queryVisitTask.TaskAllocationState != null, t => t.OriginalReReadingTask.TaskAllocationState == queryVisitTask.TaskAllocationState) - .WhereIf(queryVisitTask.TrialReadingCriterionId != null, t => t.OriginalReReadingTask.TrialReadingCriterionId == queryVisitTask.TrialReadingCriterionId) + var visitTaskQueryable = _visitTaskReReadingRepository + .Where(t => t.OriginalReReadingTask.TrialId == inQuery.TrialId /*&& t.OriginalReReadingTask.IsAnalysisCreate == false*/) + .WhereIf(inQuery.RootReReadingTaskId != null, t => t.RootReReadingTaskId == inQuery.RootReReadingTaskId || t.OriginalReReadingTaskId == inQuery.RootReReadingTaskId) + .WhereIf(!string.IsNullOrEmpty(inQuery.TaskCode), t => t.OriginalReReadingTask.TaskCode.Contains(inQuery.TaskCode!) || t.RootReReadingTask.TaskCode.Contains(inQuery.TaskCode!)) + .WhereIf(inQuery.TrialSiteId != null, t => t.OriginalReReadingTask.Subject.TrialSiteId == inQuery.TrialSiteId) + .WhereIf(inQuery.TaskState != null, t => t.OriginalReReadingTask.TaskState == inQuery.TaskState) + .WhereIf(inQuery.ReReadingApplyState != null, t => t.OriginalReReadingTask.ReReadingApplyState == inQuery.ReReadingApplyState) + .WhereIf(inQuery.RequestReReadingType != null, t => t.RequestReReadingType == inQuery.RequestReReadingType) + .WhereIf(inQuery.SubjectId != null, t => t.OriginalReReadingTask.SubjectId == inQuery.SubjectId) + .WhereIf(inQuery.IsUrgent != null, t => t.OriginalReReadingTask.IsUrgent == inQuery.IsUrgent) + .WhereIf(inQuery.DoctorUserId != null, t => t.OriginalReReadingTask.DoctorUserId == inQuery.DoctorUserId) + .WhereIf(inQuery.ArmEnum != null, t => t.OriginalReReadingTask.ArmEnum == inQuery.ArmEnum) + .WhereIf(inQuery.ReadingTaskState != null, t => t.OriginalReReadingTask.ReadingTaskState == inQuery.ReadingTaskState) + .WhereIf(inQuery.TaskAllocationState != null, t => t.OriginalReReadingTask.TaskAllocationState == inQuery.TaskAllocationState) + .WhereIf(inQuery.TrialReadingCriterionId != null, t => t.OriginalReReadingTask.TrialReadingCriterionId == inQuery.TrialReadingCriterionId) + .WhereIf(inQuery.ReadingCategory != null, t => t.OriginalReReadingTask.ReadingCategory == inQuery.ReadingCategory) - .WhereIf(!string.IsNullOrEmpty(queryVisitTask.TrialSiteCode), t => (t.OriginalReReadingTask.BlindTrialSiteCode.Contains(queryVisitTask.TrialSiteCode!) && t.OriginalReReadingTask.IsAnalysisCreate) || (t.OriginalReReadingTask.Subject.TrialSite.TrialSiteCode.Contains(queryVisitTask.TrialSiteCode!) && t.OriginalReReadingTask.IsAnalysisCreate == false)) - .WhereIf(!string.IsNullOrEmpty(queryVisitTask.TaskName), t => t.OriginalReReadingTask.TaskName.Contains(queryVisitTask.TaskName) || t.OriginalReReadingTask.TaskBlindName.Contains(queryVisitTask.TaskName)) - .WhereIf(!string.IsNullOrEmpty(queryVisitTask.SubjectCode), t => t.OriginalReReadingTask.Subject.Code.Contains(queryVisitTask.SubjectCode) || t.OriginalReReadingTask.BlindSubjectCode.Contains(queryVisitTask.SubjectCode)) - .WhereIf(queryVisitTask.BeginAllocateDate != null, t => t.OriginalReReadingTask.AllocateTime > queryVisitTask.BeginAllocateDate) - .WhereIf(queryVisitTask.EndAllocateDate != null, t => t.OriginalReReadingTask.AllocateTime < queryVisitTask.EndAllocateDate!.Value.AddDays(1)) - .ProjectTo(_mapper.ConfigurationProvider).ToListAsync(); + .WhereIf(!string.IsNullOrEmpty(inQuery.RequestReReadingReason), t => t.RequestReReadingReason.Contains(inQuery.RequestReReadingReason)) + + .WhereIf(inQuery.RequestReReadingResultEnum != null, t => t.RequestReReadingResultEnum == inQuery.RequestReReadingResultEnum) + + + .WhereIf(!string.IsNullOrEmpty(inQuery.TrialSiteCode), t => (t.OriginalReReadingTask.BlindTrialSiteCode.Contains(inQuery.TrialSiteCode!) && t.OriginalReReadingTask.IsAnalysisCreate) || (t.OriginalReReadingTask.Subject.TrialSite.TrialSiteCode.Contains(inQuery.TrialSiteCode!) && t.OriginalReReadingTask.IsAnalysisCreate == false)) + .WhereIf(!string.IsNullOrEmpty(inQuery.TaskName), t => t.OriginalReReadingTask.TaskName.Contains(inQuery.TaskName) || t.OriginalReReadingTask.TaskBlindName.Contains(inQuery.TaskName)) + .WhereIf(!string.IsNullOrEmpty(inQuery.SubjectCode), t => ((t.OriginalReReadingTask.Subject.Code.Contains(inQuery.SubjectCode) || t.OriginalReReadingTask.Subject.MedicalNo.Contains(inQuery.SubjectCode)) && t.OriginalReReadingTask.IsAnalysisCreate == false) || (t.OriginalReReadingTask.BlindSubjectCode.Contains(inQuery.SubjectCode) && t.OriginalReReadingTask.IsAnalysisCreate)) + .WhereIf(inQuery.BeginAllocateDate != null, t => t.OriginalReReadingTask.AllocateTime > inQuery.BeginAllocateDate) + .WhereIf(inQuery.EndAllocateDate != null, t => t.OriginalReReadingTask.AllocateTime < inQuery.EndAllocateDate!.Value.AddDays(1)) + + .WhereIf(inQuery.BeginRequestReReadingTime != null, t => t.RequestReReadingTime >= inQuery.BeginRequestReReadingTime) + .WhereIf(inQuery.EndRequestReReadingTime != null, t => t.RequestReReadingTime <= inQuery.EndRequestReReadingTime!.Value.AddDays(1)) + .ProjectTo(_mapper.ConfigurationProvider); //var defalutSortArray = new string[] { nameof(ReReadingTaskView.OriginalReReadingTask) + "." + nameof(ReReadingTaskView.OriginalReReadingTask.IsUrgent) + " desc", nameof(ReReadingTaskView.OriginalReReadingTask) + "." + nameof(ReReadingTaskView.OriginalReReadingTask.SubjectId), nameof(ReReadingTaskView.OriginalReReadingTask) + "." + nameof(ReReadingTaskView.OriginalReReadingTask.VisitTaskNum) }; - list = list.OrderBy(t => t.TrialSiteCode).ThenBy(t => t.SubjectCode).ThenBy(t => t.VisitTaskNum).ToList(); + var list = visitTaskQueryable.OrderBy(t => t.TrialSiteCode).ThenBy(t => t.SubjectCode).ThenBy(t => t.VisitTaskNum).ToList(); - var exportInfo = (await _trialRepository.Where(t => t.Id == queryVisitTask.TrialId).IgnoreQueryFilters().ProjectTo(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException(); + var exportInfo = (await _trialRepository.Where(t => t.Id == inQuery.TrialId).IgnoreQueryFilters().ProjectTo(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException(); exportInfo.List = ExportExcelConverterDate.ConvertToClientTimeInObject(list, _userInfo.TimeZoneId); exportInfo.IsEn_US = _userInfo.IsEn_Us; @@ -863,31 +1023,48 @@ namespace IRaCIS.Core.Application.Service.Common /// /// /// + /// /// /// /// [HttpPost] public async Task GetMedicalReviewTaskList_Export(TaskMedicalReviewQuery inQuery, [FromServices] IRepository _commonDocumentRepository, + [FromServices] IRepository _taskMedicalReviewRepository, [FromServices] IDictionaryService _dictionaryService, [FromServices] IRepository _trialRepository) { - var list = await _repository.Where(t => t.VisitTask.TrialId == inQuery.TrialId && t.MedicalManagerUserId!=null) + var taskMedicalReviewQueryable = _taskMedicalReviewRepository.Where(t => t.VisitTask.TrialId == inQuery.TrialId) + .WhereIf(inQuery.TrialSiteId != null, t => t.VisitTask.Subject.TrialSiteId == inQuery.TrialSiteId) .WhereIf(inQuery.SubjectId != null, t => t.VisitTask.SubjectId == inQuery.SubjectId) - .WhereIf(!string.IsNullOrEmpty(inQuery.SubjectCode), t => t.VisitTask.Subject.Code.Contains(inQuery.SubjectCode)) + .WhereIf(!string.IsNullOrEmpty(inQuery.SubjectCode), t => t.VisitTask.Subject.Code.Contains(inQuery.SubjectCode) || t.VisitTask.Subject.MedicalNo.Contains(inQuery.SubjectCode)) .WhereIf(!string.IsNullOrEmpty(inQuery.TaskName), t => t.VisitTask.TaskName.Contains(inQuery.TaskName) || t.VisitTask.TaskBlindName.Contains(inQuery.TaskName)) .WhereIf(inQuery.IsUrgent != null, t => t.VisitTask.IsUrgent == inQuery.IsUrgent) .WhereIf(inQuery.DoctorUserId != null, t => t.VisitTask.DoctorUserId == inQuery.DoctorUserId) .WhereIf(!string.IsNullOrEmpty(inQuery.TrialSiteCode), t => (t.VisitTask.BlindTrialSiteCode.Contains(inQuery.TrialSiteCode) && t.VisitTask.IsAnalysisCreate) || (t.VisitTask.Subject.TrialSite.TrialSiteCode.Contains(inQuery.TrialSiteCode) && t.VisitTask.IsAnalysisCreate == false)) .WhereIf(inQuery.ReadingCategory != null, t => t.VisitTask.ReadingCategory == inQuery.ReadingCategory) - .WhereIf(inQuery.ReadingTaskState != null, t => t.VisitTask.ReadingTaskState == inQuery.ReadingTaskState) + .WhereIf(inQuery.TaskState != null, t => t.VisitTask.TaskState == inQuery.TaskState) + .WhereIf(inQuery.ArmEnum != null, t => t.VisitTask.ArmEnum == inQuery.ArmEnum) + .WhereIf(inQuery.AuditState != null, t => t.AuditState == inQuery.AuditState) + .WhereIf(inQuery.MedicalManagerUserId != null, t => t.MedicalManagerUserId == inQuery.MedicalManagerUserId) + .WhereIf(inQuery.BeginSignTime != null, t => t.VisitTask.SignTime > inQuery.BeginSignTime) + .WhereIf(inQuery.EndSignTime != null, t => t.VisitTask.SignTime < inQuery.EndSignTime) + .WhereIf(inQuery.AuditAdviceEnum != null, t => t.AuditAdviceEnum == inQuery.AuditAdviceEnum) - .WhereIf(inQuery.TrialReadingCriterionId != null, t => t.VisitTask.TrialReadingCriterionId == inQuery.TrialReadingCriterionId) - .ProjectTo(_mapper.ConfigurationProvider).ToListAsync(); + .WhereIf(inQuery.DoctorUserIdeaEnum != null, t => t.DoctorUserIdeaEnum == inQuery.DoctorUserIdeaEnum) + .WhereIf(inQuery.TrialReadingCriterionId != null, t => t.VisitTask.TrialReadingCriterionId == inQuery.TrialReadingCriterionId) + .WhereIf(inQuery.IsInvalid != null, t => t.IsInvalid == inQuery.IsInvalid) + .WhereIf(inQuery.IsHaveQuestion != null, t => t.IsHaveQuestion == inQuery.IsHaveQuestion) - list = list.OrderBy(t => t.TrialSiteCode).ThenBy(t => t.SubjectCode).ThenBy(t => t.VisitTaskNum).ToList(); + .WhereIf(inQuery.BeginAllocateDate != null, t => t.AllocateTime >= inQuery.BeginAllocateDate) + .WhereIf(inQuery.EndAllocateDate != null, t => t.AllocateTime <= inQuery.EndAllocateDate) + .WhereIf(inQuery.BeginAuditSignTime != null, t => t.AuditSignTime >= inQuery.BeginAuditSignTime) + .WhereIf(inQuery.EndAuditSignTime != null, t => t.AuditSignTime <= inQuery.EndAuditSignTime) + .ProjectTo(_mapper.ConfigurationProvider); + + var list = taskMedicalReviewQueryable.OrderBy(t => t.TrialSiteCode).ThenBy(t => t.SubjectCode).ThenBy(t => t.VisitTaskNum).ToList(); var exportInfo = (await _trialRepository.Where(t => t.Id == inQuery.TrialId).IgnoreQueryFilters().ProjectTo(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException(); @@ -1326,7 +1503,7 @@ namespace IRaCIS.Core.Application.Service.Common //处理裁判标记 list = DealJudgeMark(criterion.ArbitrationRule, list); - exportInfo.List = ExportExcelConverterDate.ConvertToClientTimeInObject(list.Where(t=>t.ReadingCategory!=ReadingCategory.Global).ToList(), _userInfo.TimeZoneId); + exportInfo.List = ExportExcelConverterDate.ConvertToClientTimeInObject(list.Where(t => t.ReadingCategory != ReadingCategory.Global).ToList(), _userInfo.TimeZoneId); exportInfo.IsEn_US = _userInfo.IsEn_Us; exportInfo.ClientZoneId = _userInfo.TimeZoneId; diff --git a/IRaCIS.Core.Application/Service/Document/TrialDocumentService.cs b/IRaCIS.Core.Application/Service/Document/TrialDocumentService.cs index ca19ab0b9..1c32b6040 100644 --- a/IRaCIS.Core.Application/Service/Document/TrialDocumentService.cs +++ b/IRaCIS.Core.Application/Service/Document/TrialDocumentService.cs @@ -369,10 +369,10 @@ namespace IRaCIS.Core.Application.Services /// /// 获取确认列表情况 项目文档+系统文档+具体的人 /// - /// + /// /// [HttpPost] - public async Task<(PageOutput, object)> GetDocumentConfirmList(DocumentTrialUnionQuery querySystemDocument) + public async Task<(PageOutput, object)> GetDocumentConfirmList(DocumentTrialUnionQuery inQuery) { @@ -409,15 +409,15 @@ namespace IRaCIS.Core.Application.Services #endregion - var trialInfo = (await _repository.Where(t => t.Id == querySystemDocument.TrialId).Select(t => new { t.TrialFinishedTime, t.TrialStatusStr }).FirstNotNullAsync()); + var trialInfo = (await _repository.Where(t => t.Id == inQuery.TrialId).Select(t => new { t.TrialFinishedTime, t.TrialStatusStr }).FirstNotNullAsync()); - var trialDocQuery = from trialDocumentNeedConfirmedUserType in _repository.Where(t => t.TrialDocument.TrialId == querySystemDocument.TrialId) - join trialUser in _repository.Where(t => t.TrialId == querySystemDocument.TrialId) - .WhereIf(querySystemDocument.UserId != null, t => t.UserId == querySystemDocument.UserId) - .WhereIf(querySystemDocument.UserTypeId != null, t => t.User.UserTypeId == querySystemDocument.UserTypeId) + var trialDocQuery = from trialDocumentNeedConfirmedUserType in _repository.Where(t => t.TrialDocument.TrialId == inQuery.TrialId) + join trialUser in _repository.Where(t => t.TrialId == inQuery.TrialId) + .WhereIf(inQuery.UserId != null, t => t.UserId == inQuery.UserId) + .WhereIf(inQuery.UserTypeId != null, t => t.User.UserTypeId == inQuery.UserTypeId) on trialDocumentNeedConfirmedUserType.NeedConfirmUserTypeId equals trialUser.User.UserTypeId - join confirm in _repository.Where(t => t.TrialDocument.TrialId == querySystemDocument.TrialId) on + join confirm in _repository.Where(t => t.TrialDocument.TrialId == inQuery.TrialId) on new { trialUser.UserId, TrialDocumentId = trialDocumentNeedConfirmedUserType.TrialDocumentId } equals new { UserId = confirm.ConfirmUserId, confirm.TrialDocumentId } into cc from confirm in cc.DefaultIfEmpty() select new UnionDocumentWithConfirmInfoView() @@ -451,8 +451,8 @@ namespace IRaCIS.Core.Application.Services var systemDocQuery = from needConfirmEdUserType in _repository.WhereIf(trialInfo.TrialFinishedTime != null, u => u.SystemDocument.CreateTime < trialInfo.TrialFinishedTime) - join trialUser in _repository.Where(t => t.TrialId == querySystemDocument.TrialId) - .WhereIf(querySystemDocument.UserId != null, t => t.UserId == querySystemDocument.UserId) + join trialUser in _repository.Where(t => t.TrialId == inQuery.TrialId) + .WhereIf(inQuery.UserId != null, t => t.UserId == inQuery.UserId) on needConfirmEdUserType.NeedConfirmUserTypeId equals trialUser.User.UserTypeId join confirm in _repository.GetQueryable() on new { ConfirmUserId = trialUser.UserId, SystemDocumentId = needConfirmEdUserType.SystemDocumentId } equals new { confirm.ConfirmUserId, confirm.SystemDocumentId } into cc from confirm in cc.DefaultIfEmpty() @@ -482,14 +482,14 @@ namespace IRaCIS.Core.Application.Services }; var unionQuery = trialDocQuery.Union(systemDocQuery) - .WhereIf(!string.IsNullOrEmpty(querySystemDocument.Name), t => t.Name.Contains(querySystemDocument.Name)) - .WhereIf(querySystemDocument.FileTypeId != null, t => t.FileTypeId == querySystemDocument.FileTypeId) - .WhereIf(querySystemDocument.IsConfirmed == true, t => t.ConfirmTime != null) - .WhereIf(querySystemDocument.IsConfirmed == false, t => t.ConfirmTime == null) - .WhereIf(querySystemDocument.IsDeleted != null, t => t.IsDeleted == querySystemDocument.IsDeleted) - .WhereIf(querySystemDocument.UserTypeId != null, t => t.UserTypeId == querySystemDocument.UserTypeId); + .WhereIf(!string.IsNullOrEmpty(inQuery.Name), t => t.Name.Contains(inQuery.Name)) + .WhereIf(inQuery.FileTypeId != null, t => t.FileTypeId == inQuery.FileTypeId) + .WhereIf(inQuery.IsConfirmed == true, t => t.ConfirmTime != null) + .WhereIf(inQuery.IsConfirmed == false, t => t.ConfirmTime == null) + .WhereIf(inQuery.IsDeleted != null, t => t.IsDeleted == inQuery.IsDeleted) + .WhereIf(inQuery.UserTypeId != null, t => t.UserTypeId == inQuery.UserTypeId); - var result = await unionQuery.ToPagedListAsync(querySystemDocument.PageIndex, querySystemDocument.PageSize, querySystemDocument.SortField, querySystemDocument.Asc); + var result = await unionQuery.ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, inQuery.SortField, inQuery.Asc); var needSignTrialDocCount = await _trialDocumentRepository.AsQueryable(true) .Where(t => t.Trial.TrialUserList.Any(t => t.UserId == _userInfo.Id)) diff --git a/IRaCIS.Core.Application/Service/ImageAndDoc/StudyService.cs b/IRaCIS.Core.Application/Service/ImageAndDoc/StudyService.cs index dbed0f7c8..cdd161e9b 100644 --- a/IRaCIS.Core.Application/Service/ImageAndDoc/StudyService.cs +++ b/IRaCIS.Core.Application/Service/ImageAndDoc/StudyService.cs @@ -483,21 +483,21 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc [HttpPost] - public async Task> GetDicomAndNoneDicomStudyMonitorList(StudyQuery studyQuery) + public async Task> GetDicomAndNoneDicomStudyMonitorList(StudyQuery inQuery) { - var svExpression = QCCommon.GetStudyMonitorSubjectVisitFilter(studyQuery.VisitPlanArray); - var StudyMonitorQuery = _repository.Where(t => t.TrialId == studyQuery.TrialId, ignoreQueryFilters: true) + var svExpression = QCCommon.GetStudyMonitorSubjectVisitFilter(inQuery.VisitPlanArray); + var StudyMonitorQuery = _repository.Where(t => t.TrialId == inQuery.TrialId, ignoreQueryFilters: true) .WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.CRA, t => t.Subject.TrialSite.CRCUserList.Any(t => t.UserId == _userInfo.Id)) //.WhereIf(!string.IsNullOrEmpty(studyQuery.VisitPlanInfo), studyQuery.VisitPlanInfo.Contains('.') ? t => t.SubjectVisit.VisitNum.ToString().Contains(".") : t => t.SubjectVisit.VisitNum == decimal.Parse(studyQuery.VisitPlanInfo)) - .WhereIf(studyQuery.VisitPlanArray != null && studyQuery.VisitPlanArray?.Length > 0, svExpression) - .WhereIf(!string.IsNullOrWhiteSpace(studyQuery.SubjectInfo), t => t.Subject.Code.Contains(studyQuery.SubjectInfo)) - .WhereIf(studyQuery.SubjectId != null, t => t.SubjectId == studyQuery.SubjectId) - .WhereIf(studyQuery.SubjectVisitId != null, t => t.SubjectId == studyQuery.SubjectVisitId) - .WhereIf(studyQuery.TrialSiteId != null, t => t.Subject.TrialSiteId == studyQuery.TrialSiteId) - .WhereIf(studyQuery.IsDicom != null, t => t.IsDicom == studyQuery.IsDicom) - .WhereIf(!string.IsNullOrWhiteSpace(studyQuery.Uploader), t => t.Uploader.UserName.Contains(studyQuery.Uploader)) - .WhereIf(studyQuery.IsSuccess != null, t => t.IsSuccess == studyQuery.IsSuccess) - .WhereIf(!string.IsNullOrWhiteSpace(studyQuery.StudyCode), t => t.StudyCode.Contains(studyQuery.StudyCode)) + .WhereIf(inQuery.VisitPlanArray != null && inQuery.VisitPlanArray?.Length > 0, svExpression) + .WhereIf(!string.IsNullOrWhiteSpace(inQuery.SubjectInfo), t => t.Subject.Code.Contains(inQuery.SubjectInfo)) + .WhereIf(inQuery.SubjectId != null, t => t.SubjectId == inQuery.SubjectId) + .WhereIf(inQuery.SubjectVisitId != null, t => t.SubjectId == inQuery.SubjectVisitId) + .WhereIf(inQuery.TrialSiteId != null, t => t.Subject.TrialSiteId == inQuery.TrialSiteId) + .WhereIf(inQuery.IsDicom != null, t => t.IsDicom == inQuery.IsDicom) + .WhereIf(!string.IsNullOrWhiteSpace(inQuery.Uploader), t => t.Uploader.UserName.Contains(inQuery.Uploader)) + .WhereIf(inQuery.IsSuccess != null, t => t.IsSuccess == inQuery.IsSuccess) + .WhereIf(!string.IsNullOrWhiteSpace(inQuery.StudyCode), t => t.StudyCode.Contains(inQuery.StudyCode)) .Select(t => new UnionStudyMonitorModel() { TrialId = t.TrialId, @@ -541,7 +541,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc }); - return await StudyMonitorQuery.ToPagedListAsync(studyQuery.PageIndex, studyQuery.PageSize, string.IsNullOrEmpty(studyQuery.SortField) ? "UploadTime" : studyQuery.SortField, studyQuery.Asc); + return await StudyMonitorQuery.ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, string.IsNullOrEmpty(inQuery.SortField) ? "UploadTime" : inQuery.SortField, inQuery.Asc); diff --git a/IRaCIS.Core.Application/Service/QC/DTO/QCListViewModel.cs b/IRaCIS.Core.Application/Service/QC/DTO/QCListViewModel.cs index 3a4ba042c..7d9c33e72 100644 --- a/IRaCIS.Core.Application/Service/QC/DTO/QCListViewModel.cs +++ b/IRaCIS.Core.Application/Service/QC/DTO/QCListViewModel.cs @@ -7,6 +7,7 @@ using Newtonsoft.Json; using System.ComponentModel; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; +using System.Web; namespace IRaCIS.Core.Application.Contracts { @@ -161,9 +162,61 @@ namespace IRaCIS.Core.Application.Contracts #region 导出模型 + + public class TrainingRecordExportDTO + { + public Guid Id { get; set; } + + public Guid FileTypeId { get; set; } + + public Guid UserTypeId { get; set; } + + public string FileType { get; set; } + + public string Name { get; set; } + + [DictionaryTranslateAttribute("IsSystemDoc")] + public bool IsSystemDoc { get; set; } + + [DictionaryTranslateAttribute("YesOrNo")] + public bool IsDeleted { get; set; } + + //上传时间 + public DateTime CreateTime { get; set; } + + [DictionaryTranslateAttribute("YesOrNo")] + public bool IsConfirmed { get; set; } + + public string RealName { get; set; } + + public string UserName { get; set; } + + public string UserTypeShortName { get; set; } + + + public DateTime? ConfirmTime { get; set; } + } + public class CRCVisitExportDTO { - public ChallengeStateEnum ChallengeState { get; set; } + //关闭 未关闭 + [DictionaryTranslateAttribute("CheckIsClosedEnum")] + public ChallengeStateEnum CheckIsClosedEnum { get; set; } + + //强行要分为两个字段 有无质疑 + [DictionaryTranslateAttribute("YesOrNo")] + public bool IsChallengeClosed => (int)CheckIsClosedEnum > 0; + + //临床数据收集 + + public string ClinicalDataCollect => $"{DicomStudyCount},{NoneDicomStudyCount}{(IsBaseLine? (ClinicalInformationTransmissionEnum>0 &&IsHaveClinicalData ? "w/" : "w/o") :"" )}"; + + public int? DicomStudyCount { get; set; } + public int? NoneDicomStudyCount { get; set; } + + public int ClinicalInformationTransmissionEnum { get; set; } + + public bool IsBaseLine { get; set; } [DictionaryTranslateAttribute("YesOrNo")] public bool IsUrgent { get; set; } @@ -197,12 +250,31 @@ namespace IRaCIS.Core.Application.Contracts public DateTime? ReviewAuditTime { get; set; } public DateTime? PreliminaryAuditTime { get; set; } + //审核通过时间 public DateTime? AuditTime => QCProcessEnum == TrialQCProcess.SingleAudit ? PreliminaryAuditTime : (QCProcessEnum == TrialQCProcess.DoubleAudit ? ReviewAuditTime : null); } + public class QCVisitExportDTO: CRCVisitExportDTO + { + //上传人 + public string SubmitUserRealName { get; set; } + + public string PreliminaryAuditUserName { get; set; } + + public string ReviewAuditUserName { get; set; } + + public string CurrentActionUserName { get; set; } + + + } + public class QCChanllengeExportDto { + //审核批次 + [DictionaryTranslateAttribute("CurrentQCType")] + public CurrentQC? CurrentQCEnum { get; set; } + [DictionaryTranslateAttribute("Subject_Visit_Status")] public SubjectStatus SubjectState { get; set; } @@ -654,7 +726,6 @@ namespace IRaCIS.Core.Application.Contracts public class ReadingTaskExportDto { - //public TaskAllocationState TaskAllocationState { get; set; } [DictionaryTranslateAttribute("Subject_Visit_Status")] public SubjectStatus SubjectStatus { get; set; } @@ -662,13 +733,14 @@ namespace IRaCIS.Core.Application.Contracts public DateTime? AllocateTime { get; set; } - //public bool IsPMSetBack { get; set; } public string TaskCode { get; set; } public string TaskName { get; set; } public string TaskBlindName { get; set; } + public string FinalTaskName => TaskName != TaskBlindName ? $"{TaskName}/{TaskBlindName}" : TaskName; + public decimal VisitTaskNum { get; set; } [DictionaryTranslateAttribute("ReadingCategory")] @@ -690,6 +762,8 @@ namespace IRaCIS.Core.Application.Contracts public String TrialSiteCode { get; set; } = String.Empty; public string SubjectCode { get; set; } = String.Empty; + public string MedicalNo { get; set; } + public string FinalSubjectCode { get; set; } public string TrialReadingCriterionName { get; set; } @@ -711,8 +785,7 @@ namespace IRaCIS.Core.Application.Contracts { - //public ReadingTaskExportDto ApplyTask { get; set; } - + public string? ReReadingNewTaskCode { get; set; } @@ -742,8 +815,7 @@ namespace IRaCIS.Core.Application.Contracts public class TaskMedicalReviewExportDto : ReadingTaskExportDto { - public string MedicalNo { get; set; } = string.Empty; - + public string QuestionContent { get; set; } [DictionaryTranslateAttribute("MedicalReviewAuditState")] public MedicalReviewAuditState AuditState { get; set; } @@ -755,7 +827,8 @@ namespace IRaCIS.Core.Application.Contracts [DictionaryTranslateAttribute("AuditAdvice")] public AuditAdvice AuditAdviceEnum { get; set; } - [DictionaryTranslateAttribute("YesOrNo")] + //审核结论 + [DictionaryTranslateAttribute("IsPass")] public bool IsHaveQuestion { get; set; } @@ -764,7 +837,9 @@ namespace IRaCIS.Core.Application.Contracts //public UserSimpleInfo MedicalManagerUser { get; set; } - //public string DoctorUserName { get; set; } + public string DoctorUserName { get; set; } + + public string MedicalManagerUserName { get; set; } /// diff --git a/IRaCIS.Core.Application/Service/QC/QCListService.cs b/IRaCIS.Core.Application/Service/QC/QCListService.cs index bd065b33e..657675744 100644 --- a/IRaCIS.Core.Application/Service/QC/QCListService.cs +++ b/IRaCIS.Core.Application/Service/QC/QCListService.cs @@ -54,35 +54,35 @@ namespace IRaCIS.Core.Application.Image.QA /// /// CRC 访视上传列表 /// - /// + /// /// [HttpPost] - public async Task>> GetCRCVisitList(CRCVisitSearchDTO visitSearchDTO) + public async Task>> GetCRCVisitList(CRCVisitSearchDTO inQuery) { - var svExpression = QCCommon.GetSubjectVisitFilter(visitSearchDTO.VisitPlanArray); + var svExpression = QCCommon.GetSubjectVisitFilter(inQuery.VisitPlanArray); - var query = _subjectVisitRepository.Where(x => x.TrialId == visitSearchDTO.TrialId) + var query = _subjectVisitRepository.Where(x => x.TrialId == inQuery.TrialId) .Where(t => t.Subject.FinalSubjectVisitId != null ? t.VisitNum <= t.Subject.FinalSubjectVisit.VisitNum : true) - .WhereIf(visitSearchDTO.TrialSiteId != null, t => t.TrialSiteId == visitSearchDTO.TrialSiteId) - .WhereIf(visitSearchDTO.SubjectId != null, t => t.Subject.Id == visitSearchDTO.SubjectId) - .WhereIf(!string.IsNullOrEmpty(visitSearchDTO.SubjectInfo), t => t.Subject.Code.Contains(visitSearchDTO.SubjectInfo)) + .WhereIf(inQuery.TrialSiteId != null, t => t.TrialSiteId == inQuery.TrialSiteId) + .WhereIf(inQuery.SubjectId != null, t => t.Subject.Id == inQuery.SubjectId) + .WhereIf(!string.IsNullOrEmpty(inQuery.SubjectInfo), t => t.Subject.Code.Contains(inQuery.SubjectInfo)) - .WhereIf(visitSearchDTO.VisitPlanArray != null && visitSearchDTO.VisitPlanArray?.Length > 0, svExpression) + .WhereIf(inQuery.VisitPlanArray != null && inQuery.VisitPlanArray?.Length > 0, svExpression) //.WhereIf(!string.IsNullOrEmpty(visitSearchDTO.VisitPlanInfo), visitSearchDTO.VisitPlanInfo.Contains('.') ? t => t.InPlan == false : t => t.VisitNum == decimal.Parse(visitSearchDTO.VisitPlanInfo)) - .WhereIf(visitSearchDTO.AuditStateArray != null && visitSearchDTO.AuditStateArray?.Length > 0, t => visitSearchDTO.AuditStateArray!.Contains(t.AuditState)) - .WhereIf(visitSearchDTO.SubmitState != null, t => t.SubmitState == visitSearchDTO.SubmitState) - .WhereIf(visitSearchDTO.ChallengeState != null, t => t.ChallengeState == visitSearchDTO.ChallengeState) - .WhereIf(visitSearchDTO.IsUrgent != null, t => t.IsUrgent == visitSearchDTO.IsUrgent) + .WhereIf(inQuery.AuditStateArray != null && inQuery.AuditStateArray?.Length > 0, t => inQuery.AuditStateArray!.Contains(t.AuditState)) + .WhereIf(inQuery.SubmitState != null, t => t.SubmitState == inQuery.SubmitState) + .WhereIf(inQuery.ChallengeState != null, t => t.ChallengeState == inQuery.ChallengeState) + .WhereIf(inQuery.IsUrgent != null, t => t.IsUrgent == inQuery.IsUrgent) .WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.CRA, t => t.TrialSite.CRCUserList.Any(t => t.UserId == _userInfo.Id)) .ProjectTo(_mapper.ConfigurationProvider); var defalutSortArray = new string[] { nameof(SubjectVisit.IsUrgent) + " desc", nameof(SubjectVisit.SubjectId), nameof(SubjectVisit.VisitNum) }; - var pageList = await query.ToPagedListAsync(visitSearchDTO.PageIndex, visitSearchDTO.PageSize, visitSearchDTO.SortField, visitSearchDTO.Asc, string.IsNullOrWhiteSpace(visitSearchDTO.SortField), defalutSortArray); + var pageList = await query.ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, inQuery.SortField, inQuery.Asc, string.IsNullOrWhiteSpace(inQuery.SortField), defalutSortArray); - var config = await _repository.Where(t => t.Id == visitSearchDTO.TrialId).ProjectTo(_mapper.ConfigurationProvider).FirstOrDefaultAsync().IfNullThrowException(); - config.IsHaveSubjectClinicalData = await _clinicalDataTrialSet.AnyAsync(x => x.TrialId == visitSearchDTO.TrialId && x.IsConfirm && (x.ClinicalDataLevel == ClinicalLevel.Subject ) && x.UploadRole == UploadRole.CRC); - config.IsHaveVisitClinicalData = await _clinicalDataTrialSet.AnyAsync(x => x.TrialId == visitSearchDTO.TrialId && x.IsConfirm && (x.ClinicalDataLevel == ClinicalLevel.SubjectVisit) && x.UploadRole == UploadRole.CRC); + var config = await _repository.Where(t => t.Id == inQuery.TrialId).ProjectTo(_mapper.ConfigurationProvider).FirstOrDefaultAsync().IfNullThrowException(); + config.IsHaveSubjectClinicalData = await _clinicalDataTrialSet.AnyAsync(x => x.TrialId == inQuery.TrialId && x.IsConfirm && (x.ClinicalDataLevel == ClinicalLevel.Subject ) && x.UploadRole == UploadRole.CRC); + config.IsHaveVisitClinicalData = await _clinicalDataTrialSet.AnyAsync(x => x.TrialId == inQuery.TrialId && x.IsConfirm && (x.ClinicalDataLevel == ClinicalLevel.SubjectVisit) && x.UploadRole == UploadRole.CRC); return ResponseOutput.Ok (pageList, config); } @@ -103,7 +103,7 @@ namespace IRaCIS.Core.Application.Image.QA PageSize = 9999 }); - var pageList = list.Item1.CurrentPageData.ToList(); + var pageList = list.Data.CurrentPageData.ToList(); var data = pageList.Where(x=>x.Id==inDto.QCChallengeId||x.IsClosed==false).ToList(); @@ -144,38 +144,38 @@ namespace IRaCIS.Core.Application.Image.QA - /// - /// CRC 质疑列表 - /// - /// - /// - [HttpPost] - public async Task<(PageOutput, TrialSubjectAndSVConfig)> GetCRCChallengeList(ChallengeQuery challengeQuery) + /// + /// CRC 质疑列表 + /// + /// + /// + [HttpPost] + public async Task>> GetCRCChallengeList(ChallengeQuery inQuery) { - var svExpression = QCCommon.GetQCChallengeFilter(challengeQuery.VisitPlanArray); + var svExpression = QCCommon.GetQCChallengeFilter(inQuery.VisitPlanArray); - var query2 = _repository.Where(x => x.TrialId == challengeQuery.TrialId) + var query = _repository.Where(x => x.TrialId == inQuery.TrialId) //.WhereIf(challengeQuery.ChallengeState != null, t => t.SubjectVisit.ChallengeState == challengeQuery.ChallengeState) - .WhereIf(challengeQuery.ReuploadEnum != null, t => t.ReuploadEnum == challengeQuery.ReuploadEnum) - .WhereIf(challengeQuery.IsClosed != null, t => t.IsClosed == challengeQuery.IsClosed) - .WhereIf(challengeQuery.TrialSiteId != null, t => t.SubjectVisit.TrialSiteId == challengeQuery.TrialSiteId) - .WhereIf(challengeQuery.SubjectId != null, t => t.SubjectVisit.SubjectId == challengeQuery.SubjectId) - .WhereIf(challengeQuery.CreateUserId != null, t => t.CreateUserId == challengeQuery.CreateUserId) - .WhereIf(challengeQuery.SubjectCode != null, t => t.SubjectVisit.Subject.Code.Contains(challengeQuery.SubjectCode!)) - .WhereIf(challengeQuery.VisitPlanArray != null && challengeQuery.VisitPlanArray?.Length > 0, svExpression) + .WhereIf(inQuery.ReuploadEnum != null, t => t.ReuploadEnum == inQuery.ReuploadEnum) + .WhereIf(inQuery.IsClosed != null, t => t.IsClosed == inQuery.IsClosed) + .WhereIf(inQuery.TrialSiteId != null, t => t.SubjectVisit.TrialSiteId == inQuery.TrialSiteId) + .WhereIf(inQuery.SubjectId != null, t => t.SubjectVisit.SubjectId == inQuery.SubjectId) + .WhereIf(inQuery.CreateUserId != null, t => t.CreateUserId == inQuery.CreateUserId) + .WhereIf(inQuery.SubjectCode != null, t => t.SubjectVisit.Subject.Code.Contains(inQuery.SubjectCode!)) + .WhereIf(inQuery.VisitPlanArray != null && inQuery.VisitPlanArray?.Length > 0, svExpression) //.WhereIf(!string.IsNullOrEmpty(challengeQuery.VisitPlanInfo), challengeQuery.VisitPlanInfo.Contains('.') ? t => t.SubjectVisit.VisitNum.ToString().Contains(".") : t => t.SubjectVisit.VisitNum == decimal.Parse(challengeQuery.VisitPlanInfo)) - .WhereIf(challengeQuery.IsOverTime != null && challengeQuery.IsOverTime == true, t => t.IsClosed ? t.ClosedTime > t.DeadlineTime : DateTime.Now > t.DeadlineTime) - .WhereIf(challengeQuery.IsOverTime != null && challengeQuery.IsOverTime == false, t => t.IsClosed ? t.ClosedTime < t.DeadlineTime : DateTime.Now < t.DeadlineTime) - .WhereIf(challengeQuery.IsUrgent != null, t => t.SubjectVisit.IsUrgent == challengeQuery.IsUrgent) + .WhereIf(inQuery.IsOverTime != null && inQuery.IsOverTime == true, t => t.IsClosed ? t.ClosedTime > t.DeadlineTime : DateTime.Now > t.DeadlineTime) + .WhereIf(inQuery.IsOverTime != null && inQuery.IsOverTime == false, t => t.IsClosed ? t.ClosedTime < t.DeadlineTime : DateTime.Now < t.DeadlineTime) + .WhereIf(inQuery.IsUrgent != null, t => t.SubjectVisit.IsUrgent == inQuery.IsUrgent) .WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.CRA, t => t.SubjectVisit.TrialSite.CRCUserList.Any(t => t.UserId == _userInfo.Id)) .ProjectTo(_mapper.ConfigurationProvider); - var pageList = await query2.ToPagedListAsync(challengeQuery.PageIndex, challengeQuery.PageSize, challengeQuery.SortField, challengeQuery.Asc, string.IsNullOrWhiteSpace(challengeQuery.SortField), new string[] { "IsUrgent desc", "CreateTime asc" }); + var pageList = await query.ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, inQuery.SortField, inQuery.Asc, string.IsNullOrWhiteSpace(inQuery.SortField), new string[] { "IsUrgent desc", "CreateTime asc" }); - var config = await _repository.Where(t => t.Id == challengeQuery.TrialId).ProjectTo(_mapper.ConfigurationProvider).FirstOrDefaultAsync().IfNullThrowException(); - return (pageList, config); + var config = await _repository.Where(t => t.Id == inQuery.TrialId).ProjectTo(_mapper.ConfigurationProvider).FirstOrDefaultAsync().IfNullThrowException(); + return ResponseOutput.Ok (pageList, config); } @@ -237,39 +237,39 @@ namespace IRaCIS.Core.Application.Image.QA return result.Data.CurrentPageData.Count > 0 ? result.Data.CurrentPageData[0] : null; } - /// - /// QC 访视列表 - /// - /// - /// - [HttpPost] - public async Task>> GetQCVisitList(QCVisitSearchDTO visitSearchDTO) + /// + /// QC 访视列表 + /// + /// + /// + [HttpPost] + public async Task>> GetQCVisitList(QCVisitSearchDTO inQuery) { - var svExpression = QCCommon.GetSubjectVisitFilter(visitSearchDTO.VisitPlanArray); - var query = _subjectVisitRepository.Where(x => x.TrialId == visitSearchDTO.TrialId) - .WhereIf(visitSearchDTO.VisitId != null, t => t.Id == visitSearchDTO.VisitId) - .WhereIf(visitSearchDTO.CurrentActionUserId != null, t => t.CurrentActionUserId == visitSearchDTO.CurrentActionUserId) - .WhereIf(visitSearchDTO.ChallengeState != null, t => t.ChallengeState == visitSearchDTO.ChallengeState) - .WhereIf(visitSearchDTO.TrialSiteId != null, t => t.TrialSiteId == visitSearchDTO.TrialSiteId) - .WhereIf(visitSearchDTO.SubjectId != null, t => t.Subject.Id == visitSearchDTO.SubjectId) - .WhereIf(!string.IsNullOrEmpty(visitSearchDTO.SubjectInfo), t => /*t.Subject.FirstName.Contains(subjectInfo) || t.Subject.LastName.Contains(subjectInfo) ||*/ t.Subject.Code.Contains(visitSearchDTO.SubjectInfo)) - .WhereIf(visitSearchDTO.VisitPlanArray != null && visitSearchDTO.VisitPlanArray?.Length > 0, svExpression) + var svExpression = QCCommon.GetSubjectVisitFilter(inQuery.VisitPlanArray); + var query = _subjectVisitRepository.Where(x => x.TrialId == inQuery.TrialId) + .WhereIf(inQuery.VisitId != null, t => t.Id == inQuery.VisitId) + .WhereIf(inQuery.CurrentActionUserId != null, t => t.CurrentActionUserId == inQuery.CurrentActionUserId) + .WhereIf(inQuery.ChallengeState != null, t => t.ChallengeState == inQuery.ChallengeState) + .WhereIf(inQuery.TrialSiteId != null, t => t.TrialSiteId == inQuery.TrialSiteId) + .WhereIf(inQuery.SubjectId != null, t => t.Subject.Id == inQuery.SubjectId) + .WhereIf(!string.IsNullOrEmpty(inQuery.SubjectInfo), t => /*t.Subject.FirstName.Contains(subjectInfo) || t.Subject.LastName.Contains(subjectInfo) ||*/ t.Subject.Code.Contains(inQuery.SubjectInfo)) + .WhereIf(inQuery.VisitPlanArray != null && inQuery.VisitPlanArray?.Length > 0, svExpression) //.WhereIf(!string.IsNullOrEmpty(visitSearchDTO.VisitPlanInfo), visitSearchDTO.VisitPlanInfo.Contains('.') ? t => t.VisitNum.ToString().Contains(".") : t => t.VisitNum == decimal.Parse(visitSearchDTO.VisitPlanInfo)) //.WhereIf(visitSearchDTO.AuditState != null, t => t.AuditState == visitSearchDTO.AuditState) - .WhereIf(visitSearchDTO.AuditStateArray != null && visitSearchDTO.AuditStateArray?.Length > 0, t => visitSearchDTO.AuditStateArray!.Contains(t.AuditState)) + .WhereIf(inQuery.AuditStateArray != null && inQuery.AuditStateArray?.Length > 0, t => inQuery.AuditStateArray!.Contains(t.AuditState)) - .WhereIf(visitSearchDTO.HandleUserId != null, t => t.PreliminaryAuditUserId == visitSearchDTO.HandleUserId || t.CurrentActionUserId == visitSearchDTO.HandleUserId - || t.ReviewAuditUserId == visitSearchDTO.HandleUserId - || t.QCChallengeList.Any(t => t.CreateUserId == visitSearchDTO.HandleUserId) - || t.QCChallengeDialogList.Any(t => t.CreateUserId == visitSearchDTO.HandleUserId)) - .WhereIf(visitSearchDTO.IsUrgent != null, t => t.IsUrgent == visitSearchDTO.IsUrgent) + .WhereIf(inQuery.HandleUserId != null, t => t.PreliminaryAuditUserId == inQuery.HandleUserId || t.CurrentActionUserId == inQuery.HandleUserId + || t.ReviewAuditUserId == inQuery.HandleUserId + || t.QCChallengeList.Any(t => t.CreateUserId == inQuery.HandleUserId) + || t.QCChallengeDialogList.Any(t => t.CreateUserId == inQuery.HandleUserId)) + .WhereIf(inQuery.IsUrgent != null, t => t.IsUrgent == inQuery.IsUrgent) .Where(t => t.SubmitState != SubmitStateEnum.None) - .WhereIf(visitSearchDTO.BeginAuditTime != null, t => t.Trial.QCProcessEnum==TrialQCProcess.SingleAudit? t.PreliminaryAuditTime>= visitSearchDTO.BeginAuditTime: - (t.Trial.QCProcessEnum == TrialQCProcess.DoubleAudit?t.ReviewAuditTime>= visitSearchDTO.BeginAuditTime:true)) + .WhereIf(inQuery.BeginAuditTime != null, t => t.Trial.QCProcessEnum==TrialQCProcess.SingleAudit? t.PreliminaryAuditTime>= inQuery.BeginAuditTime: + (t.Trial.QCProcessEnum == TrialQCProcess.DoubleAudit?t.ReviewAuditTime>= inQuery.BeginAuditTime:true)) - .WhereIf(visitSearchDTO.EndAuditTime != null, t => t.Trial.QCProcessEnum == TrialQCProcess.SingleAudit ? t.PreliminaryAuditTime <= visitSearchDTO.EndAuditTime : - (t.Trial.QCProcessEnum == TrialQCProcess.DoubleAudit ? t.ReviewAuditTime <= visitSearchDTO.EndAuditTime : true)) + .WhereIf(inQuery.EndAuditTime != null, t => t.Trial.QCProcessEnum == TrialQCProcess.SingleAudit ? t.PreliminaryAuditTime <= inQuery.EndAuditTime : + (t.Trial.QCProcessEnum == TrialQCProcess.DoubleAudit ? t.ReviewAuditTime <= inQuery.EndAuditTime : true)) //.WhereIf(visitSearchDTO.SubmitState != null, t => t.SubmitState == visitSearchDTO.SubmitState) //.WhereIf(visitSearchDTO.ChallengeState != null, t => t.ChallengeState == visitSearchDTO.ChallengeState) @@ -277,12 +277,12 @@ namespace IRaCIS.Core.Application.Image.QA var defalutSortArray = new string[] { nameof(QCVisitViewModel.IsUrgent) + " desc", nameof(QCVisitViewModel.SubjectId), nameof(QCVisitViewModel.VisitNum) }; //var defalutSortArray = new string[] { nameof(SubjectVisit.IsUrgent) + " desc", nameof(QCVisitViewModel.AuditState) +" asc" }; - var pageList = await query.ToPagedListAsync(visitSearchDTO.PageIndex, visitSearchDTO.PageSize, visitSearchDTO.SortField, visitSearchDTO.Asc, string.IsNullOrWhiteSpace(visitSearchDTO.SortField), defalutSortArray); + var pageList = await query.ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, inQuery.SortField, inQuery.Asc, string.IsNullOrWhiteSpace(inQuery.SortField), defalutSortArray); - var config = await _repository.Where(t => t.Id == visitSearchDTO.TrialId).ProjectTo(_mapper.ConfigurationProvider).FirstOrDefaultAsync().IfNullThrowException(); + var config = await _repository.Where(t => t.Id == inQuery.TrialId).ProjectTo(_mapper.ConfigurationProvider).FirstOrDefaultAsync().IfNullThrowException(); return ResponseOutput.Ok (pageList, config); @@ -295,26 +295,26 @@ namespace IRaCIS.Core.Application.Image.QA /// /// 获取一致性核查列表 CRC/PM 公用 /// - /// + /// /// [HttpPost] - public async Task<(PageOutput, TrialSubjectAndSVConfig)> GetConsistencyVerificationList(CheckQuery checkQuery) + public async Task<(PageOutput, TrialSubjectAndSVConfig)> GetConsistencyVerificationList(CheckQuery inQuery) { - var svExpression = QCCommon.GetSubjectVisitFilter(checkQuery.VisitPlanArray); + var svExpression = QCCommon.GetSubjectVisitFilter(inQuery.VisitPlanArray); - var query = _subjectVisitRepository.Where(x => x.TrialId == checkQuery.TrialId) + var query = _subjectVisitRepository.Where(x => x.TrialId == inQuery.TrialId) .Where(x => x.AuditState == AuditStateEnum.QCPassed) //一致性核查中的,或者还没一致性核查的 - .WhereIf(checkQuery.CheckState != null, t => t.CheckState == checkQuery.CheckState) - .WhereIf(checkQuery.TrialSiteId != null, t => t.TrialSiteId == checkQuery.TrialSiteId) - .WhereIf(!string.IsNullOrEmpty(checkQuery.SubjectInfo), t => t.Subject.Code.Contains(checkQuery.SubjectInfo)) - .WhereIf(checkQuery.VisitPlanArray != null && checkQuery.VisitPlanArray?.Length > 0, svExpression) + .WhereIf(inQuery.CheckState != null, t => t.CheckState == inQuery.CheckState) + .WhereIf(inQuery.TrialSiteId != null, t => t.TrialSiteId == inQuery.TrialSiteId) + .WhereIf(!string.IsNullOrEmpty(inQuery.SubjectInfo), t => t.Subject.Code.Contains(inQuery.SubjectInfo)) + .WhereIf(inQuery.VisitPlanArray != null && inQuery.VisitPlanArray?.Length > 0, svExpression) //.WhereIf(!string.IsNullOrEmpty(checkQuery.VisitPlanInfo), checkQuery.VisitPlanInfo.Contains('.') ? t => t.InPlan == false : t => t.VisitNum == decimal.Parse(checkQuery.VisitPlanInfo)) .WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.CRA, t => t.TrialSite.CRCUserList.Any(t => t.UserId == _userInfo.Id))//CRC 过滤负责的site .ProjectTo(_mapper.ConfigurationProvider); - var pageList = await query.ToPagedListAsync(checkQuery.PageIndex, checkQuery.PageSize, checkQuery.SortField, checkQuery.Asc); - var config = await _repository.Where(t => t.Id == checkQuery.TrialId).ProjectTo(_mapper.ConfigurationProvider).FirstOrDefaultAsync().IfNullThrowException(); + var pageList = await query.ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, inQuery.SortField, inQuery.Asc); + var config = await _repository.Where(t => t.Id == inQuery.TrialId).ProjectTo(_mapper.ConfigurationProvider).FirstOrDefaultAsync().IfNullThrowException(); return (pageList, config); } diff --git a/IRaCIS.Core.Application/Service/QC/_MapConfig.cs b/IRaCIS.Core.Application/Service/QC/_MapConfig.cs index b5c088c66..2486bfae3 100644 --- a/IRaCIS.Core.Application/Service/QC/_MapConfig.cs +++ b/IRaCIS.Core.Application/Service/QC/_MapConfig.cs @@ -28,7 +28,18 @@ namespace IRaCIS.Core.Application.Service .ForMember(d => d.IsHaveClinicalData, u => u.MapFrom(t => t.IsBaseLine ? t.PreviousHistoryList.Any() || t.PreviousOtherList.Any() || t.ReadingClinicalDataList.Any(x => x.ClinicalDataTrialSet.UploadRole == Domain.Share.UploadRole.CRC && x.ReadingClinicalDataPDFList.Count > 0) - || t.PreviousSurgeryList.Any() : false)); + || t.PreviousSurgeryList.Any() : false)) + + .ForMember(d => d.DicomStudyCount, u => u.MapFrom(t => t.StudyList.Count())) + .ForMember(d => d.NoneDicomStudyCount, u => u.MapFrom(t => t.NoneDicomStudyList.Count(t => t.NoneDicomFileList.Any()))); + + CreateMap().IncludeBase() + .ForMember(d => d.SubmitUserRealName, u => u.MapFrom(s => s.SubmitUser.FullName)) + + .ForMember(d => d.CurrentActionUserName, u => u.MapFrom(s => s.CurrentActionUser.UserName)) + .ForMember(d => d.PreliminaryAuditUserName, u => u.MapFrom(s => s.PreliminaryAuditUser.UserName)) + .ForMember(d => d.ReviewAuditUserName, u => u.MapFrom(s => s.ReviewAuditUser.UserName)); + @@ -41,7 +52,7 @@ namespace IRaCIS.Core.Application.Service .ForMember(d => d.CreateUserName, u => u.MapFrom(s => s.CreateUser.UserName)) .ForMember(d => d.LatestReplyUserName, u => u.MapFrom(t => t.LatestReplyUser.UserName)) - .ForMember(d => d.DialogStr, u => u.MapFrom(t => string.Join(" | ", t.DialogList.OrderBy(t => t.CreateTime).Select(c => c.CreateUser.UserName + " " + c.CreateTime.ToString("yyyy-mm-dd hh:mm:ss") + " :" + c.TalkContent)))) + .ForMember(d => d.DialogStr, u => u.MapFrom(t => string.Join(" | ", t.DialogList.OrderBy(t => t.CreateTime).Select(c => c.CreateUser.UserName + " " + c.CreateTime.ToString("yyyy-MM-dd hh:mm:ss") + " :" + c.TalkContent)))) .ForMember(d => d.SubjectState, u => u.MapFrom(s => s.SubjectVisit.Subject.Status)); @@ -141,13 +152,16 @@ namespace IRaCIS.Core.Application.Service .ForMember(o => o.TrialReadingCriterionName, t => t.MapFrom(u => u.VisitTask.TrialReadingCriterion.CriterionName)) .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.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('|', u.ReadingMedicalReviewDialogList.Where(t => t.IsHaveQuestion).Select(t=>t.Questioning))) ); 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)); + .ForMember(o => o.SubjectCode, t => t.MapFrom(u => u.IsSelfAnalysis == true ? u.BlindSubjectCode : u.Subject.Code)) + + ; CreateMap() diff --git a/IRaCIS.Core.Application/Service/Visit/SubjectService.cs b/IRaCIS.Core.Application/Service/Visit/SubjectService.cs index 0f56423cb..d9e1ace36 100644 --- a/IRaCIS.Core.Application/Service/Visit/SubjectService.cs +++ b/IRaCIS.Core.Application/Service/Visit/SubjectService.cs @@ -108,27 +108,27 @@ namespace IRaCIS.Application.Services } /// 分页获取受试者列表[New] - /// /// state:1-访视中,2-出组。0-全部 + /// /// state:1-访视中,2-出组。0-全部 [HttpPost] - public async Task>> GetSubjectList(SubjectQueryParam param) + public async Task>> GetSubjectList(SubjectQueryParam inQuery) { - var subjectQuery = _subjectRepository.Where(u => u.TrialId == param.TrialId) - .WhereIf(!string.IsNullOrWhiteSpace(param.Code), t => t.Code.Contains(param.Code)) - .WhereIf(!string.IsNullOrWhiteSpace(param.Name), t => t.ShortName.Contains(param.Name)) - .WhereIf(!string.IsNullOrWhiteSpace(param.Sex), t => t.Sex.Contains(param.Sex)) - .WhereIf(param.Status != null, t => t.Status == param.Status) + var subjectQuery = _subjectRepository.Where(u => u.TrialId == inQuery.TrialId) + .WhereIf(!string.IsNullOrWhiteSpace(inQuery.Code), t => t.Code.Contains(inQuery.Code)) + .WhereIf(!string.IsNullOrWhiteSpace(inQuery.Name), t => t.ShortName.Contains(inQuery.Name)) + .WhereIf(!string.IsNullOrWhiteSpace(inQuery.Sex), t => t.Sex.Contains(inQuery.Sex)) + .WhereIf(inQuery.Status != null, t => t.Status == inQuery.Status) - .WhereIf(param.TrialSiteId != null, t => t.TrialSiteId == param.TrialSiteId) + .WhereIf(inQuery.TrialSiteId != null, t => t.TrialSiteId == inQuery.TrialSiteId) // CRC 只负责他管理site的受试者 .WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.CRA, t => t.TrialSite.CRCUserList.Any(t => t.UserId == _userInfo.Id)) .ProjectTo(_mapper.ConfigurationProvider) - .WhereIf(param.IsMissingImages != null, t => t.IsMissingImages == param.IsMissingImages); + .WhereIf(inQuery.IsMissingImages != null, t => t.IsMissingImages == inQuery.IsMissingImages); - var pageList = await subjectQuery.ToPagedListAsync(param.PageIndex, param.PageSize, param.SortField == string.Empty ? "Code" : param.SortField, param.Asc); + var pageList = await subjectQuery.ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, inQuery.SortField == string.Empty ? "Code" : inQuery.SortField, inQuery.Asc); - var trialConfig = await _repository.Where(t => t.Id == param.TrialId).ProjectTo(_mapper.ConfigurationProvider).FirstOrDefaultAsync().IfNullThrowException(); + var trialConfig = await _repository.Where(t => t.Id == inQuery.TrialId).ProjectTo(_mapper.ConfigurationProvider).FirstOrDefaultAsync().IfNullThrowException(); return ResponseOutput.Ok(pageList, trialConfig); diff --git a/IRaCIS.Core.Domain/_Config/_StaticData.cs b/IRaCIS.Core.Domain/_Config/_StaticData.cs index ddcc620c9..fd2c73df6 100644 --- a/IRaCIS.Core.Domain/_Config/_StaticData.cs +++ b/IRaCIS.Core.Domain/_Config/_StaticData.cs @@ -208,6 +208,8 @@ public static class StaticData /// public static class Export { + public const string TrialTrainingRecordList_Export = "TrialTrainingRecordList_Export"; + public const string TrialSiteUserList_Export = "TrialSiteUserList_Export"; public const string TrialSiteUserSummary_Export = "TrialSiteUserSummary_Export"; @@ -216,6 +218,8 @@ public static class StaticData public const string TrialCRCUploadImageList_Export = "TrialCRCUploadImageList_Export"; + public const string TrialQCVisitImageList_Export = "TrialQCVisitImageList_Export"; + public const string TrialQCImageChanllengeList_Export = "TrialQCImageChanllengeList_Export"; public const string TrialSubjectList_Export = "TrialSubjectList_Export"; From c1e496530d2731103bc256c6c376e1f5149a23e4 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Tue, 6 Aug 2024 16:07:47 +0800 Subject: [PATCH 191/251] =?UTF-8?q?excel=20=E5=A2=9E=E5=8A=A0=E8=8B=B1?= =?UTF-8?q?=E6=96=87=E5=90=8D=E5=AD=97=E5=AD=97=E6=AE=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Service/Common/DTO/CommonDocumentViewModel.cs | 2 ++ .../Service/Common/MailService.cs | 10 +++++----- .../Service/Management/UserFeedBackService.cs | 14 ++++++++++++-- .../Common/EmailScenarioEnum.cs | 6 ++++++ IRaCIS.Core.Domain/Common/CommonDocument.cs | 2 ++ 5 files changed, 27 insertions(+), 7 deletions(-) diff --git a/IRaCIS.Core.Application/Service/Common/DTO/CommonDocumentViewModel.cs b/IRaCIS.Core.Application/Service/Common/DTO/CommonDocumentViewModel.cs index 77e41901d..41891c999 100644 --- a/IRaCIS.Core.Application/Service/Common/DTO/CommonDocumentViewModel.cs +++ b/IRaCIS.Core.Application/Service/Common/DTO/CommonDocumentViewModel.cs @@ -48,6 +48,8 @@ namespace IRaCIS.Core.Application.ViewModel { public Guid? Id { get; set; } public string Name { get; set; } = String.Empty; + + public string NameCN { get; set; } = String.Empty; public string Path { get; set; } = String.Empty; public string Description { get; set; } = String.Empty; public bool IsDeleted { get; set; } diff --git a/IRaCIS.Core.Application/Service/Common/MailService.cs b/IRaCIS.Core.Application/Service/Common/MailService.cs index ef2839944..9fa965d6b 100644 --- a/IRaCIS.Core.Application/Service/Common/MailService.cs +++ b/IRaCIS.Core.Application/Service/Common/MailService.cs @@ -49,7 +49,7 @@ namespace IRaCIS.Application.Services Task DoctorJoinTrialEmail(Guid trialId, Guid doctorId, string baseUrl, string rootUrl); - + Task UserFeedBackMail(Guid feedBackId); } public class MailVerificationService : BaseService, IMailVerificationService @@ -733,7 +733,7 @@ namespace IRaCIS.Application.Services //用户反馈邮件 - public async Task UserFeedBack(Guid feedBackId) + public async Task UserFeedBackMail(Guid feedBackId) { var feedBack = await _repository.Where(t => t.Id == feedBackId).Include(t => t.CreateUser).ThenInclude(t => t.UserTypeRole).FirstNotNullAsync(); @@ -789,7 +789,7 @@ namespace IRaCIS.Application.Services }; - messageToSend = await GetEmailSubejctAndHtmlInfoAndBuildAsync(EmailBusinessScenario.UserResetEmail, messageToSend, emailConfigFunc); + messageToSend = await GetEmailSubejctAndHtmlInfoAndBuildAsync(EmailBusinessScenario.IRImageError, messageToSend, emailConfigFunc); } //项目相关的反馈 pm admin @@ -829,7 +829,7 @@ namespace IRaCIS.Application.Services }; - messageToSend = await GetEmailSubejctAndHtmlInfoAndBuildAsync(EmailBusinessScenario.UserResetEmail, messageToSend, emailConfigFunc); + messageToSend = await GetEmailSubejctAndHtmlInfoAndBuildAsync(EmailBusinessScenario.TrialFeedBack, messageToSend, emailConfigFunc); } //项目无关的反馈 admin zyss @@ -862,7 +862,7 @@ namespace IRaCIS.Application.Services }; - messageToSend = await GetEmailSubejctAndHtmlInfoAndBuildAsync(EmailBusinessScenario.UserResetEmail, messageToSend, emailConfigFunc); + messageToSend = await GetEmailSubejctAndHtmlInfoAndBuildAsync(EmailBusinessScenario.SysFeedBack, messageToSend, emailConfigFunc); } await SendEmailHelper.SendEmailAsync(messageToSend, _systemEmailConfig); diff --git a/IRaCIS.Core.Application/Service/Management/UserFeedBackService.cs b/IRaCIS.Core.Application/Service/Management/UserFeedBackService.cs index 5a950602d..f965b0b78 100644 --- a/IRaCIS.Core.Application/Service/Management/UserFeedBackService.cs +++ b/IRaCIS.Core.Application/Service/Management/UserFeedBackService.cs @@ -11,6 +11,8 @@ using IRaCIS.Core.Application.ViewModel; using Newtonsoft.Json; using IRaCIS.Core.Domain.Share; using IRaCIS.Core.Infrastructure; +using MailKit; +using IRaCIS.Application.Services; namespace IRaCIS.Core.Application.Service { /// @@ -49,7 +51,7 @@ namespace IRaCIS.Core.Application.Service .ProjectTo(_mapper.ConfigurationProvider); - var pageList = await userFeedBackQueryable.ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, string.IsNullOrWhiteSpace(inQuery.SortField) ? nameof(UserFeedBackView.Id) : inQuery.SortField,inQuery.Asc); + var pageList = await userFeedBackQueryable.ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, string.IsNullOrWhiteSpace(inQuery.SortField) ? nameof(UserFeedBackView.Id) : inQuery.SortField, inQuery.Asc); return pageList; } @@ -69,7 +71,8 @@ namespace IRaCIS.Core.Application.Service } - public async Task AddOrUpdateUserFeedBack(UserFeedBackAddOrEdit addOrEditUserFeedBack) + public async Task AddOrUpdateUserFeedBack(UserFeedBackAddOrEdit addOrEditUserFeedBack, + [FromServices] IMailVerificationService mailService) { addOrEditUserFeedBack.ScreenshotListStr = JsonConvert.SerializeObject(addOrEditUserFeedBack.ScreenshotList); @@ -105,8 +108,15 @@ namespace IRaCIS.Core.Application.Service } } + + var entity = await _userFeedBackRepository.InsertOrUpdateAsync(addOrEditUserFeedBack, true); + if (addOrEditUserFeedBack.VisitTaskId != null || addOrEditUserFeedBack.Id == null) + { + //await mailService.UserFeedBackMail(entity.Id); + } + return ResponseOutput.Ok(entity.Id.ToString()); } diff --git a/IRaCIS.Core.Domain.Share/Common/EmailScenarioEnum.cs b/IRaCIS.Core.Domain.Share/Common/EmailScenarioEnum.cs index ee22efd38..2520324b9 100644 --- a/IRaCIS.Core.Domain.Share/Common/EmailScenarioEnum.cs +++ b/IRaCIS.Core.Domain.Share/Common/EmailScenarioEnum.cs @@ -87,6 +87,12 @@ namespace IRaCIS.Core.Domain.Share //不登陆通过邮箱重置密码 UnloginUseEmailResetPassword = 23, + IRImageError=24, + + SysFeedBack=26, + + TrialFeedBack=27 + } diff --git a/IRaCIS.Core.Domain/Common/CommonDocument.cs b/IRaCIS.Core.Domain/Common/CommonDocument.cs index 451b0f51c..37a29aeee 100644 --- a/IRaCIS.Core.Domain/Common/CommonDocument.cs +++ b/IRaCIS.Core.Domain/Common/CommonDocument.cs @@ -23,6 +23,8 @@ namespace IRaCIS.Core.Domain.Models [Required] public string Name { get; set; } = String.Empty; + public string NameCN { get; set; } = string.Empty; + /// /// Path /// From 8b8ed1fee33f0ed10b1c9d470ff3e1e6b3d7bb58 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Tue, 6 Aug 2024 16:39:11 +0800 Subject: [PATCH 192/251] =?UTF-8?q?=E7=B3=BB=E7=BB=9F=E9=82=AE=E4=BB=B6?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.API/IRaCIS.Core.API.xml | 7 ++ .../IRaCIS.Core.Application.xml | 71 ++++++++++++++----- .../Common/DTO/EmailNoticeConfigViewModel.cs | 5 +- .../Common/EmailNoticeConfigService.cs | 2 +- .../Interface/IUserFeedBackService.cs | 21 +++--- .../Common/EmailNoticeConfig.cs | 12 +++- 6 files changed, 87 insertions(+), 31 deletions(-) diff --git a/IRaCIS.Core.API/IRaCIS.Core.API.xml b/IRaCIS.Core.API/IRaCIS.Core.API.xml index ddbe96072..726d34a48 100644 --- a/IRaCIS.Core.API/IRaCIS.Core.API.xml +++ b/IRaCIS.Core.API/IRaCIS.Core.API.xml @@ -167,6 +167,13 @@ + + + PM签名一致性分析临床数据 + + + + 提交结构化录入并签名 diff --git a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml index 970833ba3..ef44e414d 100644 --- a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml +++ b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml @@ -103,6 +103,20 @@ + + + https://www.cnblogs.com/NBDWDYS2214143926/p/13329231.html + + + + + RSA解密 + + 私钥 + 待解密的字符串(Base64) + 解密后的字符串 + + 分配规则 @@ -400,7 +414,7 @@ PM 重阅追踪 - + @@ -529,11 +543,33 @@ + + + getDocumentConfirmList 培训记录导出 + + + + + + + + 影像上传列表 只导出已上传状态的访视记录 - + + + + + + + + + + 影像质控导出 + + @@ -544,18 +580,19 @@ 质疑列表 - + - + 受试者信息导出表 - + + @@ -574,7 +611,7 @@ 影像上传监控表 - + @@ -604,7 +641,7 @@ 一致性核查记录表 - + @@ -621,22 +658,24 @@ - + PM 重阅追踪 - + + - + PM 医学审核(挑选任务生成后的列表) + @@ -12317,7 +12356,7 @@ 获取确认列表情况 项目文档+系统文档+具体的人 - + @@ -12488,7 +12527,7 @@ CRC 访视上传列表 - + @@ -12503,7 +12542,7 @@ CRC 质疑列表 - + @@ -12524,14 +12563,14 @@ QC 访视列表 - + 获取一致性核查列表 CRC/PM 公用 - + @@ -15201,7 +15240,7 @@ 分页获取受试者列表[New] - /// state:1-访视中,2-出组。0-全部 + /// state:1-访视中,2-出组。0-全部 diff --git a/IRaCIS.Core.Application/Service/Common/DTO/EmailNoticeConfigViewModel.cs b/IRaCIS.Core.Application/Service/Common/DTO/EmailNoticeConfigViewModel.cs index edb1cfc5a..3ac45cfe9 100644 --- a/IRaCIS.Core.Application/Service/Common/DTO/EmailNoticeConfigViewModel.cs +++ b/IRaCIS.Core.Application/Service/Common/DTO/EmailNoticeConfigViewModel.cs @@ -63,7 +63,7 @@ namespace IRaCIS.Core.Application.Contracts public bool? IsDistinguishCriteria { get; set; } - public bool IsSystemLevel { get; set; } = false; + public int? SystemLevel { get; set; } } @@ -128,7 +128,8 @@ namespace IRaCIS.Core.Application.Contracts public List ToUserTypeList { get; set; } public List CopyUserTypeList { get; set; } - public bool IsSystemLevel { get; set; } = false; + + public int? SystemLevel { get; set; } } diff --git a/IRaCIS.Core.Application/Service/Common/EmailNoticeConfigService.cs b/IRaCIS.Core.Application/Service/Common/EmailNoticeConfigService.cs index b634370e5..60ef71673 100644 --- a/IRaCIS.Core.Application/Service/Common/EmailNoticeConfigService.cs +++ b/IRaCIS.Core.Application/Service/Common/EmailNoticeConfigService.cs @@ -28,7 +28,7 @@ namespace IRaCIS.Core.Application.Contracts [HttpPost] public async Task> GetEmailNoticeConfigList(EmailNoticeConfigQuery queryEmailNoticeConfig) { - var emailNoticeConfigQueryable = _emailNoticeConfigrepository.Where(t=>t.IsSystemLevel==queryEmailNoticeConfig.IsSystemLevel) + var emailNoticeConfigQueryable = _emailNoticeConfigrepository.WhereIf(queryEmailNoticeConfig.SystemLevel!=null, t =>t.SystemLevel == queryEmailNoticeConfig.SystemLevel) .WhereIf(queryEmailNoticeConfig.IsDistinguishCriteria != null, t => t.IsDistinguishCriteria == queryEmailNoticeConfig.IsDistinguishCriteria) .WhereIf(queryEmailNoticeConfig.CriterionTypeEnum != null, t => t.CriterionTypeEnum == queryEmailNoticeConfig.CriterionTypeEnum) .WhereIf(queryEmailNoticeConfig.BusinessScenarioEnum != null, t => t.BusinessScenarioEnum == queryEmailNoticeConfig.BusinessScenarioEnum) diff --git a/IRaCIS.Core.Application/Service/Management/Interface/IUserFeedBackService.cs b/IRaCIS.Core.Application/Service/Management/Interface/IUserFeedBackService.cs index 6fa7976a3..e4420f4a3 100644 --- a/IRaCIS.Core.Application/Service/Management/Interface/IUserFeedBackService.cs +++ b/IRaCIS.Core.Application/Service/Management/Interface/IUserFeedBackService.cs @@ -6,19 +6,18 @@ using IRaCIS.Core.Application.ViewModel; namespace IRaCIS.Core.Application.Interfaces -{ - /// - /// IUserFeedBackService - /// - public interface IUserFeedBackService +{ + /// + /// IUserFeedBackService + /// + public interface IUserFeedBackService { - Task> GetUserFeedBackList(UserFeedBackQuery inQuery); - - Task AddOrUpdateUserFeedBack(UserFeedBackAddOrEdit addOrEditUserFeedBack); + Task> GetUserFeedBackList(UserFeedBackQuery inQuery); + + + Task DeleteUserFeedBack(Guid userFeedBackId); - Task DeleteUserFeedBack(Guid userFeedBackId); - } -} +} diff --git a/IRaCIS.Core.Domain/Common/EmailNoticeConfig.cs b/IRaCIS.Core.Domain/Common/EmailNoticeConfig.cs index 31c4dfec9..94de1e7fa 100644 --- a/IRaCIS.Core.Domain/Common/EmailNoticeConfig.cs +++ b/IRaCIS.Core.Domain/Common/EmailNoticeConfig.cs @@ -69,7 +69,7 @@ namespace IRaCIS.Core.Domain.Models - public bool IsSystemLevel { get; set; } + public int? SystemLevel { get; set; } /// /// 是否区分标准 @@ -123,4 +123,14 @@ namespace IRaCIS.Core.Domain.Models public EmailUserType EmailUserType { get; set; } } + + + public enum SysEmailLevel + { + //系统 不配置角色 + sys_not_role=1, + + //系统需要配置角色的 + sys_Config_role=2 + } } From 405db77dea742f6833d3e12fdb3cb8b26b066d9e Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Tue, 6 Aug 2024 17:41:40 +0800 Subject: [PATCH 193/251] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E9=82=AE=E4=BB=B6?= =?UTF-8?q?=E6=9F=A5=E8=AF=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Common/DTO/EmailNoticeConfigViewModel.cs | 4 +- .../Common/EmailNoticeConfigService.cs | 4 +- .../Service/Common/MailService.cs | 54 ++++++++++++------- .../Common/EmailNoticeConfig.cs | 4 +- 4 files changed, 43 insertions(+), 23 deletions(-) diff --git a/IRaCIS.Core.Application/Service/Common/DTO/EmailNoticeConfigViewModel.cs b/IRaCIS.Core.Application/Service/Common/DTO/EmailNoticeConfigViewModel.cs index 3ac45cfe9..c473097a0 100644 --- a/IRaCIS.Core.Application/Service/Common/DTO/EmailNoticeConfigViewModel.cs +++ b/IRaCIS.Core.Application/Service/Common/DTO/EmailNoticeConfigViewModel.cs @@ -63,7 +63,7 @@ namespace IRaCIS.Core.Application.Contracts public bool? IsDistinguishCriteria { get; set; } - public int? SystemLevel { get; set; } + public SysEmailLevel? SystemLevel { get; set; } } @@ -129,7 +129,7 @@ namespace IRaCIS.Core.Application.Contracts public List CopyUserTypeList { get; set; } - public int? SystemLevel { get; set; } + public SysEmailLevel SystemLevel { get; set; } } diff --git a/IRaCIS.Core.Application/Service/Common/EmailNoticeConfigService.cs b/IRaCIS.Core.Application/Service/Common/EmailNoticeConfigService.cs index 60ef71673..a9d45632e 100644 --- a/IRaCIS.Core.Application/Service/Common/EmailNoticeConfigService.cs +++ b/IRaCIS.Core.Application/Service/Common/EmailNoticeConfigService.cs @@ -28,7 +28,9 @@ namespace IRaCIS.Core.Application.Contracts [HttpPost] public async Task> GetEmailNoticeConfigList(EmailNoticeConfigQuery queryEmailNoticeConfig) { - var emailNoticeConfigQueryable = _emailNoticeConfigrepository.WhereIf(queryEmailNoticeConfig.SystemLevel!=null, t =>t.SystemLevel == queryEmailNoticeConfig.SystemLevel) + var emailNoticeConfigQueryable = _emailNoticeConfigrepository + .WhereIf(queryEmailNoticeConfig.SystemLevel == null, t => t.SystemLevel == SysEmailLevel.not_sys) + .WhereIf(queryEmailNoticeConfig.SystemLevel!=null, t =>t.SystemLevel == queryEmailNoticeConfig.SystemLevel) .WhereIf(queryEmailNoticeConfig.IsDistinguishCriteria != null, t => t.IsDistinguishCriteria == queryEmailNoticeConfig.IsDistinguishCriteria) .WhereIf(queryEmailNoticeConfig.CriterionTypeEnum != null, t => t.CriterionTypeEnum == queryEmailNoticeConfig.CriterionTypeEnum) .WhereIf(queryEmailNoticeConfig.BusinessScenarioEnum != null, t => t.BusinessScenarioEnum == queryEmailNoticeConfig.BusinessScenarioEnum) diff --git a/IRaCIS.Core.Application/Service/Common/MailService.cs b/IRaCIS.Core.Application/Service/Common/MailService.cs index 9fa965d6b..4a5c6764d 100644 --- a/IRaCIS.Core.Application/Service/Common/MailService.cs +++ b/IRaCIS.Core.Application/Service/Common/MailService.cs @@ -21,6 +21,7 @@ using DocumentFormat.OpenXml.Vml; using System.Net.Mail; using IP2Region.Net.XDB; using NPOI.SS.Formula.Eval; +using System.Linq; namespace IRaCIS.Application.Services { @@ -97,7 +98,7 @@ namespace IRaCIS.Application.Services } - private async Task GetEmailSubejctAndHtmlInfoAndBuildAsync(EmailBusinessScenario scenario, MimeMessage messageToSend, + private async Task GetEmailSubejctAndHtmlInfoAndBuildAsync(EmailBusinessScenario scenario, MimeMessage messageToSend, Func<(string topicStr, string htmlBodyStr), (string topicStr, string htmlBodyStr)> emailFunc) { var configInfo = await _emailNoticeConfigrepository.Where(t => t.BusinessScenarioEnum == scenario).FirstOrDefaultAsync(); @@ -130,7 +131,19 @@ namespace IRaCIS.Application.Services messageToSend.Body = builder.ToMessageBody(); - return messageToSend; + return configInfo; + } + + public async Task GetEmailConfigInfoAsync(EmailBusinessScenario scenario) + { + var configInfo = await _emailNoticeConfigrepository.Where(t => t.BusinessScenarioEnum == scenario).Include(t=>t.EmailNoticeUserTypeList).FirstOrDefaultAsync(); + + if (configInfo == null) + { + throw new BusinessValidationFailedException("系统未找到当前场景邮件配置信息,请联系运维人员核查"); + } + + return configInfo; } @@ -188,7 +201,7 @@ namespace IRaCIS.Application.Services }; - messageToSend = await GetEmailSubejctAndHtmlInfoAndBuildAsync(mfaType == UserMFAType.Login ? EmailBusinessScenario.MFALogin : EmailBusinessScenario.MFAUnlock, messageToSend, emailConfigFunc); + await GetEmailSubejctAndHtmlInfoAndBuildAsync(mfaType == UserMFAType.Login ? EmailBusinessScenario.MFALogin : EmailBusinessScenario.MFAUnlock, messageToSend, emailConfigFunc); var sucessHandle = GetEmailSuccessHandle(userId, verificationCode, emailAddress); @@ -226,7 +239,7 @@ namespace IRaCIS.Application.Services }; - messageToSend = await GetEmailSubejctAndHtmlInfoAndBuildAsync(EmailBusinessScenario.UserResetEmail, messageToSend, emailConfigFunc); + await GetEmailSubejctAndHtmlInfoAndBuildAsync(EmailBusinessScenario.UserResetEmail, messageToSend, emailConfigFunc); var sucessHandle = GetEmailSuccessHandle(userId, verificationCode, emailAddress); @@ -265,7 +278,7 @@ namespace IRaCIS.Application.Services }; - messageToSend = await GetEmailSubejctAndHtmlInfoAndBuildAsync(EmailBusinessScenario.UnloginUseEmailResetPassword, messageToSend, emailConfigFunc); + await GetEmailSubejctAndHtmlInfoAndBuildAsync(EmailBusinessScenario.UnloginUseEmailResetPassword, messageToSend, emailConfigFunc); ////此时不知道用户 var sucessHandle = GetEmailSuccessHandle(Guid.Empty, verificationCode, emailAddress); @@ -309,7 +322,7 @@ namespace IRaCIS.Application.Services }; - messageToSend = await GetEmailSubejctAndHtmlInfoAndBuildAsync(EmailBusinessScenario.UnloginUseEmailResetPassword, messageToSend, emailConfigFunc); + await GetEmailSubejctAndHtmlInfoAndBuildAsync(EmailBusinessScenario.UnloginUseEmailResetPassword, messageToSend, emailConfigFunc); //此时不知道用户 var sucessHandle = GetEmailSuccessHandle(Guid.Empty, verificationCode, emailAddress); @@ -351,7 +364,7 @@ namespace IRaCIS.Application.Services }; - messageToSend = await GetEmailSubejctAndHtmlInfoAndBuildAsync(EmailBusinessScenario.SiteSurveyLogin, messageToSend, emailConfigFunc); + await GetEmailSubejctAndHtmlInfoAndBuildAsync(EmailBusinessScenario.SiteSurveyLogin, messageToSend, emailConfigFunc); //此时不知道用户 var sucessHandle = GetEmailSuccessHandle(Guid.Empty, verificationCode, emailAddress); @@ -397,7 +410,7 @@ namespace IRaCIS.Application.Services }; - messageToSend = await GetEmailSubejctAndHtmlInfoAndBuildAsync(EmailBusinessScenario.SiteSurveyReject, messageToSend, emailConfigFunc); + await GetEmailSubejctAndHtmlInfoAndBuildAsync(EmailBusinessScenario.SiteSurveyReject, messageToSend, emailConfigFunc); @@ -450,7 +463,7 @@ namespace IRaCIS.Application.Services }; - messageToSend = await GetEmailSubejctAndHtmlInfoAndBuildAsync(EmailBusinessScenario.SysCreateUser, messageToSend, emailConfigFunc); + await GetEmailSubejctAndHtmlInfoAndBuildAsync(EmailBusinessScenario.SysCreateUser, messageToSend, emailConfigFunc); await SendEmailHelper.SendEmailAsync(messageToSend, _systemEmailConfig); @@ -487,7 +500,7 @@ namespace IRaCIS.Application.Services }; - messageToSend = await GetEmailSubejctAndHtmlInfoAndBuildAsync(EmailBusinessScenario.SysResetPassword, messageToSend, emailConfigFunc); + await GetEmailSubejctAndHtmlInfoAndBuildAsync(EmailBusinessScenario.SysResetPassword, messageToSend, emailConfigFunc); await SendEmailHelper.SendEmailAsync(messageToSend, _systemEmailConfig); } @@ -544,7 +557,7 @@ namespace IRaCIS.Application.Services }; - messageToSend = await GetEmailSubejctAndHtmlInfoAndBuildAsync(sysUserInfo.IsFirstAdd ? EmailBusinessScenario.SiteUseOrExternalUserFirstrJoinTrial : EmailBusinessScenario.SiteUserOrExternalUserExistJoinTrial, messageToSend, emailConfigFunc); + await GetEmailSubejctAndHtmlInfoAndBuildAsync(sysUserInfo.IsFirstAdd ? EmailBusinessScenario.SiteUseOrExternalUserFirstrJoinTrial : EmailBusinessScenario.SiteUserOrExternalUserExistJoinTrial, messageToSend, emailConfigFunc); await SendEmailHelper.SendEmailAsync(messageToSend, _systemEmailConfig); @@ -604,7 +617,7 @@ namespace IRaCIS.Application.Services }; - messageToSend = await GetEmailSubejctAndHtmlInfoAndBuildAsync(sysUserInfo.IsFirstAdd ? EmailBusinessScenario.SiteUseOrExternalUserFirstrJoinTrial : EmailBusinessScenario.SiteUserOrExternalUserExistJoinTrial, messageToSend, emailConfigFunc); + await GetEmailSubejctAndHtmlInfoAndBuildAsync(sysUserInfo.IsFirstAdd ? EmailBusinessScenario.SiteUseOrExternalUserFirstrJoinTrial : EmailBusinessScenario.SiteUserOrExternalUserExistJoinTrial, messageToSend, emailConfigFunc); await SendEmailHelper.SendEmailAsync(messageToSend, _systemEmailConfig, null); @@ -722,7 +735,7 @@ namespace IRaCIS.Application.Services }; - messageToSend = await GetEmailSubejctAndHtmlInfoAndBuildAsync(sysUserInfo.IsFirstAdd ? EmailBusinessScenario.DoctorUserFirstJoinTrial : EmailBusinessScenario.DoctorUserExistJoinTrial, messageToSend, emailConfigFunc); + await GetEmailSubejctAndHtmlInfoAndBuildAsync(sysUserInfo.IsFirstAdd ? EmailBusinessScenario.DoctorUserFirstJoinTrial : EmailBusinessScenario.DoctorUserExistJoinTrial, messageToSend, emailConfigFunc); await SendEmailHelper.SendEmailAsync(messageToSend, _systemEmailConfig, null); @@ -745,9 +758,12 @@ namespace IRaCIS.Application.Services var companyName = _userInfo.IsEn_Us ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN; + var emailConfigInfo = await GetEmailConfigInfoAsync(EmailBusinessScenario.IRImageError); - var emailList = await _repository.Where(t => t.UserTypeEnum == UserTypeEnum.Admin || t.UserTypeEnum == UserTypeEnum.ZYSS || - (isHaveTrialId ? t.UserTrials.Any(t => t.User.UserTypeEnum == UserTypeEnum.ProjectManager && t.TrialId == feedBack.TrialId) : true)).Select(t => new { t.EMail, t.UserTypeEnum, t.FullName }).ToListAsync(); + var userTypeEnumList = emailConfigInfo.EmailNoticeUserTypeList.Where(t => t.EmailUserType == EmailUserType.To).Select(t => t.UserType).ToList(); + + var emailList = await _repository.Where(t => userTypeEnumList.Contains(t.UserTypeEnum) && + (isHaveTrialId ? t.UserTrials.Any(t => t.TrialId == feedBack.TrialId) : true)).Select(t => new { t.EMail, t.UserTypeEnum, t.FullName }).ToListAsync(); //影像阅片反馈 pm @@ -789,7 +805,7 @@ namespace IRaCIS.Application.Services }; - messageToSend = await GetEmailSubejctAndHtmlInfoAndBuildAsync(EmailBusinessScenario.IRImageError, messageToSend, emailConfigFunc); + await GetEmailSubejctAndHtmlInfoAndBuildAsync(EmailBusinessScenario.IRImageError, messageToSend, emailConfigFunc); } //项目相关的反馈 pm admin @@ -819,7 +835,7 @@ namespace IRaCIS.Application.Services userNames, info.TrialCode, feedBack.CreateUser.UserTypeRole.UserTypeShortName, - feedBack.CreateUser.FullName, + feedBack.CreateUser.FullName, emailType, feedBack.QuestionDescription, _systemEmailConfig.SiteUrl @@ -829,7 +845,7 @@ namespace IRaCIS.Application.Services }; - messageToSend = await GetEmailSubejctAndHtmlInfoAndBuildAsync(EmailBusinessScenario.TrialFeedBack, messageToSend, emailConfigFunc); + await GetEmailSubejctAndHtmlInfoAndBuildAsync(EmailBusinessScenario.TrialFeedBack, messageToSend, emailConfigFunc); } //项目无关的反馈 admin zyss @@ -862,7 +878,7 @@ namespace IRaCIS.Application.Services }; - messageToSend = await GetEmailSubejctAndHtmlInfoAndBuildAsync(EmailBusinessScenario.SysFeedBack, messageToSend, emailConfigFunc); + await GetEmailSubejctAndHtmlInfoAndBuildAsync(EmailBusinessScenario.SysFeedBack, messageToSend, emailConfigFunc); } await SendEmailHelper.SendEmailAsync(messageToSend, _systemEmailConfig); diff --git a/IRaCIS.Core.Domain/Common/EmailNoticeConfig.cs b/IRaCIS.Core.Domain/Common/EmailNoticeConfig.cs index 94de1e7fa..613bc008e 100644 --- a/IRaCIS.Core.Domain/Common/EmailNoticeConfig.cs +++ b/IRaCIS.Core.Domain/Common/EmailNoticeConfig.cs @@ -69,7 +69,7 @@ namespace IRaCIS.Core.Domain.Models - public int? SystemLevel { get; set; } + public SysEmailLevel SystemLevel { get; set; } /// /// 是否区分标准 @@ -127,6 +127,8 @@ namespace IRaCIS.Core.Domain.Models public enum SysEmailLevel { + not_sys=0, + //系统 不配置角色 sys_not_role=1, From 8ec67d72f1fab7fada2018d709e4198cf4c30b06 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Tue, 6 Aug 2024 18:04:14 +0800 Subject: [PATCH 194/251] =?UTF-8?q?=E6=89=93=E5=BC=80=E7=B3=BB=E7=BB=9F?= =?UTF-8?q?=E5=8F=8D=E9=A6=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Service/Common/ExcelExportService.cs | 9 +++--- .../Service/Common/MailService.cs | 31 +++---------------- .../Service/Management/UserFeedBackService.cs | 2 +- .../Service/QC/DTO/QCListViewModel.cs | 3 ++ 4 files changed, 14 insertions(+), 31 deletions(-) diff --git a/IRaCIS.Core.Application/Service/Common/ExcelExportService.cs b/IRaCIS.Core.Application/Service/Common/ExcelExportService.cs index d2616588e..2a861eb65 100644 --- a/IRaCIS.Core.Application/Service/Common/ExcelExportService.cs +++ b/IRaCIS.Core.Application/Service/Common/ExcelExportService.cs @@ -490,10 +490,11 @@ namespace IRaCIS.Core.Application.Service.Common .WhereIf(inQuery.TrialSiteId != null, t => t.TrialSiteId == inQuery.TrialSiteId) // CRC 只负责他管理site的受试者 - .WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.CRA, t => t.TrialSite.CRCUserList.Any(t => t.UserId == _userInfo.Id)) - .ProjectTo(_mapper.ConfigurationProvider) - .WhereIf(inQuery.IsMissingImages != null, t => t.IsMissingImages == inQuery.IsMissingImages) - .ProjectTo(_mapper.ConfigurationProvider); + .WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.CRA, t => t.TrialSite.CRCUserList.Any(t => t.UserId == _userInfo.Id)) + .ProjectTo(_mapper.ConfigurationProvider) + .WhereIf(inQuery.IsMissingImages == true, t => t.MissingSubmmitCount> 0) + .WhereIf(inQuery.IsMissingImages == false, t => t.MissingSubmmitCount == 0) + ; var list = subjectQuery.OrderBy(t => t.TrialSiteCode).ThenBy(t => t.Code).ToList(); diff --git a/IRaCIS.Core.Application/Service/Common/MailService.cs b/IRaCIS.Core.Application/Service/Common/MailService.cs index 4a5c6764d..97c0ba219 100644 --- a/IRaCIS.Core.Application/Service/Common/MailService.cs +++ b/IRaCIS.Core.Application/Service/Common/MailService.cs @@ -766,18 +766,14 @@ namespace IRaCIS.Application.Services (isHaveTrialId ? t.UserTrials.Any(t => t.TrialId == feedBack.TrialId) : true)).Select(t => new { t.EMail, t.UserTypeEnum, t.FullName }).ToListAsync(); + foreach (var email in emailList) + { + messageToSend.To.Add(new MailboxAddress(email.FullName, email.EMail)); + } + //影像阅片反馈 pm if (feedBack.VisitTaskId != null) { - foreach (var email in emailList) - { - if (email.UserTypeEnum == UserTypeEnum.ProjectManager) - { - //收件地址 - messageToSend.To.Add(new MailboxAddress(email.FullName, email.EMail)); - } - } - var userNames = string.Join(',', emailList.Where(email => email.UserTypeEnum == UserTypeEnum.ProjectManager).Select(t => t.FullName)); var emailType = await _repository.Where(t => t.Parent.Code == "Email_BusinessScenario" && t.ParentId != null && t.Code == ((int)EmailBusinessScenario.UserResetEmail).ToString()).Select(t => _userInfo.IsEn_Us ? t.Value : t.ValueCN).FirstOrDefaultAsync(); @@ -811,15 +807,6 @@ namespace IRaCIS.Application.Services //项目相关的反馈 pm admin else if (feedBack.TrialId != null) { - foreach (var email in emailList) - { - if (email.UserTypeEnum == UserTypeEnum.ProjectManager || email.UserTypeEnum == UserTypeEnum.Admin) - { - //收件地址 - messageToSend.To.Add(new MailboxAddress(email.FullName, email.EMail)); - } - } - var userNames = string.Join(',', emailList.Where(email => email.UserTypeEnum == UserTypeEnum.ProjectManager || email.UserTypeEnum == UserTypeEnum.Admin).Select(t => t.FullName)); var emailType = await _repository.Where(t => t.Parent.Code == "Email_BusinessScenario" && t.ParentId != null && t.Code == ((int)EmailBusinessScenario.UserResetEmail).ToString()).Select(t => _userInfo.IsEn_Us ? t.Value : t.ValueCN).FirstOrDefaultAsync(); @@ -851,14 +838,6 @@ namespace IRaCIS.Application.Services //项目无关的反馈 admin zyss else { - foreach (var email in emailList) - { - if (email.UserTypeEnum == UserTypeEnum.ZYSS || email.UserTypeEnum == UserTypeEnum.Admin) - { - //收件地址 - messageToSend.To.Add(new MailboxAddress(email.FullName, email.EMail)); - } - } var userNames = string.Join(',', emailList.Where(email => email.UserTypeEnum == UserTypeEnum.ZYSS || email.UserTypeEnum == UserTypeEnum.Admin).Select(t => t.FullName)); diff --git a/IRaCIS.Core.Application/Service/Management/UserFeedBackService.cs b/IRaCIS.Core.Application/Service/Management/UserFeedBackService.cs index f965b0b78..5f987f320 100644 --- a/IRaCIS.Core.Application/Service/Management/UserFeedBackService.cs +++ b/IRaCIS.Core.Application/Service/Management/UserFeedBackService.cs @@ -114,7 +114,7 @@ namespace IRaCIS.Core.Application.Service if (addOrEditUserFeedBack.VisitTaskId != null || addOrEditUserFeedBack.Id == null) { - //await mailService.UserFeedBackMail(entity.Id); + await mailService.UserFeedBackMail(entity.Id); } return ResponseOutput.Ok(entity.Id.ToString()); diff --git a/IRaCIS.Core.Application/Service/QC/DTO/QCListViewModel.cs b/IRaCIS.Core.Application/Service/QC/DTO/QCListViewModel.cs index 7d9c33e72..12e02ab62 100644 --- a/IRaCIS.Core.Application/Service/QC/DTO/QCListViewModel.cs +++ b/IRaCIS.Core.Application/Service/QC/DTO/QCListViewModel.cs @@ -342,6 +342,7 @@ namespace IRaCIS.Core.Application.Contracts public class SubjectExportDTO { + public string Code { get; set; } = String.Empty; //public int? Age { get; set; } @@ -393,6 +394,8 @@ namespace IRaCIS.Core.Application.Contracts public string LatestVisitName { get; set; } = string.Empty; public string LatestBlindName { get; set; } = string.Empty; + + [DictionaryTranslateAttribute("YesOrNo")] public bool IsMissingImages => MissingSubmmitCount > 0; From 4a82812b4e0de0d6046df8ce3592088aabf45c20 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Wed, 7 Aug 2024 10:37:06 +0800 Subject: [PATCH 195/251] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=AF=BC=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.Application/Service/Common/ExcelExportService.cs | 1 - IRaCIS.Core.Application/Service/QC/_MapConfig.cs | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/IRaCIS.Core.Application/Service/Common/ExcelExportService.cs b/IRaCIS.Core.Application/Service/Common/ExcelExportService.cs index 2a861eb65..386e6d2a7 100644 --- a/IRaCIS.Core.Application/Service/Common/ExcelExportService.cs +++ b/IRaCIS.Core.Application/Service/Common/ExcelExportService.cs @@ -433,7 +433,6 @@ namespace IRaCIS.Core.Application.Service.Common ) { - var svExpression = QCCommon.GetQCChallengeFilter(inQuery.VisitPlanArray); var query = _repository.Where(x => x.TrialId == inQuery.TrialId) diff --git a/IRaCIS.Core.Application/Service/QC/_MapConfig.cs b/IRaCIS.Core.Application/Service/QC/_MapConfig.cs index 2486bfae3..16b0d4ba6 100644 --- a/IRaCIS.Core.Application/Service/QC/_MapConfig.cs +++ b/IRaCIS.Core.Application/Service/QC/_MapConfig.cs @@ -52,7 +52,7 @@ namespace IRaCIS.Core.Application.Service .ForMember(d => d.CreateUserName, u => u.MapFrom(s => s.CreateUser.UserName)) .ForMember(d => d.LatestReplyUserName, u => u.MapFrom(t => t.LatestReplyUser.UserName)) - .ForMember(d => d.DialogStr, u => u.MapFrom(t => string.Join(" | ", t.DialogList.OrderBy(t => t.CreateTime).Select(c => c.CreateUser.UserName + " " + c.CreateTime.ToString("yyyy-MM-dd hh:mm:ss") + " :" + c.TalkContent)))) + .ForMember(d => d.DialogStr, u => u.MapFrom(t => string.Join("\n\n", t.DialogList.OrderBy(t => t.CreateTime).Select(c => c.CreateUser.UserName + " (" + c.CreateTime.ToString("yyyy-MM-dd HH:mm:ss") + ") :" + c.TalkContent)))) .ForMember(d => d.SubjectState, u => u.MapFrom(s => s.SubjectVisit.Subject.Status)); From a5737073c41174d20ab9c529798bb0e8c80c86bd Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Wed, 7 Aug 2024 10:41:46 +0800 Subject: [PATCH 196/251] =?UTF-8?q?=E9=82=AE=E4=BB=B6=E5=8F=8D=E9=A6=88?= =?UTF-8?q?=E7=B1=BB=E5=9E=8B=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.Application/Service/Common/MailService.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/IRaCIS.Core.Application/Service/Common/MailService.cs b/IRaCIS.Core.Application/Service/Common/MailService.cs index 97c0ba219..e1c0a65ad 100644 --- a/IRaCIS.Core.Application/Service/Common/MailService.cs +++ b/IRaCIS.Core.Application/Service/Common/MailService.cs @@ -758,7 +758,7 @@ namespace IRaCIS.Application.Services var companyName = _userInfo.IsEn_Us ? _systemEmailConfig.CompanyShortName : _systemEmailConfig.CompanyShortNameCN; - var emailConfigInfo = await GetEmailConfigInfoAsync(EmailBusinessScenario.IRImageError); + var emailConfigInfo = await GetEmailConfigInfoAsync(feedBack.VisitTaskId != null? EmailBusinessScenario.IRImageError:(feedBack.TrialId != null? EmailBusinessScenario.TrialFeedBack: EmailBusinessScenario.SysFeedBack)); var userTypeEnumList = emailConfigInfo.EmailNoticeUserTypeList.Where(t => t.EmailUserType == EmailUserType.To).Select(t => t.UserType).ToList(); @@ -776,7 +776,7 @@ namespace IRaCIS.Application.Services { var userNames = string.Join(',', emailList.Where(email => email.UserTypeEnum == UserTypeEnum.ProjectManager).Select(t => t.FullName)); - var emailType = await _repository.Where(t => t.Parent.Code == "Email_BusinessScenario" && t.ParentId != null && t.Code == ((int)EmailBusinessScenario.UserResetEmail).ToString()).Select(t => _userInfo.IsEn_Us ? t.Value : t.ValueCN).FirstOrDefaultAsync(); + var emailType = await _repository.Where(t => t.Parent.Code == "Email_BusinessScenario" && t.ParentId != null && t.Code == ((int)EmailBusinessScenario.IRImageError).ToString()).Select(t => _userInfo.IsEn_Us ? t.Value : t.ValueCN).FirstOrDefaultAsync(); var info = await _repository.Where(t => t.Id == feedBack.VisitTaskId).Select(t => new { t.Trial.ResearchProgramNo, t.Trial.TrialCode, SubejctCode = t.Subject.Code, t.SourceSubjectVisit.VisitName }).FirstNotNullAsync(); @@ -809,7 +809,7 @@ namespace IRaCIS.Application.Services { var userNames = string.Join(',', emailList.Where(email => email.UserTypeEnum == UserTypeEnum.ProjectManager || email.UserTypeEnum == UserTypeEnum.Admin).Select(t => t.FullName)); - var emailType = await _repository.Where(t => t.Parent.Code == "Email_BusinessScenario" && t.ParentId != null && t.Code == ((int)EmailBusinessScenario.UserResetEmail).ToString()).Select(t => _userInfo.IsEn_Us ? t.Value : t.ValueCN).FirstOrDefaultAsync(); + var emailType = await _repository.Where(t => t.Parent.Code == "Email_BusinessScenario" && t.ParentId != null && t.Code == ((int)EmailBusinessScenario.TrialFeedBack).ToString()).Select(t => _userInfo.IsEn_Us ? t.Value : t.ValueCN).FirstOrDefaultAsync(); var info = await _repository.Where(t => t.Id == feedBack.TrialId).Select(t => new { t.ResearchProgramNo, t.TrialCode }).FirstNotNullAsync(); From d279bad2d0ec88f65bb9faff31284c29a2434d33 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Wed, 7 Aug 2024 13:23:50 +0800 Subject: [PATCH 197/251] =?UTF-8?q?=E7=94=A8=E6=88=B7=E5=8F=8D=E9=A6=88?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=9F=A5=E8=AF=A2=E6=9D=A1=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Service/Management/DTO/UserFeedBackViewModel.cs | 2 +- .../Service/Management/UserFeedBackService.cs | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/IRaCIS.Core.Application/Service/Management/DTO/UserFeedBackViewModel.cs b/IRaCIS.Core.Application/Service/Management/DTO/UserFeedBackViewModel.cs index a83c28ba2..63f864ece 100644 --- a/IRaCIS.Core.Application/Service/Management/DTO/UserFeedBackViewModel.cs +++ b/IRaCIS.Core.Application/Service/Management/DTO/UserFeedBackViewModel.cs @@ -53,7 +53,7 @@ namespace IRaCIS.Core.Application.ViewModel public UserTypeEnum? UserTypeEnum { get; set; } - public string? FeedBackKeyInfo { get; set; } + public string? FeedBackUserKeyInfo { get; set; } public string? QuestionDescription { get; set; } diff --git a/IRaCIS.Core.Application/Service/Management/UserFeedBackService.cs b/IRaCIS.Core.Application/Service/Management/UserFeedBackService.cs index 5f987f320..7862f41e7 100644 --- a/IRaCIS.Core.Application/Service/Management/UserFeedBackService.cs +++ b/IRaCIS.Core.Application/Service/Management/UserFeedBackService.cs @@ -44,6 +44,7 @@ namespace IRaCIS.Core.Application.Service .WhereIf(inQuery.EndCreatime != null, t => t.CreateTime == inQuery.EndCreatime) .WhereIf(inQuery.UserTypeEnum != null, t => t.CreateUser.UserTypeEnum == inQuery.UserTypeEnum) + .WhereIf(!string.IsNullOrEmpty(inQuery.FeedBackUserKeyInfo), t => t.CreateUser.FullName.Contains(inQuery.FeedBackUserKeyInfo)|| t.CreateUser.UserName.Contains(inQuery.FeedBackUserKeyInfo)) .WhereIf(!string.IsNullOrEmpty(inQuery.QuestionDescription), t => t.QuestionDescription.Contains(inQuery.QuestionDescription)) .WhereIf(!string.IsNullOrEmpty(inQuery.TrialKeyInfo), t => t.Trial.ExperimentName.Contains(inQuery.TrialKeyInfo) || t.Trial.TrialCode.Contains(inQuery.TrialKeyInfo)) .WhereIf(!string.IsNullOrEmpty(inQuery.SubejctAndVisitKeyInfo), t => t.Subject.Code.Contains(inQuery.SubejctAndVisitKeyInfo) || t.SubjectVisit.VisitName.Contains(inQuery.SubejctAndVisitKeyInfo)) From 44e4fe3a295b0e575314c7f78643a19434dc55f2 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Wed, 7 Aug 2024 15:02:07 +0800 Subject: [PATCH 198/251] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=B8=AD=E5=BF=83?= =?UTF-8?q?=E8=B0=83=E7=A0=94bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Service/SiteSurvey/TrialSiteEquipmentSurveyService.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/IRaCIS.Core.Application/Service/SiteSurvey/TrialSiteEquipmentSurveyService.cs b/IRaCIS.Core.Application/Service/SiteSurvey/TrialSiteEquipmentSurveyService.cs index 5fd3f3746..e33aade80 100644 --- a/IRaCIS.Core.Application/Service/SiteSurvey/TrialSiteEquipmentSurveyService.cs +++ b/IRaCIS.Core.Application/Service/SiteSurvey/TrialSiteEquipmentSurveyService.cs @@ -31,7 +31,7 @@ namespace IRaCIS.Core.Application.Contracts { var trialSiteEquipmentSurveyQueryable = _trialSiteEquipmentSurveyRepository.Where(t => t.TrialSiteSurveyId == trialSiteSurveyId) .WhereIf(!string.IsNullOrEmpty(scannerType), t => t.ScannerType.Contains(scannerType!)) - .ProjectTo(_mapper.ConfigurationProvider); + .ProjectTo(_mapper.ConfigurationProvider,new { isEn_Us = _userInfo.IsEn_Us }); return await trialSiteEquipmentSurveyQueryable.ToListAsync(); } From 2838f0926849f28ef9a4e9365fb2b9f7dc7663ff Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Wed, 7 Aug 2024 16:35:52 +0800 Subject: [PATCH 199/251] =?UTF-8?q?=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 --- .../Helper/ExcelExportHelper.cs | 8 +- .../Helper/FileStoreHelper.cs | 4 +- .../Service/Common/ExcelExportService.cs | 132 +++++++++++++++++- .../Service/Institution/DTO/SiteModel.cs | 1 + .../Service/QC/DTO/QCListViewModel.cs | 17 ++- .../Service/QC/_MapConfig.cs | 7 +- .../DTO/PersonalWorkstationViewModel.cs | 2 + IRaCIS.Core.Domain/_Config/_StaticData.cs | 2 + 8 files changed, 155 insertions(+), 18 deletions(-) diff --git a/IRaCIS.Core.Application/Helper/ExcelExportHelper.cs b/IRaCIS.Core.Application/Helper/ExcelExportHelper.cs index fb48b1d97..bc14bf6a8 100644 --- a/IRaCIS.Core.Application/Helper/ExcelExportHelper.cs +++ b/IRaCIS.Core.Application/Helper/ExcelExportHelper.cs @@ -117,7 +117,7 @@ public static class ExcelExportHelper - var (physicalPath, fileNmae) = await FileStoreHelper.GetCommonDocPhysicalFilePathAsync(_hostEnvironment, _commonDocumentRepository, code); + var (physicalPath, fileName) = await FileStoreHelper.GetCommonDocPhysicalFilePathAsync(_hostEnvironment, _commonDocumentRepository, code); //模板路径 @@ -157,7 +157,7 @@ public static class ExcelExportHelper } // 文件名称 从sheet里面取 - fileNmae = workbook.GetSheetName(0); + //fileNmae = workbook.GetSheetName(0); #endregion @@ -181,7 +181,7 @@ public static class ExcelExportHelper return new FileStreamResult(memoryStream, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet") { - FileDownloadName = $"{exportFileNamePrefix}_{fileNmae/*.Substring(0, fileNmae.LastIndexOf('.'))*/}_{DateTime.Now.ToString("yyyyMMddHHmmss")}.xlsx" + FileDownloadName = $"{exportFileNamePrefix}_{fileName}_{DateTime.Now.ToString("yyyyMMddHHmmss")}.xlsx" }; #endregion @@ -328,7 +328,7 @@ public static class ExcelExportHelper } // 文件名称 从sheet里面取 - fileName = workbook.GetSheetName(0); + //fileName = workbook.GetSheetName(0); #endregion #region MiniExcel diff --git a/IRaCIS.Core.Application/Helper/FileStoreHelper.cs b/IRaCIS.Core.Application/Helper/FileStoreHelper.cs index 0be0c270e..288718745 100644 --- a/IRaCIS.Core.Application/Helper/FileStoreHelper.cs +++ b/IRaCIS.Core.Application/Helper/FileStoreHelper.cs @@ -7,6 +7,7 @@ using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Hosting; using Newtonsoft.Json.Linq; using System.Configuration; +using System.Globalization; using System.Text.RegularExpressions; namespace IRaCIS.Core.Application.Helper; @@ -194,6 +195,7 @@ public static class FileStoreHelper { var doc = await _commonDocumentRepository.FirstOrDefaultAsync(t => t.Code == code); + var isEn_US = CultureInfo.CurrentCulture.Name!= "zh-CN"; if (doc == null) { //---数据库没有找到对应的数据模板文件,请联系系统运维人员。 @@ -208,7 +210,7 @@ public static class FileStoreHelper throw new BusinessValidationFailedException(StaticData.International("FileStore_TemplateFileStoragePathInvalid")); } - return (filePath, doc.Name.Trim('/')); + return (filePath, isEn_US? doc.Name.Trim('/'): doc.NameCN.Trim('/')); } diff --git a/IRaCIS.Core.Application/Service/Common/ExcelExportService.cs b/IRaCIS.Core.Application/Service/Common/ExcelExportService.cs index 386e6d2a7..bea2328b0 100644 --- a/IRaCIS.Core.Application/Service/Common/ExcelExportService.cs +++ b/IRaCIS.Core.Application/Service/Common/ExcelExportService.cs @@ -181,6 +181,132 @@ namespace IRaCIS.Core.Application.Service.Common } + /// + /// 项目列表导出---new + /// + /// + /// + /// + /// + /// + [HttpPost] + [AllowAnonymous] + public async Task GetTrialList_Export(TrialToBeDoneQuery inQuery, + [FromServices] IRepository _commonDocumentRepository, + [FromServices] IDictionaryService _dictionaryService, + [FromServices] IRepository _trialRepository + ) + { + var isPM = _userInfo.UserTypeEnumInt == (int)UserTypeEnum.ProjectManager || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.APM; + var isCRC = _userInfo.UserTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator; + var isIQC = _userInfo.UserTypeEnumInt == (int)UserTypeEnum.IQC; + var isMIM = _userInfo.UserTypeEnumInt == (int)UserTypeEnum.MIM; + var isSPMOrCPM = _userInfo.UserTypeEnumInt == (int)UserTypeEnum.SPM || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.CPM; + var isIR = _userInfo.UserTypeEnumInt == (int)UserTypeEnum.IndependentReviewer; + + + var query = _trialRepository.AsQueryable().IgnoreQueryFilters() + + .WhereIf(inQuery.SponsorId != null, o => o.SponsorId == inQuery.SponsorId) + .WhereIf(!string.IsNullOrEmpty(inQuery.Code), o => o.TrialCode.Contains(inQuery.Code)) + .WhereIf(!string.IsNullOrEmpty(inQuery.ResearchProgramNo), o => o.ResearchProgramNo.Contains(inQuery.ResearchProgramNo)) + .WhereIf(!string.IsNullOrWhiteSpace(inQuery.ExperimentName), o => o.ExperimentName.Contains(inQuery.ExperimentName)) + .WhereIf(_userInfo.UserTypeEnumInt != (int)UserTypeEnum.SuperAdmin && _userInfo.UserTypeEnumInt != (int)UserTypeEnum.Admin && _userInfo.UserTypeEnumInt != (int)UserTypeEnum.OP, t => t.TrialUserList.Any(t => t.UserId == _userInfo.Id && t.IsDeleted == false) && t.IsDeleted == false) + .WhereIf(inQuery.CriterionType != null, o => o.TrialReadingCriterionList.Any(t => t.CriterionType == inQuery.CriterionType && t.IsSigned && t.IsConfirm)) + .WhereIf(!string.IsNullOrEmpty(inQuery.PM_EMail), o => o.TrialUserList.Any(t => t.User.EMail.Contains(inQuery.PM_EMail) && (t.User.UserTypeEnum == UserTypeEnum.ProjectManager || t.User.UserTypeEnum == UserTypeEnum.APM))) + .Select(t => new TrialToBeDoneDto() + { + TrialId = t.Id, + ResearchProgramNo = t.ResearchProgramNo, + ExperimentName = t.ExperimentName, + TrialCode = t.TrialCode, + CreateTime = t.CreateTime, + Sponsor = _userInfo.IsEn_Us ? t.Sponsor.SponsorName : t.Sponsor.SponsorNameCN, + TrialStatusStr = t.TrialStatusStr, + + ExpetiedTaskCount = isPM ? t.VisitTaskList.Where(t => t.IsUrgent).Count() : 0, + + ReReadingApprovalCount = isPM ? t.VisitTaskReReadingList.Where(t => t.OriginalReReadingTask.ReReadingApplyState == ReReadingApplyState.DocotorHaveApplyed).Count() : 0, + + PendingReconciliationCount = isPM ? t.SubjectVisitList.Where(t => t.CheckState == CheckStateEnum.ToCheck).Count() : 0, + + PendingResponseCount = isPM ? t.SubjectVisitList.Where(u => u.CheckState == CheckStateEnum.CVIng && + u.CheckChallengeDialogList.OrderByDescending(t => t.CreateTime).First().UserTypeEnum == UserTypeEnum.ClinicalResearchCoordinator).Count() : 0, + + + SPM_ReReadingApprovalCount = isSPMOrCPM ? t.VisitTaskReReadingList.Where(t => t.OriginalReReadingTask.ReReadingApplyState == ReReadingApplyState.TrialGroupHaveApplyed).Count() : 0, + + SPM_ReviewerSelectApprovalCount = isSPMOrCPM ? t.EnrollList.Where(u => u.EnrollStatus == EnrollStatus.HasCommittedToCRO).Count() : 0, + + MIM_UrgentCount = isMIM ? t.TaskMedicalReviewList.Where(t => t.IsClosedDialog == false && t.VisitTask.TaskState == TaskState.Effect && t.IsInvalid == false && t.MedicalManagerUserId == _userInfo.Id) + .Where(u => u.VisitTask.IsUrgent && + u.AuditState != MedicalReviewAuditState.HaveSigned).Count() : 0, + + MIM_PendingResponseCount = isMIM ? t.TaskMedicalReviewList.Where(t => t.IsClosedDialog == false && t.VisitTask.TaskState == TaskState.Effect && t.IsInvalid == false && t.MedicalManagerUserId == _userInfo.Id) + .Where(u => u.LatestReplyUser.UserTypeEnum == UserTypeEnum.IndependentReviewer && u.AuditState == MedicalReviewAuditState.Auditing).Count() : 0, + + MIM_PendingReviewCount = isMIM ? t.TaskMedicalReviewList.Where(t => t.IsClosedDialog == false && t.VisitTask.TaskState == TaskState.Effect && t.IsInvalid == false && t.MedicalManagerUserId == _userInfo.Id) + .Where(u => u.AuditState != MedicalReviewAuditState.HaveSigned && u.LatestReplyUser.UserTypeEnum != UserTypeEnum.IndependentReviewer).Count() : 0, + + CRC_UrgentCount = isCRC ? t.SubjectVisitList.Where(c => c.TrialSite.CRCUserList.Any(u => u.UserId == _userInfo.Id) && t.IsUrgent).Count() : 0, + + CRC_CheckQuestionCount = isCRC ? t.SubjectVisitList.Where(c => c.TrialSite.CRCUserList.Any(u => u.UserId == _userInfo.Id)) + .Where(u => u.CheckState == CheckStateEnum.CVIng && u.CheckChallengeState == CheckChanllengeTypeEnum.PMWaitCRCReply).Count() : 0, + + CRC_QCQuestionCount = isCRC ? t.SubjectVisitList.Where(c => c.TrialSite.CRCUserList.Any(u => u.UserId == _userInfo.Id)).SelectMany(c => c.QCChallengeList) + .Where(u => u.IsClosed == false && (u.LatestReplyUser.UserTypeEnum == UserTypeEnum.IQC || u.LatestReplyUserId == null)).Count() : 0, + + + //待审核 审核中 加急的数量 + IQC_UrgentCount = isIQC ? t.SubjectVisitList.Where(u => u.CurrentActionUserId == _userInfo.Id && t.QCProcessEnum != TrialQCProcess.NotAudit && t.IsUrgent).Count() : 0, + + //审核未完成 + IQC_AuditToBeDealedCount = isIQC ? t.SubjectVisitList.Where(u => u.CurrentActionUserId == _userInfo.Id && t.QCProcessEnum != TrialQCProcess.NotAudit).Count() : 0, + + //质疑待处理 + IQC_QuestionToBeDealedCount = isIQC ? t.SubjectVisitList.SelectMany(c => c.QCChallengeList) + .Where(u => u.CreateUserId == _userInfo.Id && u.IsClosed == false && u.LatestReplyUser.UserTypeEnum == UserTypeEnum.ClinicalResearchCoordinator).Count() : 0, + + //待领取 + IQC_ToBeClaimedCount = isIQC ? t.SubjectVisitList.Where(t => t.SubmitState == SubmitStateEnum.Submitted && t.AuditState != AuditStateEnum.QCPassed) + .Where(u => u.CurrentActionUserId == null && (u.PreliminaryAuditUserId == null || (u.PreliminaryAuditUserId != _userInfo.Id && u.ReviewAuditUserId == null))).Count() : 0, + + + IR_ReadingCriterionList = isIR ? t.TrialReadingCriterionList.Where(t => t.IsConfirm && t.IsSigned).OrderBy(t => t.CriterionName).Select(t => t.CriterionName).ToList() : null, + + IR_PMEmailList = isIR ? t.TrialUserList.Where(t => t.User.UserTypeEnum == UserTypeEnum.ProjectManager || t.User.UserTypeEnum == UserTypeEnum.APM).OrderBy(t => t.User.EMail).Select(t => t.User.EMail).ToList() : null, + + IR_TotalReadCount = isIR ? t.VisitTaskList.Where(t => t.DoctorUserId == _userInfo.Id && t.TaskState == TaskState.Effect && t.ReadingTaskState == ReadingTaskState.HaveSigned).Count() : 0, + + + IR_UnReadCount = isIR ? t.VisitTaskList + .Where(c => c.DoctorUserId == _userInfo.Id && c.ReadingTaskState != ReadingTaskState.HaveSigned && c.TaskState == TaskState.Effect && c.TrialReadingCriterion.IsSigned) + // 前序 不存在 未一致性核查未通过的 + .Where(t => !t.Subject.SubjectVisitList.Any(sv => sv.CheckState != CheckStateEnum.CVPassed && t.VisitTaskNum > sv.VisitNum)) + //前序 不存在 未生成任务的访视 + .Where(t => t.TrialReadingCriterion.IsAutoCreate == false ? !t.Subject.SubjectCriteriaEvaluationVisitFilterList.Where(d => d.TrialReadingCriterionId == t.TrialReadingCriterionId).Any(f => f.IsGeneratedTask == false && t.VisitTaskNum > f.SubjectVisit.VisitNum) : true) + + .Where(y => y.IsFrontTaskNeedSignButNotSign == false && (y.IsNeedClinicalDataSign == false || y.IsClinicalDataSign == true)).Count() : 0, + + IR_UrgentCount = isIR ? t.VisitTaskList.Where(t => t.SourceSubjectVisit.IsUrgent).Count() : 0, + + }); + + + var list = query.ToList(); + + var exportInfo = new ExcelExportInfo(); + + exportInfo.List = ExportExcelConverterDate.ConvertToClientTimeInObject(list, _userInfo.TimeZoneId); + exportInfo.IsEn_US = _userInfo.IsEn_Us; + exportInfo.ClientZoneId = _userInfo.TimeZoneId; + + + return await ExcelExportHelper.DataExportAsync(StaticData.Export.TrialList_Export, exportInfo, exportInfo.TrialCode, _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(TrialToBeDoneDto)); + + } + + #endregion @@ -190,7 +316,7 @@ namespace IRaCIS.Core.Application.Service.Common #region 导表查询 /// - /// getDocumentConfirmList 培训记录导出 + /// getDocumentConfirmList 培训记录导出--new /// /// /// @@ -917,8 +1043,8 @@ namespace IRaCIS.Core.Application.Service.Common var list = await _repository.Where(t => t.TrialId == queryVisitTask.TrialId && t.IsAnalysisCreate == false) //.Where(t => t.IsAnalysisCreate == false && t.DoctorUserId != null) - .WhereIf(queryVisitTask.TaskState != null, t => t.TaskState == queryVisitTask.TaskState) - .WhereIf(queryVisitTask.ArmEnum != null, t => t.ArmEnum == queryVisitTask.ArmEnum) + .WhereIf(queryVisitTask.TaskState != null, t => t.TaskState == queryVisitTask.TaskState) + .WhereIf(queryVisitTask.ArmEnum != null, t => t.ArmEnum == queryVisitTask.ArmEnum) .WhereIf(queryVisitTask.TrialSiteId != null, t => t.Subject.TrialSiteId == queryVisitTask.TrialSiteId) .WhereIf(queryVisitTask.SubjectId != null, t => t.SubjectId == queryVisitTask.SubjectId) .WhereIf(queryVisitTask.IsUrgent != null, t => t.IsUrgent == queryVisitTask.IsUrgent) diff --git a/IRaCIS.Core.Application/Service/Institution/DTO/SiteModel.cs b/IRaCIS.Core.Application/Service/Institution/DTO/SiteModel.cs index e900e5c59..55213b696 100644 --- a/IRaCIS.Core.Application/Service/Institution/DTO/SiteModel.cs +++ b/IRaCIS.Core.Application/Service/Institution/DTO/SiteModel.cs @@ -36,6 +36,7 @@ namespace IRaCIS.Application.Contracts public class SiteSelectionDTO { public Guid Id { get; set; } + public string SiteName { get; set; } = String.Empty; public string SiteNameCN { get; set; } = String.Empty; diff --git a/IRaCIS.Core.Application/Service/QC/DTO/QCListViewModel.cs b/IRaCIS.Core.Application/Service/QC/DTO/QCListViewModel.cs index 12e02ab62..7740b145b 100644 --- a/IRaCIS.Core.Application/Service/QC/DTO/QCListViewModel.cs +++ b/IRaCIS.Core.Application/Service/QC/DTO/QCListViewModel.cs @@ -201,15 +201,15 @@ namespace IRaCIS.Core.Application.Contracts { //关闭 未关闭 [DictionaryTranslateAttribute("CheckIsClosedEnum")] - public ChallengeStateEnum CheckIsClosedEnum { get; set; } + public ChallengeStateEnum ChallengeState { get; set; } //强行要分为两个字段 有无质疑 [DictionaryTranslateAttribute("YesOrNo")] - public bool IsChallengeClosed => (int)CheckIsClosedEnum > 0; + public bool IsHaveChallenge => (int)ChallengeState > 0; //临床数据收集 - public string ClinicalDataCollect => $"{DicomStudyCount},{NoneDicomStudyCount}{(IsBaseLine? (ClinicalInformationTransmissionEnum>0 &&IsHaveClinicalData ? "w/" : "w/o") :"" )}"; + public string ClinicalDataCollect => $"{DicomStudyCount},{NoneDicomStudyCount}{(IsBaseLine? (ClinicalInformationTransmissionEnum>0 && IsHaveClinicalData ? ",w/" : ",w/o") :"" )}"; public int? DicomStudyCount { get; set; } public int? NoneDicomStudyCount { get; set; } @@ -266,7 +266,7 @@ namespace IRaCIS.Core.Application.Contracts public string CurrentActionUserName { get; set; } - + public string HistoryAuditUserName => string.Join(' ', PreliminaryAuditUserName, ReviewAuditUserName); } public class QCChanllengeExportDto @@ -325,7 +325,7 @@ namespace IRaCIS.Core.Application.Contracts //public bool IsUrgent { get; set; } - //public DateTime? ReUploadedTime { get; set; } + public DateTime? ReUploadedTime { get; set; } //public RequestBackStateEnum RequestBackState { get; set; } @@ -676,6 +676,8 @@ namespace IRaCIS.Core.Application.Contracts { public string? TalkContent { get; set; } = String.Empty; public string BlindName { get; set; } = String.Empty; + + [DictionaryTranslateAttribute("YesOrNo")] public bool IsUrgent { get; set; } public DateTime? CheckPassedTime { get; set; } @@ -831,11 +833,12 @@ namespace IRaCIS.Core.Application.Contracts public AuditAdvice AuditAdviceEnum { get; set; } //审核结论 - [DictionaryTranslateAttribute("IsPass")] + public bool IsHaveQuestion { get; set; } + [DictionaryTranslateAttribute("IsPass")] - + public bool? IsHaveQuestionView => AuditState == MedicalReviewAuditState.WaitAudit ? null : IsHaveQuestion; //public UserSimpleInfo DoctorUser { get; set; } //public UserSimpleInfo MedicalManagerUser { get; set; } diff --git a/IRaCIS.Core.Application/Service/QC/_MapConfig.cs b/IRaCIS.Core.Application/Service/QC/_MapConfig.cs index 16b0d4ba6..d9c9aa987 100644 --- a/IRaCIS.Core.Application/Service/QC/_MapConfig.cs +++ b/IRaCIS.Core.Application/Service/QC/_MapConfig.cs @@ -25,7 +25,8 @@ namespace IRaCIS.Core.Application.Service .ForMember(d => d.QCProcessEnum, u => u.MapFrom(s => s.Trial.QCProcessEnum)) .ForMember(d => d.SubjectCode, u => u.MapFrom(s => s.Subject.Code)) .ForMember(d => d.SubmitUserName, u => u.MapFrom(s => s.SubmitUser.FullName)) - + .ForMember(d => d.ClinicalInformationTransmissionEnum, u => u.MapFrom(s => s.Trial.ClinicalInformationTransmissionEnum)) + .ForMember(d => d.IsHaveClinicalData, u => u.MapFrom(t => t.IsBaseLine ? t.PreviousHistoryList.Any() || t.PreviousOtherList.Any() || t.ReadingClinicalDataList.Any(x => x.ClinicalDataTrialSet.UploadRole == Domain.Share.UploadRole.CRC && x.ReadingClinicalDataPDFList.Count > 0) || t.PreviousSurgeryList.Any() : false)) @@ -116,7 +117,7 @@ namespace IRaCIS.Core.Application.Service .ForMember(d => d.SubjectCode, u => u.MapFrom(s => s.Subject.Code)) .ForMember(d => d.TrialSiteCode, u => u.MapFrom(s => s.TrialSite.TrialSiteCode)) - .ForMember(d => d.CheckDialogStr, u => u.MapFrom(t => string.Join(" | ", t.CheckChallengeDialogList.OrderBy(t => t.CreateTime).Select(c => c.CreateUser.UserName + " " + c.CreateTime.ToString("yyyy-MM-dd HH:mm:ss") + " :" + c.TalkContent)))) + .ForMember(d => d.CheckDialogStr, u => u.MapFrom(t => string.Join("\n\n", t.CheckChallengeDialogList.OrderBy(t => t.CreateTime).Select(c => c.CreateUser.UserName + " (" + c.CreateTime.ToString("yyyy-MM-dd HH:mm:ss") + ") :" + c.TalkContent)))) .ForMember(d => d.ModalityList, c => c.MapFrom(s => (s.NoneDicomStudyList.Select(t => t.Modality) .Union(s.StudyList.Select(k => k.ModalityForEdit))).Distinct())) @@ -154,7 +155,7 @@ 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('|', 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))) ); CreateMap() .ForMember(o => o.TrialReadingCriterionName, t => t.MapFrom(u => u.TrialReadingCriterion.CriterionName)) diff --git a/IRaCIS.Core.Application/Service/TrialSiteUser/DTO/PersonalWorkstationViewModel.cs b/IRaCIS.Core.Application/Service/TrialSiteUser/DTO/PersonalWorkstationViewModel.cs index bb5102c50..c833214ef 100644 --- a/IRaCIS.Core.Application/Service/TrialSiteUser/DTO/PersonalWorkstationViewModel.cs +++ b/IRaCIS.Core.Application/Service/TrialSiteUser/DTO/PersonalWorkstationViewModel.cs @@ -2,6 +2,7 @@ using System.ComponentModel.DataAnnotations; using System.Web; using IRaCIS.Application.Contracts; +using IRaCIS.Core.Application.Helper; using IRaCIS.Core.Domain.Share; namespace IRaCIS.Core.Application.Contracts @@ -289,6 +290,7 @@ namespace IRaCIS.Core.Application.Contracts public string Sponsor { get; set; } + [DictionaryTranslateAttribute("TrialStatusEnum")] public string TrialStatusStr { get; set; } #region PM diff --git a/IRaCIS.Core.Domain/_Config/_StaticData.cs b/IRaCIS.Core.Domain/_Config/_StaticData.cs index fd2c73df6..3b0f84623 100644 --- a/IRaCIS.Core.Domain/_Config/_StaticData.cs +++ b/IRaCIS.Core.Domain/_Config/_StaticData.cs @@ -208,6 +208,8 @@ public static class StaticData /// public static class Export { + public const string TrialList_Export = "TrialList_Export"; + public const string TrialTrainingRecordList_Export = "TrialTrainingRecordList_Export"; public const string TrialSiteUserList_Export = "TrialSiteUserList_Export"; From 74098641f68787dd3b0140c7a5a4ebcb8dc3fd64 Mon Sep 17 00:00:00 2001 From: he <109787524@qq.com> Date: Wed, 7 Aug 2024 17:25:58 +0800 Subject: [PATCH 200/251] =?UTF-8?q?=E4=BC=91=E6=81=AF=E6=97=B6=E9=97=B4?= =?UTF-8?q?=E6=94=B9=E5=88=B0=E9=85=8D=E7=BD=AE=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.API/appsettings.Event_IRC.json | 6 +++++- IRaCIS.Core.API/appsettings.Prod_IRC.json | 4 +++- IRaCIS.Core.API/appsettings.Test_IRC.json | 5 ++++- IRaCIS.Core.API/appsettings.US_Prod_IRC.json | 5 ++++- IRaCIS.Core.API/appsettings.US_Test_IRC.json | 5 ++++- IRaCIS.Core.API/appsettings.US_Uat_IRC.json | 3 +++ IRaCIS.Core.API/appsettings.Uat_IRC.json | 5 ++++- .../Service/Management/UserService.cs | 2 +- IRaCIS.Core.Domain/_Config/_AppSettings.cs | 11 +++++++++++ IRaCIS.Core.Infra.EFCore/Common/AuditingData.cs | 1 - 10 files changed, 39 insertions(+), 8 deletions(-) diff --git a/IRaCIS.Core.API/appsettings.Event_IRC.json b/IRaCIS.Core.API/appsettings.Event_IRC.json index 216571d78..fa5674cb6 100644 --- a/IRaCIS.Core.API/appsettings.Event_IRC.json +++ b/IRaCIS.Core.API/appsettings.Event_IRC.json @@ -47,7 +47,11 @@ "ContinuousReadingTimeMin": 120, - "ReadingRestTimeMin": 10 + "ReadingRestTimeMin": 10, + + "IsNeedChangePassWord": true, + + "ChangePassWordDays": 90 }, "SystemEmailSendConfig": { "Port": 465, diff --git a/IRaCIS.Core.API/appsettings.Prod_IRC.json b/IRaCIS.Core.API/appsettings.Prod_IRC.json index 7b2b1d376..c3dd1e8a2 100644 --- a/IRaCIS.Core.API/appsettings.Prod_IRC.json +++ b/IRaCIS.Core.API/appsettings.Prod_IRC.json @@ -49,8 +49,10 @@ "ContinuousReadingTimeMin": 120, - "ReadingRestTimeMin": 10 + "ReadingRestTimeMin": 10, + "IsNeedChangePassWord": true, + "ChangePassWordDays": 90 }, "SystemEmailSendConfig": { diff --git a/IRaCIS.Core.API/appsettings.Test_IRC.json b/IRaCIS.Core.API/appsettings.Test_IRC.json index c397ac52d..377d97bc2 100644 --- a/IRaCIS.Core.API/appsettings.Test_IRC.json +++ b/IRaCIS.Core.API/appsettings.Test_IRC.json @@ -65,7 +65,10 @@ "ContinuousReadingTimeMin": 120, - "ReadingRestTimeMin": 10 + "ReadingRestTimeMin": 10, + "IsNeedChangePassWord": true, + + "ChangePassWordDays": 90 }, "SystemEmailSendConfig": { diff --git a/IRaCIS.Core.API/appsettings.US_Prod_IRC.json b/IRaCIS.Core.API/appsettings.US_Prod_IRC.json index 0c7ed8158..b2d650a67 100644 --- a/IRaCIS.Core.API/appsettings.US_Prod_IRC.json +++ b/IRaCIS.Core.API/appsettings.US_Prod_IRC.json @@ -63,7 +63,10 @@ "ContinuousReadingTimeMin": 120, - "ReadingRestTimeMin": 10 + "ReadingRestTimeMin": 10, + "IsNeedChangePassWord": true, + + "ChangePassWordDays": 90 }, "SystemEmailSendConfig": { diff --git a/IRaCIS.Core.API/appsettings.US_Test_IRC.json b/IRaCIS.Core.API/appsettings.US_Test_IRC.json index 67d4b1fe7..a0eed7266 100644 --- a/IRaCIS.Core.API/appsettings.US_Test_IRC.json +++ b/IRaCIS.Core.API/appsettings.US_Test_IRC.json @@ -69,7 +69,10 @@ "ContinuousReadingTimeMin": 120, - "ReadingRestTimeMin": 10 + "ReadingRestTimeMin": 10, + "IsNeedChangePassWord": true, + + "ChangePassWordDays": 90 }, "SystemEmailSendConfig": { diff --git a/IRaCIS.Core.API/appsettings.US_Uat_IRC.json b/IRaCIS.Core.API/appsettings.US_Uat_IRC.json index 8697adda1..f16b2410d 100644 --- a/IRaCIS.Core.API/appsettings.US_Uat_IRC.json +++ b/IRaCIS.Core.API/appsettings.US_Uat_IRC.json @@ -62,6 +62,9 @@ "ContinuousReadingTimeMin": 120, "ReadingRestTimeMin": 10, + "IsNeedChangePassWord": true, + + "ChangePassWordDays": 90, "OpenLoginMFA": true }, diff --git a/IRaCIS.Core.API/appsettings.Uat_IRC.json b/IRaCIS.Core.API/appsettings.Uat_IRC.json index 923001d1a..a107b1342 100644 --- a/IRaCIS.Core.API/appsettings.Uat_IRC.json +++ b/IRaCIS.Core.API/appsettings.Uat_IRC.json @@ -56,7 +56,10 @@ "ContinuousReadingTimeMin": 120, - "ReadingRestTimeMin": 10 + "ReadingRestTimeMin": 10, + "IsNeedChangePassWord": true, + + "ChangePassWordDays": 90 }, "SystemEmailSendConfig": { diff --git a/IRaCIS.Core.Application/Service/Management/UserService.cs b/IRaCIS.Core.Application/Service/Management/UserService.cs index a719dbab3..759578cd3 100644 --- a/IRaCIS.Core.Application/Service/Management/UserService.cs +++ b/IRaCIS.Core.Application/Service/Management/UserService.cs @@ -794,7 +794,7 @@ namespace IRaCIS.Application.Services } //超过90天没修改密码 - if (loginUser.LastChangePassWordTime != null && DateTime.Now.AddDays(-90) > loginUser.LastChangePassWordTime.Value) + if (_verifyConfig.CurrentValue.IsNeedChangePassWord&& loginUser.LastChangePassWordTime != null && DateTime.Now.AddDays(-_verifyConfig.CurrentValue.ChangePassWordDays) > loginUser.LastChangePassWordTime.Value) { loginUser.LoginState = 1; } diff --git a/IRaCIS.Core.Domain/_Config/_AppSettings.cs b/IRaCIS.Core.Domain/_Config/_AppSettings.cs index b4c890257..d4284b22e 100644 --- a/IRaCIS.Core.Domain/_Config/_AppSettings.cs +++ b/IRaCIS.Core.Domain/_Config/_AppSettings.cs @@ -36,6 +36,17 @@ namespace IRaCIS.Core.Domain.Share /// public int ReadingRestTimeMin { get; set; } + + /// + /// 是否需要修改密码 + /// + public bool IsNeedChangePassWord { get; set; } + + /// + /// 修改密码的天数 + /// + public int ChangePassWordDays { get; set; } + } public class SystemEmailSendConfig diff --git a/IRaCIS.Core.Infra.EFCore/Common/AuditingData.cs b/IRaCIS.Core.Infra.EFCore/Common/AuditingData.cs index ec1e86542..86937cd19 100644 --- a/IRaCIS.Core.Infra.EFCore/Common/AuditingData.cs +++ b/IRaCIS.Core.Infra.EFCore/Common/AuditingData.cs @@ -2870,7 +2870,6 @@ namespace IRaCIS.Core.Infra.EFCore.Common { Unit = (ValueUnit)int.Parse(x.Code), - UnitName = x.Value.ToString(), }).ToList(); //获取表格问题名称 组合成数组 From 168c7447bba032919c1b4436f07f3faf7365c3ee Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Thu, 8 Aug 2024 10:14:36 +0800 Subject: [PATCH 201/251] =?UTF-8?q?=E4=BF=AE=E6=94=B9bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.Application/Service/Management/_MapConfig.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/IRaCIS.Core.Application/Service/Management/_MapConfig.cs b/IRaCIS.Core.Application/Service/Management/_MapConfig.cs index 5619e7127..d9ec78199 100644 --- a/IRaCIS.Core.Application/Service/Management/_MapConfig.cs +++ b/IRaCIS.Core.Application/Service/Management/_MapConfig.cs @@ -131,7 +131,7 @@ namespace IRaCIS.Core.Application.Service .ForMember(d => d.ExperimentName, c => c.MapFrom(t => t.Trial.ExperimentName)) .ForMember(d => d.TrialCode, c => c.MapFrom(t => t.Trial.TrialCode)) .ForMember(d => d.SubjectCode, c => c.MapFrom(t => t.Subject.Code)) - .ForMember(d => d.TrialSiteCode, c => c.MapFrom(t => t.TrialSite.TrialSiteCode)) + .ForMember(d => d.TrialSiteCode, c => c.MapFrom(t => t.VisitTask.IsAnalysisCreate? t.VisitTask.BlindTrialSiteCode: t.TrialSite.TrialSiteCode)) .ForMember(d => d.SubjectVisitName, c => c.MapFrom(t => t.SubjectVisit.VisitName)) .ForMember(d => d.FeedBackUserName, c => c.MapFrom(t => t.CreateUser.UserName)) .ForMember(d => d.FeedBackFullName, c => c.MapFrom(t => t.CreateUser.FullName)) From ca6e96929f93589a94e3d189f5f59b84fd5913f4 Mon Sep 17 00:00:00 2001 From: he <109787524@qq.com> Date: Thu, 8 Aug 2024 10:31:14 +0800 Subject: [PATCH 202/251] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=BC=80=E5=A7=8B?= =?UTF-8?q?=E9=98=85=E7=89=87=E6=97=B6=E9=97=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Service/Reading/ReadingImageTask/ReadingImageTaskService.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/IRaCIS.Core.Application/Service/Reading/ReadingImageTask/ReadingImageTaskService.cs b/IRaCIS.Core.Application/Service/Reading/ReadingImageTask/ReadingImageTaskService.cs index 3cae0656b..c27c2e8bd 100644 --- a/IRaCIS.Core.Application/Service/Reading/ReadingImageTask/ReadingImageTaskService.cs +++ b/IRaCIS.Core.Application/Service/Reading/ReadingImageTask/ReadingImageTaskService.cs @@ -2968,7 +2968,7 @@ namespace IRaCIS.Application.Services task.SubjectCode = await _subjectRepository.Where(x => x.Id == task.SubjectId).Select(x => x.Code).FirstNotNullAsync(); } - await _visitTaskRepository.BatchUpdateNoTrackingAsync(x => x.Id == task.VisitTaskId && x.FirstReadingTime == null, x => new VisitTask() + await _visitTaskRepository.BatchUpdateNoTrackingAsync(x => x.Id == task.VisitTaskId&&x.TaskState==TaskState.Effect&&x.ReadingTaskState!=ReadingTaskState.HaveSigned && x.FirstReadingTime == null, x => new VisitTask() { FirstReadingTime = DateTime.Now, }); From 7894a4991cd2f26ee0febe2646e12f8f4041d8ff Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Thu, 8 Aug 2024 13:24:17 +0800 Subject: [PATCH 203/251] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=85=A8=E5=B1=80?= =?UTF-8?q?=E5=AF=BC=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Service/Common/ExcelExportService.cs | 22 ++++++++++++++----- .../Service/QC/DTO/QCListViewModel.cs | 5 ++++- .../Service/QC/_MapConfig.cs | 2 +- 3 files changed, 21 insertions(+), 8 deletions(-) diff --git a/IRaCIS.Core.Application/Service/Common/ExcelExportService.cs b/IRaCIS.Core.Application/Service/Common/ExcelExportService.cs index bea2328b0..acd44980c 100644 --- a/IRaCIS.Core.Application/Service/Common/ExcelExportService.cs +++ b/IRaCIS.Core.Application/Service/Common/ExcelExportService.cs @@ -1476,19 +1476,29 @@ namespace IRaCIS.Core.Application.Service.Common ).OrderByDescending(t => t.VisitTaskNum).FirstOrDefault()?.JudgeArmEnum == item.ArmEnum ? true : false; } - //全局裁判了,选择了那个全局,那么对应全局下面的访视 设置裁判标记 + + //访视、全局列表中过滤出访视进行处理 foreach (var item in resultList.Where(t => t.ReadingCategory == ReadingCategory.Visit)) { + //全局裁判了,选择了那个全局,那么对应全局下面的访视 设置裁判标记 var selectJudegeGlobalList = resultList.Where(t => t.ReadingCategory == ReadingCategory.Global && t.IsGenerateJudge == true).ToList(); - //全局修改了答案,那么给访视上赋值全局的结果 并且取的是最后的全局 - var existGlobalAnswer = selectJudegeGlobalList.Where(t => t.SubjectCode == item.SubjectCode).SelectMany(t => t.GlobalTaskAnswerList).Where(t => t.VisitTaskId == item.Id) - .OrderByDescending(t => t.GlobalTaskVisitNum).FirstOrDefault()?.Answer; + if (selectJudegeGlobalList.Count == 0) + { + //生成了裁判,但是裁判没有做 - item.OverallTumorEvaluationResult = string.IsNullOrEmpty(existGlobalAnswer) ? item.OverallTumorEvaluationResult : existGlobalAnswer; + item.IsGenerateJudge = null; + } + else + { - item.IsGenerateJudge = true; + if(selectJudegeGlobalList.Where(t => t.SubjectCode == item.SubjectCode).SelectMany(t => t.GlobalTaskAnswerList).Any(t => t.VisitTaskId == item.Id)) + { + item.IsGenerateJudge = true; + } + + } } diff --git a/IRaCIS.Core.Application/Service/QC/DTO/QCListViewModel.cs b/IRaCIS.Core.Application/Service/QC/DTO/QCListViewModel.cs index 7740b145b..e011609f2 100644 --- a/IRaCIS.Core.Application/Service/QC/DTO/QCListViewModel.cs +++ b/IRaCIS.Core.Application/Service/QC/DTO/QCListViewModel.cs @@ -935,6 +935,9 @@ namespace IRaCIS.Core.Application.Contracts public string SubjectCode { get; set; } = String.Empty; public Guid Id { get; set; } + + public Guid DoctorUserId { get; set; } + public string TaskName { get; set; } public string TaskBlindName { get; set; } @@ -964,7 +967,7 @@ namespace IRaCIS.Core.Application.Contracts //根据裁判的任务结果 设置访视任务的这个字段 该字段表示 裁判认同该任务的结果 [DictionaryTranslateAttribute("YesOrNo")] - public bool IsGenerateJudge { get; set; } + public bool? IsGenerateJudge { get; set; } [JsonIgnore] diff --git a/IRaCIS.Core.Application/Service/QC/_MapConfig.cs b/IRaCIS.Core.Application/Service/QC/_MapConfig.cs index d9c9aa987..71f380b62 100644 --- a/IRaCIS.Core.Application/Service/QC/_MapConfig.cs +++ b/IRaCIS.Core.Application/Service/QC/_MapConfig.cs @@ -192,7 +192,7 @@ namespace IRaCIS.Core.Application.Service .ForMember(o => o.OverallTumorEvaluationResult, t => t.MapFrom(u => criterionType == CriterionType.RECIST1Point1 ?( u.SourceSubjectVisit.IsBaseLine==true ? u.ReadingTaskQuestionAnswerList.Where(c => c.ReadingQuestionTrial.QuestionType == QuestionType.ExistDisease).FirstOrDefault()!.Answer: - u.ReadingTaskQuestionAnswerList.Where(c => c.ReadingQuestionTrial.QuestionType == QuestionType.Tumor).FirstOrDefault()!.Answer) + u.ReadingTaskQuestionAnswerList.Where(c => c.ReadingQuestionTrial.QuestionType == QuestionType.Tumor).Select(t=>t.IsGlobalChange?t.GlobalChangeAnswer:t.Answer).FirstOrDefault()) : criterionType == CriterionType.PCWG3 ? u.ReadingTaskQuestionAnswerList.Where(c => c.ReadingQuestionTrial.QuestionType == QuestionType.SiteVisitForTumorEvaluation).FirstOrDefault()!.Answer : String.Empty )) From d8a0c80ca41e0fd34e86df0391c056ac575b1c05 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Thu, 8 Aug 2024 13:49:10 +0800 Subject: [PATCH 204/251] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=A8=A1=E6=9D=BF?= =?UTF-8?q?=E5=88=A0=E9=99=A4=EF=BC=8C=E5=AF=BC=E8=A1=A8=E6=98=BE=E7=A4=BA?= =?UTF-8?q?=E5=90=8D=E7=A7=B0=E5=9B=BD=E9=99=85=E5=93=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.Application/Service/Common/CommonDocumentService.cs | 2 +- IRaCIS.Core.Application/Service/Common/ExcelExportService.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/IRaCIS.Core.Application/Service/Common/CommonDocumentService.cs b/IRaCIS.Core.Application/Service/Common/CommonDocumentService.cs index 0171c67c2..59038b64f 100644 --- a/IRaCIS.Core.Application/Service/Common/CommonDocumentService.cs +++ b/IRaCIS.Core.Application/Service/Common/CommonDocumentService.cs @@ -119,7 +119,7 @@ namespace IRaCIS.Core.Application.Service var filePath = FileStoreHelper.GetPhysicalFilePath(_hostEnvironment, dbbeforeEntity.Path); - if (File.Exists(filePath)) + if (File.Exists(filePath) && dbbeforeEntity.Path!=addOrEditCommonDocument.Path) { File.Delete(filePath); } diff --git a/IRaCIS.Core.Application/Service/Common/ExcelExportService.cs b/IRaCIS.Core.Application/Service/Common/ExcelExportService.cs index acd44980c..e038ae84c 100644 --- a/IRaCIS.Core.Application/Service/Common/ExcelExportService.cs +++ b/IRaCIS.Core.Application/Service/Common/ExcelExportService.cs @@ -1440,7 +1440,7 @@ namespace IRaCIS.Core.Application.Service.Common list.Add(new ExportDocumentDes() { Code = StaticData.Export.PCWG3Point1DetailedOfEvaluatedLesion_Export, ExportCatogory = ExportCatogory.DetailedOfEvaluatedLesion }); } - var result = _repository.Where(t => list.Select(c => c.Code).Contains(t.Code)).Select(c => new ExportDocumentDes() { Code = c.Code, FileName = c.Name }).ToList(); + var result = _repository.Where(t => list.Select(c => c.Code).Contains(t.Code)).Select(c => new ExportDocumentDes() { Code = c.Code, FileName =_userInfo.IsEn_Us?c.Name:c.NameCN }).ToList(); foreach (var item in list) { From 7954bdeca8b8b3f3267a263df8acfefb3017a7a7 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Thu, 8 Aug 2024 14:39:53 +0800 Subject: [PATCH 205/251] =?UTF-8?q?=E8=84=91=E8=BD=AC=E7=A7=BB=20=20?= =?UTF-8?q?=E6=9C=AA=E5=88=86=E9=85=8D=E7=9A=84=E9=80=80=E5=9B=9E=E4=B9=9F?= =?UTF-8?q?=E5=A4=B1=E6=95=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SubjectCriteriaEvaluationService.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/IRaCIS.Core.Application/Service/Reading/AdditionalEvaluate/SubjectCriteriaEvaluationService.cs b/IRaCIS.Core.Application/Service/Reading/AdditionalEvaluate/SubjectCriteriaEvaluationService.cs index e6b07c261..82f19867c 100644 --- a/IRaCIS.Core.Application/Service/Reading/AdditionalEvaluate/SubjectCriteriaEvaluationService.cs +++ b/IRaCIS.Core.Application/Service/Reading/AdditionalEvaluate/SubjectCriteriaEvaluationService.cs @@ -442,9 +442,9 @@ namespace IRaCIS.Core.Application.Service join subjectCriteriaEvaluationVisitFilter in _subjectCriteriaEvaluationVisitFilterRepository .Where(t => t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId) - .WhereIf(inQuery.ImageDeterminationResultState != null, t => t.ImageDeterminationResultState == inQuery.ImageDeterminationResultState) - .WhereIf(inQuery.ImageFilterState != null, t => t.ImageFilterState == inQuery.ImageFilterState) - .WhereIf(inQuery.IsGeneratedTask != null, t => t.IsGeneratedTask == inQuery.IsGeneratedTask) + .WhereIf(inQuery.ImageDeterminationResultState != null, t => t.ImageDeterminationResultState == inQuery.ImageDeterminationResultState) + .WhereIf(inQuery.ImageFilterState != null, t => t.ImageFilterState == inQuery.ImageFilterState) + .WhereIf(inQuery.IsGeneratedTask != null, t => t.IsGeneratedTask == inQuery.IsGeneratedTask) on subjectVisit.Id equals subjectCriteriaEvaluationVisitFilter.SubjectVisitId //into d from subjectCriteriaEvaluationVisitFilter in d.DefaultIfEmpty() @@ -687,7 +687,7 @@ namespace IRaCIS.Core.Application.Service var subjectVisit = await _subjectVisitRepository.FirstOrDefaultAsync(t => t.Id == command.SubjectVisitId); //仅仅影响该标准自己的任务 - Expression> filterExpression = t => t.TrialId == command.TrialId && t.SubjectId == command.SubjectId && t.TaskState == TaskState.Effect && t.TaskAllocationState == TaskAllocationState.Allocated + Expression> filterExpression = t => t.TrialId == command.TrialId && t.SubjectId == command.SubjectId && t.TaskState == TaskState.Effect /*&& t.TaskAllocationState == TaskAllocationState.Allocated*/ && t.TrialReadingCriterionId == command.TrialReadingCriterionId; //有序 From fbbda8c0d1e39a9da738a4d6c3b2dd29e8dec774 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Thu, 8 Aug 2024 14:49:06 +0800 Subject: [PATCH 206/251] =?UTF-8?q?=E6=98=AF=E5=90=A6=E5=8F=AF=E4=BB=A5?= =?UTF-8?q?=E5=8F=96=E6=B6=88=E5=88=86=E9=85=8Dbug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.Application/Service/Allocation/_MapConfig.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/IRaCIS.Core.Application/Service/Allocation/_MapConfig.cs b/IRaCIS.Core.Application/Service/Allocation/_MapConfig.cs index 8ae10c42c..00dc9b3ef 100644 --- a/IRaCIS.Core.Application/Service/Allocation/_MapConfig.cs +++ b/IRaCIS.Core.Application/Service/Allocation/_MapConfig.cs @@ -104,7 +104,7 @@ namespace IRaCIS.Core.Application.Service CreateMap().IncludeBase() - .ForMember(o => o.IsHaveReading, t => t.MapFrom(u => u.Subject.SubjectVisitTaskList.Any(t => t.ReadingTaskState != ReadingTaskState.WaitReading && t.TrialReadingCriterionId==u.TrialReadingCriterionId && t.DoctorUserId==u.DoctorUserId))); + .ForMember(o => o.IsHaveReading, t => t.MapFrom(u => u.Subject.SubjectVisitTaskList.Any(t => t.ReadingTaskState != ReadingTaskState.WaitReading && t.TrialReadingCriterionId==u.TrialReadingCriterionId && t.DoctorUserId==u.DoctorUserId && t.TaskState == TaskState.Effect))); CreateMap(); From 202a3c26d19931b2112483cd8e4ecc16c2acb977 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Thu, 8 Aug 2024 14:53:29 +0800 Subject: [PATCH 207/251] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=8F=96=E6=B6=88?= =?UTF-8?q?=E5=88=86=E9=85=8D=E9=AA=8C=E8=AF=81=E7=94=9F=E6=95=88=E7=9A=84?= =?UTF-8?q?=E6=98=AF=E5=90=A6=E5=BC=80=E5=A7=8B=E9=98=85=E7=89=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.Application/Service/Allocation/VisitTaskService.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/IRaCIS.Core.Application/Service/Allocation/VisitTaskService.cs b/IRaCIS.Core.Application/Service/Allocation/VisitTaskService.cs index 4898ac25c..f9c504632 100644 --- a/IRaCIS.Core.Application/Service/Allocation/VisitTaskService.cs +++ b/IRaCIS.Core.Application/Service/Allocation/VisitTaskService.cs @@ -290,7 +290,7 @@ namespace IRaCIS.Core.Application.Service.Allocation { foreach (var command in cancelCommand.CancelList.Where(t => t.IsCancelAssign)) { - if (await _visitTaskRepository.AnyAsync(t => t.TrialReadingCriterionId == cancelCommand.TrialReadingCriterionId && t.SubjectId == command.SubjectId && t.DoctorUserId == command.DoctorUserId && t.ArmEnum == command.ArmEnum && t.ReadingTaskState != ReadingTaskState.WaitReading)) + if (await _visitTaskRepository.AnyAsync(t => t.TaskState==TaskState.Effect && t.TrialReadingCriterionId == cancelCommand.TrialReadingCriterionId && t.SubjectId == command.SubjectId && t.DoctorUserId == command.DoctorUserId && t.ArmEnum == command.ArmEnum && t.ReadingTaskState != ReadingTaskState.WaitReading)) { //---当前医生已开始做该Subject 该标准的任务,不允许取消分配 throw new BusinessValidationFailedException(_localizer["VisitTask_DoctorConfigNotFound"]); From cebcf908f97a07a830f832879c776e3c14b6e32a Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Fri, 9 Aug 2024 13:12:05 +0800 Subject: [PATCH 208/251] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E8=A3=81=E5=88=A4?= =?UTF-8?q?=E6=A0=87=E4=BB=B7=E5=88=A4=E5=AE=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Helper/InternationalizationHelper.cs | 1 - .../IRaCIS.Core.Application.csproj | 18 +- .../IRaCIS.Core.Application.xml | 12 +- .../Service/Common/ExcelExportService.cs | 178 +++++++++++++----- .../Service/Management/UserService.cs | 1 - .../Service/QC/DTO/QCListViewModel.cs | 8 +- .../Service/QC/_MapConfig.cs | 3 +- .../ReadingClinicalDataService.cs | 1 - 8 files changed, 157 insertions(+), 65 deletions(-) diff --git a/IRaCIS.Core.Application/Helper/InternationalizationHelper.cs b/IRaCIS.Core.Application/Helper/InternationalizationHelper.cs index 11159c5cd..eaa357c55 100644 --- a/IRaCIS.Core.Application/Helper/InternationalizationHelper.cs +++ b/IRaCIS.Core.Application/Helper/InternationalizationHelper.cs @@ -9,7 +9,6 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; -using static BeetleX.Redis.Commands.HSCAN; using static IRaCIS.Core.Application.Service.Common.SystemMonitor; namespace IRaCIS.Core.Application.Helper diff --git a/IRaCIS.Core.Application/IRaCIS.Core.Application.csproj b/IRaCIS.Core.Application/IRaCIS.Core.Application.csproj index 72dc549f8..ab2113cba 100644 --- a/IRaCIS.Core.Application/IRaCIS.Core.Application.csproj +++ b/IRaCIS.Core.Application/IRaCIS.Core.Application.csproj @@ -63,10 +63,10 @@ - + + - - + @@ -74,22 +74,22 @@ - - - + + + - + true - + - + diff --git a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml index ef44e414d..2b89f02a7 100644 --- a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml +++ b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml @@ -543,9 +543,19 @@ + + + 项目列表导出---new + + + + + + + - getDocumentConfirmList 培训记录导出 + getDocumentConfirmList 培训记录导出--new diff --git a/IRaCIS.Core.Application/Service/Common/ExcelExportService.cs b/IRaCIS.Core.Application/Service/Common/ExcelExportService.cs index e038ae84c..f3c6f7f5b 100644 --- a/IRaCIS.Core.Application/Service/Common/ExcelExportService.cs +++ b/IRaCIS.Core.Application/Service/Common/ExcelExportService.cs @@ -16,6 +16,7 @@ using MiniExcelLibs; using MiniExcelLibs.OpenXml; using NPOI.HPSF; using NPOI.HSSF.UserModel; +using NPOI.SS.Formula.Functions; using NPOI.XSSF.UserModel; using System; using System.Collections.Generic; @@ -615,9 +616,9 @@ namespace IRaCIS.Core.Application.Service.Common .WhereIf(inQuery.TrialSiteId != null, t => t.TrialSiteId == inQuery.TrialSiteId) // CRC 只负责他管理site的受试者 - .WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.CRA, t => t.TrialSite.CRCUserList.Any(t => t.UserId == _userInfo.Id)) + .WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.CRA, t => t.TrialSite.CRCUserList.Any(t => t.UserId == _userInfo.Id)) .ProjectTo(_mapper.ConfigurationProvider) - .WhereIf(inQuery.IsMissingImages == true, t => t.MissingSubmmitCount> 0) + .WhereIf(inQuery.IsMissingImages == true, t => t.MissingSubmmitCount > 0) .WhereIf(inQuery.IsMissingImages == false, t => t.MissingSubmmitCount == 0) ; @@ -1041,7 +1042,7 @@ namespace IRaCIS.Core.Application.Service.Common [FromServices] IRepository _trialRepository) { var list = await _repository.Where(t => t.TrialId == queryVisitTask.TrialId && t.IsAnalysisCreate == false) - //.Where(t => t.IsAnalysisCreate == false && t.DoctorUserId != null) + //.Where(t => t.IsAnalysisCreate == false && t.DoctorUserId != null) .WhereIf(queryVisitTask.TaskState != null, t => t.TaskState == queryVisitTask.TaskState) .WhereIf(queryVisitTask.ArmEnum != null, t => t.ArmEnum == queryVisitTask.ArmEnum) @@ -1440,7 +1441,7 @@ namespace IRaCIS.Core.Application.Service.Common list.Add(new ExportDocumentDes() { Code = StaticData.Export.PCWG3Point1DetailedOfEvaluatedLesion_Export, ExportCatogory = ExportCatogory.DetailedOfEvaluatedLesion }); } - var result = _repository.Where(t => list.Select(c => c.Code).Contains(t.Code)).Select(c => new ExportDocumentDes() { Code = c.Code, FileName =_userInfo.IsEn_Us?c.Name:c.NameCN }).ToList(); + var result = _repository.Where(t => list.Select(c => c.Code).Contains(t.Code)).Select(c => new ExportDocumentDes() { Code = c.Code, FileName = _userInfo.IsEn_Us ? c.Name : c.NameCN }).ToList(); foreach (var item in list) { @@ -1451,73 +1452,156 @@ namespace IRaCIS.Core.Application.Service.Common public List DealJudgeMark(ArbitrationRule arbitrationRule, IEnumerable list) where T : OverallTumorEvaluationExport { - //处理裁判标记 - - var resultList = list.Where(t => t.ReadingCategory != ReadingCategory.Judge).ToList(); + //处理访视任务的裁判标记 + 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 resultList) + foreach (var item in resultExceptJudgeList) { - item.IsGenerateJudge = list.FirstOrDefault(t => t.ReadingCategory == ReadingCategory.Judge && t.SubjectCode == item.SubjectCode + item.IsGenerateJudge = judegeList.FirstOrDefault(t => t.SubjectCode == item.SubjectCode && (t.VisitTaskNum - ReadingCommon.TaskNumDic[ReadingCategory.Judge]) == item.VisitTaskNum)?.JudgeArmEnum == item.ArmEnum ? true : false; } + //如果没有产生裁判,默认选择R1 + + //找到没有裁判的访视任务 + var notJudgeList = resultExceptJudgeList.GroupBy(t => new { t.SubjectCode, t.VisitTaskNum }).Where(g => g.All(t => t.IsGenerateJudge == false)).Select(g => new { g.Key.SubjectCode, g.Key.VisitTaskNum }).ToList(); + + foreach (var item in resultExceptJudgeList) + { + if (notJudgeList.Any(t => t.SubjectCode == item.SubjectCode && t.VisitTaskNum == item.VisitTaskNum) && item.ArmEnum == Arm.DoubleReadingArm1) + { + item.IsGenerateJudge = true; + } + } + } if (arbitrationRule == ArbitrationRule.Reading) { - //先确定裁判选定的是谁 - foreach (var item in resultList) + //处理访视裁判标记 + foreach (var visitItem in resultExceptJudgeList.Where(t => t.ReadingCategory == ReadingCategory.Visit)) { - //以最后一次裁判为准 找到最大的裁判的裁判选择的Arm,相同就设置裁判标记 - item.IsGenerateJudge = list.Where(t => t.ReadingCategory == ReadingCategory.Judge && t.SubjectCode == item.SubjectCode && t.VisitTaskNum > item.VisitTaskNum - ).OrderByDescending(t => t.VisitTaskNum).FirstOrDefault()?.JudgeArmEnum == item.ArmEnum ? true : false; + //默认设置为false 只处理为true 和 空的情况 + visitItem.IsGenerateJudge = false; - } - - //访视、全局列表中过滤出访视进行处理 - foreach (var item in resultList.Where(t => t.ReadingCategory == ReadingCategory.Visit)) - { - //全局裁判了,选择了那个全局,那么对应全局下面的访视 设置裁判标记 - - var selectJudegeGlobalList = resultList.Where(t => t.ReadingCategory == ReadingCategory.Global && t.IsGenerateJudge == true).ToList(); - - if (selectJudegeGlobalList.Count == 0) + if (judegeList.Count > 0) { - //生成了裁判,但是裁判没有做 - item.IsGenerateJudge = null; + var maxFinishedJudge = judegeList.Where(t => t.ReadingTaskState == ReadingTaskState.HaveSigned).FirstOrDefault(); + + var maxNotFinishedJudge = judegeList.Where(t => t.ReadingTaskState != ReadingTaskState.HaveSigned).FirstOrDefault(); + + if (maxFinishedJudge == null && maxNotFinishedJudge != null) + { + //仅有一个未完成的全局裁判,那么都是null + if (visitItem.VisitTaskNum < maxNotFinishedJudge.VisitTaskNum) + { + visitItem.IsGenerateJudge = null; + } + } + else if (maxFinishedJudge != null && maxNotFinishedJudge == null) + { + //全局裁判都完成了,那么以最后一次裁判选择的为准 + + if (visitItem.ArmEnum == maxFinishedJudge.JudgeArmEnum && visitItem.VisitTaskNum < maxFinishedJudge.VisitTaskNum) + { + visitItem.IsGenerateJudge = true; + } + + else if (visitItem.ArmEnum == Arm.DoubleReadingArm1) + { + visitItem.IsGenerateJudge = true; + } + } + else + { + //两个都不为null 肯定是不同的裁判 + + //在完成裁判之后的,和未完成裁判之前的 + if (visitItem.VisitTaskNum < maxNotFinishedJudge.VisitTaskNum && visitItem.VisitTaskNum > maxFinishedJudge.VisitTaskNum) + { + visitItem.IsGenerateJudge = null; + } + + else if (visitItem.ArmEnum == maxFinishedJudge.JudgeArmEnum && visitItem.VisitTaskNum < maxFinishedJudge.VisitTaskNum) + { + visitItem.IsGenerateJudge = true; + } + + else if (visitItem.ArmEnum == Arm.DoubleReadingArm1) + { + visitItem.IsGenerateJudge = true; + } + + } } else { - - if(selectJudegeGlobalList.Where(t => t.SubjectCode == item.SubjectCode).SelectMany(t => t.GlobalTaskAnswerList).Any(t => t.VisitTaskId == item.Id)) + //不存在裁判 将R1设置 + if (visitItem.ArmEnum == Arm.DoubleReadingArm1) { - item.IsGenerateJudge = true; + visitItem.IsGenerateJudge = true; } - - } - } + } + #region 全局的维度考虑 - } + //// 该阅片人 subject 已完成的最大的全局(全局都是已完成的任务,裁判可能完成了,可能没完成) + //var subjectMaxGlobal = resultExceptJudgeList.Where(t => t.ReadingCategory == ReadingCategory.Global && t.SubjectCode == item.SubjectCode && t.ArmEnum == item.ArmEnum).OrderByDescending(t => t.VisitTaskNum).FirstOrDefault(); - //如果没有产生裁判,默认选择R1 + ////没有全局 + //if (subjectMaxGlobal == null) + //{ + // //这个时候肯定没有裁判 默认选择R1 - //找到没有裁判的访视任务 - var notJudgeList = resultList.GroupBy(t => new { t.SubjectCode, t.VisitTaskNum }).Where(g => g.All(t => t.IsGenerateJudge == false)).Select(g => new { g.Key.SubjectCode, g.Key.VisitTaskNum }).ToList(); + // if (item.ArmEnum == Arm.DoubleReadingArm1) + // { + // item.IsGenerateJudge = true; + // } - foreach (var item in resultList) - { - if (notJudgeList.Any(t => t.SubjectCode == item.SubjectCode && t.VisitTaskNum == item.VisitTaskNum) && item.ArmEnum == Arm.DoubleReadingArm1) - { - item.IsGenerateJudge = true; + + //} + ////有全局 + //else + //{ + // //判断当前受试者已完成的最大的全局是否有裁判 + // var existSubjectMaxGlobalJudge = judegeList.Where(t => t.SubjectCode == item.SubjectCode && t.VisitTaskNum - ReadingCommon.TaskNumDic[ReadingCategory.Judge] == subjectMaxGlobal.VisitTaskNum).FirstOrDefault(); + + // //最大的全局没有裁判(有一个做完了,有一个没做,或者都做完了,没产生裁判) + // if (existSubjectMaxGlobalJudge == null) + // { + // //找到最大的全局裁判 + // var maxJudgedGlobal= judegeList.Where(t => t.SubjectCode == item.SubjectCode ).OrderByDescending(t => t.VisitTaskNum).FirstOrDefault(); + + + // } + // else + // { + // //将该裁判选择的全局的阅片人之前的裁判标记都设置为是 + + // //是否是裁判选择的 + // if (item.ArmEnum == existSubjectMaxGlobalJudge.JudgeArmEnum) + // { + // //是否是裁判选择之前的 + // if (item.VisitTaskNum < existSubjectMaxGlobalJudge.VisitTaskNum) + // { + // item.IsGenerateJudge = true; + + // } + // } + + // } + + //} + + #endregion } } - - return resultList; + return resultExceptJudgeList; } @@ -1549,8 +1633,10 @@ namespace IRaCIS.Core.Application.Service.Common throw new Exception(_localizer["ExcelExport_UnsupportedExport"]); } - var list = await _repository.Where(t => t.TrialId == queryVisitTask.TrialId && t.TaskState == TaskState.Effect && t.IsAnalysisCreate == false && t.ReadingTaskState == ReadingTaskState.HaveSigned) + var list = await _repository.Where(t => t.TrialId == queryVisitTask.TrialId && t.IsAnalysisCreate == false && t.TaskState == TaskState.Effect) + //访视和全局查询已签名完成的,裁判可以是未签名,未完成的 + .Where(t => (t.ReadingTaskState == ReadingTaskState.HaveSigned && (t.ReadingCategory == ReadingCategory.Visit || t.ReadingCategory == ReadingCategory.Global)) || (t.ReadingCategory == ReadingCategory.Judge)) //.WhereIf(queryVisitTask.SubjectId != null, t => t.SubjectId == queryVisitTask.SubjectId) //.WhereIf(queryVisitTask.TaskState != null, t => t.TaskState == queryVisitTask.TaskState) //.WhereIf(queryVisitTask.IsSelfAnalysis != null, t => t.IsSelfAnalysis == queryVisitTask.IsSelfAnalysis) @@ -1677,10 +1763,6 @@ namespace IRaCIS.Core.Application.Service.Common var query = _repository.Where(t => t.TrialId == queryVisitTask.TrialId && t.TaskState == TaskState.Effect && t.IsAnalysisCreate == false && t.ReadingTaskState == ReadingTaskState.HaveSigned) - //.WhereIf(queryVisitTask.SubjectId != null, t => t.SubjectId == queryVisitTask.SubjectId) - //.WhereIf(queryVisitTask.TaskState != null, t => t.TaskState == queryVisitTask.TaskState) - //.WhereIf(queryVisitTask.IsSelfAnalysis != null, t => t.IsSelfAnalysis == queryVisitTask.IsSelfAnalysis) - .WhereIf(queryVisitTask.TrialReadingCriterionId != null, t => t.TrialReadingCriterionId == queryVisitTask.TrialReadingCriterionId) .WhereIf(queryVisitTask.TrialSiteId != null, t => t.Subject.TrialSiteId == queryVisitTask.TrialSiteId) diff --git a/IRaCIS.Core.Application/Service/Management/UserService.cs b/IRaCIS.Core.Application/Service/Management/UserService.cs index 759578cd3..795cb8553 100644 --- a/IRaCIS.Core.Application/Service/Management/UserService.cs +++ b/IRaCIS.Core.Application/Service/Management/UserService.cs @@ -16,7 +16,6 @@ using EasyCaching.Core; using IRaCIS.Core.Application.Contracts; using LoginReturnDTO = IRaCIS.Application.Contracts.LoginReturnDTO; using IRaCIS.Core.Application.Auth; -using BeetleX.Redis.Commands; using IRaCIS.Core.Domain.Models; using IRaCIS.Core.Application.Helper; diff --git a/IRaCIS.Core.Application/Service/QC/DTO/QCListViewModel.cs b/IRaCIS.Core.Application/Service/QC/DTO/QCListViewModel.cs index e011609f2..d5981a4a3 100644 --- a/IRaCIS.Core.Application/Service/QC/DTO/QCListViewModel.cs +++ b/IRaCIS.Core.Application/Service/QC/DTO/QCListViewModel.cs @@ -950,6 +950,8 @@ namespace IRaCIS.Core.Application.Contracts public Arm ArmEnum { get; set; } public string UserName { get; set; } + public ReadingTaskState ReadingTaskState { get; set; } + public ReadingCategory ReadingCategory { get; set; } [DictionaryTranslateAttribute("ExistDisease", CriterionType.RECIST1Point1, nameof(OverallTumorEvaluationExport.IsBaseline), "true")] @@ -964,15 +966,17 @@ namespace IRaCIS.Core.Application.Contracts public Arm? JudgeArmEnum { get; set; } + //public Guid? JudgeResultTaskId { get; set; } + //根据裁判的任务结果 设置访视任务的这个字段 该字段表示 裁判认同该任务的结果 [DictionaryTranslateAttribute("YesOrNo")] public bool? IsGenerateJudge { get; set; } - [JsonIgnore] + //[JsonIgnore] - public List GlobalTaskAnswerList { get; set; } + //public List GlobalTaskAnswerList { get; set; } } diff --git a/IRaCIS.Core.Application/Service/QC/_MapConfig.cs b/IRaCIS.Core.Application/Service/QC/_MapConfig.cs index 71f380b62..b1bfd53c1 100644 --- a/IRaCIS.Core.Application/Service/QC/_MapConfig.cs +++ b/IRaCIS.Core.Application/Service/QC/_MapConfig.cs @@ -199,8 +199,7 @@ namespace IRaCIS.Core.Application.Service .ForMember(o => o.TrialSiteCode, t => t.MapFrom(u => u.Subject.TrialSite.TrialSiteCode)) .ForMember(o => o.SubjectCode, t => t.MapFrom(u => u.Subject.Code)) .ForMember(o => o.UserName, t => t.MapFrom(u => u.DoctorUser.UserName)) - .ForMember(o => o.GlobalTaskAnswerList, t => t.MapFrom(u => u.GlobalVisitResultList.Where(t=>t.GlobalAnswerType== GlobalAnswerType.Question) - .Select(c=>new GlobalAnswerInfo() { GlobalTaskVisitNum=c.VisitTask.VisitTaskNum,VisitTaskId=c.TaskId ,Answer=c.Answer}))) + //.ForMember(o => o.GlobalTaskAnswerList, t => t.MapFrom(u => u.GlobalVisitResultList.Where(t=>t.GlobalAnswerType== GlobalAnswerType.Question).Select(c=>new GlobalAnswerInfo() { GlobalTaskVisitNum=c.VisitTask.VisitTaskNum,VisitTaskId=c.TaskId ,Answer=c.Answer}))) ; diff --git a/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs b/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs index f33e41df5..aa9c99440 100644 --- a/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs +++ b/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs @@ -12,7 +12,6 @@ using System.Linq.Dynamic.Core; using Microsoft.Extensions.Logging; using IRaCIS.Core.Infrastructure.Extention; using System.Linq; -using BeetleX.Redis.Commands; using NPOI.SS.Formula.Functions; namespace IRaCIS.Application.Services From a1778d836b1220743a613c813456eab146c91cb1 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Fri, 9 Aug 2024 13:46:08 +0800 Subject: [PATCH 209/251] =?UTF-8?q?=E8=AE=BE=E7=BD=AE=E8=BF=9E=E6=8E=A5?= =?UTF-8?q?=E8=B6=85=E6=97=B6=E6=97=B6=E9=97=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Service/TrialSiteUser/TrialDicomAEService.cs | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/IRaCIS.Core.Application/Service/TrialSiteUser/TrialDicomAEService.cs b/IRaCIS.Core.Application/Service/TrialSiteUser/TrialDicomAEService.cs index b0e1be07c..a29e92960 100644 --- a/IRaCIS.Core.Application/Service/TrialSiteUser/TrialDicomAEService.cs +++ b/IRaCIS.Core.Application/Service/TrialSiteUser/TrialDicomAEService.cs @@ -145,9 +145,21 @@ namespace IRaCIS.Core.Application.Service await client.AddRequestAsync(new DicomCEchoRequest()); - await client.SendAsync(); + // 创建一个超时任务,设置超时时间为1秒 + var timeoutTask = Task.Delay(TimeSpan.FromSeconds(3)); + + // 发送 DICOM 请求 + var sendTask = client.SendAsync(); + + // 等待任务完成,若超时任务先完成则抛出超时异常 + if (await Task.WhenAny(sendTask, timeoutTask) == timeoutTask) + { + throw new TimeoutException("DICOM 请求超时。"); + } + find.IsTestOK = true; + await _dicomAERepository.SaveChangesAsync(); return true; From 035ce2ae4e1e8570d2dbf87b3a4a4410191e04d7 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Fri, 9 Aug 2024 14:07:29 +0800 Subject: [PATCH 210/251] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E9=82=AE=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.Application/Service/Common/MailService.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/IRaCIS.Core.Application/Service/Common/MailService.cs b/IRaCIS.Core.Application/Service/Common/MailService.cs index e1c0a65ad..f71f70f4a 100644 --- a/IRaCIS.Core.Application/Service/Common/MailService.cs +++ b/IRaCIS.Core.Application/Service/Common/MailService.cs @@ -322,7 +322,7 @@ namespace IRaCIS.Application.Services }; - await GetEmailSubejctAndHtmlInfoAndBuildAsync(EmailBusinessScenario.UnloginUseEmailResetPassword, messageToSend, emailConfigFunc); + await GetEmailSubejctAndHtmlInfoAndBuildAsync(EmailBusinessScenario.ReviewerLogin, messageToSend, emailConfigFunc); //此时不知道用户 var sucessHandle = GetEmailSuccessHandle(Guid.Empty, verificationCode, emailAddress); From e705e126560870a90ae17dd7779b2f75a36f84f3 Mon Sep 17 00:00:00 2001 From: he <109787524@qq.com> Date: Fri, 9 Aug 2024 14:07:56 +0800 Subject: [PATCH 211/251] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Common/AuditingData.cs | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/IRaCIS.Core.Infra.EFCore/Common/AuditingData.cs b/IRaCIS.Core.Infra.EFCore/Common/AuditingData.cs index 86937cd19..742a51a72 100644 --- a/IRaCIS.Core.Infra.EFCore/Common/AuditingData.cs +++ b/IRaCIS.Core.Infra.EFCore/Common/AuditingData.cs @@ -328,6 +328,34 @@ namespace IRaCIS.Core.Infra.EFCore.Common }); } + + // PACS直连 + foreach (var item in entitys.Where(x => x.Entity.GetType() == typeof(TrialSiteDicomAE))) + { + var type = GetEntityAuditOpt(item); + + var entity = item.Entity as TrialSiteDicomAE; + + + await InsertInspection(entity, type, x => new InspectionConvertDTO() + { + ObjectRelationParentId=entity.TrialSiteId, + }); + } + + // PACS直连 + foreach (var item in entitys.Where(x => x.Entity.GetType() == typeof(TrialDicomAE))) + { + var type = GetEntityAuditOpt(item); + + var entity = item.Entity as TrialDicomAE; + + + await InsertInspection(entity, type, x => new InspectionConvertDTO() + { + }); + } + //系统标准问题 foreach (var item in entitys.Where(x => x.Entity.GetType() == typeof(ReadingQuestionSystem))) { @@ -2314,6 +2342,27 @@ namespace IRaCIS.Core.Infra.EFCore.Common }, new { FileCountViewStr = config?.ClinicalDataLevel == ClinicalLevel.Subject && config?.ClinicalUploadType == ClinicalUploadType.Table ? "NA" : entity.FileCount.ToString() }); } + foreach (var item in entitys.Where(x => x.Entity.GetType() == typeof(ReadingConsistentClinicalData))) + { + var type = GetEntityAuditOpt(item); + + var entity = item.Entity as ReadingConsistentClinicalData; + + var config = await _dbContext.ClinicalDataTrialSet.FindAsync(entity.ClinicalDataTrialSetId); + + await InsertInspection(item.Entity as ReadingConsistentClinicalData, type, x => new InspectionConvertDTO() + { + + IsDistinctionInterface = type == AuditOpt.Update ? true : false, + + SubjectVisitId = x.IsVisit ? x.ReadingId : null, + + ObjectRelationParentId = entity.ClinicalDataTrialSetId, + + //ObjectRelationParentId2 = x.IsVisit == false?x.ReadingId:null + }, new { FileCountViewStr = config?.ClinicalDataLevel == ClinicalLevel.Subject && config?.ClinicalUploadType == ClinicalUploadType.Table ? "NA" : entity.FileCount.ToString() }); + } + //阅片期计划 foreach (var item in entitys.Where(x => x.Entity.GetType() == typeof(ReadingPeriodSet))) { From 63e2ca07b5dac80b977ade4339acd7b7ccac78b6 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Fri, 9 Aug 2024 15:01:22 +0800 Subject: [PATCH 212/251] =?UTF-8?q?=E4=BF=AE=E6=94=B9dicomAE=20=E6=B5=8B?= =?UTF-8?q?=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../TrialSiteUser/DTO/DicomAEViewModel.cs | 9 +++ .../TrialSiteUser/TrialDicomAEService.cs | 76 ++++++++----------- 2 files changed, 41 insertions(+), 44 deletions(-) diff --git a/IRaCIS.Core.Application/Service/TrialSiteUser/DTO/DicomAEViewModel.cs b/IRaCIS.Core.Application/Service/TrialSiteUser/DTO/DicomAEViewModel.cs index 50cc7d550..2d1020723 100644 --- a/IRaCIS.Core.Application/Service/TrialSiteUser/DTO/DicomAEViewModel.cs +++ b/IRaCIS.Core.Application/Service/TrialSiteUser/DTO/DicomAEViewModel.cs @@ -61,6 +61,15 @@ namespace IRaCIS.Core.Application.ViewModel public bool IsPACSConnect { get; set; } + + public bool IsTestOK { get; set; } + } + + public class TestAECommand + { + public string CalledAE { get; set; } = string.Empty; + public string IP { get; set; } = string.Empty; + public int Port { get; set; } } diff --git a/IRaCIS.Core.Application/Service/TrialSiteUser/TrialDicomAEService.cs b/IRaCIS.Core.Application/Service/TrialSiteUser/TrialDicomAEService.cs index a29e92960..9c59315b4 100644 --- a/IRaCIS.Core.Application/Service/TrialSiteUser/TrialDicomAEService.cs +++ b/IRaCIS.Core.Application/Service/TrialSiteUser/TrialDicomAEService.cs @@ -12,6 +12,7 @@ using FellowOakDicom.Network.Client; using FellowOakDicom.Network; using IRaCIS.Application.Contracts; using IRaCIS.Core.Domain.Share; +using DocumentFormat.OpenXml.InkML; namespace IRaCIS.Core.Application.Service { /// @@ -84,6 +85,14 @@ namespace IRaCIS.Core.Application.Service VerifyMsg = _localizer["TrialDicomAE_RepeatCalledAE"] }; + var verifyExp3 = new EntityVerifyExp() + { + VerifyExp = u => u.TrialId == addOrEditDicomAE.TrialId, + + //"AE名称不能与其他项目相同" + VerifyMsg = "该项目只允许添加一条dicom AE记录(前端对接有bug时出现)" + }; + //var verifyExp2 = new EntityVerifyExp() //{ // VerifyExp = u => u.TrialId == addOrEditDicomAE.TrialId, @@ -98,7 +107,7 @@ namespace IRaCIS.Core.Application.Service if (addOrEditDicomAE.IsPACSConnect) { // 在此处拷贝automapper 映射 - var entity = await _dicomAERepository.InsertOrUpdateAsync(addOrEditDicomAE, true, verifyExp1, verifyExp2); + var entity = await _dicomAERepository.InsertOrUpdateAsync(addOrEditDicomAE, true, verifyExp3, verifyExp1, verifyExp2); return ResponseOutput.Ok(entity.Id.ToString()); } @@ -123,54 +132,33 @@ namespace IRaCIS.Core.Application.Service /// 测试scp server 是否可以连接 /// /// - [HttpGet("{dicomAEId:guid}")] - public async Task TestSCPServerConnect(Guid dicomAEId) + [HttpPost] + public async Task TestSCPServerConnect(TestAECommand inCommand) { - var find = await _dicomAERepository.FirstOrDefaultAsync(t => t.Id == dicomAEId); - - if (find == null) + try { + var client = DicomClientFactory.Create(inCommand.IP, inCommand.Port, false, "test-callingAE", inCommand.CalledAE); - return false; + client.NegotiateAsyncOps(); + + await client.AddRequestAsync(new DicomCEchoRequest()); + + // 创建一个超时任务,设置超时时间为1秒 + var timeoutTask = Task.Delay(TimeSpan.FromSeconds(3)); + + // 发送 DICOM 请求 + var sendTask = client.SendAsync(); + + // 等待任务完成,若超时任务先完成则抛出超时异常 + if (await Task.WhenAny(sendTask, timeoutTask) == timeoutTask) + { + throw new TimeoutException("DICOM 请求超时。"); + } + return true; } - else + catch (Exception ex) { - find.LatestTestTime = DateTime.Now; - - try - { - var client = DicomClientFactory.Create(find.IP, find.Port, false, "test-callingAE", find.CalledAE); - - client.NegotiateAsyncOps(); - - await client.AddRequestAsync(new DicomCEchoRequest()); - - // 创建一个超时任务,设置超时时间为1秒 - var timeoutTask = Task.Delay(TimeSpan.FromSeconds(3)); - - // 发送 DICOM 请求 - var sendTask = client.SendAsync(); - - // 等待任务完成,若超时任务先完成则抛出超时异常 - if (await Task.WhenAny(sendTask, timeoutTask) == timeoutTask) - { - throw new TimeoutException("DICOM 请求超时。"); - } - - - find.IsTestOK = true; - - await _dicomAERepository.SaveChangesAsync(); - - return true; - } - catch (Exception ex) - { - find.IsTestOK = false; - await _dicomAERepository.SaveChangesAsync(); - - return false; - } + return false; } From d62562149cb95e5ecde8c7c1a5c93f99c6198e1c Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Fri, 9 Aug 2024 15:24:40 +0800 Subject: [PATCH 213/251] =?UTF-8?q?=E4=BF=AE=E6=94=B9dicomAE=20=E6=B5=8B?= =?UTF-8?q?=E8=AF=95=E7=8A=B6=E6=80=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../IRaCIS.Core.Application.xml | 2 +- .../TrialSiteUser/DTO/DicomAEViewModel.cs | 3 +-- IRaCIS.Core.Application/TestService.cs | 27 +++++++++++++++++++ IRaCIS.Core.Domain/Image/TrialDicomAE.cs | 2 +- 4 files changed, 30 insertions(+), 4 deletions(-) diff --git a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml index 2b89f02a7..7f17ce6ef 100644 --- a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml +++ b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml @@ -9920,7 +9920,7 @@ - + 测试scp server 是否可以连接 diff --git a/IRaCIS.Core.Application/Service/TrialSiteUser/DTO/DicomAEViewModel.cs b/IRaCIS.Core.Application/Service/TrialSiteUser/DTO/DicomAEViewModel.cs index 2d1020723..cd9cbd134 100644 --- a/IRaCIS.Core.Application/Service/TrialSiteUser/DTO/DicomAEViewModel.cs +++ b/IRaCIS.Core.Application/Service/TrialSiteUser/DTO/DicomAEViewModel.cs @@ -19,7 +19,6 @@ namespace IRaCIS.Core.Application.ViewModel public DateTime? LatestTestTime { get; set; } - public bool IsTestOK { get; set; } //public bool IsPACSConnect { get; set; } @@ -62,7 +61,7 @@ namespace IRaCIS.Core.Application.ViewModel public bool IsPACSConnect { get; set; } - public bool IsTestOK { get; set; } + public bool? IsTestOK { get; set; } } public class TestAECommand diff --git a/IRaCIS.Core.Application/TestService.cs b/IRaCIS.Core.Application/TestService.cs index b0dd183e8..dd7aa1031 100644 --- a/IRaCIS.Core.Application/TestService.cs +++ b/IRaCIS.Core.Application/TestService.cs @@ -24,6 +24,7 @@ using System.Linq.Expressions; using System.Reflection.Metadata; using System.Text; using System.Text.RegularExpressions; +using Xceed.Words.NET; namespace IRaCIS.Application.Services @@ -204,6 +205,32 @@ namespace IRaCIS.Application.Services public async Task testEmail([FromServices] IWebHostEnvironment env ,string email) { + //using (DocX document = DocX.Load("C:\\Users\\hang\\Desktop\\")) + //{ + // // 查找书签对应的段落 + // var bookmark = document.Bookmarks.FirstOrDefault(b => b.Name == bookmarkName); + + // if (bookmark != null) + // { + // // 获取书签所在的段落位置 + // int paragraphIndex = document.Paragraphs.IndexOf(bookmark.Paragraph); + + // // 如果书签所在的段落在文档中 + // if (paragraphIndex >= 0) + // { + // // 删除书签所在的段落 + // document.RemoveParagraphAt(paragraphIndex); + // } + + // // 删除书签(只删除书签标记,不删除内容) + // document.Bookmarks.Remove(bookmark); + // } + + // // 保存修改 + // document.Save(); + //} + + var hiddenEmail = EmailMaskHelper.MaskEmail(email); return hiddenEmail; diff --git a/IRaCIS.Core.Domain/Image/TrialDicomAE.cs b/IRaCIS.Core.Domain/Image/TrialDicomAE.cs index 0d91a9c77..3a1f963ab 100644 --- a/IRaCIS.Core.Domain/Image/TrialDicomAE.cs +++ b/IRaCIS.Core.Domain/Image/TrialDicomAE.cs @@ -45,7 +45,7 @@ namespace IRaCIS.Core.Domain.Models public DateTime? LatestTestTime { get; set; } - public bool IsTestOK { get; set; } + public bool? IsTestOK { get; set; } } From 5f8045c611fa48f44379b6c3c5b39f2a42b121ee Mon Sep 17 00:00:00 2001 From: he <109787524@qq.com> Date: Fri, 9 Aug 2024 17:13:06 +0800 Subject: [PATCH 214/251] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=85=A8=E5=B1=80?= =?UTF-8?q?=E9=98=85=E7=89=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ReadingGlobalTaskService.cs | 36 +++++++++++-------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/IRaCIS.Core.Application/Service/Reading/ReadingImageTask/ReadingGlobalTaskService.cs b/IRaCIS.Core.Application/Service/Reading/ReadingImageTask/ReadingGlobalTaskService.cs index 5759c9ced..9c7371891 100644 --- a/IRaCIS.Core.Application/Service/Reading/ReadingImageTask/ReadingGlobalTaskService.cs +++ b/IRaCIS.Core.Application/Service/Reading/ReadingImageTask/ReadingGlobalTaskService.cs @@ -34,6 +34,23 @@ namespace IRaCIS.Application.Services await VerifyTaskIsSign(inDto.GlobalTaskId); await this.SubmitTaskChangeState(inDto.GlobalTaskId); + var globalAnswerList = await _readingGlobalTaskInfoRepository.Where(x => + x.QuestionId!=null &&x.Answer!=string.Empty&& x.Answer != null && + x.GlobalTaskId == inDto.GlobalTaskId).ToListAsync(); + + foreach (var item in globalAnswerList) + { + await _readingTaskQuestionAnswerRepository.BatchUpdateNoTrackingAsync(x => x.VisitTaskId == item.TaskId && x.ReadingQuestionTrialId == item.QuestionId + && x.Answer != item.Answer + , x => new ReadingTaskQuestionAnswer() + { + GlobalChangeAnswer = item.Answer, + IsGlobalChange = true, + }); + } + + await _readingTaskQuestionAnswerRepository.SaveChangesAsync(); + return ResponseOutput.Ok(true); } @@ -60,24 +77,15 @@ namespace IRaCIS.Application.Services if (criterionType == CriterionType.PCWG3) { await _readingTaskQuestionAnswerRepository.BatchUpdateNoTrackingAsync(x => x.VisitTaskId == item.VisitTaskId && x.ReadingQuestionTrialId == answer.QuestionId - && x.Answer != answer.Answer && answer.Answer != string.Empty && answer.Answer != null - , x => new ReadingTaskQuestionAnswer() - { + && x.Answer != answer.Answer && answer.Answer != string.Empty && answer.Answer != null + , x => new ReadingTaskQuestionAnswer() + { Answer= answer.Answer, GlobalChangeAnswer = answer.Answer, IsGlobalChange = true, - }); - } - else - { - await _readingTaskQuestionAnswerRepository.BatchUpdateNoTrackingAsync(x => x.VisitTaskId == item.VisitTaskId && x.ReadingQuestionTrialId == answer.QuestionId - && x.Answer != answer.Answer && answer.Answer != string.Empty && answer.Answer != null - , x => new ReadingTaskQuestionAnswer() - { - GlobalChangeAnswer = answer.Answer, - IsGlobalChange = true, - }); + }); } + } } From 2f1cfc3e67d4beca20841fcb8392a13cd527c6b8 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Fri, 9 Aug 2024 17:53:40 +0800 Subject: [PATCH 215/251] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=AF=BC=E5=87=BA?= =?UTF-8?q?=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../_PipelineExtensions/LocalizationConfig.cs | 8 +- .../Helper/WordTempleteHelper.cs | 101 +++++++++++++++ .../IRaCIS.Core.Application.csproj | 7 +- .../IRaCIS.Core.Application.xml | 5 + .../Service/Common/ExcelExportService.cs | 12 +- IRaCIS.Core.Application/TestService.cs | 116 +++++++++++++++--- IRaCIS.Core.Domain/_Config/_StaticData.cs | 8 ++ 7 files changed, 221 insertions(+), 36 deletions(-) create mode 100644 IRaCIS.Core.Application/Helper/WordTempleteHelper.cs diff --git a/IRaCIS.Core.API/_PipelineExtensions/LocalizationConfig.cs b/IRaCIS.Core.API/_PipelineExtensions/LocalizationConfig.cs index 45ab1ec1f..d94b96b65 100644 --- a/IRaCIS.Core.API/_PipelineExtensions/LocalizationConfig.cs +++ b/IRaCIS.Core.API/_PipelineExtensions/LocalizationConfig.cs @@ -1,4 +1,5 @@ -using Microsoft.AspNetCore.Builder; +using IRaCIS.Core.Domain.Share; +using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Localization; using System.Collections.Generic; using System.Globalization; @@ -12,8 +13,9 @@ namespace IRaCIS.Core.API { var supportedCultures = new List { - new CultureInfo("en-US"), - new CultureInfo("zh-CN") + + new CultureInfo(StaticData.CultureInfo.en_US), + new CultureInfo(StaticData.CultureInfo.zh_CN) }; var options = new RequestLocalizationOptions diff --git a/IRaCIS.Core.Application/Helper/WordTempleteHelper.cs b/IRaCIS.Core.Application/Helper/WordTempleteHelper.cs new file mode 100644 index 000000000..9f605be81 --- /dev/null +++ b/IRaCIS.Core.Application/Helper/WordTempleteHelper.cs @@ -0,0 +1,101 @@ +using IRaCIS.Core.Domain.Share; +using NPOI.XWPF.UserModel; +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Xceed.Document.NET; +using Xceed.Words.NET; + +namespace IRaCIS.Core.Application.Helper +{ + /// + /// 利用DocX 库 处理word国际化模板 + /// + public static class WordTempleteHelper + { + public static void DocX_GetInternationalTempleteStream(string filePath, Stream memoryStream) + { + + var isEn_US = CultureInfo.CurrentCulture.Name == StaticData.CultureInfo.en_US; + + using (DocX document = DocX.Load(filePath)) + { + // 查找书签 + var bookmarkEn_Start = document.Bookmarks.FirstOrDefault(b => b.Name == StaticData.CultureInfo.en_US_bookMark); + + if (bookmarkEn_Start != null) + { + // 获取书签的起始位置 + //int bookmarkCNStartPos = bookmarkCn_Start.Paragraph.StartIndex; + + var bookmarkENStartPos = bookmarkEn_Start.Paragraph.StartIndex; + + // 创建一个要删除段落的列表 + List paragraphsToRemove = new List(); + + foreach (var item in document.Paragraphs) + { + //中文模板在前,英文在后,英文模板,就删除英文之前的,中文模板就删除英文之后的 + + if (isEn_US ? item.EndIndex < bookmarkENStartPos : item.StartIndex >= bookmarkENStartPos) + { + paragraphsToRemove.Add(item); + } + } + + foreach (var paragraph in paragraphsToRemove) + { + document.RemoveParagraph(paragraph); + } + + } + + // 保存修改 + document.SaveAs(memoryStream); + } + } + + + public static void Npoi_GetInternationalTempleteStream(string filePath, Stream memoryStream) + { + + var isEn_US = CultureInfo.CurrentCulture.Name == StaticData.CultureInfo.en_US; + + using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read)) + { + XWPFDocument doc = new XWPFDocument(fs); + + // 查找包含指定书签的段落及其索引 + var bookmarkParagraph = doc.Paragraphs + .FirstOrDefault(p => p.GetCTP().GetBookmarkStartList().Any(b => b.name == StaticData.CultureInfo.en_US_bookMark)); + + if (bookmarkParagraph != null) + { + int bookmarkIndex = doc.Paragraphs.IndexOf(bookmarkParagraph); + + if (isEn_US) + { + // 从书签所在段落开始,删除之前的所有段落 + for (int i = bookmarkIndex - 1; i >= 0; i--) + { + doc.RemoveBodyElement(i); + } + } + else + { + // 删除书签之后的所有段落 + for (int i = doc.Paragraphs.Count - 1; i >= bookmarkIndex; i--) + { + doc.RemoveBodyElement(i); + } + } + } + doc.Write(memoryStream); + } + } + + } +} diff --git a/IRaCIS.Core.Application/IRaCIS.Core.Application.csproj b/IRaCIS.Core.Application/IRaCIS.Core.Application.csproj index ab2113cba..ab00314fc 100644 --- a/IRaCIS.Core.Application/IRaCIS.Core.Application.csproj +++ b/IRaCIS.Core.Application/IRaCIS.Core.Application.csproj @@ -42,7 +42,7 @@ - + @@ -50,11 +50,6 @@ - - PreserveNewest - true - PreserveNewest - Always true diff --git a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml index 7f17ce6ef..26bc2e0de 100644 --- a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml +++ b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml @@ -117,6 +117,11 @@ 解密后的字符串 + + + 利用DocX 库 处理word国际化模板 + + 分配规则 diff --git a/IRaCIS.Core.Application/Service/Common/ExcelExportService.cs b/IRaCIS.Core.Application/Service/Common/ExcelExportService.cs index f3c6f7f5b..010c2b04e 100644 --- a/IRaCIS.Core.Application/Service/Common/ExcelExportService.cs +++ b/IRaCIS.Core.Application/Service/Common/ExcelExportService.cs @@ -1522,20 +1522,18 @@ namespace IRaCIS.Core.Application.Service.Common //两个都不为null 肯定是不同的裁判 //在完成裁判之后的,和未完成裁判之前的 - if (visitItem.VisitTaskNum < maxNotFinishedJudge.VisitTaskNum && visitItem.VisitTaskNum > maxFinishedJudge.VisitTaskNum) + if (/*visitItem.VisitTaskNum < maxNotFinishedJudge.VisitTaskNum &&*/ visitItem.VisitTaskNum > maxFinishedJudge.VisitTaskNum) { visitItem.IsGenerateJudge = null; } - else if (visitItem.ArmEnum == maxFinishedJudge.JudgeArmEnum && visitItem.VisitTaskNum < maxFinishedJudge.VisitTaskNum) { visitItem.IsGenerateJudge = true; } - - else if (visitItem.ArmEnum == Arm.DoubleReadingArm1) - { - visitItem.IsGenerateJudge = true; - } + //else if (visitItem.ArmEnum == Arm.DoubleReadingArm1) + //{ + // visitItem.IsGenerateJudge = true; + //} } } diff --git a/IRaCIS.Core.Application/TestService.cs b/IRaCIS.Core.Application/TestService.cs index dd7aa1031..104a44f53 100644 --- a/IRaCIS.Core.Application/TestService.cs +++ b/IRaCIS.Core.Application/TestService.cs @@ -1,4 +1,5 @@ using Aliyun.OSS; +using DocumentFormat.OpenXml.Wordprocessing; using IP2Region.Net.XDB; using IRaCIS.Application.Contracts; using IRaCIS.Core.Application.Contracts; @@ -18,12 +19,14 @@ using Microsoft.Extensions.Options; using MiniExcelLibs; using Minio; using Minio.DataModel.Args; +using NPOI.XWPF.UserModel; using SharpCompress.Common; using Spire.Doc; using System.Linq.Expressions; using System.Reflection.Metadata; using System.Text; using System.Text.RegularExpressions; +using Xceed.Document.NET; using Xceed.Words.NET; @@ -114,7 +117,7 @@ namespace IRaCIS.Application.Services public async Task TestMinIO([FromServices] IOSSService oSSService) { - var str= await oSSService.GetSignedUrl("/01000000-c0a8-0242-1c98-08dc7ebcd37d/Read/01000000-c0a8-0242-1c98-08dc7ebcd37d/Visit/1716872544006_1716872544003.png"); + var str = await oSSService.GetSignedUrl("/01000000-c0a8-0242-1c98-08dc7ebcd37d/Read/01000000-c0a8-0242-1c98-08dc7ebcd37d/Visit/1716872544006_1716872544003.png"); //await oSSService.UploadToOSSAsync("C:\\Users\\Administrator\\Desktop\\TrialSiteUserImportTemplate.xlsx", "myfolder"); @@ -188,11 +191,11 @@ namespace IRaCIS.Application.Services Console.WriteLine("\nOriginal Data: " + dataToEncrypt); // Encrypt the data - var encryptedData = RSAHelper.Encrypt( publicKey, dataToEncrypt); + var encryptedData = RSAHelper.Encrypt(publicKey, dataToEncrypt); Console.WriteLine("\nEncrypted Data: " + encryptedData); // Decrypt the data - string decryptedData = RSAHelper.Decrypt( privateKey, encryptedData); + string decryptedData = RSAHelper.Decrypt(privateKey, encryptedData); Console.WriteLine("\nDecrypted Data: " + decryptedData); @@ -202,38 +205,111 @@ namespace IRaCIS.Application.Services [AllowAnonymous] - public async Task testEmail([FromServices] IWebHostEnvironment env ,string email) + public async Task testDoc([FromServices] IWebHostEnvironment env, string email) { - - //using (DocX document = DocX.Load("C:\\Users\\hang\\Desktop\\")) + #region DocX 测试 + //using (DocX document = DocX.Load("C:\\Users\\hang\\Desktop\\test.docx")) //{ - // // 查找书签对应的段落 - // var bookmark = document.Bookmarks.FirstOrDefault(b => b.Name == bookmarkName); + // // 查找书签 + // var bookmarkCn_Start = document.Bookmarks.FirstOrDefault(b => b.Name == "zh_cn"); + // var bookmarkEn_Start = document.Bookmarks.FirstOrDefault(b => b.Name == "en_us"); - // if (bookmark != null) + // if (bookmarkCn_Start != null && bookmarkEn_Start != null) // { - // // 获取书签所在的段落位置 - // int paragraphIndex = document.Paragraphs.IndexOf(bookmark.Paragraph); + // // 获取书签的起始位置 + // int bookmarkCNStartPos = bookmarkCn_Start.Paragraph.StartIndex; - // // 如果书签所在的段落在文档中 - // if (paragraphIndex >= 0) + // var bookmarkENStartPos = bookmarkEn_Start.Paragraph.StartIndex; + + // // // 创建一个要删除段落的列表 + // List paragraphsToRemove = new List(); + + // foreach (var item in document.Paragraphs) // { - // // 删除书签所在的段落 - // document.RemoveParagraphAt(paragraphIndex); + + // //中文模板在前,英文在后,英文模板,就删除英文之前的,中文模板就删除英文之后的 + // //_userInfo.IsEn_Us? item.EndIndex< bookmarkENStartPos :item.StartIndex>= bookmarkENStartPos + // if (item.StartIndex>= bookmarkENStartPos) + // { + // paragraphsToRemove.Add(item); + + // } + // } + + // foreach (var paragraph in paragraphsToRemove) + // { + // document.RemoveParagraph(paragraph); // } - // // 删除书签(只删除书签标记,不删除内容) - // document.Bookmarks.Remove(bookmark); // } // // 保存修改 - // document.Save(); + // document.SaveAs("C:\\Users\\hang\\Desktop\\test1.docx"); //} + #endregion + + using (FileStream fs = new FileStream("C:\\Users\\hang\\Desktop\\test.docx", FileMode.Open, FileAccess.Read)) + { + XWPFDocument doc = new XWPFDocument(fs); - var hiddenEmail = EmailMaskHelper.MaskEmail(email); + // 查找包含指定书签的段落及其索引 + var bookmarkParagraph = doc.Paragraphs + .FirstOrDefault(p => p.GetCTP().GetBookmarkStartList().Any(b => b.name == "en_us")); - return hiddenEmail; + + if (bookmarkParagraph != null) + { + int bookmarkIndex = doc.Paragraphs.IndexOf(bookmarkParagraph); + + // 删除书签之后的所有段落 + for (int i = doc.Paragraphs.Count - 1; i >= bookmarkIndex; i--) + { + doc.RemoveBodyElement(i); + } + + } + else + { + throw new BusinessValidationFailedException("word 模板没有英文书签"); + } + + // 创建一个要删除段落的列表 + + //XWPFParagraph bookmarkParagraph = null; + + //foreach (var paragraph in doc.Paragraphs) + //{ + + // foreach (var bookmark in paragraph.GetCTP().GetBookmarkStartList()) + // { + // if (bookmark.name == "en_us") + // { + // bookmarkParagraph = paragraph; + // break; + // } + // } + //} + + + + + //// 从书签所在段落开始,删除之前的所有段落 + //for (int i = bookmarkIndex - 1; i >= 0; i--) + //{ + // doc.RemoveBodyElement(i); + //} + + + + using (FileStream outStream = new FileStream("C:\\Users\\hang\\Desktop\\test1.docx", FileMode.Create, FileAccess.Write)) + { + doc.Write(outStream); + } + } + + + return "hiddenEmail"; } diff --git a/IRaCIS.Core.Domain/_Config/_StaticData.cs b/IRaCIS.Core.Domain/_Config/_StaticData.cs index 3b0f84623..117e658fa 100644 --- a/IRaCIS.Core.Domain/_Config/_StaticData.cs +++ b/IRaCIS.Core.Domain/_Config/_StaticData.cs @@ -17,6 +17,14 @@ public static class StaticData public static readonly string Zh_CN_Json = "zh-CN.json"; + public static class CultureInfo + { + public static readonly string zh_CN = "zh-CN"; + public static readonly string en_US = "en-US"; + + public static readonly string en_US_bookMark = "en_us"; + } + /// /// 获取国际化 /// From d3b8716a66992d5d941a30879fec21f479359ca5 Mon Sep 17 00:00:00 2001 From: he <109787524@qq.com> Date: Mon, 12 Aug 2024 13:01:45 +0800 Subject: [PATCH 216/251] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Service/Reading/ClinicalData/ReadingClinicalDataService.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs b/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs index aa9c99440..e9dee8944 100644 --- a/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs +++ b/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs @@ -393,7 +393,7 @@ namespace IRaCIS.Application.Services //如果先生成了任务,再签名subject级别 PM 临床数据,那么会导致其他标准的任务签名状态无法得到维护 - if (await _repository.AnyAsync(t => t.Id == data.ClinicalDataTrialSetId && t.UploadRole == UploadRole.PM && t.ClinicalDataLevel == ClinicalLevel.Subject)) + if (await _repository.AnyAsync(t => t.Id == data.ClinicalDataTrialSetId && t.UploadRole == UploadRole.PM && (t.ClinicalDataLevel == ClinicalLevel.Subject|| t.ClinicalDataLevel == ClinicalLevel.SubjectVisit))) { var needDealTrialReadingCriterionIdList = _repository.Where(t => t.Id == data.ClinicalDataTrialSetId) .SelectMany(t => t.TrialClinicalDataSetCriteriaList) From 7e8dd1c6a76e106e083c55ed4cd1dcba297650c6 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Mon, 12 Aug 2024 13:21:53 +0800 Subject: [PATCH 217/251] =?UTF-8?q?=E5=BD=B1=E5=83=8F=E8=B4=A8=E6=8E=A7?= =?UTF-8?q?=E5=A4=87=E6=B3=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Service/Common/ExcelExportService.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/IRaCIS.Core.Application/Service/Common/ExcelExportService.cs b/IRaCIS.Core.Application/Service/Common/ExcelExportService.cs index 010c2b04e..830742482 100644 --- a/IRaCIS.Core.Application/Service/Common/ExcelExportService.cs +++ b/IRaCIS.Core.Application/Service/Common/ExcelExportService.cs @@ -484,7 +484,7 @@ namespace IRaCIS.Core.Application.Service.Common } /// - /// 影像质控导出 + /// 影像质控导出---new /// /// /// @@ -503,9 +503,9 @@ namespace IRaCIS.Core.Application.Service.Common { var svExpression = QCCommon.GetSubjectVisitFilter(inQuery.VisitPlanArray); var query = _subjectVisitRepository.Where(x => x.TrialId == inQuery.TrialId) - .WhereIf(inQuery.VisitId != null, t => t.Id == inQuery.VisitId) - .WhereIf(inQuery.CurrentActionUserId != null, t => t.CurrentActionUserId == inQuery.CurrentActionUserId) - .WhereIf(inQuery.ChallengeState != null, t => t.ChallengeState == inQuery.ChallengeState) + .WhereIf(inQuery.VisitId != null, t => t.Id == inQuery.VisitId) + .WhereIf(inQuery.CurrentActionUserId != null, t => t.CurrentActionUserId == inQuery.CurrentActionUserId) + .WhereIf(inQuery.ChallengeState != null, t => t.ChallengeState == inQuery.ChallengeState) .WhereIf(inQuery.TrialSiteId != null, t => t.TrialSiteId == inQuery.TrialSiteId) .WhereIf(inQuery.SubjectId != null, t => t.Subject.Id == inQuery.SubjectId) .WhereIf(!string.IsNullOrEmpty(inQuery.SubjectInfo), t => /*t.Subject.FirstName.Contains(subjectInfo) || t.Subject.LastName.Contains(subjectInfo) ||*/ t.Subject.Code.Contains(inQuery.SubjectInfo)) From 64b5206f86997fb0c92c643bc6af915556efcbf8 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Mon, 12 Aug 2024 13:35:38 +0800 Subject: [PATCH 218/251] =?UTF-8?q?=E9=A1=B9=E7=9B=AE=E9=82=AE=E4=BB=B6?= =?UTF-8?q?=E5=88=97=E8=A1=A8=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.Application/IRaCIS.Core.Application.xml | 2 +- .../Service/Document/TrialEmailNoticeConfigService.cs | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml index 26bc2e0de..7ec1606de 100644 --- a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml +++ b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml @@ -582,7 +582,7 @@ - 影像质控导出 + 影像质控导出---new diff --git a/IRaCIS.Core.Application/Service/Document/TrialEmailNoticeConfigService.cs b/IRaCIS.Core.Application/Service/Document/TrialEmailNoticeConfigService.cs index dbd0d57d0..2103aecef 100644 --- a/IRaCIS.Core.Application/Service/Document/TrialEmailNoticeConfigService.cs +++ b/IRaCIS.Core.Application/Service/Document/TrialEmailNoticeConfigService.cs @@ -1272,6 +1272,8 @@ namespace IRaCIS.Core.Application.Service public async Task> GetSysEmailNoticeConfigList(EmailNoticeConfigQuery queryEmailNoticeConfig) { var emailNoticeConfigQueryable = _emailNoticeConfigRepository + .WhereIf(queryEmailNoticeConfig.SystemLevel == null, t => t.SystemLevel == SysEmailLevel.not_sys) + .WhereIf(queryEmailNoticeConfig.SystemLevel != null, t => t.SystemLevel == queryEmailNoticeConfig.SystemLevel) .WhereIf(queryEmailNoticeConfig.BusinessScenarioEnum != null, t => t.BusinessScenarioEnum == queryEmailNoticeConfig.BusinessScenarioEnum) .WhereIf(queryEmailNoticeConfig.IsReturnRequired != null, t => t.IsReturnRequired == queryEmailNoticeConfig.IsReturnRequired) .WhereIf(queryEmailNoticeConfig.IsEnable != null, t => t.IsEnable == queryEmailNoticeConfig.IsEnable) From 86489b2117920338096e3f52aaee4cd93a97ba73 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Mon, 12 Aug 2024 15:40:13 +0800 Subject: [PATCH 219/251] =?UTF-8?q?=E5=89=8D=E7=AB=AF=E5=9B=BD=E9=99=85?= =?UTF-8?q?=E5=8C=96=E7=8A=B6=E6=80=81=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Service/Common/InternationalizationService.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/IRaCIS.Core.Application/Service/Common/InternationalizationService.cs b/IRaCIS.Core.Application/Service/Common/InternationalizationService.cs index 6e3edeeb9..10289e9a5 100644 --- a/IRaCIS.Core.Application/Service/Common/InternationalizationService.cs +++ b/IRaCIS.Core.Application/Service/Common/InternationalizationService.cs @@ -81,7 +81,9 @@ namespace IRaCIS.Core.Application.Service { var mapItem = _mapper.Map(item); mapItem.InternationalizationType = 0; - mapItem.State = 1; + + // 0 是预翻译 1是已确认 2是后端废弃 + mapItem.State = 0; await _internationalizationRepository.AddAsync(mapItem); } From 098ade3c8a5355185cf85f64200577b3c0b16afd Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Mon, 12 Aug 2024 16:40:20 +0800 Subject: [PATCH 220/251] =?UTF-8?q?subject=20=E8=BD=AF=E5=88=A0=E9=99=A4?= =?UTF-8?q?=EF=BC=8C=E5=AF=BC=E8=87=B4=E4=BB=BB=E5=8A=A1=E5=88=97=E8=A1=A8?= =?UTF-8?q?=E7=BB=9F=E8=AE=A1=E6=95=B0=E5=AD=97=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Service/Allocation/VisitTaskService.cs | 2 +- .../Context/IRaCISDBContext.cs | 40 ++++++++++--------- 2 files changed, 22 insertions(+), 20 deletions(-) diff --git a/IRaCIS.Core.Application/Service/Allocation/VisitTaskService.cs b/IRaCIS.Core.Application/Service/Allocation/VisitTaskService.cs index f9c504632..12f90e6ca 100644 --- a/IRaCIS.Core.Application/Service/Allocation/VisitTaskService.cs +++ b/IRaCIS.Core.Application/Service/Allocation/VisitTaskService.cs @@ -786,7 +786,7 @@ namespace IRaCIS.Core.Application.Service.Allocation .WhereIf(!string.IsNullOrEmpty(queryVisitTask.SubjectCode), t => (t.Subject.Code.Contains(queryVisitTask.SubjectCode) && t.IsAnalysisCreate == false) || (t.BlindSubjectCode.Contains(queryVisitTask.SubjectCode) && t.IsAnalysisCreate)) .WhereIf(queryVisitTask.BeginAllocateDate != null, t => t.AllocateTime > queryVisitTask.BeginAllocateDate) .WhereIf(queryVisitTask.EndAllocateDate != null, t => t.AllocateTime < queryVisitTask.EndAllocateDate) - .WhereIf(queryVisitTask.BeginSignTime != null, t => t.SignTime > queryVisitTask.BeginSignTime) + .WhereIf(queryVisitTask.BeginSignTime != null, t => t.SignTime > queryVisitTask.BeginSignTime) .WhereIf(queryVisitTask.EndSignTime != null, t => t.SignTime < queryVisitTask.EndSignTime) .ProjectTo(_mapper.ConfigurationProvider); diff --git a/IRaCIS.Core.Infra.EFCore/Context/IRaCISDBContext.cs b/IRaCIS.Core.Infra.EFCore/Context/IRaCISDBContext.cs index 44a2ad291..9985806ed 100644 --- a/IRaCIS.Core.Infra.EFCore/Context/IRaCISDBContext.cs +++ b/IRaCIS.Core.Infra.EFCore/Context/IRaCISDBContext.cs @@ -21,6 +21,7 @@ using Microsoft.Identity.Client; using EntityFramework.Exceptions.Common; using System.Data; using IRaCIS.Core.Infrastructure; +using System.Reflection.Metadata; namespace IRaCIS.Core.Infra.EFCore { @@ -49,7 +50,7 @@ namespace IRaCIS.Core.Infra.EFCore public class IRaCISDBContext : DbContext { - private IUserInfo _userInfo; + private IUserInfo _userInfo; private readonly ILogger _logger; @@ -57,7 +58,7 @@ namespace IRaCIS.Core.Infra.EFCore ) : base(options) { - _userInfo= userInfo; + _userInfo = userInfo; _logger = logger; } @@ -72,7 +73,7 @@ namespace IRaCIS.Core.Infra.EFCore }); - modelBuilder.Entity().HasQueryFilter(p => p.IsAdditional==false); + modelBuilder.Entity().HasQueryFilter(p => p.IsAdditional == false); modelBuilder.Entity().HasMany(t => t.VisitTaskList).WithOne(t => t.DoctorUser).HasForeignKey(t => t.DoctorUserId).IsRequired(false); @@ -98,11 +99,12 @@ namespace IRaCIS.Core.Infra.EFCore modelBuilder.Entity().HasMany(t => t.TaskInfluenceList).WithOne(s => s.OriginalTask).HasForeignKey(t => t.OriginalTaskId); - modelBuilder.Entity().HasMany(t => t.GlobalVisitResultList).WithOne(s => s.GlobalVisitTask).HasForeignKey(t => t.GlobalTaskId); + modelBuilder.Entity().HasMany(t => t.GlobalVisitResultList).WithOne(s => s.GlobalVisitTask).HasForeignKey(t => t.GlobalTaskId); modelBuilder.Entity().HasMany(t => t.ChildList).WithOne(t => t.Parent); modelBuilder.Entity().HasMany(t => t.EarlierSubjectUserList).WithOne(t => t.OrignalSubjectUser); + modelBuilder.Entity().HasQueryFilter(b => b.Subject.IsDeleted == false); //遍历实体模型手动配置 var typesToRegister = Assembly.GetExecutingAssembly().GetTypes().Where(q => q.GetInterface(typeof(IEntityTypeConfiguration<>).FullName) != null); @@ -239,18 +241,18 @@ namespace IRaCIS.Core.Infra.EFCore public virtual DbSet CriterionNidusSystem { get; set; } - public virtual DbSet CriterionNidusTrial { get; set; } + public virtual DbSet CriterionNidusTrial { get; set; } - public virtual DbSet ReadingTrialCriterionDictionary { get; set; } + public virtual DbSet ReadingTrialCriterionDictionary { get; set; } - public virtual DbSet ReadingTableQuestionTrial { get; set; } + public virtual DbSet ReadingTableQuestionTrial { get; set; } public virtual DbSet TumorAssessment_RECIST1Point1BM { get; set; } public virtual DbSet TumorAssessment_RECIST1Point1 { get; set; } public virtual DbSet TumorAssessment_IRECIST1Point1 { get; set; } - + public virtual DbSet TrialClinicalDataSetCriterion { get; set; } public virtual DbSet TrialCriterionAdditionalAssessmentType { get; set; } @@ -319,7 +321,7 @@ namespace IRaCIS.Core.Infra.EFCore #region Trial public virtual DbSet Trial { get; set; } - + public virtual DbSet TrialDictionary { get; set; } public virtual DbSet TrialDetail { get; set; } public virtual DbSet UserTrial { get; set; } @@ -333,9 +335,9 @@ namespace IRaCIS.Core.Infra.EFCore public virtual DbSet User { get; set; } - public virtual DbSet UserPassWordLog { get; set; } + public virtual DbSet UserPassWordLog { get; set; } - public virtual DbSet TrialSiteUserSurvey { get; set; } + public virtual DbSet TrialSiteUserSurvey { get; set; } public virtual DbSet TrialSiteEquipmentSurvey { get; set; } public virtual DbSet TrialSiteSurvey { get; set; } @@ -391,8 +393,8 @@ namespace IRaCIS.Core.Infra.EFCore public virtual DbSet ClinicalTableAnswer { get; set; } - public virtual DbSet ReadModuleCriterionFrom { get; set; } - public virtual DbSet ClinicalForm { get; set; } + public virtual DbSet ReadModuleCriterionFrom { get; set; } + public virtual DbSet ClinicalForm { get; set; } #endregion @@ -448,8 +450,8 @@ namespace IRaCIS.Core.Infra.EFCore public virtual DbSet ShortcutKey { get; set; } - public virtual DbSet UserWLTemplate { get; set; } - public virtual DbSet EmailNoticeConfig { get; set; } + public virtual DbSet UserWLTemplate { get; set; } + public virtual DbSet EmailNoticeConfig { get; set; } public virtual DbSet SystemBasicData { get; set; } public virtual DbSet TrialSign { get; set; } @@ -498,7 +500,7 @@ namespace IRaCIS.Core.Infra.EFCore public virtual DbSet TrialDicomAE { get; set; } - public virtual DbSet TrialSiteDicomAE { get; set; } + public virtual DbSet TrialSiteDicomAE { get; set; } public virtual DbSet SCPImageUpload { get; set; } @@ -519,7 +521,7 @@ namespace IRaCIS.Core.Infra.EFCore } catch (UniqueConstraintException ex) { - _logger.LogError(ex.InnerException is null? ex.Message :ex.InnerException?.Message); + _logger.LogError(ex.InnerException is null ? ex.Message : ex.InnerException?.Message); throw new DBSaveFailedException("该唯一键已经存在于数据库中。"); @@ -567,7 +569,7 @@ namespace IRaCIS.Core.Infra.EFCore } } - + public async Task AddAudit() @@ -589,7 +591,7 @@ namespace IRaCIS.Core.Infra.EFCore await auditingData.InsertAddEntitys(entities); } - + } From 46a304b5a62ecc8cb6bd3ac0a12551777fb29ba2 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Mon, 12 Aug 2024 17:42:54 +0800 Subject: [PATCH 221/251] =?UTF-8?q?=E7=94=A8=E6=88=B7=20=E6=80=A7=E5=88=AB?= =?UTF-8?q?=E5=8F=AF=E4=B8=BA=E7=A9=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.Application/Service/Management/DTO/UserModel.cs | 4 ++-- .../Service/TrialSiteUser/DTO/UserTrialViewModel.cs | 2 +- IRaCIS.Core.Domain/Management/User.cs | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/IRaCIS.Core.Application/Service/Management/DTO/UserModel.cs b/IRaCIS.Core.Application/Service/Management/DTO/UserModel.cs index a54ec9ad4..3f22371f2 100644 --- a/IRaCIS.Core.Application/Service/Management/DTO/UserModel.cs +++ b/IRaCIS.Core.Application/Service/Management/DTO/UserModel.cs @@ -39,7 +39,7 @@ namespace IRaCIS.Application.Contracts public Guid Id { get; set; } public string UserName { get; set; } = string.Empty; public string RealName { get; set; } = string.Empty; - public int Sex { get; set; } // 1-男 2-女 + public int? Sex { get; set; } // 1-男 2-女 /// /// LastLoginIP @@ -131,7 +131,7 @@ namespace IRaCIS.Application.Contracts public string FirstName { get; set; } = string.Empty; public string LastName { get; set; } = string.Empty; - public int Sex { get; set; } // 1-男 2-女 + public int? Sex { get; set; } // 1-男 2-女 public int Status { get; set; } = 1; // 0-已删除 1-正常 diff --git a/IRaCIS.Core.Application/Service/TrialSiteUser/DTO/UserTrialViewModel.cs b/IRaCIS.Core.Application/Service/TrialSiteUser/DTO/UserTrialViewModel.cs index a2fdd4c03..a6d85a694 100644 --- a/IRaCIS.Core.Application/Service/TrialSiteUser/DTO/UserTrialViewModel.cs +++ b/IRaCIS.Core.Application/Service/TrialSiteUser/DTO/UserTrialViewModel.cs @@ -321,7 +321,7 @@ namespace IRaCIS.Application.Contracts public class TrialUserScreeningDTO : TrialUserAddCommand { - public int Sex { get; set; } // 1-男 2-女 + public int? Sex { get; set; } // 1-男 2-女 public string Phone { get; set; } = string.Empty; public string EMail { get; set; } = string.Empty; diff --git a/IRaCIS.Core.Domain/Management/User.cs b/IRaCIS.Core.Domain/Management/User.cs index 775c56fd5..099b0a9f9 100644 --- a/IRaCIS.Core.Domain/Management/User.cs +++ b/IRaCIS.Core.Domain/Management/User.cs @@ -36,7 +36,7 @@ namespace IRaCIS.Core.Domain.Models public string Phone { get; set; } = string.Empty; public string EMail { get; set; } = string.Empty; - public int Sex { get; set; } + public int? Sex { get; set; } public UserStateEnum Status { get; set; } = UserStateEnum.Enable; public DateTime? LastLoginTime { get; set; } From 47d8ec7576646f59c59654876ed2914a3cbc458e Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Tue, 13 Aug 2024 09:08:04 +0800 Subject: [PATCH 222/251] =?UTF-8?q?=E6=B8=85=E7=90=86=E4=B8=80=E8=87=B4?= =?UTF-8?q?=E6=80=A7=E5=88=86=E6=9E=90=E4=BB=BB=E5=8A=A1=E5=92=8C=E9=85=8D?= =?UTF-8?q?=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../IRaCIS.Core.Application.xml | 7 +++ IRaCIS.Core.Application/TestService.cs | 53 ++++++++++++++----- 2 files changed, 46 insertions(+), 14 deletions(-) diff --git a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml index 7ec1606de..36374a2b0 100644 --- a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml +++ b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml @@ -15383,6 +15383,13 @@ + + + 清理一致性分析任务 + + + + 维护临床数据 --一定要在同步表前同步数据才行 diff --git a/IRaCIS.Core.Application/TestService.cs b/IRaCIS.Core.Application/TestService.cs index 104a44f53..a28a9588c 100644 --- a/IRaCIS.Core.Application/TestService.cs +++ b/IRaCIS.Core.Application/TestService.cs @@ -69,6 +69,31 @@ namespace IRaCIS.Application.Services //_cache = cache; } + /// + /// 清理一致性分析任务 + /// + /// + /// + public async Task DeleteConsistentDate(Guid trialReadingCriterionId) + { + + + var consistentSubjectIdList = _repository.Where(t => t.TrialReadingCriterionId == trialReadingCriterionId && t.IsAnalysisCreate == true).Select(t => t.SubjectId).ToList(); + + await _repository.BatchDeleteAsync(t => t.TrialReadingCriterionId == trialReadingCriterionId); + + await _repository.BatchDeleteAsync(t => t.TrialReadingCriterionId == trialReadingCriterionId && t.IsAnalysisCreate == true); + + + + await _repository.BatchDeleteAsync(t => consistentSubjectIdList.Contains(t.ReadingConsistentClinicalData.SubjectId)); + + await _repository.BatchDeleteAsync(t => consistentSubjectIdList.Contains(t.SubjectId)); + + + await _repository.SaveChangesAsync(); + return ResponseOutput.Ok(); + } public async Task TestEFcore8() @@ -274,22 +299,22 @@ namespace IRaCIS.Application.Services throw new BusinessValidationFailedException("word 模板没有英文书签"); } - // 创建一个要删除段落的列表 + // 创建一个要删除段落的列表 - //XWPFParagraph bookmarkParagraph = null; + //XWPFParagraph bookmarkParagraph = null; - //foreach (var paragraph in doc.Paragraphs) - //{ + //foreach (var paragraph in doc.Paragraphs) + //{ - // foreach (var bookmark in paragraph.GetCTP().GetBookmarkStartList()) - // { - // if (bookmark.name == "en_us") - // { - // bookmarkParagraph = paragraph; - // break; - // } - // } - //} + // foreach (var bookmark in paragraph.GetCTP().GetBookmarkStartList()) + // { + // if (bookmark.name == "en_us") + // { + // bookmarkParagraph = paragraph; + // break; + // } + // } + //} @@ -300,7 +325,7 @@ namespace IRaCIS.Application.Services // doc.RemoveBodyElement(i); //} - + using (FileStream outStream = new FileStream("C:\\Users\\hang\\Desktop\\test1.docx", FileMode.Create, FileAccess.Write)) { From 871333b9e917051ac2a22304486354a9f1d86cdd Mon Sep 17 00:00:00 2001 From: he <109787524@qq.com> Date: Tue, 13 Aug 2024 14:53:10 +0800 Subject: [PATCH 223/251] =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Reading/ClinicalData/ReadingClinicalDataService.cs | 8 ++++---- .../Reading/ClinicalData/ReadingConsistentClinicalData.cs | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs b/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs index e9dee8944..7dcc8114c 100644 --- a/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs +++ b/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs @@ -1184,8 +1184,8 @@ namespace IRaCIS.Application.Services }).ToList(); entity.ReadingClinicalDataState = ReadingClinicalDataStatus.HaveUploaded; - entity.IsBlind = null; - entity.IsComplete = null; + entity.IsBlind = false; + entity.IsComplete = true; entity.FileCount = entity.ReadingClinicalDataPDFList.Count; await _readingConsistentClinicalDataRepository.AddAsync(entity, true); var success = await _readingConsistentClinicalDataRepository.SaveChangesAsync(); @@ -1214,8 +1214,8 @@ namespace IRaCIS.Application.Services if (indto.AddFileList.Count > 0 || indto.AddFileList.Count > 0) { - entity.IsComplete = null; - entity.IsBlind = null; + entity.IsComplete = true; + entity.IsBlind = false; } await _readingConsistentClinicalDataPDFRepository.AddRangeAsync(addFileList); diff --git a/IRaCIS.Core.Domain/Reading/ClinicalData/ReadingConsistentClinicalData.cs b/IRaCIS.Core.Domain/Reading/ClinicalData/ReadingConsistentClinicalData.cs index c57fc08e7..4de50e36a 100644 --- a/IRaCIS.Core.Domain/Reading/ClinicalData/ReadingConsistentClinicalData.cs +++ b/IRaCIS.Core.Domain/Reading/ClinicalData/ReadingConsistentClinicalData.cs @@ -54,12 +54,12 @@ namespace IRaCIS.Core.Domain.Models /// /// 是否盲化 /// - public bool? IsBlind { get; set; } + public bool? IsBlind { get; set; } = false; /// /// 是否完整 /// - public bool? IsComplete { get; set; } + public bool? IsComplete { get; set; } = true; /// /// 创建人 From a6cfe19139a095e773e69d3ee0427890bf1eb1b9 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Tue, 13 Aug 2024 15:24:17 +0800 Subject: [PATCH 224/251] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E7=94=A8=E6=88=B7?= =?UTF-8?q?=E7=B1=BB=E5=9E=8B=E8=BF=87=E6=BB=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Service/Management/UserTypeService.cs | 2 +- .../Service/QC/TrialQCQuestionService.cs | 6 +++--- .../Service/TrialSiteUser/TrialMaintenanceService.cs | 5 +++-- IRaCIS.Core.Application/TestService.cs | 4 +++- 4 files changed, 10 insertions(+), 7 deletions(-) diff --git a/IRaCIS.Core.Application/Service/Management/UserTypeService.cs b/IRaCIS.Core.Application/Service/Management/UserTypeService.cs index f12c9e3e8..ddcdf2936 100644 --- a/IRaCIS.Core.Application/Service/Management/UserTypeService.cs +++ b/IRaCIS.Core.Application/Service/Management/UserTypeService.cs @@ -119,7 +119,7 @@ namespace IRaCIS.Core.Application.Contracts if (userTypeSelectEnum == UserTypeSelectEnum.InnerUser) { - userTypeEnums = new List() { UserTypeEnum.IQC, UserTypeEnum.APM, UserTypeEnum.MIM, UserTypeEnum.QA ,UserTypeEnum.MW,UserTypeEnum.MC}; + userTypeEnums = new List() { UserTypeEnum.ClinicalResearchCoordinator, UserTypeEnum.CRA, UserTypeEnum.IQC, UserTypeEnum.APM, UserTypeEnum.MIM, UserTypeEnum.QA ,UserTypeEnum.MW,UserTypeEnum.MC}; if (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.SuperAdmin) { diff --git a/IRaCIS.Core.Application/Service/QC/TrialQCQuestionService.cs b/IRaCIS.Core.Application/Service/QC/TrialQCQuestionService.cs index 0521af0ca..ea2f77451 100644 --- a/IRaCIS.Core.Application/Service/QC/TrialQCQuestionService.cs +++ b/IRaCIS.Core.Application/Service/QC/TrialQCQuestionService.cs @@ -54,9 +54,9 @@ namespace IRaCIS.Core.Application.Contracts var trialQCQuestionQueryable = _trialQcQuestionRepository.Where(t => t.TrialId == queryTrialQCQuestionConfigure.TrialId) .WhereIf(!string.IsNullOrWhiteSpace(queryTrialQCQuestionConfigure.QuestionName), t => t.QuestionName.Contains(queryTrialQCQuestionConfigure.QuestionName)) .WhereIf(!string.IsNullOrWhiteSpace(queryTrialQCQuestionConfigure.Type), t => t.Type.Contains(queryTrialQCQuestionConfigure.Type)) - .WhereIf(queryTrialQCQuestionConfigure.IsEnable != null, t => t.IsEnable == queryTrialQCQuestionConfigure.IsEnable) - .WhereIf(queryTrialQCQuestionConfigure.IsRequired != null, t => t.IsRequired == queryTrialQCQuestionConfigure.IsRequired) - .WhereIf(queryTrialQCQuestionConfigure.LanguageType != null, t => t.LanguageType == queryTrialQCQuestionConfigure.LanguageType) + .WhereIf(queryTrialQCQuestionConfigure.IsEnable != null, t => t.IsEnable == queryTrialQCQuestionConfigure.IsEnable) + .WhereIf(queryTrialQCQuestionConfigure.IsRequired != null, t => t.IsRequired == queryTrialQCQuestionConfigure.IsRequired) + .WhereIf(queryTrialQCQuestionConfigure.LanguageType != null, t => t.LanguageType == queryTrialQCQuestionConfigure.LanguageType) .ProjectTo(_mapper.ConfigurationProvider); diff --git a/IRaCIS.Core.Application/Service/TrialSiteUser/TrialMaintenanceService.cs b/IRaCIS.Core.Application/Service/TrialSiteUser/TrialMaintenanceService.cs index 0629f5579..4734a2980 100644 --- a/IRaCIS.Core.Application/Service/TrialSiteUser/TrialMaintenanceService.cs +++ b/IRaCIS.Core.Application/Service/TrialSiteUser/TrialMaintenanceService.cs @@ -121,7 +121,8 @@ namespace IRaCIS.Application.Services { var trialType = _trialRepository.Where(t => t.Id == trialUserQuery.TrialId).Select(t => t.TrialType).FirstOrDefault(); - var userTypeEnums = new List() { UserTypeEnum.IQC, UserTypeEnum.APM, UserTypeEnum.MIM, UserTypeEnum.QA, UserTypeEnum.MW }; + var userTypeEnums = new List() { UserTypeEnum.ClinicalResearchCoordinator, UserTypeEnum.CRA, UserTypeEnum.IQC, UserTypeEnum.APM, UserTypeEnum.MIM, UserTypeEnum.QA, UserTypeEnum.MW, UserTypeEnum.MC }; + if (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.SuperAdmin) { userTypeEnums.Add(UserTypeEnum.ProjectManager); @@ -138,7 +139,7 @@ namespace IRaCIS.Application.Services .WhereIf(trialType == TrialType.NoneOfficial, t => t.IsTestUser == true || (t.IsTestUser == false && t.IsZhiZhun)) - + .Where(t=>userTypeEnums.Contains(t.UserTypeEnum)) .WhereIf(!string.IsNullOrWhiteSpace(trialUserQuery.UserRealName), t => (t.FullName).Contains(trialUserQuery.UserRealName)) diff --git a/IRaCIS.Core.Application/TestService.cs b/IRaCIS.Core.Application/TestService.cs index a28a9588c..6d617ec9c 100644 --- a/IRaCIS.Core.Application/TestService.cs +++ b/IRaCIS.Core.Application/TestService.cs @@ -85,7 +85,6 @@ namespace IRaCIS.Application.Services await _repository.BatchDeleteAsync(t => t.TrialReadingCriterionId == trialReadingCriterionId && t.IsAnalysisCreate == true); - await _repository.BatchDeleteAsync(t => consistentSubjectIdList.Contains(t.ReadingConsistentClinicalData.SubjectId)); await _repository.BatchDeleteAsync(t => consistentSubjectIdList.Contains(t.SubjectId)); @@ -199,6 +198,9 @@ namespace IRaCIS.Application.Services [UnitOfWork] public async Task Get() { + + await _repository.Where(t => t.SubjectId == Guid.Empty).Include(t => t.ReadingClinicalDataPDFList).ExecuteDeleteAsync(); + // Generate RSA keys var keyPair = RSAHelper.GenerateRSAKeyPair(2048); From c45461937d37480a0f4eb9a7a55eb855c3ec354a Mon Sep 17 00:00:00 2001 From: he <109787524@qq.com> Date: Tue, 13 Aug 2024 15:26:23 +0800 Subject: [PATCH 225/251] =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Service/Allocation/VisitTaskHelpeService.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/IRaCIS.Core.Application/Service/Allocation/VisitTaskHelpeService.cs b/IRaCIS.Core.Application/Service/Allocation/VisitTaskHelpeService.cs index 9bd628b3d..27b1e783d 100644 --- a/IRaCIS.Core.Application/Service/Allocation/VisitTaskHelpeService.cs +++ b/IRaCIS.Core.Application/Service/Allocation/VisitTaskHelpeService.cs @@ -1438,6 +1438,7 @@ namespace IRaCIS.Core.Application.Service { consistnentClinicalData.IsSign = false; consistnentClinicalData.IsBlind = false; + consistnentClinicalData.IsComplete = true; consistnentClinicalData.ReadingClinicalDataState = ReadingClinicalDataStatus.HaveUploaded; consistnentClinicalData.ClinicalDataTrialSet = null; } From d9ba6a7a895480eadb46112b8fe2dee7b4d69131 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Tue, 13 Aug 2024 17:44:27 +0800 Subject: [PATCH 226/251] =?UTF-8?q?=E4=B8=80=E8=87=B4=E6=80=A7=E5=88=86?= =?UTF-8?q?=E6=9E=90=E5=8E=9F=E9=98=85=E7=89=87=E4=BA=BA=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Service/Allocation/TaskConsistentRuleService.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/IRaCIS.Core.Application/Service/Allocation/TaskConsistentRuleService.cs b/IRaCIS.Core.Application/Service/Allocation/TaskConsistentRuleService.cs index 579c1e766..eeab0011c 100644 --- a/IRaCIS.Core.Application/Service/Allocation/TaskConsistentRuleService.cs +++ b/IRaCIS.Core.Application/Service/Allocation/TaskConsistentRuleService.cs @@ -711,7 +711,7 @@ namespace IRaCIS.Core.Application.Service IsHaveGeneratedTask = t.SubjectVisitTaskList.Any(c => c.IsSelfAnalysis == false && c.TrialReadingCriterionId == trialReadingCriterionId), - DoctorUserList = t.SubjectDoctorList.Where(t => t.TrialReadingCriterionId == trialReadingCriterionId && t.IsConfirmed).Select(t => new UserSimpleInfo() + DoctorUserList = t.SubjectDoctorList.Where(t => t.TrialReadingCriterionId == trialReadingCriterionId && t.IsConfirmed && t.ArmEnum<=Arm.DoubleReadingArm2).Select(t => new UserSimpleInfo() { UserId = t.Id, FullName = t.DoctorUser.FullName, From 4e44d163f387f7fb8dac8d32f360abb278822c24 Mon Sep 17 00:00:00 2001 From: he <109787524@qq.com> Date: Wed, 14 Aug 2024 11:21:33 +0800 Subject: [PATCH 227/251] =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Reading/ClinicalData/ReadingClinicalDataService.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs b/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs index 7dcc8114c..a4150cd7e 100644 --- a/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs +++ b/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs @@ -729,11 +729,12 @@ namespace IRaCIS.Application.Services public async Task<(List, object)> GetReadingOrTaskClinicalDataList(GetReadingOrTaskClinicalDataListInDto inDto) { var readingNameOrTaskBlindName = string.Empty; + var subjectCode = string.Empty; if (inDto.ReadingId == null) { var visitTask = await _visitTaskRepository.FirstOrDefaultAsync(x => x.Id == inDto.VisitTaskId); - - readingNameOrTaskBlindName = visitTask.TaskBlindName; + subjectCode=visitTask.BlindSubjectCode.IsNullOrEmpty() ? visitTask.Subject.Code : visitTask.BlindSubjectCode; + readingNameOrTaskBlindName = visitTask.TaskBlindName; } inDto.SelectIsSign = false; var result = await GetClinicalDataList(inDto); @@ -776,7 +777,7 @@ namespace IRaCIS.Application.Services return (result, new { - SubjectCode = await _subjectRepository.Where(x => x.Id == inDto.SubjectId).Select(x => x.Code).FirstOrDefaultAsync(), + SubjectCode = subjectCode, ReadingNameOrTaskBlindName = readingNameOrTaskBlindName, }); } From a9d81f5af53b8e7cd3df92eb9252424193cec892 Mon Sep 17 00:00:00 2001 From: he <109787524@qq.com> Date: Wed, 14 Aug 2024 13:05:35 +0800 Subject: [PATCH 228/251] =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Reading/ClinicalData/ReadingClinicalDataService.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs b/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs index a4150cd7e..df43bccba 100644 --- a/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs +++ b/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs @@ -732,8 +732,10 @@ namespace IRaCIS.Application.Services var subjectCode = string.Empty; if (inDto.ReadingId == null) { - var visitTask = await _visitTaskRepository.FirstOrDefaultAsync(x => x.Id == inDto.VisitTaskId); - subjectCode=visitTask.BlindSubjectCode.IsNullOrEmpty() ? visitTask.Subject.Code : visitTask.BlindSubjectCode; + var visitTask = await _visitTaskRepository.AsQueryable().Include(x=>x.Subject) + + .FirstOrDefaultAsync(x => x.Id == inDto.VisitTaskId); + subjectCode=visitTask.BlindSubjectCode.IsNullOrEmpty() ? visitTask.Subject.Code : visitTask.BlindSubjectCode; readingNameOrTaskBlindName = visitTask.TaskBlindName; } inDto.SelectIsSign = false; From c1fcb4f6e38119e3e8d57e46e4bab7c5798f6f1a Mon Sep 17 00:00:00 2001 From: he <109787524@qq.com> Date: Wed, 14 Aug 2024 13:37:22 +0800 Subject: [PATCH 229/251] =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Reading/ClinicalData/ReadingClinicalDataService.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs b/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs index df43bccba..31a3018a7 100644 --- a/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs +++ b/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs @@ -1272,7 +1272,9 @@ namespace IRaCIS.Application.Services var visittask = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).FirstNotNullAsync(); var readingId = visittask.SouceReadModuleId==null? visittask.SourceSubjectVisitId: visittask.SouceReadModuleId; - if (await _readingConsistentClinicalDataRepository.AnyAsync(x => x.ReadingId == readingId && x.IsSign == false)) + if (await _readingConsistentClinicalDataRepository.AnyAsync(x => x.ReadingId == readingId + + && x.ClinicalDataTrialSet.TrialClinicalDataSetCriteriaList.Any(t => t.TrialReadingCriterionId == visittask.TrialReadingCriterionId) && x.IsSign == false)) { return ResponseOutput.NotOk(_localizer["ReadingClinicalData_HaveUnsignedClinicalData"]); } From 161213f2afa237b5864dad2eb573d5838a360bb0 Mon Sep 17 00:00:00 2001 From: he <109787524@qq.com> Date: Wed, 14 Aug 2024 13:58:50 +0800 Subject: [PATCH 230/251] =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Service/Allocation/VisitTaskHelpeService.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/IRaCIS.Core.Application/Service/Allocation/VisitTaskHelpeService.cs b/IRaCIS.Core.Application/Service/Allocation/VisitTaskHelpeService.cs index 27b1e783d..1f405948e 100644 --- a/IRaCIS.Core.Application/Service/Allocation/VisitTaskHelpeService.cs +++ b/IRaCIS.Core.Application/Service/Allocation/VisitTaskHelpeService.cs @@ -1425,9 +1425,12 @@ namespace IRaCIS.Core.Application.Service && t.ClinicalUploadType == ClinicalUploadType.PDF); var taskState = exsitPDF ? TaskState.NotEffect : TaskState.Effect; + var firsttask = generateTaskCommand.GenerataConsistentTaskList[0]; + var clinicalDataList = _readingClinicalDataRepository.Where(t => t.SubjectId == subjectId + && t.ClinicalDataTrialSet.TrialClinicalDataSetCriteriaList.Any(y => y.TrialReadingCriterionId == firsttask.TrialReadingCriterionId) + && t.ClinicalDataTrialSet.ClinicalUploadType == ClinicalUploadType.PDF).Include(t => t.ReadingClinicalDataPDFList).Include(t => t.ClinicalDataTrialSet).ToList(); - var clinicalDataList = _readingClinicalDataRepository.Where(t => t.SubjectId == subjectId && t.ClinicalDataTrialSet.ClinicalUploadType == ClinicalUploadType.PDF).Include(t => t.ReadingClinicalDataPDFList).Include(t => t.ClinicalDataTrialSet).ToList(); - + foreach (var clinicalData in clinicalDataList) { var consistnentClinicalData = _mapper.Map(clinicalData); From 062387e6a8a9789d85b1b0be95a71da047dbca6e Mon Sep 17 00:00:00 2001 From: he <109787524@qq.com> Date: Wed, 14 Aug 2024 14:43:25 +0800 Subject: [PATCH 231/251] =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ClinicalData/ReadingClinicalDataService.cs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs b/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs index 31a3018a7..722c5497e 100644 --- a/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs +++ b/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs @@ -1269,7 +1269,7 @@ namespace IRaCIS.Application.Services [HttpPost] public async Task SetTaskValid(SetTaskValidInDto inDto) { - var visittask = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).FirstNotNullAsync(); + var visittask = await _visitTaskRepository.AsQueryable().Include(x=>x.TrialReadingCriterion).Where(x => x.Id == inDto.VisitTaskId).FirstNotNullAsync(); var readingId = visittask.SouceReadModuleId==null? visittask.SourceSubjectVisitId: visittask.SouceReadModuleId; if (await _readingConsistentClinicalDataRepository.AnyAsync(x => x.ReadingId == readingId @@ -1278,6 +1278,15 @@ namespace IRaCIS.Application.Services { return ResponseOutput.NotOk(_localizer["ReadingClinicalData_HaveUnsignedClinicalData"]); } + if(visittask.TrialReadingCriterion.IsReadingTaskViewInOrder== ReadingOrder.InOrder) + { + if(await _visitTaskRepository.Where(x=>x.SubjectId== visittask.SubjectId&&x.VisitTaskNum< visittask.VisitTaskNum&&x.IsAnalysisCreate==visittask.IsAnalysisCreate + &&x.IsSelfAnalysis==visittask.IsSelfAnalysis&&x.ArmEnum==visittask.ArmEnum&&x.TaskState==TaskState.NotEffect).AnyAsync() + ) + { + return ResponseOutput.NotOk(_localizer["ReadingClinicalData_NeedSetBeforeTaskEffect"]); + } + } await _visitTaskRepository.UpdatePartialFromQueryAsync(x => x.Id == inDto.VisitTaskId, x => new VisitTask() { From ab34c947ca5e02485f7dbd577ef504d51effa570 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Wed, 14 Aug 2024 14:43:48 +0800 Subject: [PATCH 232/251] =?UTF-8?q?=E5=90=8E=E7=AB=AF=E5=9B=BD=E9=99=85?= =?UTF-8?q?=E5=8C=96=E6=94=AF=E6=8C=81=EF=BC=8C=E6=97=A5=E5=BF=97=E8=AE=B0?= =?UTF-8?q?=E5=BD=95=E7=9A=84=E4=BF=A1=E6=81=AF=E5=92=8C=E8=BF=94=E5=9B=9E?= =?UTF-8?q?=E5=89=8D=E7=AB=AF=E7=9A=84=E5=9B=BD=E9=99=85=E5=8C=96=E4=B8=8D?= =?UTF-8?q?=E4=B8=80=E8=87=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.Application/BaseService.cs | 8 +- .../BusinessFilter/ProjectExceptionFilter.cs | 16 +-- .../BusinessFilter/UnifiedApiResultFilter.cs | 23 ++-- .../Helper/InternationalizationHelper.cs | 14 ++- .../Allocation/TaskConsistentRuleService.cs | 2 +- .../Common/InternationalizationService.cs | 2 +- .../Service/Visit/SubjectService.cs | 1 + IRaCIS.Core.Domain/IRaCIS.Core.Domain.csproj | 1 + .../IRaCIS.Core.Infrastructure.csproj | 2 + .../BusinessValidationFailedException.cs | 16 ++- .../_IRaCIS/Output/IResponseOutput.cs | 12 +- .../_IRaCIS/Output/ResponseOutput.cs | 104 +++++------------- .../_IRaCIS}/_Config/_StaticData.cs | 2 + 13 files changed, 92 insertions(+), 111 deletions(-) rename {IRaCIS.Core.Domain => IRaCIS.Core.Infrastructure/_IRaCIS}/_Config/_StaticData.cs (98%) diff --git a/IRaCIS.Core.Application/BaseService.cs b/IRaCIS.Core.Application/BaseService.cs index 9101ffa80..00df0c376 100644 --- a/IRaCIS.Core.Application/BaseService.cs +++ b/IRaCIS.Core.Application/BaseService.cs @@ -8,6 +8,7 @@ using Panda.DynamicWebApi; using Panda.DynamicWebApi.Attributes; using System.Diagnostics.CodeAnalysis; using IRaCIS.Core.Domain.Share; +using Microsoft.AspNetCore.Mvc; namespace IRaCIS.Core.Application { @@ -17,7 +18,8 @@ namespace IRaCIS.Core.Application #region 非泛型版本 - [Authorize, DynamicWebApi, UnifiedApiResultFilter] + [TypeFilter(typeof(UnifiedApiResultFilter))] + [Authorize, DynamicWebApi] public class BaseService : IBaseService, IDynamicWebApi { public IMapper _mapper { get; set; } @@ -83,8 +85,8 @@ namespace IRaCIS.Core.Application } - - [Authorize, DynamicWebApi, UnifiedApiResultFilter] + [TypeFilter(typeof(UnifiedApiResultFilter))] + [Authorize, DynamicWebApi] public class BaseServiceTest : IBaseServiceTest, IDynamicWebApi where T : Entity { public IMapper _mapper { get; set; } diff --git a/IRaCIS.Core.Application/BusinessFilter/ProjectExceptionFilter.cs b/IRaCIS.Core.Application/BusinessFilter/ProjectExceptionFilter.cs index 5638e52ea..62bd9b24c 100644 --- a/IRaCIS.Core.Application/BusinessFilter/ProjectExceptionFilter.cs +++ b/IRaCIS.Core.Application/BusinessFilter/ProjectExceptionFilter.cs @@ -1,4 +1,5 @@ -using IRaCIS.Core.Infrastructure; +using IRaCIS.Core.Domain.Share; +using IRaCIS.Core.Infrastructure; using IRaCIS.Core.Infrastructure.Extention; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Filters; @@ -34,7 +35,10 @@ namespace IRaCIS.Core.Application.Filter { var error = context.Exception as BusinessValidationFailedException; - context.Result = new JsonResult(ResponseOutput.NotOk(context.Exception.Message, error!.Code)); + context.Result = new JsonResult(ResponseOutput.NotOk(context.Exception.Message, error!.Code,localizedInfo: $"[{error!.LocalizedKey}]:{StaticData.Log_Locoalize_Dic[error!.LocalizedKey]}")); + + //warning 级别记录 + //_logger.LogWarning($"[{error!.LocalizedKey}]:{StaticData.Log_Locoalize_Dic[error!.LocalizedKey]}"); } else if(context.Exception.GetType() == typeof(QueryBusinessObjectNotExistException)) { @@ -44,12 +48,10 @@ namespace IRaCIS.Core.Application.Filter { context.Result = new JsonResult(ResponseOutput.NotOk(_localizer["Project_ExceptionContactDeveloper"] + (context.Exception.InnerException is null ? (context.Exception.Message /*+ context.Exception.StackTrace*/) : (context.Exception.InnerException?.Message /*+ context.Exception.InnerException?.StackTrace*/)), ApiResponseCodeEnum.ProgramException)); + + _logger.LogError(context.Exception.InnerException is null ? (context.Exception.Message + context.Exception.StackTrace) : (context.Exception.InnerException?.Message + context.Exception.InnerException?.StackTrace)); + } - - - _logger.LogError(context.Exception.InnerException is null ? (context.Exception.Message + context.Exception.StackTrace) : (context.Exception.InnerException?.Message + context.Exception.InnerException?.StackTrace)); - - } else { diff --git a/IRaCIS.Core.Application/BusinessFilter/UnifiedApiResultFilter.cs b/IRaCIS.Core.Application/BusinessFilter/UnifiedApiResultFilter.cs index 9e5fdf591..39756a340 100644 --- a/IRaCIS.Core.Application/BusinessFilter/UnifiedApiResultFilter.cs +++ b/IRaCIS.Core.Application/BusinessFilter/UnifiedApiResultFilter.cs @@ -1,6 +1,7 @@ using Microsoft.AspNetCore.Mvc.Filters; using Microsoft.AspNetCore.Mvc; using IRaCIS.Core.Domain.Share; +using Microsoft.Extensions.Logging; namespace IRaCIS.Application.Services.BusinessFilter { @@ -10,6 +11,12 @@ namespace IRaCIS.Application.Services.BusinessFilter /// public class UnifiedApiResultFilter : Attribute, IAsyncResultFilter { + private readonly ILogger _logger; + + public UnifiedApiResultFilter(ILogger logger) + { + _logger = logger; + } /// /// 异步版本 @@ -31,12 +38,11 @@ namespace IRaCIS.Application.Services.BusinessFilter var type = objectResult.Value?.GetType(); - if ( type!=null&& type.IsGenericType&&(type.GetGenericTypeDefinition()==typeof(ValueTuple<,>)|| type.GetGenericTypeDefinition()==typeof(Tuple<,>))) + if (type != null && type.IsGenericType && (type.GetGenericTypeDefinition() == typeof(ValueTuple<,>) || type.GetGenericTypeDefinition() == typeof(Tuple<,>))) { //报错 //var tuple = (object, object))objectResult.Value; - //var (val1, val2) = ((dynamic, dynamic))objectResult.Value; //var apiResponse = ResponseOutput.Ok(val1, val2); @@ -56,16 +62,19 @@ namespace IRaCIS.Application.Services.BusinessFilter objectResult.DeclaredType = apiResponse.GetType(); } - + } - //如果不是200 是IResponseOutput 不处理 - else if (statusCode != 200 && (objectResult.Value is IResponseOutput)) + //如果是200 是IResponseOutput 记录下日志 + else if (statusCode == 200 && (objectResult.Value is IResponseOutput)) { + var result = objectResult.Value as IResponseOutput; + + _logger.LogWarning($"{result.LocalizedInfo}"); } - else if(statusCode != 200&&!(objectResult.Value is IResponseOutput)) + else if (statusCode != 200 && !(objectResult.Value is IResponseOutput)) { - //---程序错误,请联系开发人员。 + //---程序错误,请联系开发人员。 var apiResponse = ResponseOutput.NotOk(StaticData.International("UnifiedAPI_ProgramError")); objectResult.Value = apiResponse; diff --git a/IRaCIS.Core.Application/Helper/InternationalizationHelper.cs b/IRaCIS.Core.Application/Helper/InternationalizationHelper.cs index eaa357c55..910f35e14 100644 --- a/IRaCIS.Core.Application/Helper/InternationalizationHelper.cs +++ b/IRaCIS.Core.Application/Helper/InternationalizationHelper.cs @@ -53,6 +53,9 @@ namespace IRaCIS.Core.Application.Helper jsonObject[item.Code] = item.Value; StaticData.En_US_Dic[item.Code] = item.Value; + + //日志记录该信息方便自己人看, 返回给客户的是配置的 + StaticData.Log_Locoalize_Dic[item.Code] = item.Description; } } else @@ -71,7 +74,7 @@ namespace IRaCIS.Core.Application.Helper } } - public static async Task AddOrUpdateJsonKeyValueAsync(string key, string value, string valueCN) + public static async Task AddOrUpdateJsonKeyValueAsync(string key, string value, string valueCN,string description) { VerifyFolder(); @@ -94,6 +97,9 @@ namespace IRaCIS.Core.Application.Helper jsonObject[key] = value; StaticData.En_US_Dic[key] = value; + + //日志记录该信息方便自己人看, 返回给客户的是配置的 + StaticData.Log_Locoalize_Dic[key] = description; } else { @@ -117,7 +123,8 @@ namespace IRaCIS.Core.Application.Helper { t.Code, t.Value, - t.ValueCN + t.ValueCN, + t.Description }).ToListAsync(); //组织成json 文件 @@ -131,6 +138,9 @@ namespace IRaCIS.Core.Application.Helper { StaticData.En_US_Dic[tojsonItem.Code] = tojsonItem.Value; StaticData.Zh_CN_Dic[tojsonItem.Code] = tojsonItem.ValueCN; + + //日志记录该信息方便自己人看, 返回给客户的是配置的 + StaticData.Log_Locoalize_Dic[tojsonItem.Code] = tojsonItem.Description; } File.WriteAllText(usJsonPath, JsonConvert.SerializeObject(StaticData.En_US_Dic)); diff --git a/IRaCIS.Core.Application/Service/Allocation/TaskConsistentRuleService.cs b/IRaCIS.Core.Application/Service/Allocation/TaskConsistentRuleService.cs index eeab0011c..44297c8fa 100644 --- a/IRaCIS.Core.Application/Service/Allocation/TaskConsistentRuleService.cs +++ b/IRaCIS.Core.Application/Service/Allocation/TaskConsistentRuleService.cs @@ -711,7 +711,7 @@ namespace IRaCIS.Core.Application.Service IsHaveGeneratedTask = t.SubjectVisitTaskList.Any(c => c.IsSelfAnalysis == false && c.TrialReadingCriterionId == trialReadingCriterionId), - DoctorUserList = t.SubjectDoctorList.Where(t => t.TrialReadingCriterionId == trialReadingCriterionId && t.IsConfirmed && t.ArmEnum<=Arm.DoubleReadingArm2).Select(t => new UserSimpleInfo() + DoctorUserList = t.SubjectDoctorList.Where(t => t.TrialReadingCriterionId == trialReadingCriterionId && t.IsConfirmed && t.ArmEnum <= Arm.DoubleReadingArm2).Select(t => new UserSimpleInfo() { UserId = t.Id, FullName = t.DoctorUser.FullName, diff --git a/IRaCIS.Core.Application/Service/Common/InternationalizationService.cs b/IRaCIS.Core.Application/Service/Common/InternationalizationService.cs index 10289e9a5..47723708e 100644 --- a/IRaCIS.Core.Application/Service/Common/InternationalizationService.cs +++ b/IRaCIS.Core.Application/Service/Common/InternationalizationService.cs @@ -184,7 +184,7 @@ namespace IRaCIS.Core.Application.Service if (addOrEditInternationalization.InternationalizationType == 1) { - await InternationalizationHelper.AddOrUpdateJsonKeyValueAsync(entity.Code, addOrEditInternationalization.Value, addOrEditInternationalization.ValueCN); + await InternationalizationHelper.AddOrUpdateJsonKeyValueAsync(entity.Code, addOrEditInternationalization.Value, addOrEditInternationalization.ValueCN,addOrEditInternationalization.Description); } else { diff --git a/IRaCIS.Core.Application/Service/Visit/SubjectService.cs b/IRaCIS.Core.Application/Service/Visit/SubjectService.cs index d9e1ace36..cb21db1dc 100644 --- a/IRaCIS.Core.Application/Service/Visit/SubjectService.cs +++ b/IRaCIS.Core.Application/Service/Visit/SubjectService.cs @@ -6,6 +6,7 @@ using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Authorization; using IRaCIS.Core.Application.Auth; using IRaCIS.Core.Domain.Models; +using IRaCIS.Core.Infrastructure; namespace IRaCIS.Application.Services { diff --git a/IRaCIS.Core.Domain/IRaCIS.Core.Domain.csproj b/IRaCIS.Core.Domain/IRaCIS.Core.Domain.csproj index ac7815099..80a3e8702 100644 --- a/IRaCIS.Core.Domain/IRaCIS.Core.Domain.csproj +++ b/IRaCIS.Core.Domain/IRaCIS.Core.Domain.csproj @@ -10,6 +10,7 @@ + diff --git a/IRaCIS.Core.Infrastructure/IRaCIS.Core.Infrastructure.csproj b/IRaCIS.Core.Infrastructure/IRaCIS.Core.Infrastructure.csproj index f2b268e49..324ac91a0 100644 --- a/IRaCIS.Core.Infrastructure/IRaCIS.Core.Infrastructure.csproj +++ b/IRaCIS.Core.Infrastructure/IRaCIS.Core.Infrastructure.csproj @@ -11,6 +11,8 @@ + + diff --git a/IRaCIS.Core.Infrastructure/_IRaCIS/Exception/BusinessValidationFailedException.cs b/IRaCIS.Core.Infrastructure/_IRaCIS/Exception/BusinessValidationFailedException.cs index cbe9ec767..1939d57cd 100644 --- a/IRaCIS.Core.Infrastructure/_IRaCIS/Exception/BusinessValidationFailedException.cs +++ b/IRaCIS.Core.Infrastructure/_IRaCIS/Exception/BusinessValidationFailedException.cs @@ -1,4 +1,5 @@ using IRaCIS.Core.Infrastructure.Extention; +using Microsoft.Extensions.Localization; using System; namespace IRaCIS.Core.Infrastructure @@ -8,15 +9,24 @@ namespace IRaCIS.Core.Infrastructure public ApiResponseCodeEnum Code { get; set; } - public BusinessValidationFailedException() + public string LocalizedKey { get; set; }=string.Empty; + + public BusinessValidationFailedException() { } + public BusinessValidationFailedException(LocalizedString message, ApiResponseCodeEnum code = ApiResponseCodeEnum.BusinessValidationFailed) : base(message) + { + Code = code; + LocalizedKey=message.Name; + + } + public BusinessValidationFailedException(string message, ApiResponseCodeEnum code = ApiResponseCodeEnum.BusinessValidationFailed) : base(message) { - Code = code; + Code = code; - } + } } } diff --git a/IRaCIS.Core.Infrastructure/_IRaCIS/Output/IResponseOutput.cs b/IRaCIS.Core.Infrastructure/_IRaCIS/Output/IResponseOutput.cs index 13b15698a..a0edd84d0 100644 --- a/IRaCIS.Core.Infrastructure/_IRaCIS/Output/IResponseOutput.cs +++ b/IRaCIS.Core.Infrastructure/_IRaCIS/Output/IResponseOutput.cs @@ -16,6 +16,9 @@ /// 消息 /// string ErrorMessage { get; } + + + public string LocalizedInfo { get; set; } } /// @@ -30,13 +33,4 @@ T Data { get; set; } } - //public interface IResponseOutput : IResponseOutput - //{ - // /// - // /// 返回数据 - // /// - // T Data { get; } - - // T2 OtherInfo { get; } - //} } diff --git a/IRaCIS.Core.Infrastructure/_IRaCIS/Output/ResponseOutput.cs b/IRaCIS.Core.Infrastructure/_IRaCIS/Output/ResponseOutput.cs index 74325db91..e0b46da46 100644 --- a/IRaCIS.Core.Infrastructure/_IRaCIS/Output/ResponseOutput.cs +++ b/IRaCIS.Core.Infrastructure/_IRaCIS/Output/ResponseOutput.cs @@ -1,4 +1,7 @@ -using Newtonsoft.Json; +using IRaCIS.Core.Domain.Share; +using Microsoft.Extensions.Localization; +using Microsoft.Extensions.Logging; +using Newtonsoft.Json; namespace IRaCIS.Core.Infrastructure.Extention { @@ -7,10 +10,10 @@ namespace IRaCIS.Core.Infrastructure.Extention /// public class ResponseOutput : IResponseOutput { - /// - /// 是否成功标记 - /// - public bool IsSuccess { get; private set; } + /// + /// 是否成功标记 + /// + public bool IsSuccess { get; private set; } public ApiResponseCodeEnum Code { get; set; } = ApiResponseCodeEnum.OK; @@ -25,34 +28,20 @@ namespace IRaCIS.Core.Infrastructure.Extention /// 数据 兼顾以前 Json序列化的时候返回属性名为“Result” /// [JsonProperty("Result")] - public T Data { get; set; } + public T Data { get; set; } [JsonProperty("OtherInfo")] public object OtherData { get; set; } + public string LocalizedInfo { get; set; } - /// - /// 成功 - /// - /// 数据 - /// 消息 - //public ResponseOutput Ok(T data, string msg = "", ApiResponseCodeEnum code = ApiResponseCodeEnum.OK) - //{ - // IsSuccess = true; - // Code = code; - // Data = data; - // ErrorMessage = msg; - - // return this; - //} - - public ResponseOutput Ok(T data, object otherData, string msg = "", ApiResponseCodeEnum code = ApiResponseCodeEnum.OK) + public ResponseOutput Ok(T data, object otherData, string msg = "", ApiResponseCodeEnum code = ApiResponseCodeEnum.OK) { IsSuccess = true; Code = code; Data = data; - OtherData=otherData; + OtherData = otherData; ErrorMessage = msg; return this; @@ -64,12 +53,13 @@ namespace IRaCIS.Core.Infrastructure.Extention /// 提示消息 /// 数据 /// - public ResponseOutput NotOk(string msg = "", T data = default, ApiResponseCodeEnum code = ApiResponseCodeEnum.OK) + public ResponseOutput NotOk(string msg = "", T data = default, ApiResponseCodeEnum code = ApiResponseCodeEnum.OK, string localizedInfo = "") { IsSuccess = false; - Code = code; + Code = code; ErrorMessage = msg; Data = data; + LocalizedInfo = localizedInfo; return this; } @@ -77,33 +67,6 @@ namespace IRaCIS.Core.Infrastructure.Extention } - //public class ResponseOutput : IResponseOutput - //{ - // [JsonProperty("Result")] - // public T Data { get; private set; } - - // public T2 OtherInfo { get; private set; } - - // public bool IsSuccess { get; private set; } - - // public ApiResponseCodeEnum Code { get; set; } - - - // public string ErrorMessage { get; private set; } - - - // public ResponseOutput Ok(T data, T2 otherInfo, string msg = "") - // { - // IsSuccess = true; - // Data = data; - // OtherInfo = otherInfo; - // ErrorMessage = msg; - - // return this; - // } - //} - - /// /// 响应数据静态输出 为了代码简洁 不用每处都New /// @@ -111,23 +74,6 @@ namespace IRaCIS.Core.Infrastructure.Extention { - //public static IResponseOutput Ok(T data, T2 otherInfo, string msg = "") - //{ - // return new ResponseOutput().Ok(data, otherInfo); - //} - - - /// - /// 成功 -----适合查询 - /// - /// 数据 - /// 消息 - /// - //public static IResponseOutput Ok(T data = default, string msg = "") - //{ - // return new ResponseOutput().Ok(data, msg); - //} - public static IResponseOutput Ok(T data = default, object otherData = default, string msg = "", ApiResponseCodeEnum code = ApiResponseCodeEnum.OK) { return new ResponseOutput().Ok(data, otherData, msg, code); @@ -147,15 +93,11 @@ namespace IRaCIS.Core.Infrastructure.Extention /// 消息 /// 数据 /// - public static IResponseOutput NotOk(string msg = "", T data = default, ApiResponseCodeEnum code = ApiResponseCodeEnum.BusinessValidationFailed) + public static IResponseOutput NotOk(string msg = "", T data = default, ApiResponseCodeEnum code = ApiResponseCodeEnum.BusinessValidationFailed, string localizedInfo = "") { - return new ResponseOutput().NotOk(msg, data, code); + return new ResponseOutput().NotOk(msg, data, code, localizedInfo); } - //public static IResponseOutput NotOk( T data = default, ApiResponseCodeEnum code = ApiResponseCodeEnum.BusinessValidationFailed) - //{ - // return new ResponseOutput().NotOk("", data, code); - //} /// /// 失败 @@ -164,7 +106,13 @@ namespace IRaCIS.Core.Infrastructure.Extention /// public static IResponseOutput NotOk(string msg = "", ApiResponseCodeEnum code = ApiResponseCodeEnum.BusinessValidationFailed) { - return new ResponseOutput().NotOk(msg,code:code); + return new ResponseOutput().NotOk(msg, code: code); + } + + public static IResponseOutput NotOk(LocalizedString msg, ApiResponseCodeEnum code = ApiResponseCodeEnum.BusinessValidationFailed) + { + + return new ResponseOutput().NotOk(msg, code: code, localizedInfo: $"[{msg.Name}]:{StaticData.Log_Locoalize_Dic[msg.Name]}" ); } public static IResponseOutput DBNotExistIfNUll(object businessObject) @@ -172,7 +120,7 @@ namespace IRaCIS.Core.Infrastructure.Extention return new ResponseOutput().NotOk($"The business object{businessObject.GetType().Name} does not exist in the database, or was deleted by someone else, or an incorrect parameter query caused"); } - + /// /// 根据布尔值返回结果 --适合删除 /// @@ -190,7 +138,7 @@ namespace IRaCIS.Core.Infrastructure.Extention /// public static IResponseOutput Result(bool success, T data = default) { - return success ? Ok(data) : NotOk("Saved failed",data); + return success ? Ok(data) : NotOk("Saved failed", data); } ///// diff --git a/IRaCIS.Core.Domain/_Config/_StaticData.cs b/IRaCIS.Core.Infrastructure/_IRaCIS/_Config/_StaticData.cs similarity index 98% rename from IRaCIS.Core.Domain/_Config/_StaticData.cs rename to IRaCIS.Core.Infrastructure/_IRaCIS/_Config/_StaticData.cs index 117e658fa..42ab4a9ca 100644 --- a/IRaCIS.Core.Domain/_Config/_StaticData.cs +++ b/IRaCIS.Core.Infrastructure/_IRaCIS/_Config/_StaticData.cs @@ -12,6 +12,8 @@ public static class StaticData public static Dictionary Zh_CN_Dic = new Dictionary(); + public static Dictionary Log_Locoalize_Dic = new Dictionary(); + public static readonly string En_US_Json = "en-US.json"; public static readonly string Zh_CN_Json = "zh-CN.json"; From 1d7e1be6413350d4cc137ace21c4d19a98a48612 Mon Sep 17 00:00:00 2001 From: he <109787524@qq.com> Date: Wed, 14 Aug 2024 15:12:20 +0800 Subject: [PATCH 233/251] =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Service/Allocation/VisitTaskHelpeService.cs | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/IRaCIS.Core.Application/Service/Allocation/VisitTaskHelpeService.cs b/IRaCIS.Core.Application/Service/Allocation/VisitTaskHelpeService.cs index 1f405948e..70269270c 100644 --- a/IRaCIS.Core.Application/Service/Allocation/VisitTaskHelpeService.cs +++ b/IRaCIS.Core.Application/Service/Allocation/VisitTaskHelpeService.cs @@ -1420,11 +1420,6 @@ namespace IRaCIS.Core.Application.Service //判断是否存在传输方式为Pdf得临床数据 - var exsitPDF = await _trialClinicalDataSetRepository.AnyAsync(t => t.TrialId == trialId && - t.TrialClinicalDataSetCriteriaList.Any(c => c.TrialReadingCriterionId == readingCriterionId) - && t.ClinicalUploadType == ClinicalUploadType.PDF); - - var taskState = exsitPDF ? TaskState.NotEffect : TaskState.Effect; var firsttask = generateTaskCommand.GenerataConsistentTaskList[0]; var clinicalDataList = _readingClinicalDataRepository.Where(t => t.SubjectId == subjectId && t.ClinicalDataTrialSet.TrialClinicalDataSetCriteriaList.Any(y => y.TrialReadingCriterionId == firsttask.TrialReadingCriterionId) @@ -1457,6 +1452,13 @@ namespace IRaCIS.Core.Application.Service foreach (var task in generateTaskCommand.GenerataConsistentTaskList) { + + var exsitPDF = await _readingClinicalDataRepository.AnyAsync(t => t.TrialId == trialId && + t.SubjectId== task.SubjectId&& + t.ClinicalDataTrialSet.TrialClinicalDataSetCriteriaList.Any(c => c.TrialReadingCriterionId == readingCriterionId) + && t.ClinicalDataTrialSet.ClinicalUploadType == ClinicalUploadType.PDF); + + var taskState = exsitPDF ? TaskState.NotEffect : TaskState.Effect; var consistentTask = new VisitTask() { TrialId = task.TrialId, From cafdbaac573bf59c62fad9778ba12fecd9de8a01 Mon Sep 17 00:00:00 2001 From: he <109787524@qq.com> Date: Wed, 14 Aug 2024 16:06:00 +0800 Subject: [PATCH 234/251] =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Reading/ClinicalData/ReadingClinicalDataService.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs b/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs index 722c5497e..f49b2e71a 100644 --- a/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs +++ b/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs @@ -1280,7 +1280,9 @@ namespace IRaCIS.Application.Services } if(visittask.TrialReadingCriterion.IsReadingTaskViewInOrder== ReadingOrder.InOrder) { - if(await _visitTaskRepository.Where(x=>x.SubjectId== visittask.SubjectId&&x.VisitTaskNum< visittask.VisitTaskNum&&x.IsAnalysisCreate==visittask.IsAnalysisCreate + if(await _visitTaskRepository.Where(x=>x.SubjectId== visittask.SubjectId + &&x.TrialReadingCriterionId== visittask.TrialReadingCriterionId + &&x.VisitTaskNum< visittask.VisitTaskNum&&x.IsAnalysisCreate==visittask.IsAnalysisCreate &&x.IsSelfAnalysis==visittask.IsSelfAnalysis&&x.ArmEnum==visittask.ArmEnum&&x.TaskState==TaskState.NotEffect).AnyAsync() ) { From 568ef0743887a361e352437e5d85d6b0fae8a287 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Wed, 14 Aug 2024 16:36:29 +0800 Subject: [PATCH 235/251] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=8F=90=E7=A4=BA?= =?UTF-8?q?=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../BusinessFilter/ProjectExceptionFilter.cs | 2 +- .../BusinessFilter/UnifiedApiResultFilter.cs | 1 + .../Service/Common/DTO/InternationalizationViewModel.cs | 3 +-- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/IRaCIS.Core.Application/BusinessFilter/ProjectExceptionFilter.cs b/IRaCIS.Core.Application/BusinessFilter/ProjectExceptionFilter.cs index 62bd9b24c..1649f3ea7 100644 --- a/IRaCIS.Core.Application/BusinessFilter/ProjectExceptionFilter.cs +++ b/IRaCIS.Core.Application/BusinessFilter/ProjectExceptionFilter.cs @@ -35,7 +35,7 @@ namespace IRaCIS.Core.Application.Filter { var error = context.Exception as BusinessValidationFailedException; - context.Result = new JsonResult(ResponseOutput.NotOk(context.Exception.Message, error!.Code,localizedInfo: $"[{error!.LocalizedKey}]:{StaticData.Log_Locoalize_Dic[error!.LocalizedKey]}")); + context.Result = new JsonResult(ResponseOutput.NotOk(context.Exception.Message,"", error!.Code,localizedInfo: $"[{error!.LocalizedKey}]:{StaticData.Log_Locoalize_Dic[error!.LocalizedKey]}")); //warning 级别记录 //_logger.LogWarning($"[{error!.LocalizedKey}]:{StaticData.Log_Locoalize_Dic[error!.LocalizedKey]}"); diff --git a/IRaCIS.Core.Application/BusinessFilter/UnifiedApiResultFilter.cs b/IRaCIS.Core.Application/BusinessFilter/UnifiedApiResultFilter.cs index 39756a340..3e135e386 100644 --- a/IRaCIS.Core.Application/BusinessFilter/UnifiedApiResultFilter.cs +++ b/IRaCIS.Core.Application/BusinessFilter/UnifiedApiResultFilter.cs @@ -69,6 +69,7 @@ namespace IRaCIS.Application.Services.BusinessFilter { var result = objectResult.Value as IResponseOutput; + //统一在这里记录国际化的日志信息 _logger.LogWarning($"{result.LocalizedInfo}"); } diff --git a/IRaCIS.Core.Application/Service/Common/DTO/InternationalizationViewModel.cs b/IRaCIS.Core.Application/Service/Common/DTO/InternationalizationViewModel.cs index eb64a391e..53b162923 100644 --- a/IRaCIS.Core.Application/Service/Common/DTO/InternationalizationViewModel.cs +++ b/IRaCIS.Core.Application/Service/Common/DTO/InternationalizationViewModel.cs @@ -76,8 +76,7 @@ namespace IRaCIS.Core.Application.ViewModel public string ValueCN { get; set; } = string.Empty; public string Module { get; set; } = string.Empty; - //关联版本历史记录表Id - public Guid? PublishLogId { get; set; } + } public class BatchAddInternationalizationDto : BatchInternationalizationDto From 5e8b5eed9f11501512f7821aa5e79a247a5363a4 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Wed, 14 Aug 2024 16:52:03 +0800 Subject: [PATCH 236/251] =?UTF-8?q?=E5=8F=96=E5=AD=97=E5=85=B8=E7=9A=84?= =?UTF-8?q?=E5=80=BC=E7=9A=84=E6=97=B6=E5=80=99=E8=BF=9B=E8=A1=8C=E5=88=A4?= =?UTF-8?q?=E6=96=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../BusinessFilter/ProjectExceptionFilter.cs | 24 ++++++++++++------- .../_IRaCIS/Output/ResponseOutput.cs | 12 +++++++++- 2 files changed, 27 insertions(+), 9 deletions(-) diff --git a/IRaCIS.Core.Application/BusinessFilter/ProjectExceptionFilter.cs b/IRaCIS.Core.Application/BusinessFilter/ProjectExceptionFilter.cs index 1649f3ea7..823c168da 100644 --- a/IRaCIS.Core.Application/BusinessFilter/ProjectExceptionFilter.cs +++ b/IRaCIS.Core.Application/BusinessFilter/ProjectExceptionFilter.cs @@ -12,13 +12,13 @@ namespace IRaCIS.Core.Application.Filter { private readonly ILogger _logger; - public IStringLocalizer _localizer; + public IStringLocalizer _localizer; - public ProjectExceptionFilter(IStringLocalizer localizer, ILogger logger) + public ProjectExceptionFilter(IStringLocalizer localizer, ILogger logger) { _logger = logger; - _localizer = localizer; - } + _localizer = localizer; + } public void OnException(ExceptionContext context) { //context.ExceptionHandled;//记录当前这个异常是否已经被处理过了 @@ -27,7 +27,7 @@ namespace IRaCIS.Core.Application.Filter { if (context.Exception.GetType().Name == "DbUpdateConcurrencyException") { - //---并发更新,当前不允许该操作 + //---并发更新,当前不允许该操作 context.Result = new JsonResult(ResponseOutput.NotOk(_localizer["ProjectException_ConcurrentUpdateNotAllowed"] + context.Exception.Message)); } @@ -35,14 +35,22 @@ namespace IRaCIS.Core.Application.Filter { var error = context.Exception as BusinessValidationFailedException; - context.Result = new JsonResult(ResponseOutput.NotOk(context.Exception.Message,"", error!.Code,localizedInfo: $"[{error!.LocalizedKey}]:{StaticData.Log_Locoalize_Dic[error!.LocalizedKey]}")); + var info = string.Empty; + + if (!string.IsNullOrWhiteSpace(error!.LocalizedKey) && StaticData.Log_Locoalize_Dic.ContainsKey(error!.LocalizedKey)) + { + info = $"[{error!.LocalizedKey}]:{StaticData.Log_Locoalize_Dic[error!.LocalizedKey]}"; + } + + + context.Result = new JsonResult(ResponseOutput.NotOk(context.Exception.Message, "", error!.Code, localizedInfo: info)); //warning 级别记录 //_logger.LogWarning($"[{error!.LocalizedKey}]:{StaticData.Log_Locoalize_Dic[error!.LocalizedKey]}"); } - else if(context.Exception.GetType() == typeof(QueryBusinessObjectNotExistException)) + else if (context.Exception.GetType() == typeof(QueryBusinessObjectNotExistException)) { - context.Result = new JsonResult(ResponseOutput.NotOk( context.Exception.Message, ApiResponseCodeEnum.DataNotExist)); + context.Result = new JsonResult(ResponseOutput.NotOk(context.Exception.Message, ApiResponseCodeEnum.DataNotExist)); } else { diff --git a/IRaCIS.Core.Infrastructure/_IRaCIS/Output/ResponseOutput.cs b/IRaCIS.Core.Infrastructure/_IRaCIS/Output/ResponseOutput.cs index e0b46da46..9023c87e5 100644 --- a/IRaCIS.Core.Infrastructure/_IRaCIS/Output/ResponseOutput.cs +++ b/IRaCIS.Core.Infrastructure/_IRaCIS/Output/ResponseOutput.cs @@ -2,6 +2,7 @@ using Microsoft.Extensions.Localization; using Microsoft.Extensions.Logging; using Newtonsoft.Json; +using static System.Runtime.InteropServices.JavaScript.JSType; namespace IRaCIS.Core.Infrastructure.Extention { @@ -112,7 +113,16 @@ namespace IRaCIS.Core.Infrastructure.Extention public static IResponseOutput NotOk(LocalizedString msg, ApiResponseCodeEnum code = ApiResponseCodeEnum.BusinessValidationFailed) { - return new ResponseOutput().NotOk(msg, code: code, localizedInfo: $"[{msg.Name}]:{StaticData.Log_Locoalize_Dic[msg.Name]}" ); + var key = msg.Name; + + var info = string.Empty; + + if (!string.IsNullOrWhiteSpace(key) && StaticData.Log_Locoalize_Dic.ContainsKey(key)) + { + info = $"[{key}]:{StaticData.Log_Locoalize_Dic[key]}"; + } + + return new ResponseOutput().NotOk(msg, code: code, localizedInfo: info); } public static IResponseOutput DBNotExistIfNUll(object businessObject) From a16f567adea0dff65e53e5fc6de03c0bb2e67ec1 Mon Sep 17 00:00:00 2001 From: he <109787524@qq.com> Date: Wed, 14 Aug 2024 17:38:44 +0800 Subject: [PATCH 237/251] =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Service/Allocation/VisitTaskHelpeService.cs | 3 +++ .../Service/Reading/ClinicalData/ReadingClinicalDataService.cs | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/IRaCIS.Core.Application/Service/Allocation/VisitTaskHelpeService.cs b/IRaCIS.Core.Application/Service/Allocation/VisitTaskHelpeService.cs index 70269270c..7ad3c40b1 100644 --- a/IRaCIS.Core.Application/Service/Allocation/VisitTaskHelpeService.cs +++ b/IRaCIS.Core.Application/Service/Allocation/VisitTaskHelpeService.cs @@ -1423,6 +1423,7 @@ namespace IRaCIS.Core.Application.Service var firsttask = generateTaskCommand.GenerataConsistentTaskList[0]; var clinicalDataList = _readingClinicalDataRepository.Where(t => t.SubjectId == subjectId && t.ClinicalDataTrialSet.TrialClinicalDataSetCriteriaList.Any(y => y.TrialReadingCriterionId == firsttask.TrialReadingCriterionId) + && t.ClinicalDataTrialSet.ClinicalDataLevel!= ClinicalLevel.Study && t.ClinicalDataTrialSet.ClinicalUploadType == ClinicalUploadType.PDF).Include(t => t.ReadingClinicalDataPDFList).Include(t => t.ClinicalDataTrialSet).ToList(); @@ -1455,7 +1456,9 @@ namespace IRaCIS.Core.Application.Service var exsitPDF = await _readingClinicalDataRepository.AnyAsync(t => t.TrialId == trialId && t.SubjectId== task.SubjectId&& + t.ClinicalDataTrialSet.TrialClinicalDataSetCriteriaList.Any(c => c.TrialReadingCriterionId == readingCriterionId) + && t.ClinicalDataTrialSet.ClinicalDataLevel != ClinicalLevel.Study && t.ClinicalDataTrialSet.ClinicalUploadType == ClinicalUploadType.PDF); var taskState = exsitPDF ? TaskState.NotEffect : TaskState.Effect; diff --git a/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs b/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs index f49b2e71a..cedfdfe7a 100644 --- a/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs +++ b/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs @@ -908,7 +908,7 @@ namespace IRaCIS.Application.Services .WhereIf(inDto.SelectIsSign, x => x.IsSign == true) .Where(x => x.ReadingId == inDto.ReadingId) .WhereIf(inDto.TrialReadingCriterionId != null, x => x.ClinicalDataTrialSet.TrialClinicalDataSetCriteriaList.Any(t => t.TrialReadingCriterionId == inDto.TrialReadingCriterionId)) - .Where(x => x.ClinicalDataTrialSet.ClinicalUploadType != ClinicalUploadType.PDF) + .Where(x => x.ClinicalDataTrialSet.ClinicalUploadType != ClinicalUploadType.PDF||x.ClinicalDataTrialSet.ClinicalDataLevel== ClinicalLevel.Study) .Select(x => new GetReadingClinicalDataListOutDto() { ClinicalDataLevel = x.ClinicalDataTrialSet.ClinicalDataLevel, From 0f2a73cb3c11847a444d3866f0bc16b591492f97 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Thu, 15 Aug 2024 09:26:46 +0800 Subject: [PATCH 238/251] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=B8=B4=E5=BA=8A?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E7=AD=BE=E5=90=8Dbug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Reading/ClinicalData/ReadingClinicalDataService.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs b/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs index f49b2e71a..15ea1ec79 100644 --- a/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs +++ b/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs @@ -478,6 +478,7 @@ namespace IRaCIS.Application.Services var needSignCount = 0; var haveSignedCount = _readingClinicalDataRepository.Where(t => t.TrialId == trialId && t.IsSign && t.ReadingClinicalDataState == ReadingClinicalDataStatus.HaveSigned && t.ReadingId == readingId && t.ClinicalDataTrialSet.UploadRole == UploadRole.PM).Count(); + ReadModule readModule = null; if (isVisit) { @@ -513,7 +514,7 @@ namespace IRaCIS.Application.Services else { //判断是影像学 还是肿瘤学阅片 - var readModule = await _readModuleRepository.Where(t => t.Id == readingId).FirstNotNullAsync(); + readModule = await _readModuleRepository.Where(t => t.Id == readingId).FirstNotNullAsync(); //CRC 阅片期自定义结构化录入是否签名 bool crcReadModuleSign = true; @@ -575,7 +576,7 @@ namespace IRaCIS.Application.Services Expression> visitTaskLambda = x => x.TrialId == trialId && x.SubjectId == subjectId && x.TrialReadingCriterionId == trialReadingCritrialId; - if (isVisit) + if (isVisit ||(isVisit==false && readModule.ReadingSetType == ReadingSetType.ImageReading)) { //访视类型的任务 不影响肿瘤学任务的临床数据状态 visitTaskLambda = visitTaskLambda.And(x => x.ArmEnum != Arm.TumorArm); From f1170244dac0775a26de753540e8a33a8348aed5 Mon Sep 17 00:00:00 2001 From: he <109787524@qq.com> Date: Thu, 15 Aug 2024 09:39:25 +0800 Subject: [PATCH 239/251] =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Service/Allocation/VisitTaskHelpeService.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/IRaCIS.Core.Application/Service/Allocation/VisitTaskHelpeService.cs b/IRaCIS.Core.Application/Service/Allocation/VisitTaskHelpeService.cs index 7ad3c40b1..72553ebd3 100644 --- a/IRaCIS.Core.Application/Service/Allocation/VisitTaskHelpeService.cs +++ b/IRaCIS.Core.Application/Service/Allocation/VisitTaskHelpeService.cs @@ -1424,7 +1424,10 @@ namespace IRaCIS.Core.Application.Service var clinicalDataList = _readingClinicalDataRepository.Where(t => t.SubjectId == subjectId && t.ClinicalDataTrialSet.TrialClinicalDataSetCriteriaList.Any(y => y.TrialReadingCriterionId == firsttask.TrialReadingCriterionId) && t.ClinicalDataTrialSet.ClinicalDataLevel!= ClinicalLevel.Study - && t.ClinicalDataTrialSet.ClinicalUploadType == ClinicalUploadType.PDF).Include(t => t.ReadingClinicalDataPDFList).Include(t => t.ClinicalDataTrialSet).ToList(); + && t.ClinicalDataTrialSet.ClinicalUploadType == ClinicalUploadType.PDF) + // crc受试者和访视的临床数据没上传 一致性分析的时候也不用显示 + .Where(x=>x.ClinicalDataTrialSet.UploadRole == UploadRole.PM||x.FileCount>0) + .Include(t => t.ReadingClinicalDataPDFList).Include(t => t.ClinicalDataTrialSet).ToList(); foreach (var clinicalData in clinicalDataList) From a5017c1571de04a710bc6eba178be6a9ccd038e0 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Thu, 15 Aug 2024 11:36:20 +0800 Subject: [PATCH 240/251] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=AF=BC=E8=A1=A8?= =?UTF-8?q?=E6=96=87=E4=BB=B6=E5=90=8D=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.Application/Helper/ExcelExportHelper.cs | 2 +- .../Service/Reading/ClinicalData/ReadingClinicalDataService.cs | 3 --- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/IRaCIS.Core.Application/Helper/ExcelExportHelper.cs b/IRaCIS.Core.Application/Helper/ExcelExportHelper.cs index bc14bf6a8..069eb3b3f 100644 --- a/IRaCIS.Core.Application/Helper/ExcelExportHelper.cs +++ b/IRaCIS.Core.Application/Helper/ExcelExportHelper.cs @@ -181,7 +181,7 @@ public static class ExcelExportHelper return new FileStreamResult(memoryStream, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet") { - FileDownloadName = $"{exportFileNamePrefix}_{fileName}_{DateTime.Now.ToString("yyyyMMddHHmmss")}.xlsx" + FileDownloadName = $"{(string.IsNullOrEmpty(exportFileNamePrefix) ? "" : exportFileNamePrefix+ "_") }{Path.GetFileNameWithoutExtension(fileName) }_{DateTime.Now.ToString("yyyyMMddHHmmss")}.xlsx" }; #endregion diff --git a/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs b/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs index 8bdde16f8..934262818 100644 --- a/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs +++ b/IRaCIS.Core.Application/Service/Reading/ClinicalData/ReadingClinicalDataService.cs @@ -430,9 +430,6 @@ namespace IRaCIS.Application.Services // data.IsComplete = inDto.IsComplete; // data.IsSign = true; // data.ReadingClinicalDataState = ReadingClinicalDataStatus.HaveSigned; - - - // var result = await _readingClinicalDataRepository.SaveChangesAsync(); From 8d4a791a1cee8ee88f617cfbfbd224bd59c537d1 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Thu, 15 Aug 2024 14:02:09 +0800 Subject: [PATCH 241/251] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=B8=80=E8=87=B4?= =?UTF-8?q?=E6=80=A7=E5=88=86=E6=9E=90=E5=A2=9E=E5=8A=A0=E9=A6=96=E6=AC=A1?= =?UTF-8?q?=E6=88=AA=E6=AD=A2=E5=85=A8=E5=B1=80=E8=AE=BF=E8=A7=86=E5=90=8D?= =?UTF-8?q?=E5=AD=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Allocation/DTO/TaskConsistentRuleViewModel.cs | 2 +- .../Service/Allocation/TaskConsistentRuleService.cs | 2 ++ .../Service/Management/UserTypeService.cs | 10 +++++----- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/IRaCIS.Core.Application/Service/Allocation/DTO/TaskConsistentRuleViewModel.cs b/IRaCIS.Core.Application/Service/Allocation/DTO/TaskConsistentRuleViewModel.cs index e45e9c2bb..0a566607e 100644 --- a/IRaCIS.Core.Application/Service/Allocation/DTO/TaskConsistentRuleViewModel.cs +++ b/IRaCIS.Core.Application/Service/Allocation/DTO/TaskConsistentRuleViewModel.cs @@ -107,7 +107,7 @@ namespace IRaCIS.Core.Application.ViewModel public class DoctorSelfConsistentSubjectView: ConsistentCommonView { - + public string FirstGlobalVisitName { get; set; } = string.Empty; public string? BlindSubjectCode { get; set; } public List VisitTaskList { get; set; } diff --git a/IRaCIS.Core.Application/Service/Allocation/TaskConsistentRuleService.cs b/IRaCIS.Core.Application/Service/Allocation/TaskConsistentRuleService.cs index 44297c8fa..440aefe37 100644 --- a/IRaCIS.Core.Application/Service/Allocation/TaskConsistentRuleService.cs +++ b/IRaCIS.Core.Application/Service/Allocation/TaskConsistentRuleService.cs @@ -599,6 +599,8 @@ namespace IRaCIS.Core.Application.Service IsReReadingOrBackInfluenceAnalysis = t.IsReReadingOrBackInfluenceAnalysis, + FirstGlobalVisitName= t.ReadModuleList.Where(c=>c.TrialReadingCriterionId== trialReadingCriterionId && c.ModuleType== ModuleTypeEnum.Global).OrderBy(k=>k.SubjectVisit.VisitNum).Select(u=>u.SubjectVisit.VisitName).FirstOrDefault(), + BlindSubjectCode = t.SubjectVisitTaskList.Where(t => t.IsAnalysisCreate && t.TrialReadingCriterionId == trialReadingCriterionId).OrderByDescending(t => t.BlindSubjectCode).Select(t => t.BlindSubjectCode).FirstOrDefault(), IsHaveGeneratedTask = t.SubjectVisitTaskList.Any(c => c.DoctorUserId == doctorUserId && c.IsSelfAnalysis == true && c.TrialReadingCriterionId == trialReadingCriterionId), diff --git a/IRaCIS.Core.Application/Service/Management/UserTypeService.cs b/IRaCIS.Core.Application/Service/Management/UserTypeService.cs index ddcdf2936..f608346b2 100644 --- a/IRaCIS.Core.Application/Service/Management/UserTypeService.cs +++ b/IRaCIS.Core.Application/Service/Management/UserTypeService.cs @@ -119,12 +119,12 @@ namespace IRaCIS.Core.Application.Contracts if (userTypeSelectEnum == UserTypeSelectEnum.InnerUser) { - userTypeEnums = new List() { UserTypeEnum.ClinicalResearchCoordinator, UserTypeEnum.CRA, UserTypeEnum.IQC, UserTypeEnum.APM, UserTypeEnum.MIM, UserTypeEnum.QA ,UserTypeEnum.MW,UserTypeEnum.MC}; + userTypeEnums = new List() { UserTypeEnum.ClinicalResearchCoordinator, UserTypeEnum.ProjectManager, UserTypeEnum.CRA, UserTypeEnum.IQC, UserTypeEnum.APM, UserTypeEnum.MIM, UserTypeEnum.QA ,UserTypeEnum.MW,UserTypeEnum.MC}; - if (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.SuperAdmin) - { - userTypeEnums.Add(UserTypeEnum.ProjectManager); - } + //if (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.SuperAdmin) + //{ + // userTypeEnums.Add(UserTypeEnum.ProjectManager); + //} } if (userTypeSelectEnum == UserTypeSelectEnum.SiteSurvey) From 32c4d634edee0a8538503cdfae6c3e6b1c59f2ff Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Thu, 15 Aug 2024 14:37:04 +0800 Subject: [PATCH 242/251] =?UTF-8?q?=E5=86=85=E9=83=A8=E4=BA=BA=E5=91=98=20?= =?UTF-8?q?=E7=9B=B4=E6=8E=A5pm=20=E5=8F=AF=E4=BB=A5=E5=8A=A0pm?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Service/TrialSiteUser/TrialMaintenanceService.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/IRaCIS.Core.Application/Service/TrialSiteUser/TrialMaintenanceService.cs b/IRaCIS.Core.Application/Service/TrialSiteUser/TrialMaintenanceService.cs index 4734a2980..9e060eb76 100644 --- a/IRaCIS.Core.Application/Service/TrialSiteUser/TrialMaintenanceService.cs +++ b/IRaCIS.Core.Application/Service/TrialSiteUser/TrialMaintenanceService.cs @@ -123,7 +123,7 @@ namespace IRaCIS.Application.Services var userTypeEnums = new List() { UserTypeEnum.ClinicalResearchCoordinator, UserTypeEnum.CRA, UserTypeEnum.IQC, UserTypeEnum.APM, UserTypeEnum.MIM, UserTypeEnum.QA, UserTypeEnum.MW, UserTypeEnum.MC }; - if (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.SuperAdmin) + //if (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.SuperAdmin) { userTypeEnums.Add(UserTypeEnum.ProjectManager); } From fa929ebde4e99df6785b04ae5b73f82e1ed979cc Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Thu, 15 Aug 2024 15:29:25 +0800 Subject: [PATCH 243/251] =?UTF-8?q?=E9=82=AE=E4=BB=B6=E9=85=8D=E7=BD=AE5s?= =?UTF-8?q?=E8=B6=85=E6=97=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.Application/Helper/SendEmailHelper.cs | 12 ++++++++---- .../Document/TrialEmailNoticeConfigService.cs | 2 +- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/IRaCIS.Core.Application/Helper/SendEmailHelper.cs b/IRaCIS.Core.Application/Helper/SendEmailHelper.cs index 974a60f02..7a223b275 100644 --- a/IRaCIS.Core.Application/Helper/SendEmailHelper.cs +++ b/IRaCIS.Core.Application/Helper/SendEmailHelper.cs @@ -52,15 +52,19 @@ public static class SendEmailHelper public static async Task TestEmailConfigAsync(SystemEmailSendConfig _systemEmailConfig) { - using (var client = new MailKit.Net.Smtp.SmtpClient()) + using (var cts = new CancellationTokenSource(TimeSpan.FromSeconds(5))) { + using (var client = new MailKit.Net.Smtp.SmtpClient()) + { - await client.ConnectAsync(_systemEmailConfig.Host, _systemEmailConfig.Port, SecureSocketOptions.Auto); + await client.ConnectAsync(_systemEmailConfig.Host, _systemEmailConfig.Port, SecureSocketOptions.Auto, cts.Token); - await client.AuthenticateAsync(_systemEmailConfig.FromEmail, _systemEmailConfig.AuthorizationCode); + await client.AuthenticateAsync(_systemEmailConfig.FromEmail, _systemEmailConfig.AuthorizationCode, cts.Token); - await client.DisconnectAsync(true); + await client.DisconnectAsync(true); + } } + return true; } diff --git a/IRaCIS.Core.Application/Service/Document/TrialEmailNoticeConfigService.cs b/IRaCIS.Core.Application/Service/Document/TrialEmailNoticeConfigService.cs index 2103aecef..5698b1e26 100644 --- a/IRaCIS.Core.Application/Service/Document/TrialEmailNoticeConfigService.cs +++ b/IRaCIS.Core.Application/Service/Document/TrialEmailNoticeConfigService.cs @@ -1479,7 +1479,7 @@ namespace IRaCIS.Core.Application.Service { //---发件人配置错误,请核对服务器地址或者授权码是否填写有误 - throw new BusinessValidationFailedException(_localizer["TrialEmailN_InvalidSenderEmailConfig"] + ex.Message); + throw new BusinessValidationFailedException(_localizer["TrialEmailN_InvalidSenderEmailConfig"]); } From d97025aecae079265fdfc8fa380539229f1a3148 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Thu, 15 Aug 2024 17:08:03 +0800 Subject: [PATCH 244/251] =?UTF-8?q?=E9=A1=B9=E7=9B=AEAE=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.API/Progranm.cs | 2 +- IRaCIS.Core.API/appsettings.Test_IRC.json | 6 ++++++ .../Service/TrialSiteUser/TrialConfigService.cs | 10 +++++++++- IRaCIS.Core.Domain.Share/Trial/TrialExpedited.cs | 9 +++++++++ IRaCIS.Core.Domain/Common/Internationalization.cs | 4 +++- IRaCIS.Core.Domain/_Config/_AppSettings.cs | 9 +++++++++ 6 files changed, 37 insertions(+), 3 deletions(-) diff --git a/IRaCIS.Core.API/Progranm.cs b/IRaCIS.Core.API/Progranm.cs index 40ffb2743..915ff6018 100644 --- a/IRaCIS.Core.API/Progranm.cs +++ b/IRaCIS.Core.API/Progranm.cs @@ -117,7 +117,7 @@ builder.Services.AddOptions().Configure(_configuratio builder.Services.AddOptions().Configure(_configuration.GetSection("AliyunOSS")); builder.Services.AddOptions().Configure(_configuration.GetSection("ObjectStoreService")); builder.Services.AddOptions().Configure(_configuration.GetSection("EncrypteResponseConfig")); - +builder.Services.AddOptions().Configure(_configuration.GetSection("SystemPacsConfig")); //动态WebApi + UnifiedApiResultFilter 省掉控制器代码 diff --git a/IRaCIS.Core.API/appsettings.Test_IRC.json b/IRaCIS.Core.API/appsettings.Test_IRC.json index 377d97bc2..b525fec8a 100644 --- a/IRaCIS.Core.API/appsettings.Test_IRC.json +++ b/IRaCIS.Core.API/appsettings.Test_IRC.json @@ -85,7 +85,13 @@ "CompanyNameCN": "上海展影医疗科技有限公司", "CompanyShortName": "Extensive Imaging", "CompanyShortNameCN": "展影医疗" + }, + + "SystemPacsConfig": { + "Port": "11113", + "IP": "106.14.89.110" } + diff --git a/IRaCIS.Core.Application/Service/TrialSiteUser/TrialConfigService.cs b/IRaCIS.Core.Application/Service/TrialSiteUser/TrialConfigService.cs index 636a8c3b2..b130638a7 100644 --- a/IRaCIS.Core.Application/Service/TrialSiteUser/TrialConfigService.cs +++ b/IRaCIS.Core.Application/Service/TrialSiteUser/TrialConfigService.cs @@ -22,6 +22,7 @@ using IRaCIS.Core.Domain.Models; using IRaCIS.Application.Contracts; using SixLabors.ImageSharp.Formats.Tiff.Compression.Decompressors; using Newtonsoft.Json; +using Microsoft.Extensions.Options; namespace IRaCIS.Core.Application { @@ -1347,7 +1348,7 @@ namespace IRaCIS.Core.Application { var codeList = await _repository.Where(t => t.TrialId == incommand.TrialId) - .WhereIf(incommand.Id!=null,t=>t.Id!=incommand.Id) + .WhereIf(incommand.Id != null, t => t.Id != incommand.Id) .Select(t => t.Code).ToListAsync(); @@ -1384,5 +1385,12 @@ namespace IRaCIS.Core.Application return JsonConvert.DeserializeObject(extralConfig) ?? new TrialExtraConfig(); } + + public async Task GetTrialPacsConfigInfo(Guid trialId, [FromServices] IOptionsMonitor optionsMonitor) + { + var trialCode = await _trialRepository.Where(t => t.Id == trialId).Select(t => t.TrialCode).FirstOrDefaultAsync(); + + return new TrialPacsInfo() { Ip=optionsMonitor.CurrentValue.IP,Port=optionsMonitor.CurrentValue.Port,TrialCalledAE=$"EI{trialCode}" }; + } } } diff --git a/IRaCIS.Core.Domain.Share/Trial/TrialExpedited.cs b/IRaCIS.Core.Domain.Share/Trial/TrialExpedited.cs index 506830ba6..dcdb9c795 100644 --- a/IRaCIS.Core.Domain.Share/Trial/TrialExpedited.cs +++ b/IRaCIS.Core.Domain.Share/Trial/TrialExpedited.cs @@ -64,6 +64,15 @@ namespace IRaCIS.Core.Domain.Share } + public class TrialPacsInfo + { + public int Port { get; set; } + + public string Ip { get; set; } + + public string TrialCalledAE { get; set; } + } + public class SiteSurveyModifyFiled { public string NeedModifyFiled { get; set; } diff --git a/IRaCIS.Core.Domain/Common/Internationalization.cs b/IRaCIS.Core.Domain/Common/Internationalization.cs index 0da0a2f35..1f6b63cc7 100644 --- a/IRaCIS.Core.Domain/Common/Internationalization.cs +++ b/IRaCIS.Core.Domain/Common/Internationalization.cs @@ -29,7 +29,9 @@ namespace IRaCIS.Core.Domain.Models public Guid UpdateUserId { get; set; } - + /// + /// 0 1 2 预翻译 已确认 废除 + /// public int State { get; set; } diff --git a/IRaCIS.Core.Domain/_Config/_AppSettings.cs b/IRaCIS.Core.Domain/_Config/_AppSettings.cs index d4284b22e..fac748828 100644 --- a/IRaCIS.Core.Domain/_Config/_AppSettings.cs +++ b/IRaCIS.Core.Domain/_Config/_AppSettings.cs @@ -78,6 +78,15 @@ namespace IRaCIS.Core.Domain.Share } + public class SystemPacsConfig + { + public int Port { get; set; } + + public string IP { get; set; } + } + + + public class EncreptResponseOption { public bool IsEnable { get; set; } From 0689f731b76f7e3bed79b99fa3dad2b864b1533a Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Thu, 15 Aug 2024 17:41:38 +0800 Subject: [PATCH 245/251] =?UTF-8?q?=E6=B5=8B=E8=AF=95=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E6=96=87=E4=BB=B6=E6=8B=B7=E8=B4=9D=E6=98=AF?= =?UTF-8?q?=E5=90=A6=E7=94=9F=E6=95=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.API/appsettings.Test_IRC.json | 4 ---- 1 file changed, 4 deletions(-) diff --git a/IRaCIS.Core.API/appsettings.Test_IRC.json b/IRaCIS.Core.API/appsettings.Test_IRC.json index b525fec8a..938cbb330 100644 --- a/IRaCIS.Core.API/appsettings.Test_IRC.json +++ b/IRaCIS.Core.API/appsettings.Test_IRC.json @@ -91,8 +91,4 @@ "Port": "11113", "IP": "106.14.89.110" } - - - - } From 3701d8bcd9a73a86c5f351a18558a12cbb16ed98 Mon Sep 17 00:00:00 2001 From: hang <87227557@qq.com> Date: Thu, 15 Aug 2024 23:53:25 +0800 Subject: [PATCH 246/251] =?UTF-8?q?=E7=B2=BE=E7=AE=80=E5=AE=9E=E4=BD=93?= =?UTF-8?q?=E5=87=86=E5=A4=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.Domain/BaseModel/Entity.cs | 48 +++++++++++ IRaCIS.Core.Domain/BaseModel/IAuditAdd.cs | 4 +- IRaCIS.Core.Domain/BaseModel/IAuditUpdate.cs | 6 +- IRaCIS.Core.Domain/BaseModel/ISoftDelete.cs | 16 ++-- IRaCIS.Core.Domain/Common/CommonDocument.cs | 88 ++++---------------- 5 files changed, 83 insertions(+), 79 deletions(-) diff --git a/IRaCIS.Core.Domain/BaseModel/Entity.cs b/IRaCIS.Core.Domain/BaseModel/Entity.cs index 939bf9f13..8482a17d4 100644 --- a/IRaCIS.Core.Domain/BaseModel/Entity.cs +++ b/IRaCIS.Core.Domain/BaseModel/Entity.cs @@ -17,4 +17,52 @@ namespace IRaCIS.Core.Domain.Models abstract TKey Id { get; set; } } + #region 减少实体属性,增加基类 + + public abstract class BaseAuditAddEntity : Entity, IAuditAdd + { + + public Guid CreateUserId { get; set; } + public DateTime CreateTime { get; set; } + } + + public abstract class BaseFullAuditEntity : Entity, IAuditUpdate, IAuditAdd + { + public Guid CreateUserId { get; set; } + public DateTime CreateTime { get; set; } + public Guid UpdateUserId { get; set; } + public DateTime UpdateTime { get; set; } + } + + + public abstract class BaseFullAuditDeleteEntity : Entity, IAuditUpdate, IAuditAdd, ISoftDelete + { + public Guid? DeleteUserId { get; set; } + public bool IsDeleted { get; set; } + public DateTime? DeletedTime { get; set; } + public Guid CreateUserId { get; set; } + public DateTime CreateTime { get; set; } + public Guid UpdateUserId { get; set; } + public DateTime UpdateTime { get; set; } + } + + + + public abstract class BaseAuditAddEntityWithUserName : Entity, IAuditAddWithUserName + { + public string CreateUser { get; set; } + + public Guid CreateUserId { get; set; } + public DateTime CreateTime { get; set; } + } + + public abstract class BaseAuditUpdateEntity : Entity, IAuditUpdate + { + public Guid UpdateUserId { get; set; } + public DateTime UpdateTime { get; set; } + } + + + #endregion + } diff --git a/IRaCIS.Core.Domain/BaseModel/IAuditAdd.cs b/IRaCIS.Core.Domain/BaseModel/IAuditAdd.cs index 70cd25e2b..4786c8e6d 100644 --- a/IRaCIS.Core.Domain/BaseModel/IAuditAdd.cs +++ b/IRaCIS.Core.Domain/BaseModel/IAuditAdd.cs @@ -19,7 +19,9 @@ namespace IRaCIS.Core.Domain.Models public interface IAuditAddWithUserName : IAuditAdd { - string CreateUser { get; set; } + public string CreateUser { get; set; } } + + } diff --git a/IRaCIS.Core.Domain/BaseModel/IAuditUpdate.cs b/IRaCIS.Core.Domain/BaseModel/IAuditUpdate.cs index e154ccecc..05d422a16 100644 --- a/IRaCIS.Core.Domain/BaseModel/IAuditUpdate.cs +++ b/IRaCIS.Core.Domain/BaseModel/IAuditUpdate.cs @@ -5,7 +5,6 @@ namespace IRaCIS.Core.Domain.Models public interface IAuditUpdate where TKey : struct { public TKey UpdateUserId { get; set; } - //string UpdateUserName { get; set; } public DateTime UpdateTime { get; set; } } @@ -13,4 +12,9 @@ namespace IRaCIS.Core.Domain.Models { } + + + + + } diff --git a/IRaCIS.Core.Domain/BaseModel/ISoftDelete.cs b/IRaCIS.Core.Domain/BaseModel/ISoftDelete.cs index 8cfa535b1..e0549348b 100644 --- a/IRaCIS.Core.Domain/BaseModel/ISoftDelete.cs +++ b/IRaCIS.Core.Domain/BaseModel/ISoftDelete.cs @@ -2,16 +2,18 @@ namespace IRaCIS.Core.Domain.Models { - - - public interface ISoftDelete + public interface ISoftDelete where TKey : struct { - bool IsDeleted { get; set; } + public TKey? DeleteUserId { get; set; } + public bool IsDeleted { get; set; } public DateTime? DeletedTime { get; set; } - - public Guid? DeleteUserId { get; set; } } - + public interface ISoftDelete : ISoftDelete + { + + } + + } diff --git a/IRaCIS.Core.Domain/Common/CommonDocument.cs b/IRaCIS.Core.Domain/Common/CommonDocument.cs index 37a29aeee..579fb3da8 100644 --- a/IRaCIS.Core.Domain/Common/CommonDocument.cs +++ b/IRaCIS.Core.Domain/Common/CommonDocument.cs @@ -9,82 +9,30 @@ using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; namespace IRaCIS.Core.Domain.Models { - /// - ///CommonDocument - /// - [Table("CommonDocument")] - public class CommonDocument : Entity, IAuditUpdate, IAuditAdd,ISoftDelete - { + /// + ///CommonDocument + /// + [Table("CommonDocument")] + public class CommonDocument : BaseFullAuditDeleteEntity + { + + public string Code { get; set; } = String.Empty; - [Required] - public string Code { get; set; } = String.Empty; + public string Name { get; set; } = String.Empty; - [Required] - public string Name { get; set; } = String.Empty; + public string NameCN { get; set; } = string.Empty; - public string NameCN { get; set; } = string.Empty; - - /// - /// Path - /// - [Required] - public string Path { get; set; } = String.Empty; - - /// - /// CreateTime - /// - [Required] - public DateTime CreateTime { get; set; } - - /// - /// CreateUserId - /// - [Required] - public Guid CreateUserId { get; set; } - - /// - /// UpdateTime - /// - [Required] - public DateTime UpdateTime { get; set; } - - /// - /// UpdateUserId - /// - [Required] - public Guid UpdateUserId { get; set; } - - /// - /// Description - /// - [Required] - public string Description { get; set; } = String.Empty; - - /// - /// IsDeleted - /// - [Required] - public bool IsDeleted { get; set; } - - public DateTime? DeletedTime { get; set; } - - public Guid? DeleteUserId { get; set; } + public string Path { get; set; } = String.Empty; - public CriterionType? CriterionTypeEnum { get; set; } - public CommonDocumentFileType FileTypeEnum { get; set; } - public EmailBusinessScenario BusinessScenarioEnum { get; set; } + public string Description { get; set; } = String.Empty; + + public CriterionType? CriterionTypeEnum { get; set; } + public CommonDocumentFileType FileTypeEnum { get; set; } + public EmailBusinessScenario BusinessScenarioEnum { get; set; } - //[Required] - //public Guid FileTypeId { get; set; } - //public Guid ModuleTypeId { get; set; } + } - - //public Dictionary FileType { get; set; } - //public Dictionary ModuleType { get; set; } - - } - -} +} From 423fa4001ba51c1562528160781df9a53bf7e247 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Fri, 16 Aug 2024 09:54:06 +0800 Subject: [PATCH 247/251] =?UTF-8?q?=E4=BF=AE=E6=94=B9T4=E6=A8=A1=E6=9D=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.Test/IRaCIS.Core.Test.csproj | 11 +++---- .../TT_Template/IRaCIS.Core.Dto.tt | 24 ++++++++------- .../TT_Template/IRaCIS.Core.Entity.cs | 2 +- .../TT_Template/IRaCIS.Core.Entity.tt | 30 ++++++++----------- 4 files changed, 34 insertions(+), 33 deletions(-) diff --git a/IRaCIS.Core.Test/IRaCIS.Core.Test.csproj b/IRaCIS.Core.Test/IRaCIS.Core.Test.csproj index dae984eb7..2d9915d1d 100644 --- a/IRaCIS.Core.Test/IRaCIS.Core.Test.csproj +++ b/IRaCIS.Core.Test/IRaCIS.Core.Test.csproj @@ -77,11 +77,6 @@ True IRaCIS.Core.Dto.tt - - True - True - IRaCIS.Core.Entity.tt - True True @@ -102,12 +97,18 @@ True IRaCIS.Core.Services.tt + + True + True + IRaCIS.Core.Entity.tt + + diff --git a/IRaCIS.Core.Test/TT_Template/IRaCIS.Core.Dto.tt b/IRaCIS.Core.Test/TT_Template/IRaCIS.Core.Dto.tt index bf59c18a7..128807500 100644 --- a/IRaCIS.Core.Test/TT_Template/IRaCIS.Core.Dto.tt +++ b/IRaCIS.Core.Test/TT_Template/IRaCIS.Core.Dto.tt @@ -42,30 +42,34 @@ using IRaCIS.Core.Domain.Share; using System.Collections.Generic; namespace IRaCIS.Core.Application.ViewModel { - /// <#=tableName#>View 列表视图模型 - public class <#=tableName#>View + <# var excludedColumns = new[] { "CreateUserId", "UpdateUserId", "CreateTime", "UpdateTime" };#> + + /// <#=tableName#>View 列表视图 + public class <#=tableName#>View:<#=tableName#>AddOrEdit { <# foreach(DbColumn column in DbHelper.GetDbColumns(config.ConnectionString, config.DbDatabase, tableName)){#> + <# if (excludedColumns.Contains(column.ColumnName)){ #> public <#= column.CSharpType#><# if(column.CommonType.IsValueType && column.IsNullable){#>?<#}#> <#=column.ColumnName#> { get; set; } + <# }#> <# }#> } - ///<#=tableName#>Query 列表查询参数模型 + ///<#=tableName#>Query 列表查询参数 public class <#=tableName#>Query { - <# foreach(DbColumn column in DbHelper.GetDbColumns(config.ConnectionString, config.DbDatabase, tableName)){#><# if(column.CSharpType=="string"){#> - /// <#= column.Remark == "" ? column.ColumnName : column.Remark.Replace("\r\n","") #> - public <#= column.CSharpType#><# if(column.CommonType.IsValueType && column.IsNullable){#>?<#}#> <#=column.ColumnName#> { get; set; } - - <# }#> - <# }#> + <# foreach(DbColumn column in DbHelper.GetDbColumns(config.ConnectionString, config.DbDatabase, tableName)){#><# if(column.CSharpType=="string"){#> + public <#= column.CSharpType#><# if(column.CommonType.IsValueType && column.IsNullable){#>?<#}#> <#=column.ColumnName#> { get; set; } + <# }#> + <# }#> } - /// <#=tableName#>AddOrEdit 列表查询参数模型 + /// <#=tableName#>AddOrEdit 添加编辑 public class <#=tableName#>AddOrEdit { <# foreach(DbColumn column in DbHelper.GetDbColumns(config.ConnectionString, config.DbDatabase, tableName)){#> + <# if (!excludedColumns.Contains(column.ColumnName)){ #> public <#= column.CSharpType#><# if(column.CommonType.IsValueType && column.IsNullable){#>?<#}#> <#=column.ColumnName#> { get; set; } + <#}#> <# }#> } diff --git a/IRaCIS.Core.Test/TT_Template/IRaCIS.Core.Entity.cs b/IRaCIS.Core.Test/TT_Template/IRaCIS.Core.Entity.cs index 171fad3cb..b28b04f64 100644 --- a/IRaCIS.Core.Test/TT_Template/IRaCIS.Core.Entity.cs +++ b/IRaCIS.Core.Test/TT_Template/IRaCIS.Core.Entity.cs @@ -1,3 +1,3 @@ - + diff --git a/IRaCIS.Core.Test/TT_Template/IRaCIS.Core.Entity.tt b/IRaCIS.Core.Test/TT_Template/IRaCIS.Core.Entity.tt index c15229ffb..248a2d82a 100644 --- a/IRaCIS.Core.Test/TT_Template/IRaCIS.Core.Entity.tt +++ b/IRaCIS.Core.Test/TT_Template/IRaCIS.Core.Entity.tt @@ -1,4 +1,4 @@ -<#@ template debug="false" hostspecific="true" language="C#" #> +<#@ template debug="false" hostspecific="true" language="C#" #> <#@ output extension=".cs" #> <#@ assembly name="System.Core.dll" #> <#@ assembly name="System.Data.dll" #> @@ -27,13 +27,13 @@ <# foreach (var item in DbHelper.GetDbTablesNew(config.ConnectionString, config.DbDatabase,config.TableName)) { var tableName=item.ToString(); - manager.StartBlock(tableName+".cs",OutputPath1);//文件名 + manager.StartBlock(tableName+".cs",OutputPath1);//ļ #> //-------------------------------------------------------------------- -// 此代码由T4模板自动生成 byzhouhang 20210918 -// 生成时间 <#=DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")#> -// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。 +// ˴T4ģԶ byzhouhang 20210918 +// ʱ <#=DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")#> +// ԴļĸĿܻᵼ²ȷΪɴ룬ЩĽᶪʧ using System; using IRaCIS.Core.Domain.Share; using System.ComponentModel.DataAnnotations; @@ -44,19 +44,15 @@ namespace IRaCIS.Core.Domain.Models ///<#=tableName#> /// [Table("<#=tableName#>")] - public class <#=tableName#> : Entity, IAuditUpdate, IAuditAdd + public class <#=tableName#> : BaseFullAuditEntity { - <# foreach(DbColumn column in DbHelper.GetDbColumns(config.ConnectionString, config.DbDatabase, tableName)){#> - - /// - /// <#= column.Remark == "" ? column.ColumnName : column.Remark.Replace("\r\n"," ") #> - /// - <# - if(column.IsPrimaryKey) - {#>[Key] - <#}#><# if(!column.IsNullable) {#>[Required] - <# }#>public <#= column.CSharpType#><# if(column.CommonType.IsValueType && column.IsNullable){#>?<#}#> <#=column.ColumnName#> { get; set; } - <#}#> + <# var excludedColumns = new[] { "CreateUserId", "Id", "UpdateUserId", "CreateTime", "UpdateTime", "DeleteUserId", "IsDeleted", "DeletedTime" };#> + <# foreach(DbColumn column in DbHelper.GetDbColumns(config.ConnectionString, config.DbDatabase, tableName)){ #> + <# if (!excludedColumns.Contains(column.ColumnName)){ #> + /// <#= column.Remark == "" ? column.ColumnName : column.Remark.Replace("\r\n"," ") #> + public <#= column.CSharpType#><# if(column.CommonType.IsValueType && column.IsNullable){#>?<#}#> <#=column.ColumnName#> { get; set; } + <#}#> + <#}#> } public virtual DbSet<<#=tableName#>> <#=tableName#> { get; set; } From e3188c0419828076857fb98dfa7f72652ae5cc0d Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Fri, 16 Aug 2024 10:15:50 +0800 Subject: [PATCH 248/251] =?UTF-8?q?=E6=B8=85=E7=90=86=E6=B2=A1=E7=94=A8?= =?UTF-8?q?=E7=9A=84=E5=AD=98=E5=82=A8=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Helper/FileStoreHelper.cs | 357 ------------------ 1 file changed, 357 deletions(-) diff --git a/IRaCIS.Core.Application/Helper/FileStoreHelper.cs b/IRaCIS.Core.Application/Helper/FileStoreHelper.cs index 288718745..55c01d7f0 100644 --- a/IRaCIS.Core.Application/Helper/FileStoreHelper.cs +++ b/IRaCIS.Core.Application/Helper/FileStoreHelper.cs @@ -129,65 +129,6 @@ public static class FileStoreHelper #endregion - /// - /// - /// - /// - /// - /// - /// - /// - public static async Task<(string PhysicalPath, string FileName)> GetSystemClinicalPathAsync(IWebHostEnvironment _hostEnvironment, IRepository _clinicalDataTrialSetRepository, Guid id) - { - var systemClinicalData = await _clinicalDataTrialSetRepository.FirstOrDefaultAsync(t => t.Id == id); - - if (systemClinicalData == null || systemClinicalData.Path == string.Empty) - { - //---数据库没有找到对应的数据模板文件,请联系系统运维人员。 - throw new BusinessValidationFailedException(StaticData.International("FileStore_TemplateFileNotFound")); - } - - var filePath = FileStoreHelper.GetPhysicalFilePath(_hostEnvironment, systemClinicalData.Path); - - if (!System.IO.File.Exists(filePath)) - { - //---数据模板文件存储路径上未找对应文件,请联系系统运维人员。 - throw new BusinessValidationFailedException(StaticData.International("FileStore_TemplateFileStoragePathInvalid")); - } - - return (filePath, systemClinicalData.FileName); - } - - - /// - /// - /// - /// - /// - /// - /// - /// - public static async Task<(string PhysicalPath, string FileName)> GetTrialClinicalPathAsync(IWebHostEnvironment _hostEnvironment, IRepository _clinicalDataTrialSetRepository, Guid id) - { - var trialClinicalData = await _clinicalDataTrialSetRepository.FirstOrDefaultAsync(t => t.Id == id); - - if (trialClinicalData == null|| trialClinicalData.Path==string.Empty) - { - //---数据库没有找到对应的数据模板文件,请联系系统运维人员。 - throw new BusinessValidationFailedException(StaticData.International("FileStore_TemplateFileNotFound")); - } - - var filePath = FileStoreHelper.GetPhysicalFilePath(_hostEnvironment, trialClinicalData.Path); - - if (!System.IO.File.Exists(filePath)) - { - //---数据模板文件存储路径上未找对应文件,请联系系统运维人员。 - throw new BusinessValidationFailedException(StaticData.International("FileStore_TemplateFileStoragePathInvalid")); - } - - return (filePath, trialClinicalData.FileName); - } - //通过编码获取通用文档具体物理路径 @@ -237,44 +178,6 @@ public static class FileStoreHelper return writeCount; } - // 获取项目签名文档存放路径 - - public static (string PhysicalPath, string RelativePath) GetTrialSignDocPath(IWebHostEnvironment _hostEnvironment, Guid trialId, string fileName) - { - var rootPath = FileStoreHelper.GetIRaCISRootDataFolder(_hostEnvironment); - - //文件类型路径处理 - var uploadFolderPath = Path.Combine(rootPath, StaticData.Folder.TrialDataFolder, trialId.ToString(), StaticData.Folder.SignDocumentFolder); - if (!Directory.Exists(uploadFolderPath)) Directory.CreateDirectory(uploadFolderPath); - - var (trustedFileNameForFileStorage, fileRealName) = FileStoreHelper.GetStoreFileName(fileName); - - var relativePath = $"/{StaticData.Folder.IRaCISDataFolder}/{StaticData.Folder.TrialDataFolder}/{trialId}/{StaticData.Folder.SignDocumentFolder}/{trustedFileNameForFileStorage}"; - - var serverFilePath = Path.Combine(uploadFolderPath, trustedFileNameForFileStorage); - - return (serverFilePath, relativePath); - } - - // 获取系统签名文档存放路径 - public static (string PhysicalPath, string RelativePath) GetSystemSignDocPath(IWebHostEnvironment _hostEnvironment, string fileName) - { - var rootPath = FileStoreHelper.GetIRaCISRootDataFolder(_hostEnvironment); - - - //文件类型路径处理 - var uploadFolderPath = Path.Combine(rootPath, StaticData.Folder.SystemDataFolder, StaticData.Folder.SignDocumentFolder); - if (!Directory.Exists(uploadFolderPath)) Directory.CreateDirectory(uploadFolderPath); - - - var (trustedFileNameForFileStorage, fileRealName) = FileStoreHelper.GetStoreFileName(fileName); - - var relativePath = $"/{StaticData.Folder.IRaCISDataFolder}/{StaticData.Folder.SystemDataFolder}/{ StaticData.Folder.SignDocumentFolder}/{trustedFileNameForFileStorage}"; - - var serverFilePath = Path.Combine(uploadFolderPath, trustedFileNameForFileStorage); - - return (serverFilePath, relativePath); - } // 获取通用文档存放路径(excel模板 ) @@ -297,224 +200,6 @@ public static class FileStoreHelper return (serverFilePath, relativePath); } - //获取系统通知文档存放路径 - - public static (string PhysicalPath, string RelativePath) GetSystemNoticePath(IWebHostEnvironment _hostEnvironment, string fileName) - { - var rootPath = FileStoreHelper.GetIRaCISRootDataFolder(_hostEnvironment); - - //文件类型路径处理 - var uploadFolderPath = Path.Combine(rootPath, StaticData.Folder.SystemDataFolder, StaticData.Folder.NoticeAttachment); - if (!Directory.Exists(uploadFolderPath)) Directory.CreateDirectory(uploadFolderPath); - - - var (trustedFileNameForFileStorage, fileRealName) = FileStoreHelper.GetStoreFileName(fileName); - - - - var relativePath = $"/{StaticData.Folder.IRaCISDataFolder}/{StaticData.Folder.SystemDataFolder}/{StaticData.Folder.NoticeAttachment}/{trustedFileNameForFileStorage}"; - - var serverFilePath = Path.Combine(uploadFolderPath, trustedFileNameForFileStorage); - - return (serverFilePath, relativePath); - } - - // 获取一致性核查路径 - public static (string PhysicalPath, string RelativePath) GetTrialCheckFilePath(IWebHostEnvironment _hostEnvironment, string fileName,Guid trialId) - { - var rootPath = FileStoreHelper.GetIRaCISRootDataFolder(_hostEnvironment); - - //上传根路径 - string uploadFolderPath = Path.Combine(rootPath, StaticData.Folder.TrialDataFolder, trialId.ToString(), StaticData.Folder.UploadEDCData); - - if (!Directory.Exists(uploadFolderPath)) Directory.CreateDirectory(uploadFolderPath); - - - //存放核对表 - var (trustedFileNameForFileStorage, realFileName) = FileStoreHelper.GetStoreFileName(fileName); - - - var relativePath = $"/{StaticData.Folder.IRaCISDataFolder}/{StaticData.Folder.TrialDataFolder}/{trialId}/{StaticData.Folder.UploadEDCData}/{trustedFileNameForFileStorage}"; - - var serverFilePath = Path.Combine(uploadFolderPath, trustedFileNameForFileStorage); - - return (serverFilePath, relativePath); - } - - - public static (string PhysicalPath, string RelativePath, string FileRealName) GetClinicalTemplatePath(IWebHostEnvironment _hostEnvironment, string fileName,Guid trialId) - { - - var rootPath = FileStoreHelper.GetIRaCISRootDataFolder(_hostEnvironment); - - string uploadFolderPath = Path.Combine(rootPath, StaticData.Folder.TrialDataFolder, "ClinicalTemplate", trialId.ToString(), StaticData.Folder.TreatmenthistoryFolder); - - if (!Directory.Exists(uploadFolderPath)) Directory.CreateDirectory(uploadFolderPath); - - var (trustedFileNameForFileStorage, fileRealName) = FileStoreHelper.GetStoreFileName(fileName); - - - var relativePath = $"/{StaticData.Folder.IRaCISDataFolder}/{StaticData.Folder.TrialDataFolder}/ClinicalTemplate/{trialId}/{StaticData.Folder.TreatmenthistoryFolder}/{trustedFileNameForFileStorage}"; - - var serverFilePath = Path.Combine(uploadFolderPath, trustedFileNameForFileStorage); - - return (serverFilePath, relativePath, fileRealName); - - } - - - public static (string PhysicalPath, string RelativePath, string FileRealName) GetReadClinicalDataPath(IWebHostEnvironment _hostEnvironment, string fileName, Guid trialId, Guid siteId, Guid subjectId, Guid readingId) - { - var rootPath = FileStoreHelper.GetIRaCISRootDataFolder(_hostEnvironment); - - string uploadFolderPath = Path.Combine(rootPath, StaticData.Folder.TrialDataFolder, trialId.ToString(), siteId.ToString(), subjectId.ToString(), StaticData.Folder.Reading, readingId.ToString()); - - if (!Directory.Exists(uploadFolderPath)) Directory.CreateDirectory(uploadFolderPath); - - var (trustedFileNameForFileStorage, fileRealName) = FileStoreHelper.GetStoreFileName(fileName); - - - var relativePath = $"/{StaticData.Folder.IRaCISDataFolder}/{StaticData.Folder.TrialDataFolder}/{trialId}/{siteId}/{subjectId}/{StaticData.Folder.Reading}/{readingId}/{trustedFileNameForFileStorage}"; - - var serverFilePath = Path.Combine(uploadFolderPath, trustedFileNameForFileStorage); - - return (serverFilePath, relativePath, fileRealName); - - } - - //获取临床数据存放路径 - public static (string PhysicalPath, string RelativePath,string FileRealName) GetClinicalDataPath(IWebHostEnvironment _hostEnvironment, string fileName,Guid trialId,Guid siteId,Guid subjectId,Guid subjectVisitId) - { - var rootPath = FileStoreHelper.GetIRaCISRootDataFolder(_hostEnvironment); - - string uploadFolderPath = Path.Combine(rootPath, StaticData.Folder.TrialDataFolder, trialId.ToString(),siteId.ToString(), subjectId.ToString(), subjectVisitId.ToString(), StaticData.Folder.TreatmenthistoryFolder); - - if (!Directory.Exists(uploadFolderPath)) Directory.CreateDirectory(uploadFolderPath); - - var (trustedFileNameForFileStorage, fileRealName) = FileStoreHelper.GetStoreFileName(fileName); - - - var relativePath = $"/{StaticData.Folder.IRaCISDataFolder}/{StaticData.Folder.TrialDataFolder}/{trialId}/{siteId}/{subjectId}/{subjectVisitId}/{StaticData.Folder.TreatmenthistoryFolder}/{trustedFileNameForFileStorage}"; - - var serverFilePath = Path.Combine(uploadFolderPath, trustedFileNameForFileStorage); - - return (serverFilePath, relativePath, fileRealName); - - } - - - public static (string PhysicalPath, string RelativePath, string FileRealName) GetClinicalDataPath(IWebHostEnvironment _hostEnvironment, string fileName, Guid trialId , Guid subjectId) - { - var rootPath = FileStoreHelper.GetIRaCISRootDataFolder(_hostEnvironment); - - string uploadFolderPath = Path.Combine(rootPath, StaticData.Folder.TrialDataFolder, trialId.ToString(), subjectId.ToString(), StaticData.Folder.TreatmenthistoryFolder); - - if (!Directory.Exists(uploadFolderPath)) Directory.CreateDirectory(uploadFolderPath); - - var (trustedFileNameForFileStorage, fileRealName) = FileStoreHelper.GetStoreFileName(fileName); - - - var relativePath = $"/{StaticData.Folder.IRaCISDataFolder}/{StaticData.Folder.TrialDataFolder}/{trialId}/{subjectId}/{StaticData.Folder.TreatmenthistoryFolder}/{trustedFileNameForFileStorage}"; - - var serverFilePath = Path.Combine(uploadFolderPath, trustedFileNameForFileStorage); - - return (serverFilePath, relativePath, fileRealName); - - } - - - /// - /// 上传截图 - /// - /// - /// - /// - /// - /// - /// - public static (string PhysicalPath, string RelativePath, string FileRealName) GetUploadPrintscreenFilePath(IWebHostEnvironment _hostEnvironment, string fileName, Guid trialId, Guid siteid, Guid subjectId) - { - var rootPath = FileStoreHelper.GetIRaCISRootDataFolder(_hostEnvironment); - - string uploadFolderPath = Path.Combine(rootPath, StaticData.Folder.TrialDataFolder, trialId.ToString(), siteid.ToString(), subjectId.ToString()); - - if (!Directory.Exists(uploadFolderPath)) Directory.CreateDirectory(uploadFolderPath); - - var (trustedFileNameForFileStorage, fileRealName) = FileStoreHelper.GetStoreFileName(fileName); - - - var relativePath = $"/{StaticData.Folder.IRaCISDataFolder}/{StaticData.Folder.TrialDataFolder}/{trialId}/{siteid}/{subjectId}/{trustedFileNameForFileStorage}"; - - var serverFilePath = Path.Combine(uploadFolderPath, trustedFileNameForFileStorage); - - return (serverFilePath, relativePath, fileRealName); - } - - - /// - /// 通用获取文件路径 - /// - /// - /// - /// - /// - /// - /// - public static (string PhysicalPath, string RelativePath, string FileRealName) GetFilePath(IWebHostEnvironment _hostEnvironment, string fileName, Guid trialId, Guid id,string type) - { - var rootPath = FileStoreHelper.GetIRaCISRootDataFolder(_hostEnvironment); - - string uploadFolderPath = Path.Combine(rootPath, StaticData.Folder.TrialDataFolder, trialId.ToString(), id.ToString(), type); - - if (!Directory.Exists(uploadFolderPath)) Directory.CreateDirectory(uploadFolderPath); - - var (trustedFileNameForFileStorage, fileRealName) = FileStoreHelper.GetStoreFileName(fileName); - - - var relativePath = $"/{StaticData.Folder.IRaCISDataFolder}/{StaticData.Folder.TrialDataFolder}/{trialId}/{id}/{type}/{trustedFileNameForFileStorage}"; - - var serverFilePath = Path.Combine(uploadFolderPath, trustedFileNameForFileStorage); - - return (serverFilePath, relativePath, fileRealName); - } - - public static (string PhysicalPath, string RelativePath, string FileRealName) GetMedicalReviewImage(IWebHostEnvironment _hostEnvironment, string fileName, Guid trialId, Guid taskMedicalReviewId) - { - var rootPath = FileStoreHelper.GetIRaCISRootDataFolder(_hostEnvironment); - - string uploadFolderPath = Path.Combine(rootPath, StaticData.Folder.TrialDataFolder, trialId.ToString(), taskMedicalReviewId.ToString(), StaticData.Folder.MedicalReview); - - if (!Directory.Exists(uploadFolderPath)) Directory.CreateDirectory(uploadFolderPath); - - var (trustedFileNameForFileStorage, fileRealName) = FileStoreHelper.GetStoreFileName(fileName); - - - var relativePath = $"/{StaticData.Folder.IRaCISDataFolder}/{StaticData.Folder.TrialDataFolder}/{trialId}/{taskMedicalReviewId}/{StaticData.Folder.MedicalReview}/{trustedFileNameForFileStorage}"; - - var serverFilePath = Path.Combine(uploadFolderPath, trustedFileNameForFileStorage); - - return (serverFilePath, relativePath, fileRealName); - } - - //获取非dicom文件存放路径 - public static (string PhysicalPath, string RelativePath, string FileRealName) GetNoneDicomFilePath(IWebHostEnvironment _hostEnvironment, string fileName, Guid trialId, Guid siteId, Guid subjectId, Guid subjectVisitId) - { - var rootPath = FileStoreHelper.GetIRaCISRootDataFolder(_hostEnvironment); - - string uploadFolderPath = Path.Combine(rootPath, StaticData.Folder.TrialDataFolder, trialId.ToString(), siteId.ToString(), subjectId.ToString(), subjectVisitId.ToString(), StaticData.Folder.NoneDicomFolder); - - if (!Directory.Exists(uploadFolderPath)) Directory.CreateDirectory(uploadFolderPath); - - var (trustedFileNameForFileStorage, fileRealName) = FileStoreHelper.GetStoreFileName(fileName); - - - var relativePath = $"/{StaticData.Folder.IRaCISDataFolder}/{StaticData.Folder.TrialDataFolder}/{trialId}/{siteId}/{subjectId}/{subjectVisitId}/{StaticData.Folder.NoneDicomFolder}/{trustedFileNameForFileStorage}"; - - var serverFilePath = Path.Combine(uploadFolderPath, trustedFileNameForFileStorage); - - return (serverFilePath, relativePath, fileRealName); - } - // 获取 入组确认 PD 进展发送邮件Word|PDF 存放路径 public static (string PhysicalPath, string RelativePath, string FileRealName) GetSubjectEnrollConfirmOrPDEmailPath(IWebHostEnvironment _hostEnvironment, string fileName, Guid trialId, Guid trialSiteId, Guid subjectId,bool isChangeToPdfFormat=false) @@ -631,49 +316,7 @@ public static class FileStoreHelper - // 获取医生通用文件存放路径 - public static (string PhysicalPath, string RelativePath) GetDoctorOrdinaryFilePath(IWebHostEnvironment _hostEnvironment, string fileName,Guid doctorId,string attachmentType) - { - - var rootPath = FileStoreHelper.GetIRaCISRootDataFolder(_hostEnvironment); - - //文件类型路径处理 - var uploadFolderPath = Path.Combine(rootPath, "UploadFile", doctorId.ToString(), attachmentType); - if (!Directory.Exists(uploadFolderPath)) Directory.CreateDirectory(uploadFolderPath); - - - var (trustedFileNameForFileStorage, fileRealName) = FileStoreHelper.GetStoreFileName(fileName); - - - - var relativePath = $"/{StaticData.Folder.IRaCISDataFolder}/{StaticData.Folder.UploadFileFolder}/{doctorId}/{attachmentType}/{trustedFileNameForFileStorage}"; - - var serverFilePath = Path.Combine(uploadFolderPath, trustedFileNameForFileStorage); - - return (serverFilePath, relativePath); - } - - public static (string PhysicalPath, string RelativePath) GetNonDoctorFilePath(IWebHostEnvironment _hostEnvironment, string fileName, string attachmentType) - { - - var rootPath = FileStoreHelper.GetIRaCISRootDataFolder(_hostEnvironment); - - //文件类型路径处理 - var uploadFolderPath = Path.Combine(rootPath, StaticData.Folder.UploadFileFolder, attachmentType); - if (!Directory.Exists(uploadFolderPath)) Directory.CreateDirectory(uploadFolderPath); - - - var (trustedFileNameForFileStorage, fileRealName) = FileStoreHelper.GetStoreFileName(fileName); - - - - var relativePath = $"/{StaticData.Folder.IRaCISDataFolder}/{StaticData.Folder.UploadFileFolder}/{attachmentType}/{trustedFileNameForFileStorage}"; - - var serverFilePath = Path.Combine(uploadFolderPath, trustedFileNameForFileStorage); - - return (serverFilePath, relativePath); - } From 45dd2e90c5a8d1bfea595a9a34a4628ecea7ecc6 Mon Sep 17 00:00:00 2001 From: he <109787524@qq.com> Date: Fri, 16 Aug 2024 11:27:52 +0800 Subject: [PATCH 249/251] =?UTF-8?q?=E4=BF=AE=E6=94=B9ip=E4=B8=8D=E4=B8=80?= =?UTF-8?q?=E6=A0=B7=E6=8F=90=E9=86=92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.Application/Service/Management/UserService.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/IRaCIS.Core.Application/Service/Management/UserService.cs b/IRaCIS.Core.Application/Service/Management/UserService.cs index 795cb8553..e25cfbfc5 100644 --- a/IRaCIS.Core.Application/Service/Management/UserService.cs +++ b/IRaCIS.Core.Application/Service/Management/UserService.cs @@ -18,6 +18,7 @@ using LoginReturnDTO = IRaCIS.Application.Contracts.LoginReturnDTO; using IRaCIS.Core.Application.Auth; using IRaCIS.Core.Domain.Models; using IRaCIS.Core.Application.Helper; +using IP2Region.Net.Abstractions; namespace IRaCIS.Application.Services { @@ -37,6 +38,7 @@ namespace IRaCIS.Application.Services private readonly IReadingImageTaskService _readingImageTaskService; private readonly IOptionsMonitor _verifyConfig; private readonly SystemEmailSendConfig _systemEmailConfig; + public ISearcher _searcher; public UserService(IRepository userRepository, @@ -44,6 +46,7 @@ namespace IRaCIS.Application.Services IRepository verificationCodeRepository, IRepository doctorRepository, IEasyCachingProvider cache, + ISearcher searcher, IReadingImageTaskService readingImageTaskService, IRepository userTrialRepository, IOptionsMonitor verifyConfig, @@ -57,6 +60,7 @@ namespace IRaCIS.Application.Services this._userPassWordLogRepository = userPassWordLogRepository; _verifyConfig = verifyConfig; _cache = cache; + this._searcher = searcher; this._readingImageTaskService = readingImageTaskService; _userRepository = userRepository; _mailVerificationService = mailVerificationService; @@ -828,10 +832,12 @@ namespace IRaCIS.Application.Services }); } + var ipinfo = _searcher.Search(_userInfo.IP); + var iPRegion = string.Join('|', ipinfo.Split('|').TakeLast(3)); await _userRepository.BatchUpdateNoTrackingAsync(x => x.Id == loginUser.Id, x => new User() { - LastLoginIP = _userInfo.IP, + LastLoginIP = iPRegion, LastLoginTime = DateTime.Now }); From 6b536f4a4f39e557daaa54f5af34c8ee2449962e Mon Sep 17 00:00:00 2001 From: he <109787524@qq.com> Date: Fri, 16 Aug 2024 15:38:15 +0800 Subject: [PATCH 250/251] =?UTF-8?q?=E4=BF=AE=E6=94=B9IP?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.Application/Service/Management/UserService.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/IRaCIS.Core.Application/Service/Management/UserService.cs b/IRaCIS.Core.Application/Service/Management/UserService.cs index e25cfbfc5..3fe37375c 100644 --- a/IRaCIS.Core.Application/Service/Management/UserService.cs +++ b/IRaCIS.Core.Application/Service/Management/UserService.cs @@ -806,12 +806,14 @@ namespace IRaCIS.Application.Services //登录成功 清除缓存 _cache.Set(cacheKey, 0, TimeSpan.FromMinutes(lockoutMinutes)); + var ipinfo = _searcher.Search(_userInfo.IP); + var iPRegion = string.Join('|', ipinfo.Split('|').TakeLast(3)); if (loginUser.LastLoginIP != string.Empty) { // 与上一次IP不一致 - if (loginUser.LastLoginIP != _userInfo.IP) + if (loginUser.LastLoginIP != iPRegion) { loginUser.LoginState = 2; } @@ -832,9 +834,7 @@ namespace IRaCIS.Application.Services }); } - var ipinfo = _searcher.Search(_userInfo.IP); - - var iPRegion = string.Join('|', ipinfo.Split('|').TakeLast(3)); + await _userRepository.BatchUpdateNoTrackingAsync(x => x.Id == loginUser.Id, x => new User() { LastLoginIP = iPRegion, From 7546ba412c6c9ba31c12a23000f294fc2c39c67f Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Fri, 16 Aug 2024 15:42:12 +0800 Subject: [PATCH 251/251] =?UTF-8?q?dicom=20ae=20=E6=8F=90=E7=A4=BA?= =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Service/TrialSiteUser/TrialSiteDicomAEService.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/IRaCIS.Core.Application/Service/TrialSiteUser/TrialSiteDicomAEService.cs b/IRaCIS.Core.Application/Service/TrialSiteUser/TrialSiteDicomAEService.cs index 7bd160513..5ed3452e0 100644 --- a/IRaCIS.Core.Application/Service/TrialSiteUser/TrialSiteDicomAEService.cs +++ b/IRaCIS.Core.Application/Service/TrialSiteUser/TrialSiteDicomAEService.cs @@ -51,8 +51,7 @@ namespace IRaCIS.Core.Application.Service { var verifyExp1 = new EntityVerifyExp() { - VerifyExp = u => u.IP == addOrEditTrialSiteDicomAE.IP && u.Port == addOrEditTrialSiteDicomAE.Port - && u.CallingAE == addOrEditTrialSiteDicomAE.CallingAE && u.TrialId == addOrEditTrialSiteDicomAE.TrialId + VerifyExp = u => u.CallingAE == addOrEditTrialSiteDicomAE.CallingAE && u.TrialId == addOrEditTrialSiteDicomAE.TrialId && u.TrialSiteId == addOrEditTrialSiteDicomAE.TrialSiteId, //"不允许添加相同的记录"