From d719015fa2e28a6792192697eac7a5472aee333c Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Thu, 4 Jun 2026 13:08:37 +0800 Subject: [PATCH] =?UTF-8?q?zip=20=E6=B5=81=E6=96=B9=E5=BC=8Fdemo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Common/TrialImageDownloadService.cs | 88 +++++++++++++------ IRaCIS.Core.Application/TestService.cs | 23 ----- 2 files changed, 62 insertions(+), 49 deletions(-) diff --git a/IRaCIS.Core.Application/Service/Common/TrialImageDownloadService.cs b/IRaCIS.Core.Application/Service/Common/TrialImageDownloadService.cs index bba480b31..5bf9183b6 100644 --- a/IRaCIS.Core.Application/Service/Common/TrialImageDownloadService.cs +++ b/IRaCIS.Core.Application/Service/Common/TrialImageDownloadService.cs @@ -1,4 +1,5 @@ using Aliyun.OSS; +using CommunityToolkit.HighPerformance; using DocumentFormat.OpenXml.EMMA; using DocumentFormat.OpenXml.Office.CustomUI; using DocumentFormat.OpenXml.Office2010.Excel; @@ -148,11 +149,9 @@ namespace IRaCIS.Core.Application.Service private async Task CreateVisitZipAsync(string zipPath, List zipItems) { - Directory.CreateDirectory( - Path.GetDirectoryName(zipPath)!); + Directory.CreateDirectory(Path.GetDirectoryName(zipPath)!); - await using var zipFileStream = - new FileStream(zipPath, FileMode.Create, FileAccess.Write, FileShare.None, bufferSize: 4 * 1024 * 1024, useAsync: true); + await using var zipFileStream = new FileStream(zipPath, FileMode.Create, FileAccess.Write, FileShare.None, bufferSize: 4 * 1024 * 1024, useAsync: true); using var archive = new ZipArchive(zipFileStream, ZipArchiveMode.Create, leaveOpen: false); @@ -177,7 +176,9 @@ namespace IRaCIS.Core.Application.Service if (!success) { - Log.Logger.Warning($"合并多帧失败:{item.ZipEntryPath}"); + Log.Logger.Warning($"合并多帧失败:{item.ZipEntryPath} ossPath: {item.OssPath}"); + + throw new Exception($"合并多帧失败-终止当前zip包:{item.ZipEntryPath} ossPath: {item.OssPath}"); } } @@ -235,8 +236,7 @@ namespace IRaCIS.Core.Application.Service var downloadVisits = MiniExcel.Query(Path.Combine(rootFolder, "download.xlsx")).ToList().Where(t => t.SubjectCode.IsNotNullOrEmpty() && t.VisitName.IsNotNullOrEmpty()).ToList(); - downloadVisits = downloadVisits.Where(t => !oldVisits.Any(old => old.VisitNum == t.VisitNum && old.SubjectCode == t.SubjectCode && - old.VisitName.Trim().ToLower() == t.VisitName.Trim().ToLower())).ToList(); + downloadVisits = downloadVisits.Where(t => !oldVisits.Any(old => old.VisitNum == t.VisitNum && old.SubjectCode == t.SubjectCode && old.VisitName.Trim().ToLower() == t.VisitName.Trim().ToLower())).ToList(); var visitIndex = 0; var skipCount = 0; @@ -298,7 +298,7 @@ namespace IRaCIS.Core.Application.Service if (downloadInfo == null) { - return ResponseOutput.Ok(); + continue; } #region 排除已经下载的 @@ -312,8 +312,7 @@ namespace IRaCIS.Core.Application.Service StreamReaderFunc = (stream) => new StreamReader(stream, Encoding.GetEncoding("gb2312")) }).ToList(); - if (existVisits.Any(old => old.VisitNum == downloadVisit.VisitNum && old.SubjectCode == downloadVisit.SubjectCode && - old.VisitName.Trim().ToLower() == downloadVisit.VisitName.Trim().ToLower())) + if (existVisits.Any(old => old.VisitNum == downloadVisit.VisitNum && old.SubjectCode == downloadVisit.SubjectCode && old.VisitName.Trim().ToLower() == downloadVisit.VisitName.Trim().ToLower())) { Log.Logger.Warning($"[{visitIndex}] Excel显示已下载,跳过当前访视:{downloadVisit.SubjectCode} {downloadVisit.VisitName} {downloadVisit.VisitNum}"); skipCount++; @@ -342,6 +341,8 @@ namespace IRaCIS.Core.Application.Service var visitFolderName = $"{visitItem.SubjectCode}_{visitItem.VisitName.Trim()}"; + #region DICOM + foreach (var studyInfo in visitItem.StudyList) { var dirDic = new Dictionary(); @@ -394,6 +395,11 @@ namespace IRaCIS.Core.Application.Service foreach (var group in list.GroupBy(t => new { t.StudyInstanceUid, t.DicomStudyId })) { + using var ms = new MemoryStream(); + + await DicomDIRHelper.GenerateStudyDIR(group.ToList(), dirDic, outputStream: ms); + + var dicomDirBytes = ms.ToArray(); zipItems.Add(new ZipItem { @@ -401,7 +407,7 @@ namespace IRaCIS.Core.Application.Service CustomWriter = async entryStream => { - await DicomDIRHelper.GenerateStudyDIR(group.ToList(), dirDic, outputStream: entryStream); + await entryStream.WriteAsync(dicomDirBytes); } }); } @@ -412,7 +418,7 @@ namespace IRaCIS.Core.Application.Service #endregion - #region DICOM + foreach (var seriesInfo in studyInfo.SeriesList) { @@ -429,11 +435,13 @@ namespace IRaCIS.Core.Application.Service } } - #endregion } + #endregion + + #region NoneDicom foreach (var study in visitItem.NoneDicomStudyList) @@ -453,15 +461,40 @@ namespace IRaCIS.Core.Application.Service #endregion - var zipPath = Path.Combine(rootFolder, visitFolderName + ".zip"); - Log.Logger.Warning($"开始压缩访视:{visitFolderName}"); + #region zip - await CreateVisitZipAsync(zipPath, zipItems); - DownloadLogger.Write(logFilePath, visitItem.SubjectCode, visitItem.VisitNum, visitItem.VisitName, "Success"); + var zipPath = Path.Combine(trialFolderPath, visitFolderName + ".zip"); + + Log.Logger.Warning($"[{visitIndex}] {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}开始打包下载访视:{visitFolderName}"); + + try + { + await CreateVisitZipAsync(zipPath, zipItems); + + //Log.Logger.Warning($"zip exists={File.Exists(zipPath)} size={new FileInfo(zipPath).Length}"); + + Log.Logger.Warning($"[{visitIndex}] {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}访视打包下载完成:{visitFolderName}"); + + DownloadLogger.Write(logFilePath, visitItem.SubjectCode, visitItem.VisitNum, visitItem.VisitName, "Success"); + + } + catch (Exception ex) + { + Log.Logger.Warning($"出现异常{ex}删除压缩包:{visitFolderName}"); + //如果有异常,删除失败的压缩包 + if (File.Exists(zipPath)) + { + File.Delete(zipPath); + } + + } + + + #endregion + - Log.Logger.Warning($"访视压缩完成:{visitFolderName}"); #endregion @@ -486,8 +519,6 @@ namespace IRaCIS.Core.Application.Service public static class DownloadLogger { - - public static void Write( string logFilePath, string subjectCode, @@ -495,27 +526,34 @@ namespace IRaCIS.Core.Application.Service string visitName, string? message = null) { - bool fileExists = File.Exists(logFilePath); + // 一次性打开文件流 using var stream = new FileStream( logFilePath, FileMode.Append, FileAccess.Write, FileShare.ReadWrite); - using var writer = new StreamWriter(stream, Encoding.UTF8); + // 首次创建时写入 BOM + if (!fileExists) + { + var bom = new UTF8Encoding(true).GetPreamble(); + stream.Write(bom, 0, bom.Length); + } + using var writer = new StreamWriter(stream, new UTF8Encoding(false)); - // 首次写入表头 + // 写入表头 if (!fileExists) { writer.WriteLine("Time,SubjectCode,VisitNum,VisitName,Message"); } + // 写入数据 string line = string.Join(",", [ - Escape(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")), + Escape(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")), subjectCode, visitNum, visitName, @@ -525,14 +563,12 @@ namespace IRaCIS.Core.Application.Service writer.WriteLine(line); } - // 防止逗号、换行导致 CSV 错乱 private static string Escape(string? value) { if (string.IsNullOrEmpty(value)) return ""; value = value.Replace("\"", "\"\""); - return $"\"{value}\""; } } diff --git a/IRaCIS.Core.Application/TestService.cs b/IRaCIS.Core.Application/TestService.cs index 34e6f3364..83ca9053e 100644 --- a/IRaCIS.Core.Application/TestService.cs +++ b/IRaCIS.Core.Application/TestService.cs @@ -1,30 +1,17 @@ using Aliyun.OSS; -using DocumentFormat.OpenXml.Spreadsheet; using FellowOakDicom; using FellowOakDicom.Imaging; using IRaCIS.Application.Contracts; -using IRaCIS.Core.Application.BusinessFilter; using IRaCIS.Core.Application.Contracts; using IRaCIS.Core.Application.Helper; -using IRaCIS.Core.Application.Helper.OtherTool; -using IRaCIS.Core.Application.Service.BusinessFilter; using IRaCIS.Core.Application.ViewModel; -using IRaCIS.Core.Domain; -using IRaCIS.Core.Domain.Models; -using IRaCIS.Core.Domain.Share; -using IRaCIS.Core.Infra.EFCore; using IRaCIS.Core.Infra.EFCore.Context; using IRaCIS.Core.Infrastructure; using IRaCIS.Core.Infrastructure.Encryption; using IRaCIS.Core.Infrastructure.NewtonsoftJson; using MassTransit; -using MassTransit.Caching.Internals; -using MassTransit.Mediator; -using MathNet.Numerics; -using MaxMind.GeoIP2; using Medallion.Threading; using Microsoft.AspNetCore.Authorization; -using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; @@ -32,25 +19,15 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using MiniExcelLibs; -using Minio.DataModel; using Newtonsoft.Json; -using NPOI.SS.Formula.Functions; using NPOI.XWPF.UserModel; -using SharpCompress.Common; using SixLabors.ImageSharp; using SixLabors.ImageSharp.Formats.Jpeg; using SixLabors.ImageSharp.Processing; -using System.Collections.Concurrent; using System.ComponentModel.DataAnnotations; -using System.Diagnostics; -using System.Globalization; -using System.IO; using System.Linq.Dynamic.Core; -using System.Reactive.Subjects; -using System.Reflection.Metadata.Ecma335; using System.Runtime.InteropServices; using System.Text; -using static IRaCIS.Core.Domain.Share.StaticData;