From 578aaa467ce39f557b599457d9f661ce09941b4f Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Fri, 6 Jun 2025 11:12:46 +0800 Subject: [PATCH] =?UTF-8?q?=E9=82=AE=E4=BB=B6=E4=BF=AE=E6=94=B9+=E5=BD=B1?= =?UTF-8?q?=E5=83=8F=E5=AF=BC=E5=87=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../IRaCIS.Core.Application.xml | 76 +++++-- .../Common/DTO/EmailNoticeConfigViewModel.cs | 11 + .../Common/EmailNoticeConfigService.cs | 38 ++++ ...ervice.cs => TrialImageDownloadService.cs} | 19 +- .../ImageAndDoc/DTO/UnionStudyViewDodel.cs | 104 ++++++++++ .../ImageAndDoc/DownloadAndUploadService.cs | 188 +++++++++++++++++- IRaCIS.Core.Domain/Allocation/VisitTask.cs | 5 + 7 files changed, 406 insertions(+), 35 deletions(-) rename IRaCIS.Core.Application/Service/Common/{BackDownloadService.cs => TrialImageDownloadService.cs} (91%) diff --git a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml index 41a0fe48e..138f78165 100644 --- a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml +++ b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml @@ -549,20 +549,6 @@ - - - 项目影像后台下载,不打包 - - - - - - - 项目影像后台下载,不打包 - - - - 系统模板文档配置表 @@ -1067,6 +1053,27 @@ PublishLogService + + + 项目影像后台下载,不打包 + + + + + + + 项目影像后台下载,不打包 + + + + + + + 后端api swagger 下载项目影像 + + + + 医生文档关联关系维护 @@ -2016,6 +2023,14 @@ + + + 更新后处理上传的检查modality + + + + + 影像下载成功回调 @@ -2030,12 +2045,18 @@ - + - 更新后处理上传的检查modality + 获取项目影像统计,有影像的subject 数量 访视数量 - - + + + + + + 批量勾选访视 进行下载 + + @@ -2342,7 +2363,7 @@ FrontAuditConfigService - + FrontAuditConfigService @@ -2457,11 +2478,19 @@ - + + + 获取模块类型列表 + + + + + 获取Description + @@ -16041,6 +16070,13 @@ 系统邮件配置表 + + + 批量更新邮件主题中英文 + + + + ISystemBasicDataService diff --git a/IRaCIS.Core.Application/Service/Common/DTO/EmailNoticeConfigViewModel.cs b/IRaCIS.Core.Application/Service/Common/DTO/EmailNoticeConfigViewModel.cs index c36c3cbac..a6ae722e9 100644 --- a/IRaCIS.Core.Application/Service/Common/DTO/EmailNoticeConfigViewModel.cs +++ b/IRaCIS.Core.Application/Service/Common/DTO/EmailNoticeConfigViewModel.cs @@ -143,6 +143,17 @@ namespace IRaCIS.Core.Application.Contracts } + public class BatchUpdateEmailTopicCommand + { + [NotDefault] + public Guid Id { get; set; } + + public string EmailTopic { get; set; } = string.Empty; + + public string EmailTopicCN { get; set; } = string.Empty; + } + + public class EmailNoticeConfigExportDto { public Guid? Id { get; set; } diff --git a/IRaCIS.Core.Application/Service/Common/EmailNoticeConfigService.cs b/IRaCIS.Core.Application/Service/Common/EmailNoticeConfigService.cs index 0096f4495..e6f856a0e 100644 --- a/IRaCIS.Core.Application/Service/Common/EmailNoticeConfigService.cs +++ b/IRaCIS.Core.Application/Service/Common/EmailNoticeConfigService.cs @@ -41,6 +41,44 @@ namespace IRaCIS.Core.Application.Contracts return await emailNoticeConfigQueryable.ToPagedListAsync(inQuery); } + /// + /// 批量更新邮件主题中英文 + /// + /// + /// + public async Task BatchUpdateEmail(List inCommandList) + { + var findIdList = inCommandList.Select(x => x.Id).ToList(); + + var regex = new Regex(@"\{\s*\d+\s*\}"); + + foreach (var inCommand in inCommandList) + { + if (regex.Matches($"{inCommand.EmailTopic}{inCommand.EmailTopicCN}") + .Any(t => t.Value.Contains(" "))) + { + //邮件模板占位符不允许有空格,请核查占位符的地方 + return ResponseOutput.NotOk(I18n.T("EmailNoticeConfig_ContainEmpty")); + } + } + + var list = _emailNoticeConfigrepository.Where(t => findIdList.Contains(t.Id), true).ToList(); + + foreach (var item in list) + { + var exist = inCommandList.FirstOrDefault(t => t.Id == item.Id); + if (exist != null) + { + item.EmailTopic = exist.EmailTopic; + item.EmailTopicCN = exist.EmailTopicCN; + } + } + + await _emailNoticeConfigrepository.SaveChangesAsync(); + + + return ResponseOutput.Ok(); + } public async Task AddOrUpdateEmailNoticeConfig(EmailNoticeConfigAddOrEdit addOrEditEmailNoticeConfig) { diff --git a/IRaCIS.Core.Application/Service/Common/BackDownloadService.cs b/IRaCIS.Core.Application/Service/Common/TrialImageDownloadService.cs similarity index 91% rename from IRaCIS.Core.Application/Service/Common/BackDownloadService.cs rename to IRaCIS.Core.Application/Service/Common/TrialImageDownloadService.cs index 05a2af38c..dfe3cf445 100644 --- a/IRaCIS.Core.Application/Service/Common/BackDownloadService.cs +++ b/IRaCIS.Core.Application/Service/Common/TrialImageDownloadService.cs @@ -22,20 +22,31 @@ namespace IRaCIS.Core.Application.Service /// /// /// - [AllowAnonymous] [ApiExplorerSettings(GroupName = "Common")] - public class BackDownloadService(IRepository _trialRepository, IOSSService _oSSService, IWebHostEnvironment _hostEnvironment) : BaseService + public class TrialImageDownloadService(IRepository _trialRepository, IOSSService _oSSService, IWebHostEnvironment _hostEnvironment) : BaseService { + + + + + + /// + /// 后端api swagger 下载项目影像 + /// + /// + /// + [HttpPost] + [AllowAnonymous] public async Task DownloadTrialImage(Guid trialId) { - + var subjectCodeList = new List() { "S040001", "S140001", "S190002" }; var downloadInfo = _trialRepository.Where(t => t.Id == trialId).Select(t => new { t.ResearchProgramNo, - VisitList = t.SubjectVisitList.Select(sv => new + VisitList = t.SubjectVisitList.Where(t=>subjectCodeList.Contains(t.Subject.Code)).Select(sv => new { TrialSiteCode = sv.TrialSite.TrialSiteCode, SubjectCode = sv.Subject.Code, diff --git a/IRaCIS.Core.Application/Service/ImageAndDoc/DTO/UnionStudyViewDodel.cs b/IRaCIS.Core.Application/Service/ImageAndDoc/DTO/UnionStudyViewDodel.cs index ab5eff287..81af79674 100644 --- a/IRaCIS.Core.Application/Service/ImageAndDoc/DTO/UnionStudyViewDodel.cs +++ b/IRaCIS.Core.Application/Service/ImageAndDoc/DTO/UnionStudyViewDodel.cs @@ -546,6 +546,110 @@ namespace IRaCIS.Core.Application.Contracts } + public class TrialExportImageCommand + { + [NotDefault] + public Guid TrialId { get; set; } + + public List SubjectVisitIdList { get; set; } + + + public bool IsKeyImage { get; set; } + } + + + public class TrialVisitImageQuery : PageInput + { + [NotDefault] + public Guid TrialId { get; set; } + + + public Guid? TrialSiteId { get; set; } + + public string? SubjectCode { get; set; } + + public DateTime? BeginScanDate { get; set; } + public DateTime? EndScanDate { get; set; } + } + public class TrialVisitImageStatView + { + public Guid TrialId { get; set; } + + public Guid SubjectVisitId { get; set; } + + public Guid TrialSiteId { get; set; } + + public string TrialSiteCode { get; set; } + + public string SubjectCode { get; set; } + + public string VisitName { get; set; } + + public decimal VisitNum { get; set; } + + public DateTime? EarliestScanDate { get; set; } + public DateTime? LatestScanDate { get; set; } + + + + public int TotalStudyCount { get; set; } + + public int TotalImageCount { get; set; } + + public long? TotalImageSize { get; set; } + + public string TotalImageSizeStr => TotalImageSize.HasValue + ? $"{TotalImageSize.Value / 1024d / 1024d:F3} MB" + : "0.000 MB"; + + + #region 废弃,为了字段排序 + //public int TotalStudyCount => DicomStudyCount + NoneDicomStudyCount; + + //public int TotalImageCount => DicomImageCount + NoneDicomImageCount; + + //public long? TotalImageSize => DicomImageSize + NoneDicomImageSize; + + //public int DicomStudyCount { get; set; } + //public int DicomImageCount { get; set; } + //public long? DicomImageSize { get; set; } + + + //public int NoneDicomStudyCount { get; set; } + //public int NoneDicomImageCount { get; set; } + //public long? NoneDicomImageSize { get; set; } + + #endregion + + + } + + + public class TrialImageStatInfo + { + public int SubjectCount { get; set; } + + public int SubjectVisitCount { get; set; } + + public long? TotalImageSize { get; set; } + + + public string TotalImageSizeStr => TotalImageSize.HasValue + ? $"{TotalImageSize.Value / 1024d / 1024d:F3} MB" + : "0.000 MB"; + + + public string SubjectImageAVGSizeStr => TotalImageSize.HasValue + ? $"{TotalImageSize.Value / SubjectCount / 1024d / 1024d:F3} MB" + : "0.000 MB"; + + + public string SubjectVisitImageAVGSizeStr => TotalImageSize.HasValue + ? $"{TotalImageSize.Value / SubjectVisitCount / 1024d / 1024d:F3} MB" + : "0.000 MB"; + + + } public class TrialImageDownloadView { public Guid TrialId { get; set; } diff --git a/IRaCIS.Core.Application/Service/ImageAndDoc/DownloadAndUploadService.cs b/IRaCIS.Core.Application/Service/ImageAndDoc/DownloadAndUploadService.cs index 494022bf3..b9175ac2b 100644 --- a/IRaCIS.Core.Application/Service/ImageAndDoc/DownloadAndUploadService.cs +++ b/IRaCIS.Core.Application/Service/ImageAndDoc/DownloadAndUploadService.cs @@ -1117,7 +1117,18 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc } - + /// + /// 更新后处理上传的检查modality + /// + /// + /// + /// + [HttpPut] + public async Task UpdateTaskStudyModality(Guid taskStudyId, string modality) + { + await _taskStudyRepository.UpdatePartialFromQueryAsync(t => t.Id == taskStudyId, u => new TaskStudy() { ModalityForEdit = modality }, true); + return ResponseOutput.Ok(); + } /// /// 影像下载成功回调 @@ -1154,19 +1165,174 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc return await query.ToPagedListAsync(inQuery); } - /// - /// 更新后处理上传的检查modality - /// - /// - /// - /// - [HttpPut] - public async Task UpdateTaskStudyModality(Guid taskStudyId, string modality) + + + #region 影像汇总页面 + + public async Task>> GetTrialVisitImageStatList(TrialVisitImageQuery inQuery) { - await _taskStudyRepository.UpdatePartialFromQueryAsync(t => t.Id == taskStudyId, u => new TaskStudy() { ModalityForEdit = modality }, true); - return ResponseOutput.Ok(); + var query = _subjectVisitRepository.Where(t => t.TrialId == inQuery.TrialId) + .WhereIf(inQuery.TrialSiteId != null, t => t.TrialSiteId == inQuery.TrialSiteId) + .WhereIf(inQuery.SubjectCode.IsNotNullOrEmpty(), t => t.Subject.Code.Contains(inQuery.SubjectCode)) + .WhereIf(inQuery.BeginScanDate != null, t => t.LatestScanDate >= inQuery.BeginScanDate) + .WhereIf(inQuery.EndScanDate != null, t => t.LatestScanDate == inQuery.EndScanDate) + .Select(t => new TrialVisitImageStatView() + { + TrialId = t.TrialId, + SubjectCode = t.Subject.Code, + TrialSiteCode = t.TrialSite.TrialSiteCode, + TrialSiteId = t.TrialSiteId, + VisitName = t.VisitName, + VisitNum = t.VisitNum, + EarliestScanDate = t.EarliestScanDate, + LatestScanDate = t.LatestScanDate, + + + TotalStudyCount = t.StudyList.Count() + t.NoneDicomStudyList.Count(), + + TotalImageCount = t.StudyList.Sum(t => t.InstanceCount) + t.NoneDicomStudyList.Sum(t => t.FileCount), + + TotalImageSize = t.StudyList.SelectMany(t => t.InstanceList).Sum(t => t.FileSize) + t.NoneDicomStudyList.SelectMany(t => t.NoneDicomFileList).Sum(t => t.FileSize), + + + //DicomStudyCount = t.StudyList.Count(), + //NoneDicomStudyCount = t.NoneDicomStudyList.Count(), + + //DicomImageCount = t.StudyList.Sum(t => t.InstanceCount), + //NoneDicomImageCount = t.NoneDicomStudyList.Sum(t => t.FileCount), + + //DicomImageSize = t.StudyList.SelectMany(t => t.InstanceList).Sum(t => t.FileSize), + //NoneDicomImageSize = t.NoneDicomStudyList.SelectMany(t => t.NoneDicomFileList).Sum(t => t.FileSize) + }); + + + var pagelist = await query.ToPagedListAsync(inQuery); + + return ResponseOutput.Ok(pagelist); } + /// + /// 获取项目影像统计,有影像的subject 数量 访视数量 + /// + /// + /// + public async Task GetTrialVisitImageStatInfo(Guid trialId) + { + var subjectImageList = _subjectVisitRepository.Where(t => t.TrialId == trialId) + .Where(t => t.StudyList.Sum(t => t.InstanceCount) > 0 || t.NoneDicomStudyList.Sum(t => t.FileCount) > 0) + .GroupBy(t => t.SubjectId) + .Select(g => new + { + SubjectId = g.Key, + VisitCount = g.Count(), + ImageSize = g.Sum(t => t.NoneDicomStudyList.SelectMany(t => t.NoneDicomFileList).Sum(t => t.FileSize) + + g.Sum(t => t.StudyList.SelectMany(t => t.InstanceList).Sum(t => t.FileSize))) + }) + .ToList(); + + var subjectCount = subjectImageList.Count; + + var subjectVisitCount = subjectImageList.Sum(t => t.VisitCount); + + var totalImageSize = subjectImageList.Sum(t => t.ImageSize); + + return ResponseOutput.Ok(new TrialImageStatInfo { SubjectCount = subjectCount, SubjectVisitCount = subjectVisitCount, TotalImageSize = totalImageSize }); + + + } + + /// + /// 批量勾选访视 进行下载 + /// + /// + /// + public async Task GetExportSubjectVisitImageList(TrialExportImageCommand inCommand) + { + + if (inCommand.IsKeyImage) + { + var downloadInfo = _visitTaskRepository.Where(t => t.TrialId == inCommand.TrialId && t.ReadingCategory == ReadingCategory.Visit && t.IsAnalysisCreate == false) + .Where(t => inCommand.SubjectVisitIdList.Contains((Guid)t.SourceSubjectVisitId)) + .Select(t => new + { + t.Trial.ResearchProgramNo, + CriterionName = t.TrialReadingCriterion.CriterionName, + + TrialSiteCode = t.Subject.TrialSite.TrialSiteCode, + SubjectCode = t.Subject.Code, + VisitName = (string?)t.SourceSubjectVisit.VisitName, + + QuestionMarkPictureList = t.ReadingTaskQuestionMarkList.SelectMany(c => new List() { c.PicturePath, c.OtherPicturePath }).ToList(), + + TableQuestionRowPictureList = t.LesionList.SelectMany(c => new List() { c.PicturePath, c.OtherPicturePath }).ToList(), + + + IsJudgeSelect = t.JudgeResultTaskId == t.Id + + + }).FirstOrDefault(); + + return ResponseOutput.Ok(downloadInfo); + } + else + { + + var downloadInfo = _trialRepository.Where(t => t.Id == inCommand.TrialId).Select(t => new + { + t.ResearchProgramNo, + + VisitList = t.SubjectVisitList.Where(t => inCommand.SubjectVisitIdList.Contains(t.Id)).Select(sv => new + { + TrialSiteCode = sv.TrialSite.TrialSiteCode, + 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 + }) + }) + + }), + + NoneDicomStudyList = sv.NoneDicomStudyList.Select(nd => new + { + nd.Modality, + nd.StudyCode, + nd.ImageDate, + + FileList = nd.NoneDicomFileList.Select(file => new + { + file.FileName, + file.Path, + file.FileType + }) + }) + }).ToList() + + }).FirstOrDefault(); + + + return ResponseOutput.Ok(downloadInfo); + } + + + + } + + #endregion + + + #region 之前后端下载废弃 diff --git a/IRaCIS.Core.Domain/Allocation/VisitTask.cs b/IRaCIS.Core.Domain/Allocation/VisitTask.cs index 10453517e..928bb0148 100644 --- a/IRaCIS.Core.Domain/Allocation/VisitTask.cs +++ b/IRaCIS.Core.Domain/Allocation/VisitTask.cs @@ -9,6 +9,11 @@ namespace IRaCIS.Core.Domain.Models; public class VisitTask : BaseFullAuditEntity { #region 导航属性 + + [JsonIgnore] + + public List ReadingTaskQuestionMarkList { get; set; } + [JsonIgnore] public List TaskStudyList { get; set; }