增加 MassTransit 移除 MediatR

IRC_NewDev
hang 2024-08-19 17:49:08 +08:00
parent 4c9a8aadab
commit d34eca2cb8
19 changed files with 287 additions and 400 deletions

View File

@ -10,8 +10,7 @@ using IRaCIS.Core.Application.Contracts.Dicom;
using IRaCIS.Core.Application.Contracts.Dicom.DTO; using IRaCIS.Core.Application.Contracts.Dicom.DTO;
using IRaCIS.Core.Application.Filter; using IRaCIS.Core.Application.Filter;
using IRaCIS.Core.Application.Helper; using IRaCIS.Core.Application.Helper;
using IRaCIS.Core.Application.MediatR.CommandAndQueries; using IRaCIS.Core.Application.MassTransit.Command;
using IRaCIS.Core.Application.MediatR.Handlers;
using IRaCIS.Core.Application.Service; using IRaCIS.Core.Application.Service;
using IRaCIS.Core.Application.Service.ImageAndDoc; using IRaCIS.Core.Application.Service.ImageAndDoc;
using IRaCIS.Core.Application.Service.Reading.Dto; using IRaCIS.Core.Application.Service.Reading.Dto;
@ -21,7 +20,7 @@ using IRaCIS.Core.Infra.EFCore;
using IRaCIS.Core.Infrastructure; using IRaCIS.Core.Infrastructure;
using IRaCIS.Core.Infrastructure.Extention; using IRaCIS.Core.Infrastructure.Extention;
using MassTransit; using MassTransit;
using MediatR; using MassTransit.Mediator;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Cors.Infrastructure; using Microsoft.AspNetCore.Cors.Infrastructure;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
@ -232,9 +231,12 @@ namespace IRaCIS.Core.API.Controllers
{ {
public IMapper _mapper { get; set; } public IMapper _mapper { get; set; }
public IUserInfo _userInfo { get; set; } public IUserInfo _userInfo { get; set; }
private readonly IMediator _mediator; private readonly IMediator _mediator;
public IStringLocalizer _localizer { get; set; } public IStringLocalizer _localizer { get; set; }
@ -266,11 +268,6 @@ namespace IRaCIS.Core.API.Controllers
[FromServices] IRepository<StudyMonitor> _studyMonitorRepository) [FromServices] IRepository<StudyMonitor> _studyMonitorRepository)
{ {
if (_provider.Get<List<SystemAnonymization>>(StaticData.Anonymize.Anonymize_AddFixedFiled).Value == null)
{
await _mediator.Send(new AnonymizeCacheRequest());
}
var savedInfo = _studyService.GetSaveToDicomInfo(preArchiveStudyCommand.SubjectVisitId); var savedInfo = _studyService.GetSaveToDicomInfo(preArchiveStudyCommand.SubjectVisitId);
var studyMonitor = new StudyMonitor() var studyMonitor = new StudyMonitor()
@ -743,11 +740,16 @@ namespace IRaCIS.Core.API.Controllers
//---请保证上传数据符合模板文件中的样式,且存在有效数据。 //---请保证上传数据符合模板文件中的样式,且存在有效数据。
return ResponseOutput.NotOk(_localizer["UploadDownLoad_InvalidData"]); return ResponseOutput.NotOk(_localizer["UploadDownLoad_InvalidData"]);
} }
} }
await _mediator.Send(new ConsistencyVerificationRequest() { ETCList = etcCheckList, TrialId = trialId });
// 适合获取结果的
//var client = _mediator.CreateRequestClient<ConsistenCheckCommand>();
//await client.GetResponse<ConsistenCheckResult>(new ConsistenCheckCommand() { ETCList = etcCheckList, TrialId = trialId });
//不获取结果,不用定义返回类型
await _mediator.Send(new ConsistenCheckCommand() { ETCList = etcCheckList, TrialId = trialId });
return ResponseOutput.Ok(); return ResponseOutput.Ok();

View File

@ -4,8 +4,6 @@ using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Serilog; using Serilog;
using MediatR;
using IRaCIS.Core.Application.MediatR.Handlers;
using System.Threading.Tasks; using System.Threading.Tasks;
using MassTransit; using MassTransit;
using MassTransit.NewIdProviders; using MassTransit.NewIdProviders;
@ -33,6 +31,8 @@ using Microsoft.AspNetCore.Http;
using IRaCIS.Core.Infrastructure.Extention; using IRaCIS.Core.Infrastructure.Extention;
using Newtonsoft.Json; using Newtonsoft.Json;
using Microsoft.AspNetCore.Diagnostics; using Microsoft.AspNetCore.Diagnostics;
using IRaCIS.Core.Application.MassTransit.Command;
using IRaCIS.Core.Application.MassTransit.Consumer;
#region 获取环境变量 #region 获取环境变量
@ -138,7 +138,14 @@ builder.Services.AddSwaggerSetup();
builder.Services.AddJWTAuthSetup(_configuration); builder.Services.AddJWTAuthSetup(_configuration);
// MediatR 进程内消息 事件解耦 从程序集中 注册命令和handler对应关系 // MediatR 进程内消息 事件解耦 从程序集中 注册命令和handler对应关系
builder.Services.AddMediatR(cfg => cfg.RegisterServicesFromAssemblyContaining<ConsistencyVerificationHandler>()); //builder.Services.AddMediatR(cfg => cfg.RegisterServicesFromAssemblyContaining<ConsistencyVerificationHandler>());
//masstransit组件 也支持MediatR 中介者模式但是支持分布式考虑后续所以在次替代MediatR
builder.Services.AddMediator(cfg =>
{
cfg.AddConsumer<ConsistencyCheckConsumer>();
});
// EasyCaching 缓存 // EasyCaching 缓存
builder.Services.AddEasyCachingSetup(_configuration); builder.Services.AddEasyCachingSetup(_configuration);

View File

@ -10,7 +10,6 @@ using System.Linq;
using System.Reflection; using System.Reflection;
using IRaCIS.Core.Domain.Models; using IRaCIS.Core.Domain.Models;
using IRaCIS.Core.Domain.Share; using IRaCIS.Core.Domain.Share;
using MediatR;
using IRaCIS.Application.Services; using IRaCIS.Application.Services;
using IRaCIS.Application.Interfaces; using IRaCIS.Application.Interfaces;
using AutoMapper; using AutoMapper;

View File

@ -74,7 +74,6 @@
<PackageReference Include="fo-dicom.Codecs" Version="5.14.4" /> <PackageReference Include="fo-dicom.Codecs" Version="5.14.4" />
<PackageReference Include="IP2Region.Net" Version="2.0.2" /> <PackageReference Include="IP2Region.Net" Version="2.0.2" />
<PackageReference Include="MailKit" Version="4.2.0" /> <PackageReference Include="MailKit" Version="4.2.0" />
<PackageReference Include="MediatR" Version="12.2.0" />
<PackageReference Include="MimeKit" Version="4.2.0" /> <PackageReference Include="MimeKit" Version="4.2.0" />
<PackageReference Include="MiniExcel" Version="1.32.0" /> <PackageReference Include="MiniExcel" Version="1.32.0" />
<PackageReference Include="Minio" Version="6.0.3" /> <PackageReference Include="Minio" Version="6.0.3" />
@ -86,7 +85,7 @@
<PackageReference Include="Panda.DynamicWebApi" Version="1.2.2" /> <PackageReference Include="Panda.DynamicWebApi" Version="1.2.2" />
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.5" /> <PackageReference Include="SixLabors.ImageSharp" Version="3.1.5" />
<PackageReference Include="Swashbuckle.AspNetCore.Filters" Version="8.0.2" /> <PackageReference Include="Swashbuckle.AspNetCore.Filters" Version="8.0.2" />
<PackageReference Include="WinSCP" Version="6.3.3" /> <PackageReference Include="MassTransit.AspNetCore" Version="7.3.1" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@ -9911,6 +9911,11 @@
TrialSiteDicomAEService TrialSiteDicomAEService
</summary> </summary>
</member> </member>
<member name="M:IRaCIS.Core.Application.MassTransit.Consumer.ConsistencyCheckConsumer.#ctor(IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.DicomStudy},IRaCIS.Core.Domain.Share.IUserInfo,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.Subject},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.SubjectVisit},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.TrialSite},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.NoneDicomStudy},AutoMapper.IMapper,Microsoft.Extensions.Localization.IStringLocalizer)">
<summary>
构造函数注入
</summary>
</member>
<member name="T:IRaCIS.Core.Application.ViewModel.TaskAllocationRuleView"> <member name="T:IRaCIS.Core.Application.ViewModel.TaskAllocationRuleView">
<summary> TaskAllocationRuleView 列表视图模型 </summary> <summary> TaskAllocationRuleView 列表视图模型 </summary>
</member> </member>
@ -13308,21 +13313,6 @@
维护 IsFrontTaskNeedSignButNotSign 字段 另外附加评估结果 维护 IsFrontTaskNeedSignButNotSign 字段 另外附加评估结果
</summary> </summary>
</member> </member>
<member name="M:IRaCIS.Core.Application.MediatR.Handlers.AnonymizeCacheHandler.#ctor(IRaCIS.Core.Infra.EFCore.IRepository,EasyCaching.Core.IEasyCachingProvider)">
<summary>
构造函数注入
</summary>
</member>
<member name="M:IRaCIS.Core.Application.MediatR.Handlers.ConsistencyVerificationHandler.#ctor(IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.DicomStudy},IRaCIS.Core.Domain.Share.IUserInfo,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.Subject},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.SubjectVisit},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.TrialSite},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.NoneDicomStudy},AutoMapper.IMapper,Microsoft.Extensions.Localization.IStringLocalizer)">
<summary>
构造函数注入
</summary>
</member>
<member name="M:IRaCIS.Core.Application.MediatR.Handlers.TrialStateCacheHandler.#ctor(IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.Trial},EasyCaching.Core.IEasyCachingProvider)">
<summary>
构造函数注入
</summary>
</member>
<member name="M:IRaCIS.Application.Services.BackGroundJob.IRaCISCHangfireJob.MemoryCacheTrialStatusAsync"> <member name="M:IRaCIS.Application.Services.BackGroundJob.IRaCISCHangfireJob.MemoryCacheTrialStatusAsync">
<summary> <summary>
缓存项目状态 缓存项目状态

View File

@ -0,0 +1,96 @@
using MiniExcelLibs.Attributes;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace IRaCIS.Core.Application.MassTransit.Command
{
public record ConsistenCheckCommand
{
public List<CheckViewModel> ETCList { get; set; } = new List<CheckViewModel>();
public Guid TrialId { get; set; }
}
public record ConsistenCheckResult
{
}
public class CheckDBModel : CheckViewModel
{
public Guid SubjectVisitId { get; set; }
public Guid StudyId { get; set; }
}
//[ExcelImporter(/*ImportResultFilter = typeof(ImportResultFilteTest),*/ IsLabelingError = true)]
public class CheckViewModel
{
//[Required(ErrorMessage = "中心编号不能为空")]
//[ImporterHeader(Name = "Site ID", AutoTrim = true)]
[ExcelColumnName("Site ID")]
public string SiteCode { get; set; } = string.Empty;
//[Required(ErrorMessage = "受试者筛选号不能为空")]
//[ImporterHeader(Name = "Subject ID", AutoTrim = true)]
[ExcelColumnName("Subject ID")]
public string SubjectCode { get; set; } = string.Empty;
//[Required(ErrorMessage = "访视名称不能为空")]
//[ImporterHeader(Name = "Visit Name", AutoTrim = true)]
[ExcelColumnName("Visit Name")]
public string VisitName { get; set; } = string.Empty;
//[Required(ErrorMessage = "检查日期不能为空")]
[CanConvertToTime(ErrorMessage = "Does not conform to Study Date format")]
//[ImporterHeader(Name = "Study Date", AutoTrim = true)]
[ExcelColumnName("Study Date")]
public string StudyDate { get; set; } = string.Empty;
//[Required(ErrorMessage = "Modality不能为空")]
//[ImporterHeader(Name = "Modality", AutoTrim = true)]
[ExcelColumnName("Modality")]
public string Modality { get; set; } = string.Empty;
public override bool Equals(object? obj)
{
if (obj == null) return false;
var checkModel = obj as CheckViewModel;
if (checkModel is not null)
{
return SiteCode == checkModel.SiteCode && SubjectCode == checkModel.SubjectCode && VisitName == checkModel.VisitName && StudyDate == checkModel.StudyDate && Modality == checkModel.Modality;
}
else
{
return false;
}
}
public override int GetHashCode()
{
return (SiteCode + SubjectCode + VisitName + StudyDate + Modality).GetHashCode();
}
}
}

View File

@ -1,16 +1,22 @@
using AutoMapper; using AutoMapper;
using IRaCIS.Core.Application.MediatR.CommandAndQueries; using IRaCIS.Core.Application.Contracts.DTO;
using IRaCIS.Core.Application.MassTransit.Command;
using IRaCIS.Core.Domain.Share; using IRaCIS.Core.Domain.Share;
using MassTransit;
using Microsoft.Extensions.Localization;
using Newtonsoft.Json; using Newtonsoft.Json;
using MediatR; using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions; using System.Linq.Expressions;
using System.Text; using System.Text;
using Microsoft.Extensions.Localization; using System.Threading.Tasks;
namespace IRaCIS.Core.Application.MediatR.Handlers namespace IRaCIS.Core.Application.MassTransit.Consumer
{ {
public class ConsistencyVerificationHandler : IRequestHandler<ConsistencyVerificationRequest, string> public class ConsistencyCheckConsumer : IConsumer<ConsistenCheckCommand>
{ {
private readonly IRepository<DicomStudy> _studyRepository; private readonly IRepository<DicomStudy> _studyRepository;
private readonly IUserInfo _userInfo; private readonly IUserInfo _userInfo;
private readonly IRepository<Subject> _subjectRepository; private readonly IRepository<Subject> _subjectRepository;
@ -24,7 +30,7 @@ namespace IRaCIS.Core.Application.MediatR.Handlers
/// 构造函数注入 /// 构造函数注入
/// </summary> /// </summary>
public ConsistencyVerificationHandler(IRepository<DicomStudy> studyRepository, IUserInfo userInfo, public ConsistencyCheckConsumer(IRepository<DicomStudy> studyRepository, IUserInfo userInfo,
IRepository<Subject> subjectRepository, IRepository<SubjectVisit> subjectVisitRepository, IRepository<Subject> subjectRepository, IRepository<SubjectVisit> subjectVisitRepository,
IRepository<TrialSite> trialSiteRepository, IRepository<NoneDicomStudy> noneDicomStudyRepository, IRepository<TrialSite> trialSiteRepository, IRepository<NoneDicomStudy> noneDicomStudyRepository,
IMapper mapper, IStringLocalizer localizer) IMapper mapper, IStringLocalizer localizer)
@ -39,19 +45,22 @@ namespace IRaCIS.Core.Application.MediatR.Handlers
_localizer = localizer; _localizer = localizer;
} }
async Task<string> IRequestHandler<ConsistencyVerificationRequest, string>.Handle(ConsistencyVerificationRequest request, CancellationToken cancellationToken)
public async Task Consume(ConsumeContext<ConsistenCheckCommand> context)
{ {
var trialId = request.TrialId;
var trialId = context.Message.TrialId;
//处理Excel大小写 //处理Excel大小写
request.ETCList.ForEach(t => { t.Modality = t.Modality.ToUpper().Trim(); t.StudyDate = Convert.ToDateTime(t.StudyDate).ToString("yyyy-MM-dd"); t.SiteCode = t.SiteCode.ToUpper().Trim(); t.VisitName = t.VisitName.ToUpper().Trim(); t.SubjectCode = t.SubjectCode.ToUpper().Trim(); }); context.Message.ETCList.ForEach(t => { t.Modality = t.Modality.ToUpper().Trim(); t.StudyDate = Convert.ToDateTime(t.StudyDate).ToString("yyyy-MM-dd"); t.SiteCode = t.SiteCode.ToUpper().Trim(); t.VisitName = t.VisitName.ToUpper().Trim(); t.SubjectCode = t.SubjectCode.ToUpper().Trim(); });
var etcList = request.ETCList; var etcList = context.Message.ETCList;
//Expression<Func<SubjectVisit, bool>> subjectVisitLambda2 = x => x.TrialId == request.TrialId; //Expression<Func<SubjectVisit, bool>> subjectVisitLambda2 = x => x.TrialId == request.TrialId;
//subjectVisitLambda2= subjectVisitLambda2.And(x => x.CheckState == CheckStateEnum.ToCheck && x.AuditState == AuditStateEnum.QCPassed || (x.CheckState == CheckStateEnum.CVIng && x.AuditState == AuditStateEnum.QCPassed)); //subjectVisitLambda2= subjectVisitLambda2.And(x => x.CheckState == CheckStateEnum.ToCheck && x.AuditState == AuditStateEnum.QCPassed || (x.CheckState == CheckStateEnum.CVIng && x.AuditState == AuditStateEnum.QCPassed));
Expression<Func<SubjectVisit, bool>> subjectVisitLambda = x => x.TrialId == request.TrialId && Expression<Func<SubjectVisit, bool>> subjectVisitLambda = x => x.TrialId == trialId &&
(x.CheckState == CheckStateEnum.ToCheck && x.AuditState == AuditStateEnum.QCPassed || (x.CheckState == CheckStateEnum.CVIng && x.AuditState == AuditStateEnum.QCPassed)); (x.CheckState == CheckStateEnum.ToCheck && x.AuditState == AuditStateEnum.QCPassed || (x.CheckState == CheckStateEnum.CVIng && x.AuditState == AuditStateEnum.QCPassed));
var dicomQuery = from sv in _subjectVisitRepository.Where(subjectVisitLambda) var dicomQuery = from sv in _subjectVisitRepository.Where(subjectVisitLambda)
@ -274,11 +283,13 @@ namespace IRaCIS.Core.Application.MediatR.Handlers
} }
await _subjectVisitRepository.SaveChangesAsync(); await _subjectVisitRepository.SaveChangesAsync();
return "OK";
} //await context.RespondAsync<ConsistenCheckResult>(new
//{
//});
} }
} }
}

View File

@ -10,7 +10,6 @@ using IRaCIS.Core.Infrastructure;
using DocumentFormat.OpenXml.Presentation; using DocumentFormat.OpenXml.Presentation;
using IRaCIS.Core.Domain.Models; using IRaCIS.Core.Domain.Models;
using IRaCIS.Core.Application.Filter; using IRaCIS.Core.Application.Filter;
using IRaCIS.Core.Application.MediatR.Handlers;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Newtonsoft.Json; using Newtonsoft.Json;
using System.Threading; using System.Threading;

View File

@ -5,10 +5,8 @@
//-------------------------------------------------------------------- //--------------------------------------------------------------------
using IRaCIS.Core.Application.Interfaces; using IRaCIS.Core.Application.Interfaces;
using IRaCIS.Core.Application.MediatR.Handlers;
using IRaCIS.Core.Application.ViewModel; using IRaCIS.Core.Application.ViewModel;
using IRaCIS.Core.Infra.EFCore; using IRaCIS.Core.Infra.EFCore;
using MediatR;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
namespace IRaCIS.Core.Application.Service namespace IRaCIS.Core.Application.Service
{ {
@ -18,12 +16,10 @@ namespace IRaCIS.Core.Application.Service
[ApiExplorerSettings(GroupName = "Image")] [ApiExplorerSettings(GroupName = "Image")]
public class SystemAnonymizationService : BaseService, ISystemAnonymizationService public class SystemAnonymizationService : BaseService, ISystemAnonymizationService
{ {
private readonly IMediator _mediator;
private readonly IRepository<SystemAnonymization> systemAnonymizationRepository; private readonly IRepository<SystemAnonymization> systemAnonymizationRepository;
public SystemAnonymizationService(IMediator mediator, IRepository<SystemAnonymization> systemAnonymizationRepository) public SystemAnonymizationService( IRepository<SystemAnonymization> systemAnonymizationRepository)
{ {
_mediator = mediator;
this.systemAnonymizationRepository = systemAnonymizationRepository; this.systemAnonymizationRepository = systemAnonymizationRepository;
} }
@ -47,7 +43,6 @@ namespace IRaCIS.Core.Application.Service
var entity = await _repository.InsertOrUpdateAsync<SystemAnonymization, SystemAnonymizationAddOrEdit>(addOrEditSystemAnonymization, true); var entity = await _repository.InsertOrUpdateAsync<SystemAnonymization, SystemAnonymizationAddOrEdit>(addOrEditSystemAnonymization, true);
await _mediator.Send(new AnonymizeCacheRequest());
return ResponseOutput.Ok(entity.Id.ToString()); return ResponseOutput.Ok(entity.Id.ToString());

View File

@ -1,5 +1,4 @@
using IRaCIS.Application.Contracts; using IRaCIS.Application.Contracts;
using IRaCIS.Core.Application.MediatR.CommandAndQueries;
using IRaCIS.Core.Domain.Share; using IRaCIS.Core.Domain.Share;
using Newtonsoft.Json; using Newtonsoft.Json;
@ -489,7 +488,14 @@ namespace IRaCIS.Core.Application.Contracts.DTO
} }
} }
public class ParamInfoDto
{
public string Modality { get; set; }
public string StudyDate { get; set; }
}
public class QCChanllengeDialogDTO : CheckChanllengeDialogDTO public class QCChanllengeDialogDTO : CheckChanllengeDialogDTO

View File

@ -2,7 +2,6 @@
using IRaCIS.Core.Application.Contracts.DTO; using IRaCIS.Core.Application.Contracts.DTO;
using IRaCIS.Core.Application.Service.Inspection.DTO; using IRaCIS.Core.Application.Service.Inspection.DTO;
using IRaCIS.Core.Domain.Share; using IRaCIS.Core.Domain.Share;
using MediatR;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
@ -40,6 +39,6 @@ namespace IRaCIS.Core.Application.Image.QA
Task<IResponseOutput> VerifyCanQCPassedOrFailed(Guid subjectVisitId); Task<IResponseOutput> VerifyCanQCPassedOrFailed(Guid subjectVisitId);
Task<IResponseOutput> ForwardSVDicomImage(Guid[] subjectVisitIdList); //Task<IResponseOutput> ForwardSVDicomImage(Guid[] subjectVisitIdList);
} }
} }

View File

@ -2,11 +2,9 @@
using IRaCIS.Core.Application.Contracts.DTO; using IRaCIS.Core.Application.Contracts.DTO;
using IRaCIS.Core.Application.Filter; using IRaCIS.Core.Application.Filter;
using IRaCIS.Core.Domain.Share; using IRaCIS.Core.Domain.Share;
using MediatR;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using System.Data; using System.Data;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using WinSCP;
using Newtonsoft.Json; using Newtonsoft.Json;
using IRaCIS.Core.Infrastructure; using IRaCIS.Core.Infrastructure;
using IRaCIS.Core.Application.Service.Inspection.DTO; using IRaCIS.Core.Application.Service.Inspection.DTO;
@ -2109,109 +2107,113 @@ namespace IRaCIS.Core.Application.Image.QA
} }
#region 转发影像 暂时不用 废弃
//[HttpPost("{trialId:guid}")]
////[Authorize(Policy = IRaCISPolicy.PM_APM)]
//[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
//public async Task<IResponseOutput> ForwardSVDicomImage(Guid[] subjectVisitIdList)
//{
[HttpPost("{trialId:guid}")] // bool isSuccess = false;
//[Authorize(Policy = IRaCISPolicy.PM_APM)]
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
public async Task<IResponseOutput> ForwardSVDicomImage(Guid[] subjectVisitIdList)
{
bool isSuccess = false;
foreach (var subjectVisitId in subjectVisitIdList) // foreach (var subjectVisitId in subjectVisitIdList)
{ // {
var info = (await _subjectVisitRepository.Where(t => t.Id == subjectVisitId).ProjectTo<DicomTrialSiteSubjectInfo>(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException(); // var info = (await _subjectVisitRepository.Where(t => t.Id == subjectVisitId).ProjectTo<DicomTrialSiteSubjectInfo>(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException();
var targetPath = "/IMPORT-IMAGES/" + info.TrialCode + "_" + info.SubjectCode + "_" + info.VisitName; // var targetPath = "/IMPORT-IMAGES/" + info.TrialCode + "_" + info.SubjectCode + "_" + info.VisitName;
var path = FileStoreHelper.GetSubjectVisitDicomFolderPhysicalPath(_hostEnvironment, info.TrialId, info.TrialSiteId, info.SubjectId, info.SubjectVisitId); // var path = FileStoreHelper.GetSubjectVisitDicomFolderPhysicalPath(_hostEnvironment, info.TrialId, info.TrialSiteId, info.SubjectId, info.SubjectVisitId);
try // try
{ // {
// 主机及端口信息后面可以改到 配置文件 // // 主机及端口信息后面可以改到 配置文件
SessionOptions sessionOptions = new SessionOptions // SessionOptions sessionOptions = new SessionOptions
{ // {
Protocol = Protocol.Sftp, // Protocol = Protocol.Sftp,
PortNumber = 8022, // PortNumber = 8022,
HostName = "CS-690-sftp.mint-imaging.com", // HostName = "CS-690-sftp.mint-imaging.com",
UserName = "zdong", // UserName = "zdong",
Password = "Everest@2021", // Password = "Everest@2021",
SshHostKeyFingerprint = @"ecdsa-sha2-nistp384 384 59gkjJ5lMwv3jsB8Wz2B35tBAIor5pSd8PcJYtoamPo=" // SshHostKeyFingerprint = @"ecdsa-sha2-nistp384 384 59gkjJ5lMwv3jsB8Wz2B35tBAIor5pSd8PcJYtoamPo="
}; // };
using (Session session = new Session()) // using (Session session = new Session())
{ // {
var studyFolders = (new DirectoryInfo(path)).GetDirectories(); // var studyFolders = (new DirectoryInfo(path)).GetDirectories();
session.Open(sessionOptions); // session.Open(sessionOptions);
if (!session.FileExists(targetPath)) // if (!session.FileExists(targetPath))
{ // {
session.CreateDirectory(targetPath); // session.CreateDirectory(targetPath);
} // }
foreach (var studyFolder in studyFolders) // foreach (var studyFolder in studyFolders)
{ // {
var targetFolder = Path.Combine(targetPath, studyFolder.Name); // var targetFolder = Path.Combine(targetPath, studyFolder.Name);
if (!session.FileExists(targetFolder)) // if (!session.FileExists(targetFolder))
{ // {
session.CreateDirectory(targetFolder); // session.CreateDirectory(targetFolder);
} // }
foreach (var file in studyFolder.GetFiles()) // foreach (var file in studyFolder.GetFiles())
{ // {
if (file.Extension.Contains("dcm", StringComparison.OrdinalIgnoreCase)) // if (file.Extension.Contains("dcm", StringComparison.OrdinalIgnoreCase))
{ // {
string remoteFilePath = // string remoteFilePath =
RemotePath.TranslateLocalPathToRemote(file.FullName, studyFolder.FullName, targetFolder); // RemotePath.TranslateLocalPathToRemote(file.FullName, studyFolder.FullName, targetFolder);
var result = session.PutFiles(file.FullName, remoteFilePath, false); // var result = session.PutFiles(file.FullName, remoteFilePath, false);
if (!result.IsSuccess) // if (!result.IsSuccess)
{ // {
await _subjectVisitRepository.BatchUpdateNoTrackingAsync(t => t.Id == subjectVisitId, // await _subjectVisitRepository.BatchUpdateNoTrackingAsync(t => t.Id == subjectVisitId,
u => new SubjectVisit() { ForwardState = ForwardStateEnum.ForwardFailed }); // u => new SubjectVisit() { ForwardState = ForwardStateEnum.ForwardFailed });
//---转发影像失败。 // //---转发影像失败。
return ResponseOutput.NotOk(_localizer["QCOperation_ForwardingFailed"] + result.Failures.ToString() + result.ToJson()); // return ResponseOutput.NotOk(_localizer["QCOperation_ForwardingFailed"] + result.Failures.ToString() + result.ToJson());
} // }
} // }
} // }
} // }
} // }
await _subjectVisitRepository.UpdatePartialFromQueryAsync(t => t.Id == subjectVisitId, // await _subjectVisitRepository.UpdatePartialFromQueryAsync(t => t.Id == subjectVisitId,
u => new SubjectVisit() { ForwardState = ForwardStateEnum.Forwarded, ForwardUserId = _userInfo.Id, ForwardTime = DateTime.Now }); // u => new SubjectVisit() { ForwardState = ForwardStateEnum.Forwarded, ForwardUserId = _userInfo.Id, ForwardTime = DateTime.Now });
isSuccess = true; // isSuccess = true;
} // }
catch (Exception e) // catch (Exception e)
{ // {
await _subjectVisitRepository.UpdatePartialFromQueryAsync(t => t.Id == subjectVisitId, // await _subjectVisitRepository.UpdatePartialFromQueryAsync(t => t.Id == subjectVisitId,
u => new SubjectVisit() { ForwardState = ForwardStateEnum.ForwardFailed }); // u => new SubjectVisit() { ForwardState = ForwardStateEnum.ForwardFailed });
// --转发影像失败 // // --转发影像失败
return ResponseOutput.NotOk(_localizer["QCOperation_ForwardingFailed"] + e.Message); // return ResponseOutput.NotOk(_localizer["QCOperation_ForwardingFailed"] + e.Message);
} // }
} // }
await _subjectVisitRepository.SaveChangesAsync(); // await _subjectVisitRepository.SaveChangesAsync();
// //---转发影像失败。
// return isSuccess ? ResponseOutput.Ok() : ResponseOutput.NotOk(_localizer["QCOperation_ForwardingFailed"]);
//}
#endregion
//---转发影像失败。
return isSuccess ? ResponseOutput.Ok() : ResponseOutput.NotOk(_localizer["QCOperation_ForwardingFailed"]);
}

View File

@ -3,7 +3,7 @@ using AutoMapper.EquivalencyExpression;
using IRaCIS.Application.Contracts; using IRaCIS.Application.Contracts;
using IRaCIS.Core.Application.Contracts; using IRaCIS.Core.Application.Contracts;
using IRaCIS.Core.Application.Contracts.DTO; using IRaCIS.Core.Application.Contracts.DTO;
using IRaCIS.Core.Application.MediatR.CommandAndQueries; using IRaCIS.Core.Application.MassTransit.Command;
using IRaCIS.Core.Domain.Share; using IRaCIS.Core.Domain.Share;
using static IRaCIS.Core.Application.Contracts.SubjectProgressDto; using static IRaCIS.Core.Application.Contracts.SubjectProgressDto;

View File

@ -1,4 +1,5 @@
using IRaCIS.Core.Infrastructure.Extention; using IRaCIS.Core.Infrastructure.Extention;
using MiniExcelLibs.Attributes;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
namespace IRaCIS.Application.Contracts namespace IRaCIS.Application.Contracts
@ -103,5 +104,53 @@ namespace IRaCIS.Application.Contracts
public int InconsistentCount { get; set; } public int InconsistentCount { get; set; }
} }
public class VisitPlanInfluenceSubjectVisitDTO
{
[ExcelColumn(Ignore = true)]
public Guid StudyId { get; set; }
[ExcelColumn(Ignore = true)]
public Guid TrialId { get; set; }
[ExcelColumn(Ignore = true)]
public Guid SubjectVisitId { get; set; }
[ExcelColumnName("中心编号")]
public string TrialSiteCode { get; set; } = string.Empty;
[ExcelColumnName("受试者")]
public string SubjectCode { get; set; } = string.Empty;
[ExcelColumnName("访视名称")]
public string VisitName { get; set; } = string.Empty;
[ExcelColumn(Name = "检查时间", Format = "yyyy-MM-dd HH:mm:ss")]
public DateTime StudyTime { get; set; }
[ExcelColumnName("检查技术")]
public string Modality { get; set; } = string.Empty;
[ExcelColumn(Ignore = true)]
public bool IsDicomStudy { get; set; }
[ExcelColumnName("影像类型")]
public string ImageType => IsDicomStudy ? "Dicom" : "非Dicom";
[ExcelColumnName("历史窗口")]
public string HistoryWindow { get; set; } = string.Empty;
[ExcelColumnName("之前超窗调整后没超窗")]
public bool IsOverWindowNowNotOverWindow { get; set; }
[ExcelColumnName("目前窗口")]
public string NowWindow { get; set; } = string.Empty;
[ExcelColumn(Ignore = true)]
public DateTime CreateTime { get; set; }
}
} }

View File

@ -3,7 +3,6 @@ using IRaCIS.Application.Contracts;
using IRaCIS.Core.Application.Filter; using IRaCIS.Core.Application.Filter;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using IRaCIS.Core.Domain.Share; using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Application.MediatR.CommandAndQueries;
using IRaCIS.Core.Infrastructure; using IRaCIS.Core.Infrastructure;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using IRaCIS.Core.Application.Auth; using IRaCIS.Core.Application.Auth;

View File

@ -2,7 +2,6 @@
using IRaCIS.Application.Contracts; using IRaCIS.Application.Contracts;
using IRaCIS.Core.Application.Contracts; using IRaCIS.Core.Application.Contracts;
using IRaCIS.Core.Application.Contracts.Dicom.DTO; using IRaCIS.Core.Application.Contracts.Dicom.DTO;
using IRaCIS.Core.Application.MediatR.CommandAndQueries;
using IRaCIS.Core.Domain.Share; using IRaCIS.Core.Domain.Share;
namespace IRaCIS.Core.Application.Service namespace IRaCIS.Core.Application.Service

View File

@ -1,176 +0,0 @@
using IRaCIS.Core.Domain.Share;
using MediatR;
using MiniExcelLibs.Attributes;
using System.ComponentModel.DataAnnotations;
using System.Linq;
namespace IRaCIS.Core.Application.MediatR.CommandAndQueries
{
public class ConsistencyVerificationRequest : IRequest<string>
{
public List<CheckViewModel> ETCList { get; set; } = new List<CheckViewModel>();
public Guid TrialId { get; set; }
}
public class CheckDBModel : CheckViewModel
{
public Guid SubjectVisitId { get; set; }
public Guid StudyId { get; set; }
}
//public class ImportResultFilteTest : IImportResultFilter
//{
// public ImportResult<T> Filter<T>(ImportResult<T> importResult) where T : class, new()
// {
// if (typeof(T).IsAssignableFrom(typeof(CheckViewModel)))
// {
// var data = (List<CheckViewModel>)importResult.Data;
// var dt = DateTime.Now ;
// foreach (var item in data)
// {
// var index= data.IndexOf(item);
// if ( DateTime.TryParse(item.StudyDate, out dt) == false)
// {
// importResult.RowErrors.Add(new DataRowErrorInfo() { RowIndex = index, FieldErrors = new Dictionary<string, string> { { StaticData.International("ConsistencyVerification_Tech") , StaticData.International("ConsistencyVerification_Time") } } });
// }
// }
// }
// return importResult;
// }
//}
public class ParamInfoDto
{
public string Modality { get; set; }
public string StudyDate { get; set; }
//public int ErrorType { get; set; }
}
//[ExcelImporter(/*ImportResultFilter = typeof(ImportResultFilteTest),*/ IsLabelingError = true)]
public class CheckViewModel
{
//[Required(ErrorMessage = "中心编号不能为空")]
//[ImporterHeader(Name = "Site ID", AutoTrim = true)]
[ExcelColumnName("Site ID")]
public string SiteCode { get; set; } = string.Empty;
//[Required(ErrorMessage = "受试者筛选号不能为空")]
//[ImporterHeader(Name = "Subject ID", AutoTrim = true)]
[ExcelColumnName("Subject ID")]
public string SubjectCode { get; set; } = string.Empty;
//[Required(ErrorMessage = "访视名称不能为空")]
//[ImporterHeader(Name = "Visit Name", AutoTrim = true)]
[ExcelColumnName("Visit Name")]
public string VisitName { get; set; } = string.Empty;
//[Required(ErrorMessage = "检查日期不能为空")]
[CanConvertToTime(ErrorMessage = "Does not conform to Study Date format")]
//[ImporterHeader(Name = "Study Date", AutoTrim = true)]
[ExcelColumnName("Study Date")]
public string StudyDate { get; set; } = string.Empty;
//[Required(ErrorMessage = "Modality不能为空")]
//[ImporterHeader(Name = "Modality", AutoTrim = true)]
[ExcelColumnName("Modality")]
public string Modality { get; set; } = string.Empty;
public override bool Equals(object? obj)
{
if (obj == null) return false;
var checkModel = obj as CheckViewModel;
if (checkModel is not null)
{
return SiteCode == checkModel.SiteCode && SubjectCode == checkModel.SubjectCode && VisitName == checkModel.VisitName && StudyDate == checkModel.StudyDate && Modality == checkModel.Modality;
}
else
{
return false;
}
}
public override int GetHashCode()
{
return (SiteCode + SubjectCode + VisitName + StudyDate + Modality).GetHashCode();
}
}
public class VisitPlanInfluenceSubjectVisitDTO
{
[ExcelColumn(Ignore = true)]
public Guid StudyId { get; set; }
[ExcelColumn(Ignore = true)]
public Guid TrialId { get; set; }
[ExcelColumn(Ignore = true)]
public Guid SubjectVisitId { get; set; }
[ExcelColumnName("中心编号")]
public string TrialSiteCode { get; set; } = string.Empty;
[ExcelColumnName("受试者")]
public string SubjectCode { get; set; } = string.Empty;
[ExcelColumnName("访视名称")]
public string VisitName { get; set; } = string.Empty;
[ExcelColumn(Name = "检查时间", Format = "yyyy-MM-dd HH:mm:ss")]
public DateTime StudyTime { get; set; }
[ExcelColumnName("检查技术")]
public string Modality { get; set; } = string.Empty;
[ExcelColumn(Ignore = true)]
public bool IsDicomStudy { get; set; }
[ExcelColumnName("影像类型")]
public string ImageType => IsDicomStudy ? "Dicom" : "非Dicom";
[ExcelColumnName("历史窗口")]
public string HistoryWindow { get; set; } = string.Empty;
[ExcelColumnName("之前超窗调整后没超窗")]
public bool IsOverWindowNowNotOverWindow { get; set; }
[ExcelColumnName("目前窗口")]
public string NowWindow { get; set; } = string.Empty;
[ExcelColumn(Ignore =true)]
public DateTime CreateTime { get; set; }
}
}

View File

@ -1,44 +0,0 @@
using EasyCaching.Core;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Infra.EFCore;
using MediatR;
namespace IRaCIS.Core.Application.MediatR.Handlers
{
public class AnonymizeCacheRequest : IRequest<bool>
{
}
public class AnonymizeCacheHandler : IRequestHandler<AnonymizeCacheRequest,bool>
{
private readonly IRepository _repository;
private readonly IEasyCachingProvider _provider;
/// <summary>
/// 构造函数注入
/// </summary>
public AnonymizeCacheHandler(IRepository repository, IEasyCachingProvider provider)
{
_repository = repository;
_provider = provider;
}
public Task<bool> Handle(AnonymizeCacheRequest request, CancellationToken cancellationToken)
{
var systemAnonymizationList = _repository.Where<SystemAnonymization>(t => t.IsEnable).ToList();
_provider.Set(StaticData.Anonymize.Anonymize_AddFixedFiled, systemAnonymizationList.Where(t => t.IsAdd && t.IsFixed).ToList(), TimeSpan.FromDays(7));
_provider.Set(StaticData.Anonymize.Anonymize_AddIRCInfoFiled, systemAnonymizationList.Where(t => t.IsAdd && t.IsFixed == false).ToList(), TimeSpan.FromDays(7));
_provider.Set(StaticData.Anonymize.Anonymize_FixedField, systemAnonymizationList.Where(t => t.IsAdd == false && t.IsFixed).ToList(), TimeSpan.FromDays(7));
_provider.Set(StaticData.Anonymize.Anonymize_IRCInfoField, systemAnonymizationList.Where(t => t.IsAdd == false && t.IsFixed == false).ToList(), TimeSpan.FromDays(7));
return Task.FromResult(true);
}
}
}

View File

@ -1,45 +0,0 @@
using EasyCaching.Core;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Infra.EFCore;
using MediatR;
namespace IRaCIS.Core.Application.MediatR.Handlers
{
public class TrialStateCacheRequest : IRequest<bool>
{
}
public class TrialStateCacheHandler : IRequestHandler<TrialStateCacheRequest, bool>
{
private readonly IRepository<Trial> _trialRepository;
private readonly IEasyCachingProvider _provider;
/// <summary>
/// 构造函数注入
/// </summary>
public TrialStateCacheHandler(IRepository<Trial> trialRepository, IEasyCachingProvider provider)
{
_trialRepository = trialRepository;
_provider = provider;
}
public async Task<bool> Handle(TrialStateCacheRequest request, CancellationToken cancellationToken)
{
//项目启动将项目状态缓存因为hangfire 加入后台任务,还是向队列添加任务,执行都有延迟,效果不好
var list = await _trialRepository.Select(t => new { TrialId = t.Id, TrialStatusStr = t.TrialStatusStr }).ToListAsync();
// 每天都会有任务刷新状态,项目编辑 添加时 都会处理到缓存中
list.ForEach(t => _provider.Set(t.TrialId.ToString(), t.TrialStatusStr, TimeSpan.FromDays(7)));
return true;
}
}
}