Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing

This commit is contained in:
he
2026-04-21 11:19:17 +08:00
10 changed files with 22267 additions and 14 deletions
@@ -1,4 +1,5 @@
using FellowOakDicom;
using IRaCIS.Core.Application.Helper;
using IRaCIS.Core.Application.Service.ImageAndDoc.DTO;
using IRaCIS.Core.Domain.Share;
using Newtonsoft.Json;
@@ -981,7 +982,7 @@ namespace IRaCIS.Core.Application.Contracts
}
public class SubjectVisitMarkQuery:PageInput
public class SubjectVisitMarkQuery : PageInput
{
public Guid TrialId { get; set; }
@@ -1065,4 +1066,29 @@ namespace IRaCIS.Core.Application.Contracts
public List<StudyBasicInfo> UploadStudyList { get; set; }
}
public class StudyMaskImageCommand
{
public Guid? SeriesId { get; set; }
public List<Guid>? InstanceIdList { get; set; }
public List<MaskRegion> MaskRegionList { get; set; }
}
public class StudyUndoMaskImageCommand
{
public Guid? SeriesId { get; set; }
public List<Guid>? InstanceIdList { get; set; }
}
public class InstanceIdPath
{
public Guid Id { get; set; }
public string Path { get; set; }
}
}
@@ -7,6 +7,8 @@ using IRaCIS.Core.Infrastructure;
using Medallion.Threading;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using SkiaSharp;
using System.Drawing;
using ZiggyCreatures.Caching.Fusion;
namespace IRaCIS.Core.Application.Service.ImageAndDoc
@@ -25,7 +27,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
IRepository<StudyMonitor> _studyMonitorRepository,
IRepository<SystemAnonymization> _systemAnonymizationRepository,
IRepository<NoneDicomStudy> _noneDicomStudyRepository,
IDistributedLockProvider _distributedLockProvider,
IDistributedLockProvider _distributedLockProvider, IOSSService _oSSService,
IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer, IFusionCache _fusionCache) : BaseService, IStudyService
{
@@ -66,6 +68,116 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
}
/// <summary>
/// 标注遮盖影像 路径后面加了.MaskImage 就是遮盖的新路径
/// </summary>
/// <returns></returns>
public async Task<IResponseOutput> StudyMaskImage(StudyMaskImageCommand inCommand)
{
if (inCommand.SeriesId == null && inCommand.InstanceIdList == null)
{
return ResponseOutput.NotOk("SeriesId and InstanceIdList can not both be null");
}
var idPathList = new List<InstanceIdPath>();
if (inCommand.SeriesId == null && inCommand.InstanceIdList != null)
{
idPathList = await _dicomInstanceRepository.Where(t => inCommand.InstanceIdList.Contains(t.Id)).Select(t => new InstanceIdPath { Id = t.Id, Path = t.Path }).ToListAsync();
}
else
{
idPathList = await _dicomInstanceRepository.Where(t => t.SeriesId == inCommand.SeriesId).Select(t => new InstanceIdPath { Id = t.Id, Path = t.Path }).ToListAsync();
}
var errorPathList = new List<string>();
foreach (var item in idPathList)
{
var path = item.Path;
try
{
var inputStream = await _oSSService.GetStreamFromOSSAsync(path);
var outPutStream = await DicomPixelMasker.MaskAsync(inputStream, inCommand.MaskRegionList);
var prefix = path.Substring(1, path.LastIndexOf('/') - 1);
var maskPath = $"{Path.GetFileName(path)}.MaskImage";
//清理缓存的里面的遮盖图,多次遮盖同一张图时,清除缓存很重要
await _oSSService.DeleteFromPrefix(maskPath, true);
await _oSSService.UploadToOSSAsync(outPutStream, prefix, maskPath);
await _dicomInstanceRepository.BatchUpdateNoTrackingAsync(t => t.Id == item.Id, u => new DicomInstance() { IsMasked = true });
}
catch (Exception ex)
{
errorPathList.Add(path);
Log.Logger.Error(ex, $"StudyMaskImage Error for InstanceIdList Path:{path} {ex.Message}");
}
}
await _dicomInstanceRepository.SaveChangesAsync();
return ResponseOutput.Ok(errorPathList);
}
/// <summary>
/// 撤销遮盖的影像,可以单张,也可以整个序列
/// </summary>
/// <param name="inCommand"></param>
/// <returns></returns>
public async Task<IResponseOutput> StudyUndoMaskImage(StudyUndoMaskImageCommand inCommand)
{
if (inCommand.SeriesId == null && inCommand.InstanceIdList == null)
{
return ResponseOutput.NotOk("SeriesId and InstanceIdList can not both be null");
}
var idPathList = new List<InstanceIdPath>();
if (inCommand.SeriesId == null && inCommand.InstanceIdList != null)
{
idPathList = await _dicomInstanceRepository.Where(t => inCommand.InstanceIdList.Contains(t.Id)).Select(t => new InstanceIdPath { Id = t.Id, Path = t.Path }).ToListAsync();
}
else
{
idPathList = await _dicomInstanceRepository.Where(t => t.SeriesId == inCommand.SeriesId).Select(t => new InstanceIdPath { Id = t.Id, Path = t.Path }).ToListAsync();
}
foreach (var item in idPathList)
{
if (item.Path.EndsWith(".MaskImage"))
{
var newPath = item.Path[..^10];
//await _oSSService.DeleteFromPrefix(newPath, true);
await _dicomInstanceRepository.BatchUpdateNoTrackingAsync(t => t.Id == item.Id, u => new DicomInstance() { Path = newPath, IsMasked = false });
}
}
await _dicomInstanceRepository.SaveChangesAsync();
return ResponseOutput.Ok();
}
[TrialGlobalLimit("AfterStopCannNotOpt")]
public async Task<IResponseOutput> PreArchiveDicomStudy(PreArchiveDicomStudyCommand preArchiveStudyCommand)
@@ -349,7 +461,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
}
var @lock2 = _distributedLockProvider.CreateLock($"StudyCommit");
@@ -359,7 +471,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
await _dicomInstanceRepository.SaveChangesAsync();
}
await _fileUploadRecordRepository.BatchUpdateNoTrackingAsync(t => t.UploadBatchId == incommand.UploadBatchId, u => new FileUploadRecord() { StudyCode = findStudy.StudyCode });
await _fileUploadRecordRepository.BatchUpdateNoTrackingAsync(t => t.UploadBatchId == incommand.UploadBatchId, u => new FileUploadRecord() { StudyCode = findStudy.StudyCode });
}
catch (Exception ex)
{
@@ -462,7 +574,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
Id = t.Id,
Bodypart = t.BodyPart,
BodyPartForEditOther=t.BodyPartForEditOther,
BodyPartForEditOther = t.BodyPartForEditOther,
Modalities = t.Modality,