111 lines
4.5 KiB
C#
111 lines
4.5 KiB
C#
using IRaCIS.Core.Application.Contracts;
|
|
using IRaCIS.Core.Application.Helper;
|
|
using Microsoft.AspNetCore.Authorization;
|
|
using Microsoft.AspNetCore.Hosting;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using System.Linq.Dynamic.Core;
|
|
|
|
namespace IRaCIS.Core.Application.Services
|
|
{
|
|
[ApiExplorerSettings(GroupName = "Image")]
|
|
[AllowAnonymous]
|
|
public class InstanceService(IRepository<DicomInstance> _instanceRepository,
|
|
IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer, IWebHostEnvironment _hostEnvironment) : BaseService, IInstanceService
|
|
{
|
|
|
|
|
|
/// <summary> 指定资源Id,获取Dicom序列所属的实例信息列表 </summary>
|
|
/// <param name="seriesId"> Dicom序列的Id </param>
|
|
[HttpGet("{seriesId:guid}")]
|
|
public async Task<IResponseOutput<List<DicomInstanceDTO>>> List(Guid seriesId)
|
|
{
|
|
var qcAuditState = await _instanceRepository.Where(s => s.SeriesId == seriesId).Select(t => t.DicomStudy.SubjectVisit.AuditState).FirstOrDefaultAsync();
|
|
|
|
//质控通过以后,过滤删除的 质控之前的不过滤
|
|
var isQCFinished = qcAuditState == AuditStateEnum.QCPassed;
|
|
|
|
var list = await _instanceRepository.Where(s => s.SeriesId == seriesId).IgnoreQueryFilters()
|
|
.WhereIf(isQCFinished, t => t.IsDeleted == false)
|
|
.OrderBy(s => s.InstanceNumber).ThenBy(s => s.InstanceTime).ThenBy(s => s.CreateTime)
|
|
.ProjectTo<DicomInstanceDTO>(_mapper.ConfigurationProvider).ToListAsync();
|
|
|
|
// ⭐ DICOM 空间排序(带兜底)
|
|
var sorted = DicomSortHelper.SortSlices(
|
|
list,
|
|
x => x.ImagePositionPatient,
|
|
x => x.ImageOrientationPatient,
|
|
x => x.InstanceNumber
|
|
);
|
|
|
|
var seriesInfo = await _instanceRepository.Where(s => s.SeriesId == seriesId).Select(t => new
|
|
{
|
|
t.DicomSerie.ImageResizePath,
|
|
t.DicomSerie.IsDeleted,
|
|
t.DicomSerie.IsReading,
|
|
SubjectCode = t.DicomSerie.SubjectVisit.Subject.Code,
|
|
t.DicomSerie.SubjectVisit.VisitName
|
|
}).FirstOrDefaultAsync();
|
|
|
|
return ResponseOutput.Ok(sorted, seriesInfo);
|
|
}
|
|
|
|
|
|
/// <summary> 指定资源Id,获取Dicom序列所属的实例Id列表 </summary>
|
|
/// <param name="seriesId"> Dicom序列的Id </param>
|
|
/// <param name="tpCode"></param>
|
|
/// <param name="key"></param>
|
|
[HttpGet, Route("{seriesId:guid}/{tpCode?}/{key?}")]
|
|
public IEnumerable<Guid> List(Guid seriesId, string tpCode, bool? key)
|
|
{
|
|
//if (key != null && key.HasValue && key.Value)
|
|
//{
|
|
// return _keyInstanceRepository.Where(s => s.TpCode == tpCode).Select(t => t.InstanceId).Distinct();
|
|
//}
|
|
//else
|
|
return _instanceRepository.Where(s => s.SeriesId == seriesId).OrderBy(s => s.InstanceNumber).Select(t => t.Id);
|
|
}
|
|
|
|
[AllowAnonymous]
|
|
[HttpGet, Route("{instanceId:guid}")]
|
|
public async Task<FileContentResult> Preview(Guid instanceId)
|
|
{
|
|
var path = string.Empty;
|
|
|
|
path = (await _instanceRepository.Where(s => s.Id == instanceId).Select(t => t.Path).FirstOrDefaultAsync()).IfNullThrowException();
|
|
|
|
var physicalPath = FileStoreHelper.GetPhysicalFilePath(_hostEnvironment, path);
|
|
|
|
using (var sw = ImageHelper.RenderPreviewJpeg(physicalPath))
|
|
{
|
|
var bytes = new byte[sw.Length];
|
|
sw.Read(bytes, 0, bytes.Length);
|
|
sw.Close();
|
|
return new FileContentResult(bytes, "image/jpeg");
|
|
}
|
|
|
|
|
|
}
|
|
|
|
[AllowAnonymous]
|
|
[HttpGet, Route("{instanceId:guid}")]
|
|
public async Task<FileContentResult> Content(Guid instanceId)
|
|
{
|
|
var filePath = string.Empty;
|
|
var path = (await _instanceRepository.Where(s => s.Id == instanceId).Select(t => t.Path).FirstOrDefaultAsync()).IfNullThrowException();
|
|
|
|
|
|
var physicalPath = FileStoreHelper.GetPhysicalFilePath(_hostEnvironment, path);
|
|
|
|
|
|
using (var sw = new FileStream(physicalPath, FileMode.Open, FileAccess.Read, FileShare.Read))
|
|
{
|
|
var bytes = new byte[sw.Length];
|
|
sw.Read(bytes, 0, bytes.Length);
|
|
sw.Close();
|
|
return new FileContentResult(bytes, "application/octet-stream");
|
|
}
|
|
}
|
|
|
|
|
|
}
|
|
} |