增加下载监控接口
continuous-integration/drone/push Build is passing Details

IRC_NewDev
hang 2024-09-11 14:41:04 +08:00
parent cb6f93ec0a
commit 36c354c8f0
14 changed files with 227 additions and 72 deletions

View File

@ -1031,13 +1031,12 @@
<param name="inQuery"></param>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.Application.Service.ImageAndDoc.DownloadAndUploadService.GetIRReadingDownloadStudyInfo(IRaCIS.Core.Application.Contracts.IRDownloadQuery,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.Subject})">
<member name="M:IRaCIS.Core.Application.Service.ImageAndDoc.DownloadAndUploadService.GetIRReadingDownloadStudyInfo(IRaCIS.Core.Application.Contracts.IRDownloadQuery)">
<summary>
IR 阅片页面获取下载检查的信息 会根据标准进行过滤检查,(后端要考虑到一致性分析 subjectCode的问题
检查在访视下面所以需要传递下载的访视Id另外下载访视下面那些检查就把访视下的对应的检查Id 丢到数组里就好
</summary>
<param name="inQuery"></param>
<param name="_subjectRepository"></param>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.Application.Service.ImageAndDoc.DownloadAndUploadService.GetTaskUploadedDicomStudyList(IRaCIS.Core.Application.Contracts.IRTaskUploadedDicomStudyQuery)">
@ -1047,6 +1046,20 @@
<param name="inQuery"></param>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.Application.Service.ImageAndDoc.DownloadAndUploadService.DownloadImageSuccess(System.Guid)">
<summary>
影像下载成功回调
</summary>
<param name="trialImageDownloadId"></param>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.Application.Service.ImageAndDoc.DownloadAndUploadService.GetTrialDownloadList(IRaCIS.Core.Application.Contracts.TrialIamgeDownQuery)">
<summary>
项目影像下载监控列表
</summary>
<param name="inQuery"></param>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.Application.Service.ImageAndDoc.DownloadAndUploadService.RequestPackageAndAnonymizImage(System.Guid,System.Guid,System.Boolean,System.Boolean)">
<summary>
打包和匿名化影像 默认是匿名化打包,也可以不匿名化打包

View File

@ -1,4 +1,5 @@
using IRaCIS.Core.Application.Service.ImageAndDoc.DTO;
using IRaCIS.Core.Domain.Share;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
@ -551,6 +552,49 @@ namespace IRaCIS.Core.Application.Contracts
}
public class TrialImageDownloadView
{
public Guid TrialId { get; set; }
public string SubjectCode { get; set; }
public bool IsSuccess { get; set; }
public DateTime DownloadStartTime { get; set; }
public DateTime? DownloadEndTime { get; set; }
public string VisitName { get; set; }
public ImageType ImageType { get; set; }
public int NoneDicomStudyCount { get; set; }
public int DicomStudyCount { get; set; }
public int ImageCount { get; set; }
public long ImageSize { get; set; }
public string UserName { get; set; }
public string UserFullName { get; set; }
public DateTime CreateTime { get; set; }
}
public class TrialIamgeDownQuery:PageInput
{
[NotDefault]
public Guid TrialId { get; set; }
public string? SubjectCode { get; set; }
public ImageType? ImageType { get; set; }
public UserTypeEnum? UserType { get; set; }
public bool? IsSuccess { get; set; }
}
public class SubjectVisitTaskInfo
{

View File

@ -49,7 +49,9 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
IRepository<ReadingQuestionCriterionTrial> _readingQuestionCriterionTrialRepository,
IRepository<NoneDicomStudy> _noneDicomStudyReposiotry,
IRepository<NoneDicomStudyFile> _noneDicomStudyFileReposiotry,
IDistributedLockProvider _distributedLockProvider) : BaseService, IDownloadAndUploadService
IDistributedLockProvider _distributedLockProvider,
IRepository<TrialImageDownload> _trialImageDownloadRepository,
IRepository<Subject> _subjectRepository) : BaseService, IDownloadAndUploadService
{
@ -220,9 +222,6 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
}
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
public async Task<IResponseOutput> PreArchiveDicomStudy(PriArchiveTaskStudyCommand preArchiveStudyCommand)
@ -678,11 +677,14 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
var isQueryDicom = inQuery.DicomStudyIdList.Count > 0;
var isQueryNoneDicom = inQuery.NoneDicomStudyIdList.Count > 0;
var imageType = (isQueryDicom && isQueryNoneDicom) ? ImageType.DicomAndNoneDicom : (isQueryDicom ? ImageType.Dicom : ImageType.NoneDicom);
var query = from sv in _subjectVisitRepository.Where(t => t.Id == inQuery.SubjectVisitId)
select new
{
TrialId = sv.TrialId,
SubjectCode = sv.Subject.Code,
VisitName = sv.VisitName,
@ -719,14 +721,31 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
{
file.FileName,
file.Path,
file.FileType
file.FileType,
file.FileSize,
})
}).ToList()
};
var result = query.FirstOrDefault();
return ResponseOutput.Ok(result);
var preDownloadInfo = new TrialImageDownload()
{
Id = NewId.NextSequentialGuid(),
TrialId = result.TrialId,
SubjectCode = result.SubjectCode,
DownloadStartTime = DateTime.Now,
IsSuccess = false,
ImageType = imageType,
VisitName = string.Join(" | ", result.VisitName),
NoneDicomStudyCount = result.NoneDicomStudyList.Count(),
DicomStudyCount = result.StudyList.Count(),
ImageCount = result.StudyList.Sum(s => s.SeriesList.Sum(s => s.InstanceList.Count())) + result.NoneDicomStudyList.Sum(s => s.FileList.Count()),
ImageSize = result.StudyList.Sum(t => t.SeriesList.Sum(s => s.InstanceList.Sum(i => i.FileSize))) + result.NoneDicomStudyList.Sum(t => t.FileList.Sum(s => s.FileSize))
?? 0
};
return ResponseOutput.Ok(result, preDownloadInfo.Id);
}
@ -817,17 +836,18 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
/// 检查在访视下面所以需要传递下载的访视Id另外下载访视下面那些检查就把访视下的对应的检查Id 丢到数组里就好
/// </summary>
/// <param name="inQuery"></param>
/// <param name="_subjectRepository"></param>
/// <returns></returns>
[HttpPost]
public async Task<IResponseOutput> GetIRReadingDownloadStudyInfo(IRDownloadQuery inQuery, [FromServices] IRepository<Subject> _subjectRepository)
public async Task<IResponseOutput> GetIRReadingDownloadStudyInfo(IRDownloadQuery inQuery)
{
var info = await _readingQuestionCriterionTrialRepository.Where(t => t.Id == inQuery.TrialReadingCriterionId)
.Select(t => new { t.IsImageFilter, t.CriterionModalitys }).FirstNotNullAsync();
.Select(t => new { t.IsImageFilter, t.CriterionModalitys, t.TrialId }).FirstNotNullAsync();
var isQueryDicom = inQuery.DicomStudyIdList.Count > 0;
var isQueryNoneDicom = inQuery.NoneDicomStudyIdList.Count > 0;
var imageType = (isQueryDicom && isQueryNoneDicom) ? ImageType.DicomAndNoneDicom : (isQueryDicom ? ImageType.Dicom : ImageType.NoneDicom);
var taskIdList = inQuery.SubjectVisitTaskList.Select(t => t.TaskId).ToList();
var subjectVisitIdList = inQuery.SubjectVisitTaskList.Select(t => t.SubjectVisitId).ToList();
@ -856,7 +876,8 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
InstancePathList = z.DicomInstanceList.Select(k => new
{
k.Path
k.Path,
k.FileSize
})
})
@ -874,7 +895,8 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
{
file.FileName,
file.Path,
file.FileType
file.FileType,
file.FileSize
})
})
};
@ -885,7 +907,24 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
return ResponseOutput.Ok(result);
var preDownloadInfo = new TrialImageDownload()
{
Id = NewId.NextSequentialGuid(),
TrialId = info.TrialId,
SubjectCode = inQuery.SubjectCode,
DownloadStartTime = DateTime.Now,
IsSuccess = false,
ImageType = imageType,
VisitName = string.Join(" | ", result.Select(t => t.VisitName).OrderBy(t => t).ToList()),
NoneDicomStudyCount = result.Sum(t => t.NoneDicomStudyList.Count()),
DicomStudyCount = result.Sum(t => t.StudyList.Count()),
ImageCount = result.Sum(t => t.StudyList.Sum(s => s.SeriesList.Sum(s => s.InstancePathList.Count())) + t.NoneDicomStudyList.Sum(s => s.FileList.Count())),
ImageSize = result.Sum(t => t.StudyList.Sum(t => t.SeriesList.Sum(s => s.InstancePathList.Sum(i => i.FileSize))) + t.NoneDicomStudyList.Sum(t => t.FileList.Sum(s => s.FileSize))
) ?? 0
};
await _trialImageDownloadRepository.AddAsync(preDownloadInfo);
return ResponseOutput.Ok(result, preDownloadInfo.Id);
}
/// <summary>
@ -937,6 +976,36 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
/// <summary>
/// 影像下载成功回调
/// </summary>
/// <param name="trialImageDownloadId"></param>
/// <returns></returns>
public async Task<IResponseOutput> DownloadImageSuccess(Guid trialImageDownloadId)
{
await _trialImageDownloadRepository.UpdatePartialFromQueryAsync(t => t.Id == trialImageDownloadId, u => new TrialImageDownload()
{ DownloadEndTime = DateTime.Now, IsSuccess = true }, true);
return ResponseOutput.Ok();
}
/// <summary>
/// 项目影像下载监控列表
/// </summary>
/// <param name="inQuery"></param>
/// <returns></returns>
[HttpPost]
public async Task<PageOutput<TrialImageDownloadView>> GetTrialDownloadList(TrialIamgeDownQuery inQuery)
{
var query = _trialImageDownloadRepository.Where(t => t.TrialId == inQuery.TrialId)
.WhereIf(inQuery.SubjectCode.IsNotNullOrEmpty(), t => t.SubjectCode.Contains(inQuery.SubjectCode))
.WhereIf(inQuery.ImageType != null, t => t.ImageType == inQuery.ImageType)
.WhereIf(inQuery.UserType != null, t => t.CreateUser.UserTypeEnum == inQuery.UserType)
.WhereIf(inQuery.IsSuccess != null, t => t.IsSuccess == inQuery.IsSuccess)
.ProjectTo<TrialImageDownloadView>(_mapper.ConfigurationProvider);
return await query.ToPagedListAsync(inQuery);
}
#region 之前后端下载废弃
/// <summary>
@ -1361,9 +1430,6 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
}
#endregion
#region 按照任务为维度 展示上传的列表 废弃
/// <summary>
/// IR 影像上传任务列表 --old 20240903 界面调整,现在先废弃

View File

@ -143,6 +143,9 @@ namespace IRaCIS.Core.Application.Service
.ForMember(d => d.NoneDicomStudyList, u => u.MapFrom(s => s.SourceSubjectVisit.NoneDicomStudyList))
;
CreateMap<TrialImageDownload, TrialImageDownloadView>()
.ForMember(d => d.UserFullName, u => u.MapFrom(s => s.CreateUser.FullName))
.ForMember(d => d.UserName, u => u.MapFrom(s => s.CreateUser.UserName));
}
}

View File

@ -86,6 +86,10 @@ namespace IRaCIS.Core.Domain.Models
public DateTime CreateTime { get; set; }
public Guid UpdateUserId { get; set; }
public DateTime UpdateTime { get; set; }
//[ForeignKey("CreateUserId")]
//[JsonIgnore]
//public User CreateUser { get; set; }
}

View File

@ -0,0 +1,50 @@
using IRaCIS.Core.Domain.Models;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace IRaCIS.Core.Domain.Models
{
[Table("TrialImageDownload")]
public class TrialImageDownload : BaseFullAuditEntity
{
#region 导航属性
[JsonIgnore]
public Trial Trial { get; set; }
[JsonIgnore]
public User CreateUser { get; set; }
#endregion
public Guid TrialId { get; set; }
public string SubjectCode { get; set; }
public bool IsSuccess { get; set; }
public DateTime DownloadStartTime { get; set; }
public DateTime? DownloadEndTime { get; set; }
public string VisitName { get; set; }
public ImageType ImageType { get; set; }
public int NoneDicomStudyCount { get; set; }
public int DicomStudyCount { get; set; }
public int ImageCount { get; set; }
public long ImageSize { get; set; }
}
public enum ImageType
{
Dicom = 1,
NoneDicom = 2,
DicomAndNoneDicom = 3
};
}

View File

@ -16,8 +16,7 @@ namespace IRaCIS.Core.Domain.Models
[JsonIgnore]
public List<SystemDocConfirmedUser> SystemDocConfirmedList { get; set; }
[JsonIgnore]
public List<UserDoctor> UserDoctors { get; set; } = new List<UserDoctor>();
[JsonIgnore]
public List<TrialUser> UserTrials { get; set; } = new List<TrialUser>();

View File

@ -527,6 +527,10 @@ namespace IRaCIS.Core.Infra.EFCore
public virtual DbSet<EnrollReadingCriterion> EnrollReadingCriterion { get; set; }
#endregion
public virtual DbSet<TrialImageDownload> TrialImageDownload { get; set; }
}

View File

@ -1,42 +0,0 @@
using IRaCIS.Core.Domain.Models;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace IRaCIS.Core.Infra.EFCore.EntityConfigration
{
//public class StudyConfigration : IEntityTypeConfiguration<DicomStudy>
//{
// /// <summary>
// /// 一个外键,关联多个表 ReadingId
// /// </summary>
// /// <param name="builder"></param>
// public void Configure(EntityTypeBuilder<DicomStudy> builder)
// {
// builder
// .HasMany(s => s.ReadingClinicalDataList)
// .WithOne(c => c.DicomStudy)
// .HasForeignKey(s => new { s.StudyId })
// .HasPrincipalKey(c => new { c.Id });
// builder
// .HasMany(s => s.ReadingConsistentClinicalDataList)
// .WithOne(c => c.DicomStudy)
// .HasForeignKey(s => new { s.StudyId })
// .HasPrincipalKey(c => new { c.Id });
// }
//}
//public class UserConfigration : IEntityTypeConfiguration<User>
//{
// public void Configure(EntityTypeBuilder<User> builder)
// {
// //对于阅片人来讲,会有很多任务
// builder.HasMany(t => t.VisitTaskList).WithOne(t => t.DoctorUser).HasForeignKey(t => t.DoctorUserId).IsRequired(false);
// }
//}
}

View File

@ -9,7 +9,6 @@ namespace IRaCIS.Core.Infra.EFCore.EntityConfigration
{
public void Configure(EntityTypeBuilder<Subject> builder)
{
//不能同时配置一对多 和一对一 但是有时表要存储多的最新的 比如受试者 最新的访视 在这里要显示配置
builder.HasOne(s => s.LatestSubjectVisit).WithMany().HasForeignKey(t => t.LatestSubjectVisitId);
builder.HasOne(s => s.FinalSubjectVisit).WithMany().HasForeignKey(t => t.FinalSubjectVisitId);
@ -20,10 +19,8 @@ namespace IRaCIS.Core.Infra.EFCore.EntityConfigration
{
public void Configure(EntityTypeBuilder<Dictionary> builder)
{
//自身同时存在一对多 和一对一的关系,配置一对多的就可以,一对一 不用配置,有点奇怪
builder.HasMany(t => t.ChildList).WithOne(t => t.Parent).HasForeignKey(d => d.ParentId);
}
}
@ -46,4 +43,14 @@ namespace IRaCIS.Core.Infra.EFCore.EntityConfigration
builder.HasMany(t => t.EarlierSubjectUserList).WithOne(t => t.ReplacedSubjectUser).HasForeignKey(t => t.ReplacedSubjectUserId);
}
}
public class UserConfigration : IEntityTypeConfiguration<User>
{
public void Configure(EntityTypeBuilder<User> builder)
{
builder.HasMany(t => t.VisitTaskList).WithOne(t => t.DoctorUser).HasForeignKey(t => t.DoctorUserId);
//builder.HasOne(t => t.Doctor).WithOne(t => t.User);
}
}
}

View File

@ -5,8 +5,6 @@ using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace IRaCIS.Core.Infra.EFCore.EntityConfigration
{
public class SubjectCriteriaEvaluationConfigration : IEntityTypeConfiguration<SubjectCriteriaEvaluation>
{

View File

@ -25,8 +25,6 @@ namespace IRaCIS.Core.Infra.EFCore.EntityConfigration
//subject 删除了,但是任务没删除,导致的查询问题
builder.HasQueryFilter(b => b.Subject.IsDeleted == false);
//builder.HasOne(t => t.Subject).WithMany(s => s.SubjectVisitTaskList).HasForeignKey(t => t.SubjectId);
//builder.HasMany(t => t.TaskMedicalReviewList).WithOne(t => t.VisitTask).HasForeignKey(t => t.VisitTaskId);
}
}
public class ReadingQuestionTrialConfigration : IEntityTypeConfiguration<ReadingQuestionTrial>

View File

@ -96,10 +96,13 @@ public class AuditEntityInterceptor(IUserInfo _userInfo, ILogger<AuditEntityInte
{
addEntity.CreateTime = DateTime.Now;
}
if (addEntity.CreateUserId == default(Guid))
{
addEntity.CreateUserId = _userInfo.Id;
}
}
if (entry.Entity is IAuditUpdate updateEntity)
{
updateEntity.UpdateTime = DateTime.Now;
@ -113,10 +116,14 @@ public class AuditEntityInterceptor(IUserInfo _userInfo, ILogger<AuditEntityInte
addEntity3.CreateTime = DateTime.Now;
}
if (addEntity3.CreateUserId == default(Guid))
{
addEntity3.CreateUserId = _userInfo.Id;
addEntity3.CreateUser = _userInfo.RealName;
}
}
break;
}
}

View File

@ -16,6 +16,10 @@ namespace IRaCIS.Core.Infrastructure.Extention
{
return string.IsNullOrEmpty(value);
}
public static bool IsNotNullOrEmpty(this string value)
{
return !string.IsNullOrEmpty(value);
}
// 扩展 IEnumerable<T> 类型
public static bool IsNullOrEmpty<T>(this IEnumerable<T> enumerable)