撤销遮盖接口初步完成
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
parent
8259e2fea3
commit
6bb3be17ee
|
|
@ -1584,6 +1584,10 @@ public class OSSService(IOptionsMonitor<ObjectStoreServiceOptions> options,
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public async Task DeleteFromPrefix(string prefix, bool isCache = false)
|
public async Task DeleteFromPrefix(string prefix, bool isCache = false)
|
||||||
{
|
{
|
||||||
|
if (prefix.StartsWith("/"))
|
||||||
|
{
|
||||||
|
prefix = prefix.TrimStart("/");
|
||||||
|
}
|
||||||
|
|
||||||
//打开了同步的,删除的时候,一起删除
|
//打开了同步的,删除的时候,一起删除
|
||||||
if (ObjectStoreServiceOptions.IsOpenStoreSync && ObjectStoreServiceOptions.SyncConfigList.Any(t => t.IsOpenSync))
|
if (ObjectStoreServiceOptions.IsOpenStoreSync && ObjectStoreServiceOptions.SyncConfigList.Any(t => t.IsOpenSync))
|
||||||
|
|
|
||||||
|
|
@ -2967,10 +2967,17 @@
|
||||||
</member>
|
</member>
|
||||||
<member name="M:IRaCIS.Core.Application.Service.ImageAndDoc.StudyService.StudyMaskImage(IRaCIS.Core.Application.Contracts.StudyMaskImageCommand)">
|
<member name="M:IRaCIS.Core.Application.Service.ImageAndDoc.StudyService.StudyMaskImage(IRaCIS.Core.Application.Contracts.StudyMaskImageCommand)">
|
||||||
<summary>
|
<summary>
|
||||||
标注遮盖影像
|
标注遮盖影像 路径后面加了.MaskImage 就是遮盖的新路径
|
||||||
</summary>
|
</summary>
|
||||||
<returns></returns>
|
<returns></returns>
|
||||||
</member>
|
</member>
|
||||||
|
<member name="M:IRaCIS.Core.Application.Service.ImageAndDoc.StudyService.StudyUndoMaskImage(IRaCIS.Core.Application.Contracts.StudyUndoMaskImageCommand)">
|
||||||
|
<summary>
|
||||||
|
撤销遮盖的影像,可以单张,也可以整个序列
|
||||||
|
</summary>
|
||||||
|
<param name="inCommand"></param>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
<member name="M:IRaCIS.Core.Application.Service.ImageAndDoc.StudyService.Preview(System.Guid)">
|
<member name="M:IRaCIS.Core.Application.Service.ImageAndDoc.StudyService.Preview(System.Guid)">
|
||||||
<summary> 指定资源Id,渲染Dicom检查的Jpeg预览图像 </summary>
|
<summary> 指定资源Id,渲染Dicom检查的Jpeg预览图像 </summary>
|
||||||
<param name="studyId"> Dicom检查的Id </param>
|
<param name="studyId"> Dicom检查的Id </param>
|
||||||
|
|
@ -17248,17 +17255,17 @@
|
||||||
</member>
|
</member>
|
||||||
<member name="F:IRaCIS.Core.Application.ViewModel.AccessToDialogueEnum.Question">
|
<member name="F:IRaCIS.Core.Application.ViewModel.AccessToDialogueEnum.Question">
|
||||||
<summary>
|
<summary>
|
||||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
质疑
|
||||||
</summary>
|
</summary>
|
||||||
</member>
|
</member>
|
||||||
<member name="F:IRaCIS.Core.Application.ViewModel.AccessToDialogueEnum.Consistency">
|
<member name="F:IRaCIS.Core.Application.ViewModel.AccessToDialogueEnum.Consistency">
|
||||||
<summary>
|
<summary>
|
||||||
һ<EFBFBD><EFBFBD><EFBFBD>Ժ˲<EFBFBD>
|
一致性核查
|
||||||
</summary>
|
</summary>
|
||||||
</member>
|
</member>
|
||||||
<member name="T:IRaCIS.Core.Application.ViewModel.CopyFrontAuditConfigItemDto">
|
<member name="T:IRaCIS.Core.Application.ViewModel.CopyFrontAuditConfigItemDto">
|
||||||
<summary>
|
<summary>
|
||||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
复制
|
||||||
</summary>
|
</summary>
|
||||||
</member>
|
</member>
|
||||||
<member name="T:IRaCIS.Core.Application.ViewModel.SystemNoticeView">
|
<member name="T:IRaCIS.Core.Application.ViewModel.SystemNoticeView">
|
||||||
|
|
|
||||||
|
|
@ -1077,4 +1077,18 @@ namespace IRaCIS.Core.Application.Contracts
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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,7 @@ using IRaCIS.Core.Infrastructure;
|
||||||
using Medallion.Threading;
|
using Medallion.Threading;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using SkiaSharp;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using ZiggyCreatures.Caching.Fusion;
|
using ZiggyCreatures.Caching.Fusion;
|
||||||
|
|
||||||
|
|
@ -68,7 +69,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 标注遮盖影像
|
/// 标注遮盖影像 路径后面加了.MaskImage 就是遮盖的新路径
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public async Task<IResponseOutput> StudyMaskImage(StudyMaskImageCommand inCommand)
|
public async Task<IResponseOutput> StudyMaskImage(StudyMaskImageCommand inCommand)
|
||||||
|
|
@ -78,20 +79,25 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
||||||
return ResponseOutput.NotOk("SeriesId and InstanceIdList can not both be null");
|
return ResponseOutput.NotOk("SeriesId and InstanceIdList can not both be null");
|
||||||
}
|
}
|
||||||
|
|
||||||
var instancePathList = new List<string>();
|
|
||||||
|
var idPathList = new List<InstanceIdPath>();
|
||||||
|
|
||||||
if (inCommand.SeriesId == null && inCommand.InstanceIdList != null)
|
if (inCommand.SeriesId == null && inCommand.InstanceIdList != null)
|
||||||
{
|
{
|
||||||
instancePathList = await _dicomInstanceRepository.Where(t => inCommand.InstanceIdList.Contains(t.Id)).Select(t => t.Path).ToListAsync();
|
idPathList = await _dicomInstanceRepository.Where(t => inCommand.InstanceIdList.Contains(t.Id)).Select(t => new InstanceIdPath { Id = t.Id, Path = t.Path }).ToListAsync();
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
instancePathList = await _dicomInstanceRepository.Where(t => t.SeriesId == inCommand.SeriesId).Select(t => t.Path).ToListAsync();
|
idPathList = await _dicomInstanceRepository.Where(t => t.SeriesId == inCommand.SeriesId).Select(t => new InstanceIdPath { Id = t.Id, Path = t.Path }).ToListAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var path in instancePathList)
|
var errorPathList = new List<string>();
|
||||||
|
|
||||||
|
foreach (var item in idPathList)
|
||||||
{
|
{
|
||||||
|
var path = item.Path;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var inputStream = await _oSSService.GetStreamFromOSSAsync(path);
|
var inputStream = await _oSSService.GetStreamFromOSSAsync(path);
|
||||||
|
|
@ -99,21 +105,79 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
||||||
var outPutStream = await DicomPixelMasker.MaskAsync(inputStream, inCommand.MaskRegionList);
|
var outPutStream = await DicomPixelMasker.MaskAsync(inputStream, inCommand.MaskRegionList);
|
||||||
|
|
||||||
var prefix = path.Substring(1, path.LastIndexOf('/') - 1);
|
var prefix = path.Substring(1, path.LastIndexOf('/') - 1);
|
||||||
await _oSSService.UploadToOSSAsync(outPutStream, prefix, $"MaskImage_{Path.GetFileName(path)}");
|
|
||||||
|
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)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
errorPathList.Add(path);
|
||||||
|
|
||||||
Log.Logger.Error(ex, $"StudyMaskImage Error for InstanceIdList Path:{path} {ex.Message}");
|
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();
|
return ResponseOutput.Ok();
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
[TrialGlobalLimit("AfterStopCannNotOpt")]
|
[TrialGlobalLimit("AfterStopCannNotOpt")]
|
||||||
|
|
||||||
public async Task<IResponseOutput> PreArchiveDicomStudy(PreArchiveDicomStudyCommand preArchiveStudyCommand)
|
public async Task<IResponseOutput> PreArchiveDicomStudy(PreArchiveDicomStudyCommand preArchiveStudyCommand)
|
||||||
|
|
|
||||||
|
|
@ -82,6 +82,9 @@ public class DicomInstance : BaseFullDeleteAuditEntity, IEntitySeqId
|
||||||
|
|
||||||
public bool IsReading { get; set; } = true;
|
public bool IsReading { get; set; } = true;
|
||||||
|
|
||||||
|
[Comment("是否已经影像遮盖")]
|
||||||
|
public bool IsMasked { get; set; } = false;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#region DIR 增加
|
#region DIR 增加
|
||||||
|
|
|
||||||
22061
IRaCIS.Core.Infra.EFCore/Migrations/20260421023504_addImageMask.Designer.cs
generated
Normal file
22061
IRaCIS.Core.Infra.EFCore/Migrations/20260421023504_addImageMask.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,30 @@
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace IRaCIS.Core.Infra.EFCore.Migrations
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public partial class addImageMask : Migration
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.AddColumn<bool>(
|
||||||
|
name: "IsMasked",
|
||||||
|
table: "DicomInstance",
|
||||||
|
type: "bit",
|
||||||
|
nullable: false,
|
||||||
|
defaultValue: false,
|
||||||
|
comment: "是否已经影像遮盖");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "IsMasked",
|
||||||
|
table: "DicomInstance");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1168,6 +1168,10 @@ namespace IRaCIS.Core.Infra.EFCore.Migrations
|
||||||
b.Property<bool>("IsEncapsulated")
|
b.Property<bool>("IsEncapsulated")
|
||||||
.HasColumnType("bit");
|
.HasColumnType("bit");
|
||||||
|
|
||||||
|
b.Property<bool>("IsMasked")
|
||||||
|
.HasColumnType("bit")
|
||||||
|
.HasComment("是否已经影像遮盖");
|
||||||
|
|
||||||
b.Property<bool>("IsReading")
|
b.Property<bool>("IsReading")
|
||||||
.HasColumnType("bit");
|
.HasColumnType("bit");
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue