186 lines
7.2 KiB
C#
186 lines
7.2 KiB
C#
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");
|
||
}
|
||
}
|
||
|
||
|
||
}
|
||
} |