diff --git a/IRaCIS.Core.Application/TestService.cs b/IRaCIS.Core.Application/TestService.cs index 634ad7f0d..08f48d8af 100644 --- a/IRaCIS.Core.Application/TestService.cs +++ b/IRaCIS.Core.Application/TestService.cs @@ -379,6 +379,7 @@ namespace IRaCIS.Core.Application.Service var folder = FileStoreHelper.GetIRaCISRootDataFolder(_hostEnvironment); var outputFile = Path.Combine(folder, $"{Guid.NewGuid()}_deleteKey_info.txt"); + var outputFile2 = Path.Combine(folder, $"{Guid.NewGuid()}_deleteKeyExport_info.txt"); var outputErrorFile = Path.Combine(folder, $"{Guid.NewGuid()}_deleteKeyerror.txt"); var outputErrorFile2 = Path.Combine(folder, $"{Guid.NewGuid()}_deleteKeyerrorStudy.txt"); @@ -408,12 +409,6 @@ namespace IRaCIS.Core.Application.Service do { - //var tt = _ossClient.ListObjects(new Aliyun.OSS.ListObjectsRequest(aliConfig.BucketName) - //{ - // Prefix = "01000000-ac13-0242-6397-08dcd2d2a091/Image/08dd9c04-c1b2-c2da-0242-ac1301000000/01000000-ac13-0242-235b-08dd9c04c1b3", // 根目录,留空即可 - // MaxKeys = 100, - //}); - result = _ossClient.ListObjectVersions(request); if (result.ObjectVersionSummaries != null) @@ -465,9 +460,7 @@ namespace IRaCIS.Core.Application.Service continue; // 没找到可恢复版本 - var localPath = Path.Combine(folder, prevVersion.Key.Trim('/').Replace('/', Path.DirectorySeparatorChar)); - Directory.CreateDirectory(Path.GetDirectoryName(localPath)); - + try { @@ -490,36 +483,44 @@ namespace IRaCIS.Core.Application.Service var studyInstanceUID = dicomFile.Dataset.GetString(DicomTag.StudyInstanceUID); var findInfo = await _studyRepository.Where(t => t.StudyInstanceUid == studyInstanceUID && t.TrialId == Guid.Parse("01000000-ac13-0242-6397-08dcd2d2a091")) - .Select(t => new { t.StudyInstanceUid, t.Subject.Code, t.SubjectVisit.VisitName }).FirstOrDefaultAsync(); + .Select(t => new { t.StudyInstanceUid, t.Subject.Code, t.SubjectVisit.VisitName, t.SubjectId, t.SubjectVisitId }).FirstOrDefaultAsync(); if (findInfo != null) { // 再保存到另一个路径(可以使用 fo-dicom 保存) - var anotherPath = Path.Combine(folder, findInfo.Code, findInfo.VisitName, studyInstanceUID); + + var fileName = Path.GetFileNameWithoutExtension(prevVersion.Key); + var anotherPath = Path.Combine(folder, findInfo.Code, findInfo.VisitName, studyInstanceUID, fileName); + // 去掉 folder 部分,得到相对路径 + var relativePath = Path.GetRelativePath(folder, anotherPath); Directory.CreateDirectory(Path.GetDirectoryName(anotherPath)); dicomFile.Save(anotherPath); + + await File.AppendAllTextAsync(outputFile2, $"{findInfo.SubjectId},{findInfo.SubjectVisitId},{prevVersion.Key},{prevVersion.VersionId},{relativePath},{findInfo.Code},{findInfo.VisitName},{findInfo.StudyInstanceUid},{fileName}" + Environment.NewLine); } else { await File.AppendAllTextAsync(outputErrorFile2, $"{studyInstanceUID},{prevVersion.Key},{prevVersion.VersionId}" + Environment.NewLine); } - Console.WriteLine($"读取到 studyInstanceUID: {studyInstanceUID}"); + //Console.WriteLine($"读取到 studyInstanceUID: {studyInstanceUID}"); - // 保存到原本路径 - memStream.Position = 0; - using (var fs = File.Create(localPath)) - { - memStream.CopyTo(fs); - } + //var localPath = Path.Combine(folder, prevVersion.Key.Trim('/').Replace('/', Path.DirectorySeparatorChar)); + //Directory.CreateDirectory(Path.GetDirectoryName(localPath)); + //// 保存到原本路径 + //memStream.Position = 0; + //using (var fs = File.Create(localPath)) + //{ + // memStream.CopyTo(fs); + //} } - Console.WriteLine($"✅ 下载成功: {prevVersion.Key} (version={prevVersion.VersionId})"); + //Console.WriteLine($"✅ 下载成功: {prevVersion.Key} (version={prevVersion.VersionId})"); } catch (Exception ex) { @@ -569,6 +570,109 @@ namespace IRaCIS.Core.Application.Service + public async Task OSSDeleteReStorre([FromServices] IOSSService _oSSService, [FromServices] IWebHostEnvironment _hostEnvironment) + { + var aliConfig = _oSSService.ObjectStoreServiceOptions.AliyunOSS; + + var tempToken = _oSSService.GetObjectStoreTempToken(); + + var _ossClient = new OssClient(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? aliConfig.EndPoint : aliConfig.InternalEndpoint, + tempToken.AliyunOSS.AccessKeyId, + tempToken.AliyunOSS.AccessKeySecret, + tempToken.AliyunOSS.SecurityToken); + + + var allVersions = new List(); + var allDeleteMarkers = new List(); + + var request = new ListObjectVersionsRequest(tempToken.AliyunOSS.BucketName) + { + Prefix = "test-delete-restore", + //Prefix = "01000000-ac13-0242-6397-08dcd2d2a091/Image/08dd9c04-c1b2-c2da-0242-ac1301000000/01000000-ac13-0242-235b-08dd9c04c1b3", + MaxKeys = 1000, + }; + + ObjectVersionList result; + do + { + + result = _ossClient.ListObjectVersions(request); + + if (result.ObjectVersionSummaries != null) + allVersions.AddRange(result.ObjectVersionSummaries); + + if (result.DeleteMarkerSummaries != null) + allDeleteMarkers.AddRange(result.DeleteMarkerSummaries); + + request.KeyMarker = result.NextKeyMarker; + request.VersionIdMarker = result.NextVersionIdMarker; + + } while (result.IsTruncated); + + Console.WriteLine($"共找到 {allDeleteMarkers.Count} 个删除标记"); + + var versionsByKey = allVersions + .GroupBy(v => v.Key) + .ToDictionary(g => g.Key, g => g.OrderByDescending(x => x.LastModified).ToList()); + + + foreach (var del in allDeleteMarkers) + { + #region 防止阿里云过期 + if (tempToken.AliyunOSS.Expiration.AddSeconds(10) <= DateTime.Now) + { + tempToken = _oSSService.GetObjectStoreTempToken(); + + _ossClient = new OssClient(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? aliConfig.EndPoint : aliConfig.InternalEndpoint, + tempToken.AliyunOSS.AccessKeyId, + tempToken.AliyunOSS.AccessKeySecret, + tempToken.AliyunOSS.SecurityToken); + } + + #endregion + + if (!versionsByKey.TryGetValue(del.Key, out var versions)) + continue; // 没有历史版本无法恢复 + + var prevVersion = versions.FirstOrDefault(v => v.LastModified < del.LastModified); + if (prevVersion == null) + continue; // 没找到可恢复版本 + + + + + // 创建 CopyObject 请求 + // 先用构造函数指定源和目标 + var copyReq = new CopyObjectRequest( + sourceBucketName: tempToken.AliyunOSS.BucketName, + sourceKey: prevVersion.Key, + destinationBucketName: tempToken.AliyunOSS.BucketName, + destinationKey: prevVersion.Key // 覆盖到同名 Key,达到“恢复”的效果 + ); + + // 再设置版本号 + copyReq.SourceVersionId = prevVersion.VersionId; + + + + try + { + var copyResult = _ossClient.CopyObject(copyReq); + Console.WriteLine($"✅ 恢复成功: {prevVersion.Key}, 新版本ID={copyResult.VersionId}"); + } + catch (Exception ex) + { + Console.WriteLine($"❌ 恢复失败: {prevVersion.Key}, 错误: {ex.Message}"); + } + + + } + + return ResponseOutput.Ok(); + + + } + [AllowAnonymous] public async Task UserCreateSourceDeal([FromServices] IRepository _identityUserRepository,