irc-netcore-api/IRaCIS.Core.Application/Service/ImageAndDoc/SeriesService.cs

186 lines
7.2 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using IRaCIS.Core.Application.Contracts.Dicom.DTO;
using IRaCIS.Core.Application.Helper;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
namespace IRaCIS.Core.Application.Services
{
[ApiExplorerSettings(GroupName = "Image")]
[AllowAnonymous]
public class SeriesService(IRepository<DicomSeries> _seriesRepository,
IRepository<DicomInstance> _instanceRepository,
IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer, IWebHostEnvironment _hostEnvironment) : BaseService
{
//医生读片那一块有耦合,关键序列 这里暂时留存
/// <summary> 指定资源Id获取Dicom检查所属序列信息列表 </summary>
/// <param name="studyId"> Dicom检查的Id </param>
[HttpGet, Route("{studyId:guid}")]
public async Task<IResponseOutput<List<DicomSeriesDTO>>> List(Guid studyId)
{
//质控的时候要标记序列和instance 删除 ,所以要返回全部,但是 质控通过后pm 进去看的时候要看过滤后的
var qcAuditState = await _seriesRepository.Where(s => s.StudyId == studyId).Select(t => t.DicomStudy.SubjectVisit.AuditState).FirstOrDefaultAsync();
//质控通过以后,预览过滤删除的 质控之前的不过滤
var isQCFinished = qcAuditState == AuditStateEnum.QCPassed;
//断点
var seriesList = await _seriesRepository.Where(s => s.StudyId == studyId).IgnoreQueryFilters()
.WhereIf(isQCFinished, t => t.IsDeleted == false)
.OrderBy(s => s.SeriesNumber).ThenBy(s => s.SeriesTime).ThenBy(s => s.CreateTime)
.ProjectTo<DicomSeriesDTO>(_mapper.ConfigurationProvider).ToListAsync();
var instanceList = await _instanceRepository.Where(s => s.StudyId == studyId).IgnoreQueryFilters()
.WhereIf(isQCFinished, t => t.IsDeleted == false)
.OrderBy(t => t.SeriesId).ThenBy(t => t.InstanceNumber)
.ThenBy(s => s.InstanceTime).ThenBy(s => s.CreateTime)
.Select(t => new { t.SeriesId, t.Id, t.Path, t.NumberOfFrames, t.InstanceNumber, t.HtmlPath, t.IsReading, t.IsDeleted }).ToListAsync();//.GroupBy(u => u.SeriesId);
foreach (var series in seriesList)
{
series.InstanceInfoList = instanceList.Where(t => t.SeriesId == series.Id).OrderBy(t => t.InstanceNumber).Select(k =>
new InstanceBasicInfo()
{
Id = k.Id,
NumberOfFrames = k.NumberOfFrames,
HtmlPath = k.HtmlPath,
Path = k.Path,
InstanceNumber = k.InstanceNumber,
IsReading = k.IsReading,
IsDeleted = k.IsDeleted
}).ToList();
series.InstanceCount = series.InstanceInfoList.Count;
}
#region 暂时废弃
//bool hasKeyInstance = false;
//var SeriesIdList = _imageLabelRepository.Where(u => u.TpCode == tpCode).Select(s => s.SeriesId).Distinct().ToList();
//var instanceIdList = _imageLabelRepository.Where(u => u.TpCode == tpCode).Select(s => s.InstanceId).Distinct().ToList();
//foreach (var item in seriesList)
//{
// if (SeriesIdList.Contains(item.Id))
// {
// item.HasLabel = true;
// hasKeyInstance = true;
// }
// else item.HasLabel = false;
//}
//if (hasKeyInstance)
//{
// seriesList.Add(new DicomSeriesWithLabelDTO
// {
// KeySeries = true,
// Id = SeriesIdList[0],
// InstanceCount = instanceIdList.Count,
// HasLabel = true,
// Modality = seriesList[0].Modality,
// Description = "Key Series"
// });
//}
//var idList = await _instanceRepository.Where(s => s.StudyId == studyId).OrderBy(t => t.SeriesId).ThenBy(t => t.InstanceNumber)
// .ThenBy(s => s.InstanceTime).ThenBy(s => s.CreateTime)
// .Select(t => new { t.SeriesId, t.Id, t.Path }).ToListAsync();//.GroupBy(u => u.SeriesId);
//foreach (var item in seriesList)
//{
// if (item.KeySeries)
// {
// item.InstanceList = instanceIdList;
// }
// else
// {
// //item.InstanceList = idList.Where(s => s.SeriesId == item.Id).OrderBy(t => t.InstanceNumber)
// // .ThenBy(s => s.InstanceTime).ThenBy(s => s.CreateTime).Select(u => u.Id).ToList();
// item.InstanceList = idList.Where(s => s.SeriesId == item.Id).Select(u => u.Id).ToList();
// item.InstancePathList = idList.Where(s => s.SeriesId == item.Id).Select(u => u.Path).ToList();
// }
//}
#endregion
return ResponseOutput.Ok(seriesList);
}
/// <summary> 指定资源Id渲染Dicom序列的Jpeg预览图像 </summary>
/// <param name="seriesId"> Dicom序列的Id </param>
[HttpGet, Route("{seriesId:guid}")]
[AllowAnonymous]
public async Task<FileContentResult> Preview(Guid seriesId)
{
string path = string.Empty;
path = (await _instanceRepository.Where(s => s.SeriesId == seriesId).Select(t => t.Path).FirstOrDefaultAsync()).IfNullThrowException();
#region 切换磁盘存储之前
//var physicalPath = FileStoreHelper.GetPhysicalFilePath(_hostEnvironment, path);
#endregion
#region 切换磁盘存储后
var physicalPath = FileStoreHelper.GetPhysicalFilePath(_hostEnvironment, path);
//不存在,去其他路径找
if (!File.Exists(physicalPath))
{
//找到所有磁盘
var drives = DriveInfo.GetDrives()
.Where(d => d.DriveType == DriveType.Fixed && d.IsReady)
//剩余空间最多的
.OrderByDescending(d => d.AvailableFreeSpace)
//存储空间相同,则按照按照总空间从大到小排序
.ThenByDescending(d => d.TotalSize - d.TotalFreeSpace)
.Select(d => d.RootDirectory.FullName)
.ToList();
foreach (var drive in drives)
{
physicalPath = Path.Combine(drive, _hostEnvironment.EnvironmentName, path.Trim('/'));
if (File.Exists(physicalPath))
{
break;
}
}
}
#endregion
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");
}
}
}
}