Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is failing
Details
continuous-integration/drone/push Build is failing
Details
commit
cdadad9ec5
|
@ -15,8 +15,8 @@
|
||||||
"RoleArn": "arn:aws:iam::471112624751:role/lili_s3_access",
|
"RoleArn": "arn:aws:iam::471112624751:role/lili_s3_access",
|
||||||
"AccessKeyId": "AKIAW3MEAFJXZ2TZK7GM",
|
"AccessKeyId": "AKIAW3MEAFJXZ2TZK7GM",
|
||||||
"SecretAccessKey": "9MLQCQ1HifEVW1gf068zBRAOb4wNnfrOkvBVByth",
|
"SecretAccessKey": "9MLQCQ1HifEVW1gf068zBRAOb4wNnfrOkvBVByth",
|
||||||
"BucketName": "ei-med-s3-lili-uat-store",
|
"BucketName": "ei-med-s3-lili-store",
|
||||||
"ViewEndpoint": "https://ei-med-s3-lili-uat-store.s3.amazonaws.com/",
|
"ViewEndpoint": "https://ei-med-s3-lili-store.s3.amazonaws.com",
|
||||||
"DurationSeconds": 7200
|
"DurationSeconds": 7200
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -134,7 +134,7 @@ builder.Services.AddDynamicWebApiSetup();
|
||||||
//AutoMapper
|
//AutoMapper
|
||||||
builder.Services.AddAutoMapperSetup();
|
builder.Services.AddAutoMapperSetup();
|
||||||
//EF ORM QueryWithNoLock
|
//EF ORM QueryWithNoLock
|
||||||
builder.Services.AddEFSetup(_configuration,enviromentName);
|
builder.Services.AddEFSetup(_configuration, enviromentName);
|
||||||
//Http 响应压缩
|
//Http 响应压缩
|
||||||
builder.Services.AddResponseCompressionSetup();
|
builder.Services.AddResponseCompressionSetup();
|
||||||
//Swagger Api 文档
|
//Swagger Api 文档
|
||||||
|
@ -151,15 +151,17 @@ builder.Services.AddJWTAuthSetup(_configuration);
|
||||||
builder.Services.AddMediator(cfg =>
|
builder.Services.AddMediator(cfg =>
|
||||||
{
|
{
|
||||||
cfg.AddConsumer<ConsistencyCheckConsumer>();
|
cfg.AddConsumer<ConsistencyCheckConsumer>();
|
||||||
cfg.AddConsumer<AddUserLogTriggerConsumer>();
|
|
||||||
cfg.AddConsumer<AddSubjectTriggerConsumer>();
|
cfg.AddConsumer<AddSubjectTriggerConsumer>();
|
||||||
|
cfg.AddConsumer<AddSubjectTriggerConsumer2>();
|
||||||
|
//cfg.ConfigureMediator((context, cfg) => cfg.UseHttpContextScopeFilter(context));
|
||||||
});
|
});
|
||||||
|
|
||||||
// 添加 MassTransit 和 InMemory 传输
|
//添加 MassTransit 和 InMemory 传输
|
||||||
builder.Services.AddMassTransit(cfg =>
|
builder.Services.AddMassTransit(cfg =>
|
||||||
{
|
{
|
||||||
// 注册消费者
|
// 注册消费者
|
||||||
//cfg.AddConsumer<AddSubjectTriggerConsumer>(); // 替换为你的消费者类
|
cfg.AddConsumer<AddSubjectTriggerConsumer>(); // 替换为你的消费者类
|
||||||
|
cfg.AddConsumer<AddSubjectTriggerConsumer2>();
|
||||||
|
|
||||||
// 使用 InMemory 作为消息传递机制
|
// 使用 InMemory 作为消息传递机制
|
||||||
cfg.UsingInMemory((context, cfg) =>
|
cfg.UsingInMemory((context, cfg) =>
|
||||||
|
@ -167,9 +169,8 @@ builder.Services.AddMassTransit(cfg =>
|
||||||
// 这里可以进行额外的配置
|
// 这里可以进行额外的配置
|
||||||
cfg.ConfigureEndpoints(context); // 自动配置所有消费者的端点
|
cfg.ConfigureEndpoints(context); // 自动配置所有消费者的端点
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
@ -211,6 +212,7 @@ builder.Services.AddSingleton<ISearcher>(new Searcher(CachePolicy.Content, Path.
|
||||||
//builder.Services.AddExceptionHandler<GlobalExceptionHandler>();
|
//builder.Services.AddExceptionHandler<GlobalExceptionHandler>();
|
||||||
//builder.Services.AddProblemDetails();
|
//builder.Services.AddProblemDetails();
|
||||||
|
|
||||||
|
|
||||||
#region 历史废弃配置
|
#region 历史废弃配置
|
||||||
//builder.Services.AddMemoryCache();
|
//builder.Services.AddMemoryCache();
|
||||||
////上传限制 配置
|
////上传限制 配置
|
||||||
|
|
|
@ -32,8 +32,8 @@
|
||||||
"RoleArn": "arn:aws:iam::471112624751:role/lili_s3_access",
|
"RoleArn": "arn:aws:iam::471112624751:role/lili_s3_access",
|
||||||
"AccessKeyId": "AKIAW3MEAFJXZ2TZK7GM",
|
"AccessKeyId": "AKIAW3MEAFJXZ2TZK7GM",
|
||||||
"SecretAccessKey": "9MLQCQ1HifEVW1gf068zBRAOb4wNnfrOkvBVByth",
|
"SecretAccessKey": "9MLQCQ1HifEVW1gf068zBRAOb4wNnfrOkvBVByth",
|
||||||
"BucketName": "ei-med-s3-lili-uat-store",
|
"BucketName": "ei-med-s3-lili-store",
|
||||||
"ViewEndpoint": "https://ei-med-s3-lili-uat-store.s3.amazonaws.com",
|
"ViewEndpoint": "https://ei-med-s3-lili-store.s3.amazonaws.com",
|
||||||
"DurationSeconds": 7200
|
"DurationSeconds": 7200
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -71,7 +71,6 @@
|
||||||
<PackageReference Include="RestSharp" Version="112.0.0" />
|
<PackageReference Include="RestSharp" Version="112.0.0" />
|
||||||
<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="MassTransit.AspNetCore" Version="7.3.1" />
|
|
||||||
<PackageReference Include="ZiggyCreatures.FusionCache" Version="1.3.0" />
|
<PackageReference Include="ZiggyCreatures.FusionCache" Version="1.3.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
|
|
@ -712,6 +712,30 @@
|
||||||
<param name="_trialRepository"></param>
|
<param name="_trialRepository"></param>
|
||||||
<returns></returns>
|
<returns></returns>
|
||||||
</member>
|
</member>
|
||||||
|
<member name="M:IRaCIS.Core.Application.Service.Common.ExcelExportService.GetTrialDownloadList_Export(IRaCIS.Core.Application.Contracts.TrialIamgeDownQuery,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.TrialImageDownload},IRaCIS.Application.Interfaces.IDictionaryService,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.Trial})">
|
||||||
|
<summary>
|
||||||
|
影像下载记录表
|
||||||
|
</summary>
|
||||||
|
<param name="inQuery"></param>
|
||||||
|
<param name="_trialImageDownloadRepository"></param>
|
||||||
|
<param name="_dictionaryService"></param>
|
||||||
|
<param name="_trialRepository"></param>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
|
<member name="M:IRaCIS.Core.Application.Service.Common.ExcelExportService.GetSCPImageUploadList_Export(IRaCIS.Application.Contracts.SCPImageUploadQuery,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.SCPImageUpload},IRaCIS.Application.Interfaces.IDictionaryService,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.Trial})">
|
||||||
|
<summary>
|
||||||
|
影像接收记录表
|
||||||
|
</summary>
|
||||||
|
<param name="inQuery"></param>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
|
<member name="M:IRaCIS.Core.Application.Service.Common.ExcelExportService.GetPatientList_Export(IRaCIS.Application.Contracts.PatientTrialQuery,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.SCPPatient},IRaCIS.Application.Interfaces.IDictionaryService,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.Trial})">
|
||||||
|
<summary>
|
||||||
|
影像检查列表-患者为维度组织
|
||||||
|
</summary>
|
||||||
|
<param name="inQuery"></param>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
<member name="M:IRaCIS.Core.Application.Service.Common.ExcelExportService.GetSelfAnalysisTaskList_Export(IRaCIS.Core.Application.ViewModel.VisitTaskQuery,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.CommonDocument},IRaCIS.Application.Interfaces.IDictionaryService,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.Trial})">
|
<member name="M:IRaCIS.Core.Application.Service.Common.ExcelExportService.GetSelfAnalysisTaskList_Export(IRaCIS.Core.Application.ViewModel.VisitTaskQuery,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.CommonDocument},IRaCIS.Application.Interfaces.IDictionaryService,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.Trial})">
|
||||||
<summary>
|
<summary>
|
||||||
自身一致性分析(仅做了resist1.1)
|
自身一致性分析(仅做了resist1.1)
|
||||||
|
@ -12676,6 +12700,11 @@
|
||||||
<param name="_trialRepository"></param>
|
<param name="_trialRepository"></param>
|
||||||
<param name="_mapper"></param>
|
<param name="_mapper"></param>
|
||||||
</member>
|
</member>
|
||||||
|
<member name="T:IRaCIS.Core.Application.MassTransit.Consumer.MediatorHttpContextScopeFilterExtensions">
|
||||||
|
<summary>
|
||||||
|
参考链接:https://github.com/MassTransit/MassTransit/discussions/2498
|
||||||
|
</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>
|
||||||
|
|
|
@ -3,10 +3,15 @@
|
||||||
using AutoMapper;
|
using AutoMapper;
|
||||||
using IRaCIS.Core.Domain;
|
using IRaCIS.Core.Domain;
|
||||||
using MassTransit;
|
using MassTransit;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
||||||
namespace IRaCIS.Core.Application.MassTransit.Consumer;
|
namespace IRaCIS.Core.Application.MassTransit.Consumer;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 添加Subject 触发添加访视 不能代替 Trigger,稽查BatchId 不一致
|
/// 添加Subject 触发添加访视 不能代替 Trigger,稽查BatchId 不一致
|
||||||
/// 因为消费者这里的数据库上下文 和消息发送者上下文不是同一个,相当于两个独立的事务
|
/// 因为消费者这里的数据库上下文 和消息发送者上下文不是同一个,相当于两个独立的事务
|
||||||
|
@ -25,7 +30,7 @@ public class AddSubjectTriggerConsumer(IRepository<SubjectVisit> _subjectVisitRe
|
||||||
{
|
{
|
||||||
var addSubjectEvent = context.Message;
|
var addSubjectEvent = context.Message;
|
||||||
|
|
||||||
|
|
||||||
{
|
{
|
||||||
Console.WriteLine(_visitStageRepository._dbContext.GetHashCode());
|
Console.WriteLine(_visitStageRepository._dbContext.GetHashCode());
|
||||||
|
|
||||||
|
@ -53,3 +58,44 @@ public class AddSubjectTriggerConsumer(IRepository<SubjectVisit> _subjectVisitRe
|
||||||
await _subjectVisitRepository.AddRangeAsync(svList);
|
await _subjectVisitRepository.AddRangeAsync(svList);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class AddSubjectTriggerConsumer2(IRepository<SubjectVisit> _subjectVisitRepository,
|
||||||
|
|
||||||
|
IRepository<VisitStage> _visitStageRepository,
|
||||||
|
IRepository<Trial> _trialRepository,
|
||||||
|
IMapper _mapper) : IConsumer<AddSubjectTriggerCommand2>
|
||||||
|
{
|
||||||
|
public async Task Consume(ConsumeContext<AddSubjectTriggerCommand2> context)
|
||||||
|
{
|
||||||
|
var addSubjectEvent = context.Message;
|
||||||
|
|
||||||
|
|
||||||
|
{
|
||||||
|
Console.WriteLine(_visitStageRepository._dbContext.GetHashCode());
|
||||||
|
|
||||||
|
Console.WriteLine("两个 DbContext 不是同一个实例");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//添加受试者的时候,获取访视计划列表,添加到受试者访视表。
|
||||||
|
var visitPlanList = await _visitStageRepository.Where(t => t.TrialId == addSubjectEvent.TrialId && t.IsConfirmed).ToListAsync();
|
||||||
|
|
||||||
|
var svList = _mapper.Map<List<SubjectVisit>>(visitPlanList);
|
||||||
|
|
||||||
|
var IsEnrollementQualificationConfirm = await _trialRepository.Where(t => t.Id == addSubjectEvent.TrialId).Select(u => u.IsEnrollementQualificationConfirm).FirstOrDefaultAsync();
|
||||||
|
|
||||||
|
svList.ForEach(t =>
|
||||||
|
{
|
||||||
|
t.SubjectId = addSubjectEvent.SubjectId;
|
||||||
|
t.TrialId = addSubjectEvent.TrialId;
|
||||||
|
t.TrialSiteId = addSubjectEvent.TrialSiteId;
|
||||||
|
t.IsEnrollmentConfirm = t.IsBaseLine ? IsEnrollementQualificationConfirm : false;
|
||||||
|
t.Id = NewId.NextGuid();
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
await _subjectVisitRepository.AddRangeAsync(svList);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,83 @@
|
||||||
|
|
||||||
|
|
||||||
|
using IRaCIS.Core.Application.MassTransit.Consumer;
|
||||||
|
using MassTransit;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
||||||
|
namespace IRaCIS.Core.Application.MassTransit.Consumer;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 参考链接:https://github.com/MassTransit/MassTransit/discussions/2498
|
||||||
|
/// </summary>
|
||||||
|
public static class MediatorHttpContextScopeFilterExtensions
|
||||||
|
{
|
||||||
|
public static void UseHttpContextScopeFilter(this IMediatorConfigurator configurator, IServiceProvider serviceProvider)
|
||||||
|
{
|
||||||
|
var filter = new HttpContextScopeFilter(serviceProvider.GetRequiredService<IHttpContextAccessor>());
|
||||||
|
|
||||||
|
configurator.ConfigurePublish(x => x.UseFilter(filter));
|
||||||
|
configurator.ConfigureSend(x => x.UseFilter(filter));
|
||||||
|
configurator.UseFilter(filter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class HttpContextScopeFilter :
|
||||||
|
IFilter<PublishContext>,
|
||||||
|
IFilter<SendContext>,
|
||||||
|
IFilter<ConsumeContext>
|
||||||
|
{
|
||||||
|
private readonly IHttpContextAccessor _httpContextAccessor;
|
||||||
|
|
||||||
|
public HttpContextScopeFilter(IHttpContextAccessor httpContextAccessor)
|
||||||
|
{
|
||||||
|
_httpContextAccessor = httpContextAccessor;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AddPayload(PipeContext context)
|
||||||
|
{
|
||||||
|
if (_httpContextAccessor.HttpContext == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var serviceProvider = _httpContextAccessor.HttpContext.RequestServices;
|
||||||
|
context.GetOrAddPayload(() => serviceProvider);
|
||||||
|
context.GetOrAddPayload<IServiceScope>(() => new NoopScope(serviceProvider));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task Send(PublishContext context, IPipe<PublishContext> next)
|
||||||
|
{
|
||||||
|
AddPayload(context);
|
||||||
|
return next.Send(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task Send(SendContext context, IPipe<SendContext> next)
|
||||||
|
{
|
||||||
|
AddPayload(context);
|
||||||
|
return next.Send(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task Send(ConsumeContext context, IPipe<ConsumeContext> next)
|
||||||
|
{
|
||||||
|
AddPayload(context);
|
||||||
|
return next.Send(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Probe(ProbeContext context)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
private class NoopScope :
|
||||||
|
IServiceScope
|
||||||
|
{
|
||||||
|
public NoopScope(IServiceProvider serviceProvider)
|
||||||
|
{
|
||||||
|
ServiceProvider = serviceProvider;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public IServiceProvider ServiceProvider { get; }
|
||||||
|
}
|
||||||
|
}
|
|
@ -1204,6 +1204,145 @@ namespace IRaCIS.Core.Application.Service.Common
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 影像下载记录表
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="inQuery"></param>
|
||||||
|
/// <param name="_trialImageDownloadRepository"></param>
|
||||||
|
/// <param name="_dictionaryService"></param>
|
||||||
|
/// <param name="_trialRepository"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpPost]
|
||||||
|
public async Task<IActionResult> GetTrialDownloadList_Export(TrialIamgeDownQuery inQuery,
|
||||||
|
[FromServices] IRepository<TrialImageDownload> _trialImageDownloadRepository,
|
||||||
|
[FromServices] IDictionaryService _dictionaryService,
|
||||||
|
[FromServices] IRepository<Trial> _trialRepository)
|
||||||
|
{
|
||||||
|
var query = _trialImageDownloadRepository.Where(t => t.TrialId == inQuery.TrialId)
|
||||||
|
.WhereIf(inQuery.SubjectCode.IsNotNullOrEmpty(), t => t.SubjectCode.Contains(inQuery.SubjectCode))
|
||||||
|
.WhereIf(inQuery.IP.IsNotNullOrEmpty(), t => t.IP.Contains(inQuery.IP))
|
||||||
|
.WhereIf(inQuery.Name.IsNotNullOrEmpty(), t => t.CreateUser.UserName.Contains(inQuery.Name) || t.CreateUser.FullName.Contains(inQuery.Name))
|
||||||
|
.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)
|
||||||
|
.WhereIf(inQuery.DownloadStartTime != null, t => t.DownloadStartTime >= inQuery.DownloadStartTime)
|
||||||
|
.WhereIf(inQuery.DownloadEndTime != null, t => t.DownloadEndTime <= inQuery.DownloadEndTime)
|
||||||
|
|
||||||
|
.ProjectTo<TrialImageDownloadExportDto>(_mapper.ConfigurationProvider);
|
||||||
|
|
||||||
|
var list = query.SortToListAsync(inQuery);
|
||||||
|
|
||||||
|
|
||||||
|
var exportInfo = (await _trialRepository.Where(t => t.Id == inQuery.TrialId).IgnoreQueryFilters().ProjectTo<ExcelExportInfo>(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException();
|
||||||
|
|
||||||
|
exportInfo.List = ExportExcelConverterDate.ConvertToClientTimeInObject(list, _userInfo.TimeZoneId);
|
||||||
|
exportInfo.CurrentTime = ExportExcelConverterDate.DateTimeInternationalToString(DateTime.Now, _userInfo.TimeZoneId);
|
||||||
|
|
||||||
|
|
||||||
|
return await ExcelExportHelper.DataExportAsync(StaticData.Export.TrialImageDownloadList_Export, exportInfo, $"{exportInfo.ResearchProgramNo}", _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(TrialImageDownloadExportDto));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 影像接收记录表
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="inQuery"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpPost]
|
||||||
|
public async Task<IActionResult> GetSCPImageUploadList_Export(SCPImageUploadQuery inQuery,
|
||||||
|
[FromServices] IRepository<SCPImageUpload> _scpImageUploadRepository,
|
||||||
|
[FromServices] IDictionaryService _dictionaryService,
|
||||||
|
[FromServices] IRepository<Trial> _trialRepository)
|
||||||
|
{
|
||||||
|
var query = _scpImageUploadRepository.Where(t => t.TrialId == inQuery.TrialId)
|
||||||
|
.WhereIf(!string.IsNullOrWhiteSpace(inQuery.CalledAE), t => t.CalledAE.Contains(inQuery.CalledAE))
|
||||||
|
.WhereIf(!string.IsNullOrWhiteSpace(inQuery.CallingAEIP), t => t.CallingAEIP.Contains(inQuery.CallingAEIP))
|
||||||
|
.WhereIf(!string.IsNullOrWhiteSpace(inQuery.CallingAE), t => t.CallingAE.Contains(inQuery.CallingAE))
|
||||||
|
.WhereIf(inQuery.StartTime != null, t => t.StartTime >= inQuery.StartTime)
|
||||||
|
.WhereIf(inQuery.EndTime != null, t => t.EndTime <= inQuery.EndTime)
|
||||||
|
.WhereIf(!string.IsNullOrWhiteSpace(inQuery.TrialSiteKeyInfo), t => t.TrialSite.TrialSiteCode.Contains(inQuery.TrialSiteKeyInfo)
|
||||||
|
|| t.TrialSite.TrialSiteAliasName.Contains(inQuery.TrialSiteKeyInfo) || t.TrialSite.TrialSiteName.Contains(inQuery.TrialSiteKeyInfo))
|
||||||
|
.ProjectTo<SCPImageUploadExportDTO>(_mapper.ConfigurationProvider);
|
||||||
|
|
||||||
|
|
||||||
|
var list = query.SortToListAsync(inQuery);
|
||||||
|
|
||||||
|
var exportInfo = (await _trialRepository.Where(t => t.Id == inQuery.TrialId).IgnoreQueryFilters().ProjectTo<ExcelExportInfo>(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException();
|
||||||
|
|
||||||
|
exportInfo.List = ExportExcelConverterDate.ConvertToClientTimeInObject(list, _userInfo.TimeZoneId);
|
||||||
|
exportInfo.CurrentTime = ExportExcelConverterDate.DateTimeInternationalToString(DateTime.Now, _userInfo.TimeZoneId);
|
||||||
|
|
||||||
|
|
||||||
|
return await ExcelExportHelper.DataExportAsync(StaticData.Export.TrialSCPImageUploadList_Export, exportInfo, $"{exportInfo.ResearchProgramNo}", _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(SCPImageUploadExportDTO));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///影像检查列表-患者为维度组织
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="inQuery"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpPost]
|
||||||
|
public async Task<IActionResult> GetPatientList_Export(PatientTrialQuery inQuery,
|
||||||
|
[FromServices] IRepository<SCPPatient> _patientRepository,
|
||||||
|
[FromServices] IDictionaryService _dictionaryService,
|
||||||
|
[FromServices] IRepository<Trial> _trialRepository)
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
var query = _patientRepository.Where(t => t.TrialId == inQuery.TrialId)
|
||||||
|
.WhereIf(!string.IsNullOrWhiteSpace(inQuery.PatientIdStr), t => t.PatientIdStr.Contains(inQuery.PatientIdStr))
|
||||||
|
.WhereIf(!string.IsNullOrWhiteSpace(inQuery.PatientName), t => t.PatientName.Contains(inQuery.PatientName))
|
||||||
|
.WhereIf(!string.IsNullOrWhiteSpace(inQuery.SubejctCode), t => t.Subject.Code.Contains(inQuery.SubejctCode))
|
||||||
|
.WhereIf(!string.IsNullOrWhiteSpace(inQuery.TrialSiteKeyInfo), t => t.TrialSite.TrialSiteCode.Contains(inQuery.TrialSiteKeyInfo)
|
||||||
|
|| t.TrialSite.TrialSiteAliasName.Contains(inQuery.TrialSiteKeyInfo) || t.TrialSite.TrialSiteName.Contains(inQuery.TrialSiteKeyInfo))
|
||||||
|
.WhereIf(!string.IsNullOrWhiteSpace(inQuery.CallingAE), t => t.SCPStudyList.Any(t => t.CallingAE == inQuery.CallingAE))
|
||||||
|
.WhereIf(!string.IsNullOrWhiteSpace(inQuery.CalledAE), t => t.SCPStudyList.Any(t => t.CalledAE == inQuery.CalledAE))
|
||||||
|
.WhereIf(inQuery.BeginPushTime != null, t => t.LatestPushTime >= inQuery.BeginPushTime)
|
||||||
|
.WhereIf(inQuery.EndPushTime != null, t => t.LatestPushTime <= inQuery.EndPushTime);
|
||||||
|
|
||||||
|
|
||||||
|
var resultQuery = from patient in query
|
||||||
|
|
||||||
|
select new SCPPatientSubjectExportDTO()
|
||||||
|
{
|
||||||
|
//CreateUserId = patient.CreateUserId,
|
||||||
|
//UpdateTime = patient.UpdateTime,
|
||||||
|
//UpdateUserId = patient.UpdateUserId,
|
||||||
|
//TrialId = patient.TrialId,
|
||||||
|
//SubejctId = patient.SubjectId,
|
||||||
|
//CreateTime = patient.CreateTime,
|
||||||
|
//PatientId = patient.Id,
|
||||||
|
|
||||||
|
PatientBirthDate = patient.PatientBirthDate,
|
||||||
|
CalledAEList = patient.SCPStudyList.Select(t => t.CalledAE).Distinct().ToList(),
|
||||||
|
CallingAEList = patient.SCPStudyList.Select(t => t.CallingAE).Distinct().ToList(),
|
||||||
|
EarliestStudyTime = patient.EarliestStudyTime,
|
||||||
|
LatestStudyTime = patient.LatestStudyTime,
|
||||||
|
LatestPushTime = patient.LatestPushTime,
|
||||||
|
PatientAge = patient.PatientAge,
|
||||||
|
PatientName = patient.PatientName,
|
||||||
|
PatientIdStr = patient.PatientIdStr,
|
||||||
|
PatientSex = patient.PatientSex,
|
||||||
|
StudyCount = patient.SCPStudyList.Count(),
|
||||||
|
SubjectCode = patient.Subject.Code,
|
||||||
|
TrialSiteAliasName = patient.TrialSite.TrialSiteAliasName,
|
||||||
|
TrialSiteCode = patient.TrialSite.TrialSiteCode,
|
||||||
|
TrialSiteName = patient.TrialSite.TrialSiteName
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
var list = query.SortToListAsync(inQuery);
|
||||||
|
|
||||||
|
var exportInfo = (await _trialRepository.Where(t => t.Id == inQuery.TrialId).IgnoreQueryFilters().ProjectTo<ExcelExportInfo>(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException();
|
||||||
|
|
||||||
|
exportInfo.List = ExportExcelConverterDate.ConvertToClientTimeInObject(list, _userInfo.TimeZoneId);
|
||||||
|
exportInfo.CurrentTime = ExportExcelConverterDate.DateTimeInternationalToString(DateTime.Now, _userInfo.TimeZoneId);
|
||||||
|
|
||||||
|
|
||||||
|
return await ExcelExportHelper.DataExportAsync(StaticData.Export.TrialSCPImageUploadPatientList_Export, exportInfo, $"{exportInfo.ResearchProgramNo}", _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(SCPPatientSubjectExportDTO));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 自身一致性分析(仅做了resist1.1)
|
/// 自身一致性分析(仅做了resist1.1)
|
||||||
|
|
|
@ -82,6 +82,13 @@ namespace IRaCIS.Core.Application.Service
|
||||||
CreateMap<ExploreRecommend, ExploreRecommendView>();
|
CreateMap<ExploreRecommend, ExploreRecommendView>();
|
||||||
CreateMap<ExploreRecommend, ExploreRecommendAddOrEdit>().ReverseMap();
|
CreateMap<ExploreRecommend, ExploreRecommendAddOrEdit>().ReverseMap();
|
||||||
|
|
||||||
|
|
||||||
|
CreateMap<TrialImageDownload, TrialImageDownloadExportDto>()
|
||||||
|
.ForMember(d => d.UserFullName, u => u.MapFrom(s => s.CreateUser.FullName))
|
||||||
|
.ForMember(d => d.UserTypeEnum, u => u.MapFrom(s => s.CreateUser.UserTypeEnum))
|
||||||
|
.ForMember(d => d.UserName, u => u.MapFrom(s => s.CreateUser.UserName));
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -871,6 +871,95 @@ namespace IRaCIS.Core.Application.Contracts
|
||||||
public bool IsInvalid { get; set; }
|
public bool IsInvalid { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class TrialImageDownloadExportDto
|
||||||
|
{
|
||||||
|
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; }
|
||||||
|
|
||||||
|
[DictionaryTranslateAttribute("downloadImageType")]
|
||||||
|
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 string IP { get; set; }
|
||||||
|
|
||||||
|
[DictionaryTranslateAttribute("UserType")]
|
||||||
|
public UserTypeEnum UserTypeEnum { get; set; }
|
||||||
|
|
||||||
|
public string ImageSizeStr => (ImageSize / Math.Pow(1024, 2)).ToString("F3") + 'M';
|
||||||
|
|
||||||
|
public string UploadIntervalStr
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
var uploadTimeSpan = DownloadEndTime - DownloadStartTime;
|
||||||
|
|
||||||
|
return $" {uploadTimeSpan?.Hours}:{uploadTimeSpan?.Minutes}:{uploadTimeSpan?.Seconds}.{uploadTimeSpan?.Milliseconds}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public class SCPImageUploadExportDTO
|
||||||
|
{
|
||||||
|
public string CallingAE { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
public string CalledAE { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
public string CallingAEIP { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
public DateTime StartTime { get; set; }
|
||||||
|
|
||||||
|
public DateTime EndTime { get; set; }
|
||||||
|
|
||||||
|
public int FileCount { get; set; }
|
||||||
|
|
||||||
|
public long FileSize { get; set; }
|
||||||
|
|
||||||
|
public int StudyCount { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
public Guid TrialId { get; set; }
|
||||||
|
public Guid TrialSiteId { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
public string TrialSiteCode { get; set; }
|
||||||
|
|
||||||
|
public string TrialSiteName { get; set; }
|
||||||
|
|
||||||
|
public string TrialSiteAliasName { get; set; }
|
||||||
|
|
||||||
|
public string UploadIntervalStr
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
var uploadTimeSpan = EndTime - StartTime;
|
||||||
|
|
||||||
|
return $" {uploadTimeSpan.Hours}:{uploadTimeSpan.Minutes}:{uploadTimeSpan.Seconds}.{uploadTimeSpan.Milliseconds}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public string ImageSizeStr => (FileSize / Math.Pow(1024, 2)).ToString("F3") + 'M';
|
||||||
|
}
|
||||||
|
|
||||||
public class AnalysisExortCommon
|
public class AnalysisExortCommon
|
||||||
{
|
{
|
||||||
|
|
|
@ -256,9 +256,45 @@ namespace IRaCIS.Application.Contracts
|
||||||
public string? TrialSiteName { get; set; }
|
public string? TrialSiteName { get; set; }
|
||||||
|
|
||||||
public string? TrialSiteAliasName { get; set; }
|
public string? TrialSiteAliasName { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public class SCPPatientSubjectExportDTO
|
||||||
|
{
|
||||||
|
public int? StudyCount { get; set; }
|
||||||
|
|
||||||
|
public string? SubjectCode { get; set; }
|
||||||
|
|
||||||
|
public string? TrialSiteCode { get; set; }
|
||||||
|
|
||||||
|
public string? TrialSiteName { get; set; }
|
||||||
|
|
||||||
|
public string? TrialSiteAliasName { get; set; }
|
||||||
|
|
||||||
|
public string PatientIdStr { get; set; } = string.Empty;
|
||||||
|
public string PatientName { get; set; } = string.Empty;
|
||||||
|
public string PatientAge { get; set; } = string.Empty;
|
||||||
|
public string PatientSex { get; set; } = string.Empty;
|
||||||
|
public string PatientBirthDate { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
public DateTime? EarliestStudyTime { get; set; }
|
||||||
|
|
||||||
|
public DateTime? LatestStudyTime { get; set; }
|
||||||
|
|
||||||
|
public DateTime LatestPushTime { get; set; }
|
||||||
|
|
||||||
|
public List<string> CallingAEList { get; set; } = new List<string>();
|
||||||
|
|
||||||
|
public List<string> CalledAEList { get; set; } = new List<string>();
|
||||||
|
|
||||||
|
public string CallingAEListStr => string.Join(",", CallingAEList);
|
||||||
|
|
||||||
|
public string CalledAEListStr => string.Join(",", CalledAEList);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public class PatientQuery : PageInput
|
public class PatientQuery : PageInput
|
||||||
{
|
{
|
||||||
|
|
|
@ -112,9 +112,13 @@ namespace IRaCIS.Core.Application.Service
|
||||||
|
|
||||||
CreateMap<SCPImageUpload, SCPImageUploadView>()
|
CreateMap<SCPImageUpload, SCPImageUploadView>()
|
||||||
.ForMember(d => d.TrialSiteCode, u => u.MapFrom(s => s.TrialSite.TrialSiteCode))
|
.ForMember(d => d.TrialSiteCode, u => u.MapFrom(s => s.TrialSite.TrialSiteCode))
|
||||||
.ForMember(d => d.TrialSiteAliasName, u => u.MapFrom(s => s.TrialSite.TrialSiteAliasName))
|
.ForMember(d => d.TrialSiteAliasName, u => u.MapFrom(s => s.TrialSite.TrialSiteAliasName))
|
||||||
.ForMember(d => d.TrialSiteName, u => u.MapFrom(s => s.TrialSite.TrialSiteName))
|
.ForMember(d => d.TrialSiteName, u => u.MapFrom(s => s.TrialSite.TrialSiteName));
|
||||||
;
|
|
||||||
|
CreateMap<SCPImageUpload, SCPImageUploadExportDTO>()
|
||||||
|
.ForMember(d => d.TrialSiteCode, u => u.MapFrom(s => s.TrialSite.TrialSiteCode))
|
||||||
|
.ForMember(d => d.TrialSiteAliasName, u => u.MapFrom(s => s.TrialSite.TrialSiteAliasName))
|
||||||
|
.ForMember(d => d.TrialSiteName, u => u.MapFrom(s => s.TrialSite.TrialSiteName));
|
||||||
|
|
||||||
|
|
||||||
CreateMap<SCPStudy, DicomStudy>();
|
CreateMap<SCPStudy, DicomStudy>();
|
||||||
|
|
|
@ -16,6 +16,7 @@ using Medallion.Threading;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
using MiniExcelLibs;
|
using MiniExcelLibs;
|
||||||
|
@ -126,7 +127,11 @@ namespace IRaCIS.Core.Application.Service
|
||||||
}
|
}
|
||||||
|
|
||||||
//My project is a monolithic project,And the efcore context repository is scoped registered.
|
//My project is a monolithic project,And the efcore context repository is scoped registered.
|
||||||
public async Task<IResponseOutput> TestMasstransitMeditor([FromServices] IScopedMediator _mediator, [FromServices] IRepository<TestLength> _testLengthRepository)
|
public async Task<IResponseOutput> TestMasstransitMeditor(
|
||||||
|
[FromServices] IScopedMediator _mediatorScoped,
|
||||||
|
[FromServices] IMediator _mediator,
|
||||||
|
[FromServices] IRepository<TestLength> _testLengthRepository
|
||||||
|
)
|
||||||
{
|
{
|
||||||
|
|
||||||
var dbContext = _testLengthRepository._dbContext;
|
var dbContext = _testLengthRepository._dbContext;
|
||||||
|
@ -143,12 +148,13 @@ namespace IRaCIS.Core.Application.Service
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// add 1 recored
|
// add 1 recored
|
||||||
await _testLengthRepository.AddAsync(new TestLength() { Name = "xxxx" });
|
await _testLengthRepository.AddAsync(new TestLength() { Name = "xxxx" });
|
||||||
|
|
||||||
// The consumer method will inject the repository and add 3 pieces of data, but the savechanges method of the repository will not be called
|
// The consumer method will inject the repository and add 3 pieces of data, but the savechanges method of the repository will not be called
|
||||||
await _mediator.Send(new AddSubjectTriggerCommand { SubjectId = Guid.Empty });
|
await _mediatorScoped.Send(new AddSubjectTriggerCommand { SubjectId = Guid.Empty });
|
||||||
|
|
||||||
|
await _mediator.Send(new AddSubjectTriggerCommand2 { SubjectId = Guid.Empty });
|
||||||
|
|
||||||
// this will save 1 record not 4 record ,Why is the dbcontext different? Can it be in the same transaction?
|
// this will save 1 record not 4 record ,Why is the dbcontext different? Can it be in the same transaction?
|
||||||
await _testLengthRepository.SaveChangesAsync();
|
await _testLengthRepository.SaveChangesAsync();
|
||||||
|
|
|
@ -14,3 +14,11 @@ public class AddSubjectTriggerCommand : DomainCommand
|
||||||
public Guid TrialSiteId { get; set; }
|
public Guid TrialSiteId { get; set; }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class AddSubjectTriggerCommand2
|
||||||
|
{
|
||||||
|
public Guid SubjectId { get; set; }
|
||||||
|
public Guid TrialId { get; set; }
|
||||||
|
|
||||||
|
public Guid TrialSiteId { get; set; }
|
||||||
|
}
|
||||||
|
|
|
@ -25,6 +25,8 @@
|
||||||
<PackageReference Include="EntityFrameworkCore.Triggered" Version="3.2.2" />
|
<PackageReference Include="EntityFrameworkCore.Triggered" Version="3.2.2" />
|
||||||
<PackageReference Include="EntityFrameworkCore.Projectables" Version="3.0.4" />
|
<PackageReference Include="EntityFrameworkCore.Projectables" Version="3.0.4" />
|
||||||
<PackageReference Include="EntityFrameworkCore.Exceptions.SqlServer" Version="8.1.3" />
|
<PackageReference Include="EntityFrameworkCore.Exceptions.SqlServer" Version="8.1.3" />
|
||||||
|
<PackageReference Include="MassTransit" Version="8.2.5" />
|
||||||
|
<PackageReference Include="MassTransit.EntityFrameworkCore" Version="8.2.5" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Localization.Abstractions" Version="8.0.8" />
|
<PackageReference Include="Microsoft.Extensions.Localization.Abstractions" Version="8.0.8" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="8.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="8.0.0" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="8.0.8" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="8.0.8" />
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using EntityFramework.Exceptions.Common;
|
using EntityFramework.Exceptions.Common;
|
||||||
|
using IRaCIS.Core.Domain.BaseModel;
|
||||||
using IRaCIS.Core.Domain.Models;
|
using IRaCIS.Core.Domain.Models;
|
||||||
using IRaCIS.Core.Domain.Share;
|
using IRaCIS.Core.Domain.Share;
|
||||||
using IRaCIS.Core.Infra.EFCore.Common;
|
using IRaCIS.Core.Infra.EFCore.Common;
|
||||||
|
@ -11,7 +12,12 @@ using System.Data;
|
||||||
|
|
||||||
|
|
||||||
namespace IRaCIS.Core.Infra.EFCore;
|
namespace IRaCIS.Core.Infra.EFCore;
|
||||||
|
/// <summary>
|
||||||
|
/// ef 官方文档 :https://learn.microsoft.com/zh-cn/ef/core/logging-events-diagnostics/interceptors
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="_userInfo"></param>
|
||||||
|
/// <param name="_logger"></param>
|
||||||
|
/// <param name="_mediator"></param>
|
||||||
public class AuditEntityInterceptor(IUserInfo _userInfo,
|
public class AuditEntityInterceptor(IUserInfo _userInfo,
|
||||||
ILogger<AuditEntityInterceptor> _logger
|
ILogger<AuditEntityInterceptor> _logger
|
||||||
, IMediator _mediator
|
, IMediator _mediator
|
||||||
|
@ -28,9 +34,18 @@ public class AuditEntityInterceptor(IUserInfo _userInfo,
|
||||||
public override ValueTask<InterceptionResult<int>> SavingChangesAsync(DbContextEventData eventData,
|
public override ValueTask<InterceptionResult<int>> SavingChangesAsync(DbContextEventData eventData,
|
||||||
InterceptionResult<int> result, CancellationToken cancellationToken = default)
|
InterceptionResult<int> result, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
//////领域命令 (同一个事务提交的一些逻辑,类似Trigger 保存事务之前执行的一些逻辑)
|
//////领域命令 (同一个事务提交的一些逻辑,类似Trigger 保存事务之前执行的一些逻辑) IMediator 和autofac 有冲突,不在一个事务,废弃。
|
||||||
//eventData.Context.AddDomainCommands();
|
//eventData.Context.AddDomainCommands();
|
||||||
//await DispatchDomainCommands(eventData.Context);
|
//await DispatchDomainCommands(eventData.Context);
|
||||||
|
// var domainEvent = JsonSerializer.Deserialize(storedEvent.EventData, Type.GetType(storedEvent.EventType));
|
||||||
|
//// 序列化事件
|
||||||
|
//var eventData = JsonSerializer.Serialize(domainEvent);
|
||||||
|
|
||||||
|
//var storedEvent = new StoredEvent
|
||||||
|
//{
|
||||||
|
// EventType = domainEvent.GetType().Name,
|
||||||
|
// EventData = eventData
|
||||||
|
//};
|
||||||
|
|
||||||
//领域事件
|
//领域事件
|
||||||
eventData.Context.AddDomainEvents();
|
eventData.Context.AddDomainEvents();
|
||||||
|
|
|
@ -1,14 +1,20 @@
|
||||||
using IRaCIS.Core.Domain;
|
using IRaCIS.Core.Domain;
|
||||||
using IRaCIS.Core.Domain.Models;
|
using IRaCIS.Core.Domain.Models;
|
||||||
using MassTransit;
|
using MassTransit;
|
||||||
|
using MassTransit.Mediator;
|
||||||
using Microsoft.EntityFrameworkCore.Diagnostics;
|
using Microsoft.EntityFrameworkCore.Diagnostics;
|
||||||
using System.Data;
|
using System.Data;
|
||||||
|
|
||||||
namespace IRaCIS.Core.Infra.EFCore.Interceptor
|
namespace IRaCIS.Core.Infra.EFCore.Interceptor
|
||||||
{
|
{
|
||||||
// ISendEndpoint:提供了Send方法,用于发送命令。
|
// 命令(Command):是一种定向的消息,应该由一个特定的接收者处理。用 Send 发送。
|
||||||
//IPublishEndpoint:提供了Publish方法,用于发布事件。
|
// 事件(Event):是一种广播式消息,可以有多个订阅者接收并处理。用 Publish 发布。
|
||||||
public class DispatchDomainEventsInterceptor(IPublishEndpoint publishEndpoint) : SaveChangesInterceptor
|
// IPublishEndpoint:提供了Publish方法,用于发布事件,该接口仅负责发布消息,不会依赖于接收者的存在,发布者和消费者可以是完全分离的
|
||||||
|
// IMediator 适用于单进程内的消息传递,不涉及外部消息中间件(如 RabbitMQ、Azure Service Bus 等) 使用本地的内存队列,而不是跨进程消息传递,适合轻量级、无中间件的场景
|
||||||
|
// 发件箱模式参考: https://dev.to/antonmartyniuk/use-masstransit-to-implement-outbox-pattern-with-ef-core-and-mongodb-oep#:~:text=MongoDB%20replica%20set%20is%20required%20for%20both%20publisher%20and%20consumer
|
||||||
|
// 1、IPublishEndpoint 才会将事件存储到发件箱表中, 高级IBus接口时 - 消息不会存储在发件箱中,必须有savechanges 才会一起提交保存到数据库中
|
||||||
|
// 2、进入消息代理之前,发布事件在OutboxState OutboxMessage, 进入消费者以后(已经删除OutboxState OutboxMessage),消费失败,需要修改代码重新发布,然后之前消费事件的重新处理,错误处理参考:https://www.youtube.com/watch?v=3TMKUu7c4lc
|
||||||
|
public class DispatchDomainEventsInterceptor(IMediator _mediator) : SaveChangesInterceptor
|
||||||
{
|
{
|
||||||
|
|
||||||
//领域事件通常与数据变更密切相关。如果在 SaveChanges 之前发布事件,有可能事件发布时的数据状态还没有被持久化到数据库。这可能导致事件消费者看到的是一个不一致的状态
|
//领域事件通常与数据变更密切相关。如果在 SaveChanges 之前发布事件,有可能事件发布时的数据状态还没有被持久化到数据库。这可能导致事件消费者看到的是一个不一致的状态
|
||||||
|
@ -52,7 +58,7 @@ namespace IRaCIS.Core.Infra.EFCore.Interceptor
|
||||||
//这种方式会导致消息没处理
|
//这种方式会导致消息没处理
|
||||||
//await publishEndpoint.Publish(domainEvent);
|
//await publishEndpoint.Publish(domainEvent);
|
||||||
|
|
||||||
await publishEndpoint.Publish(domainEvent.GetType(), domainEvent);
|
await _mediator.Publish(domainEvent.GetType(), domainEvent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,6 @@
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="AutoMapper" Version="13.0.1" />
|
<PackageReference Include="AutoMapper" Version="13.0.1" />
|
||||||
<PackageReference Include="AutoMapper.Collection.EntityFrameworkCore" Version="10.0.0" />
|
<PackageReference Include="AutoMapper.Collection.EntityFrameworkCore" Version="10.0.0" />
|
||||||
<PackageReference Include="MassTransit" Version="8.2.5" />
|
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration" Version="8.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Configuration" Version="8.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Localization.Abstractions" Version="8.0.8" />
|
<PackageReference Include="Microsoft.Extensions.Localization.Abstractions" Version="8.0.8" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||||
|
|
|
@ -252,7 +252,11 @@ public static class StaticData
|
||||||
|
|
||||||
public const string TrialMedicalReviewList_Export = "TrialMedicalReviewList_Export";
|
public const string TrialMedicalReviewList_Export = "TrialMedicalReviewList_Export";
|
||||||
|
|
||||||
|
public static string TrialImageDownloadList_Export = "TrialImageDownloadList_Export";
|
||||||
|
|
||||||
|
public static string TrialSCPImageUploadList_Export = "TrialSCPImageUploadList_Export";
|
||||||
|
|
||||||
|
public static string TrialSCPImageUploadPatientList_Export = "TrialSCPImageUploadPatientList_Export";
|
||||||
|
|
||||||
//public const string TrialRECIST1Point1SelfAnalysisList_Export = "TrialRECIST1Point1SelfAnalysisList_Export";
|
//public const string TrialRECIST1Point1SelfAnalysisList_Export = "TrialRECIST1Point1SelfAnalysisList_Export";
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue