diff --git a/IRC.Core.SCP/appsettings.Prod_IRC_SCP.json b/IRC.Core.SCP/appsettings.Prod_IRC_SCP.json index 6def61882..f204a222f 100644 --- a/IRC.Core.SCP/appsettings.Prod_IRC_SCP.json +++ b/IRC.Core.SCP/appsettings.Prod_IRC_SCP.json @@ -31,10 +31,8 @@ }, "ConnectionStrings": { - //"RemoteNew": "Server=47.117.165.18,1434;Database=Prod_Study;User ID=sa;Password=zhanying@2021;TrustServerCertificate=true", - //"Hangfire": "Server=47.117.165.18,1434;Database=Prod_Study_Hangfire;User ID=sa;Password=zhanying@2021;TrustServerCertificate=true", - "RemoteNew": "Server=prod_mssql_standard,1433;Database=Prod_Study;User ID=sa;Password=zhanying@2021;TrustServerCertificate=true", - "Hangfire": "Server=prod_mssql_standard,1433;Database=Prod_Study_Hangfire;User ID=sa;Password=zhanying@2021;TrustServerCertificate=true" + "RemoteNew": "Server=us-prod-mssql-service,1433;Database=US_IRC;User ID=sa;Password=xc@123456;TrustServerCertificate=true", + "Hangfire": "Server=us-prod-mssql-service,1433;Database=US_IRC_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true" }, "BasicSystemConfig": { diff --git a/IRC.Core.SCP/appsettings.Uat_IRC_SCP.json b/IRC.Core.SCP/appsettings.Uat_IRC_SCP.json index 9079082c4..e293c065a 100644 --- a/IRC.Core.SCP/appsettings.Uat_IRC_SCP.json +++ b/IRC.Core.SCP/appsettings.Uat_IRC_SCP.json @@ -20,16 +20,6 @@ "region": "oss-cn-shanghai" }, - "MinIO": { - "endPoint": "47.117.164.182", - "port": "9001", - "useSSL": false, - "accessKey": "b9Ul0e98xPzt6PwRXA1Q", - "secretKey": "DzMaU2L4OXl90uytwOmDXF2encN0Jf4Nxu2XkYqQ", - "bucketName": "hir-uat", - "viewEndpoint": "http://hir.uat.extimaging.com/oss/hir-uat" - }, - "AWS": { "endPoint": "s3.us-east-1.amazonaws.com", "useSSL": false, @@ -40,8 +30,8 @@ } }, "ConnectionStrings": { - "RemoteNew": "Server=47.117.164.182,1434;Database=Uat_HIR;User ID=sa;Password=xc@123456;TrustServerCertificate=true", - "Hangfire": "Server=47.117.164.182,1434;Database=Uat_HIR_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true" + "RemoteNew": "Server=47.117.164.182,1434;Database=Uat_IRC;User ID=sa;Password=xc@123456;TrustServerCertificate=true", + "Hangfire": "Server=47.117.164.182,1434;Database=Uat_IRC.Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true" }, "BasicSystemConfig": { diff --git a/IRaCIS.Core.API/Controllers/UploadDownLoadController.cs b/IRaCIS.Core.API/Controllers/UploadDownLoadController.cs index aa4d6a673..a59862537 100644 --- a/IRaCIS.Core.API/Controllers/UploadDownLoadController.cs +++ b/IRaCIS.Core.API/Controllers/UploadDownLoadController.cs @@ -10,8 +10,7 @@ using IRaCIS.Core.Application.Contracts.Dicom; using IRaCIS.Core.Application.Contracts.Dicom.DTO; using IRaCIS.Core.Application.Filter; using IRaCIS.Core.Application.Helper; -using IRaCIS.Core.Application.MediatR.CommandAndQueries; -using IRaCIS.Core.Application.MediatR.Handlers; +using IRaCIS.Core.Application.MassTransit.Command; using IRaCIS.Core.Application.Service; using IRaCIS.Core.Application.Service.ImageAndDoc; using IRaCIS.Core.Application.Service.Reading.Dto; @@ -21,7 +20,7 @@ using IRaCIS.Core.Infra.EFCore; using IRaCIS.Core.Infrastructure; using IRaCIS.Core.Infrastructure.Extention; using MassTransit; -using MediatR; +using MassTransit.Mediator; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Cors.Infrastructure; using Microsoft.AspNetCore.Hosting; @@ -232,9 +231,12 @@ namespace IRaCIS.Core.API.Controllers { public IMapper _mapper { get; set; } public IUserInfo _userInfo { get; set; } + + private readonly IMediator _mediator; + public IStringLocalizer _localizer { get; set; } @@ -266,11 +268,6 @@ namespace IRaCIS.Core.API.Controllers [FromServices] IRepository _studyMonitorRepository) { - if (_provider.Get>(StaticData.Anonymize.Anonymize_AddFixedFiled).Value == null) - { - await _mediator.Send(new AnonymizeCacheRequest()); - } - var savedInfo = _studyService.GetSaveToDicomInfo(preArchiveStudyCommand.SubjectVisitId); var studyMonitor = new StudyMonitor() @@ -743,11 +740,16 @@ namespace IRaCIS.Core.API.Controllers //---请保证上传数据符合模板文件中的样式,且存在有效数据。 return ResponseOutput.NotOk(_localizer["UploadDownLoad_InvalidData"]); } - } - await _mediator.Send(new ConsistencyVerificationRequest() { ETCList = etcCheckList, TrialId = trialId }); + + // 适合获取结果的 + //var client = _mediator.CreateRequestClient(); + //await client.GetResponse(new ConsistenCheckCommand() { ETCList = etcCheckList, TrialId = trialId }); + + //不获取结果,不用定义返回类型 + await _mediator.Send(new ConsistenCheckCommand() { ETCList = etcCheckList, TrialId = trialId }); return ResponseOutput.Ok(); @@ -889,89 +891,6 @@ namespace IRaCIS.Core.API.Controllers - #region 废弃 - - /// - /// 下载多个医生的所有附件 - /// - /// - /// - [Obsolete] - [HttpPost, Route("file/downloadDoctorAttachments")] - public async Task> DownloadAttachment(Guid[] doctorIds) - { - - var path = await _fileService.CreateDoctorsAllAttachmentZip(doctorIds); - - return ResponseOutput.Ok(new UploadFileInfoDTO - { - FilePath = path, - FullFilePath = path + "?access_token=" + HttpContext.Request.Headers["Authorization"].ToString().Substring(7) - - }); - } - - /// - /// 下载指定医生的指定附件 - /// - /// 医生Id - /// 要下载的附件Id - /// - [HttpPost, Route("file/downloadByAttachmentId/{doctorId}")] - [Obsolete] - public async Task> DownloadAttachmentById(Guid doctorId, Guid[] attachmentIds) - { - var path = await _fileService.CreateZipPackageByAttachment(doctorId, attachmentIds); - return ResponseOutput.Ok(new UploadFileInfoDTO - { - FilePath = await _fileService.CreateZipPackageByAttachment(doctorId, attachmentIds), - FullFilePath = path + "?access_token=" + HttpContext.Request.Headers["Authorization"].ToString().Substring(7) - }); - } - - - /// - /// 下载医生官方简历 首页 区分 中文和英文 - /// - /// - /// - /// - [HttpPost, Route("file/downloadOfficialCV/{language}")] - [Obsolete] - public async Task> DownloadOfficialResume(int language, Guid[] doctorIds) - { - - var path = await _fileService.CreateDoctorsAllAttachmentZip(doctorIds); - return ResponseOutput.Ok(new UploadFileInfoDTO - { - FilePath = await _fileService.CreateOfficialResumeZip(language, doctorIds), - FullFilePath = path + "?access_token=" + HttpContext.Request.Headers["Authorization"].ToString().Substring(7) - }); - } - - - - - /// - /// 入组 项目下载简历 - /// - /// - /// - /// - /// - [HttpPost, Route("enroll/downloadResume/{trialId:guid}/{language}")] - [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })] - [AllowAnonymous] - [Obsolete] - public async Task> DownloadResume(int language, Guid trialId, Guid[] doctorIdArray) - { - var zipPath = await _fileService.CreateOfficialResumeZip(language, doctorIdArray); - - return ResponseOutput.Ok(zipPath); - } - #endregion - - } #endregion diff --git a/IRaCIS.Core.API/IRaCIS.Core.API.xml b/IRaCIS.Core.API/IRaCIS.Core.API.xml index 726d34a48..d82437315 100644 --- a/IRaCIS.Core.API/IRaCIS.Core.API.xml +++ b/IRaCIS.Core.API/IRaCIS.Core.API.xml @@ -326,38 +326,6 @@ - - - 下载多个医生的所有附件 - - - - - - - 下载指定医生的指定附件 - - 医生Id - 要下载的附件Id - - - - - 下载医生官方简历 首页 区分 中文和英文 - - - - - - - - 入组 项目下载简历 - - - - - - 通用文件下载 diff --git a/IRaCIS.Core.API/Progranm.cs b/IRaCIS.Core.API/Progranm.cs index 64f3f79a7..6ca55a98b 100644 --- a/IRaCIS.Core.API/Progranm.cs +++ b/IRaCIS.Core.API/Progranm.cs @@ -4,8 +4,6 @@ using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Configuration; using Serilog; -using MediatR; -using IRaCIS.Core.Application.MediatR.Handlers; using System.Threading.Tasks; using MassTransit; using MassTransit.NewIdProviders; @@ -33,6 +31,8 @@ using Microsoft.AspNetCore.Http; using IRaCIS.Core.Infrastructure.Extention; using Newtonsoft.Json; using Microsoft.AspNetCore.Diagnostics; +using IRaCIS.Core.Application.MassTransit.Command; +using IRaCIS.Core.Application.MassTransit.Consumer; #region 获取环境变量 @@ -138,7 +138,14 @@ builder.Services.AddSwaggerSetup(); builder.Services.AddJWTAuthSetup(_configuration); // MediatR 进程内消息 事件解耦 从程序集中 注册命令和handler对应关系 -builder.Services.AddMediatR(cfg => cfg.RegisterServicesFromAssemblyContaining()); +//builder.Services.AddMediatR(cfg => cfg.RegisterServicesFromAssemblyContaining()); + +//masstransit组件 也支持MediatR 中介者模式,但是支持分布式,考虑后续,所以在次替代MediatR +builder.Services.AddMediator(cfg => +{ + cfg.AddConsumer(); +}); + // EasyCaching 缓存 builder.Services.AddEasyCachingSetup(_configuration); diff --git a/IRaCIS.Core.API/_ServiceExtensions/AutofacModuleSetup.cs b/IRaCIS.Core.API/_ServiceExtensions/AutofacModuleSetup.cs index 3806353b2..cc0e50dc5 100644 --- a/IRaCIS.Core.API/_ServiceExtensions/AutofacModuleSetup.cs +++ b/IRaCIS.Core.API/_ServiceExtensions/AutofacModuleSetup.cs @@ -10,7 +10,6 @@ using System.Linq; using System.Reflection; using IRaCIS.Core.Domain.Models; using IRaCIS.Core.Domain.Share; -using MediatR; using IRaCIS.Application.Services; using IRaCIS.Application.Interfaces; using AutoMapper; diff --git a/IRaCIS.Core.Application/IRaCIS.Core.Application.csproj b/IRaCIS.Core.Application/IRaCIS.Core.Application.csproj index ab00314fc..4a29c0a3b 100644 --- a/IRaCIS.Core.Application/IRaCIS.Core.Application.csproj +++ b/IRaCIS.Core.Application/IRaCIS.Core.Application.csproj @@ -74,7 +74,6 @@ - @@ -86,7 +85,7 @@ - + diff --git a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml index 3aa7acb09..1a4367aee 100644 --- a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml +++ b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml @@ -9911,6 +9911,11 @@ TrialSiteDicomAEService + + + 构造函数注入 + + TaskAllocationRuleView 列表视图模型 @@ -13308,21 +13313,6 @@ 维护 IsFrontTaskNeedSignButNotSign 字段 另外附加评估结果 - - - 构造函数注入 - - - - - 构造函数注入 - - - - - 构造函数注入 - - 缓存项目状态 diff --git a/IRaCIS.Core.Application/MassTransit/Command/ConsistenCheckCommand.cs b/IRaCIS.Core.Application/MassTransit/Command/ConsistenCheckCommand.cs new file mode 100644 index 000000000..6b24a12c2 --- /dev/null +++ b/IRaCIS.Core.Application/MassTransit/Command/ConsistenCheckCommand.cs @@ -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 ETCList { get; set; } = new List(); + + 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(); + } + } + + + +} diff --git a/IRaCIS.Core.Application/_MediatR/Handlers/ConsistencyVerificationHandler.cs b/IRaCIS.Core.Application/MassTransit/Consumer/ConsistencyCheckConsumer.cs similarity index 93% rename from IRaCIS.Core.Application/_MediatR/Handlers/ConsistencyVerificationHandler.cs rename to IRaCIS.Core.Application/MassTransit/Consumer/ConsistencyCheckConsumer.cs index 975656660..5cf6ff049 100644 --- a/IRaCIS.Core.Application/_MediatR/Handlers/ConsistencyVerificationHandler.cs +++ b/IRaCIS.Core.Application/MassTransit/Consumer/ConsistencyCheckConsumer.cs @@ -1,16 +1,22 @@ 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 MassTransit; +using Microsoft.Extensions.Localization; using Newtonsoft.Json; -using MediatR; +using System; +using System.Collections.Generic; +using System.Linq; using System.Linq.Expressions; 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 + public class ConsistencyCheckConsumer : IConsumer { + private readonly IRepository _studyRepository; private readonly IUserInfo _userInfo; private readonly IRepository _subjectRepository; @@ -24,7 +30,7 @@ namespace IRaCIS.Core.Application.MediatR.Handlers /// 构造函数注入 /// - public ConsistencyVerificationHandler(IRepository studyRepository, IUserInfo userInfo, + public ConsistencyCheckConsumer(IRepository studyRepository, IUserInfo userInfo, IRepository subjectRepository, IRepository subjectVisitRepository, IRepository trialSiteRepository, IRepository noneDicomStudyRepository, IMapper mapper, IStringLocalizer localizer) @@ -39,19 +45,22 @@ namespace IRaCIS.Core.Application.MediatR.Handlers _localizer = localizer; } - async Task IRequestHandler.Handle(ConsistencyVerificationRequest request, CancellationToken cancellationToken) + + + public async Task Consume(ConsumeContext context) { - var trialId = request.TrialId; + + var trialId = context.Message.TrialId; //处理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(); }); - var etcList = request.ETCList; + 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 = context.Message.ETCList; //Expression> 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)); - Expression> subjectVisitLambda = x => x.TrialId == request.TrialId && + Expression> subjectVisitLambda = x => x.TrialId == trialId && (x.CheckState == CheckStateEnum.ToCheck && x.AuditState == AuditStateEnum.QCPassed || (x.CheckState == CheckStateEnum.CVIng && x.AuditState == AuditStateEnum.QCPassed)); var dicomQuery = from sv in _subjectVisitRepository.Where(subjectVisitLambda) @@ -190,7 +199,7 @@ namespace IRaCIS.Core.Application.MediatR.Handlers dbSV.CheckUserId = _userInfo.Id; dbSV.CheckPassedTime = DateTime.Now; dbSV.CheckChallengeState = CheckChanllengeTypeEnum.Closed; - + //---核对EDC数据,完全一致 dbSV.CheckResult = _localizer["ConsistencyVerification_EDCB"]; //---自动核查通过 @@ -274,11 +283,13 @@ namespace IRaCIS.Core.Application.MediatR.Handlers } await _subjectVisitRepository.SaveChangesAsync(); - return "OK"; + //await context.RespondAsync(new + //{ + + //}); } + } - - } diff --git a/IRaCIS.Core.Application/Service/ImageAndDoc/StudyService.cs b/IRaCIS.Core.Application/Service/ImageAndDoc/StudyService.cs index cdd161e9b..6a824473d 100644 --- a/IRaCIS.Core.Application/Service/ImageAndDoc/StudyService.cs +++ b/IRaCIS.Core.Application/Service/ImageAndDoc/StudyService.cs @@ -10,7 +10,6 @@ using IRaCIS.Core.Infrastructure; using DocumentFormat.OpenXml.Presentation; using IRaCIS.Core.Domain.Models; using IRaCIS.Core.Application.Filter; -using IRaCIS.Core.Application.MediatR.Handlers; using Microsoft.AspNetCore.Http; using Newtonsoft.Json; using System.Threading; diff --git a/IRaCIS.Core.Application/Service/ImageAndDoc/SystemAnonymizationService.cs b/IRaCIS.Core.Application/Service/ImageAndDoc/SystemAnonymizationService.cs index 791f5e997..a2c4d82bf 100644 --- a/IRaCIS.Core.Application/Service/ImageAndDoc/SystemAnonymizationService.cs +++ b/IRaCIS.Core.Application/Service/ImageAndDoc/SystemAnonymizationService.cs @@ -5,10 +5,8 @@ //-------------------------------------------------------------------- using IRaCIS.Core.Application.Interfaces; -using IRaCIS.Core.Application.MediatR.Handlers; using IRaCIS.Core.Application.ViewModel; using IRaCIS.Core.Infra.EFCore; -using MediatR; using Microsoft.AspNetCore.Mvc; namespace IRaCIS.Core.Application.Service { @@ -18,12 +16,10 @@ namespace IRaCIS.Core.Application.Service [ApiExplorerSettings(GroupName = "Image")] public class SystemAnonymizationService : BaseService, ISystemAnonymizationService { - private readonly IMediator _mediator; private readonly IRepository systemAnonymizationRepository; - public SystemAnonymizationService(IMediator mediator, IRepository systemAnonymizationRepository) + public SystemAnonymizationService( IRepository systemAnonymizationRepository) { - _mediator = mediator; this.systemAnonymizationRepository = systemAnonymizationRepository; } @@ -47,7 +43,6 @@ namespace IRaCIS.Core.Application.Service var entity = await _repository.InsertOrUpdateAsync(addOrEditSystemAnonymization, true); - await _mediator.Send(new AnonymizeCacheRequest()); return ResponseOutput.Ok(entity.Id.ToString()); diff --git a/IRaCIS.Core.Application/Service/QC/DTO/QARecordViewModel.cs b/IRaCIS.Core.Application/Service/QC/DTO/QARecordViewModel.cs index 5bd23bee9..1ea08ae56 100644 --- a/IRaCIS.Core.Application/Service/QC/DTO/QARecordViewModel.cs +++ b/IRaCIS.Core.Application/Service/QC/DTO/QARecordViewModel.cs @@ -1,5 +1,4 @@ using IRaCIS.Application.Contracts; -using IRaCIS.Core.Application.MediatR.CommandAndQueries; using IRaCIS.Core.Domain.Share; 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 diff --git a/IRaCIS.Core.Application/Service/QC/DTO/QCListViewModel.cs b/IRaCIS.Core.Application/Service/QC/DTO/QCListViewModel.cs index c06c05c5f..ceb1e0de1 100644 --- a/IRaCIS.Core.Application/Service/QC/DTO/QCListViewModel.cs +++ b/IRaCIS.Core.Application/Service/QC/DTO/QCListViewModel.cs @@ -310,7 +310,7 @@ namespace IRaCIS.Core.Application.Contracts { if (!ClosedTime.HasValue) return ""; - else return string.Format("{0}d {1}h {2}min", (ClosedTime - CreateTime)?.Days, (ClosedTime - CreateTime)?.Hours, (ClosedTime - CreateTime)?.Minutes); + else return string.Format("{0}d {1}h {2}m", (ClosedTime - CreateTime)?.Days, (ClosedTime - CreateTime)?.Hours, (ClosedTime - CreateTime)?.Minutes); } } diff --git a/IRaCIS.Core.Application/Service/QC/Interface/IQCOperationService.cs b/IRaCIS.Core.Application/Service/QC/Interface/IQCOperationService.cs index ad9244d10..f76c8cedb 100644 --- a/IRaCIS.Core.Application/Service/QC/Interface/IQCOperationService.cs +++ b/IRaCIS.Core.Application/Service/QC/Interface/IQCOperationService.cs @@ -2,7 +2,6 @@ using IRaCIS.Core.Application.Contracts.DTO; using IRaCIS.Core.Application.Service.Inspection.DTO; using IRaCIS.Core.Domain.Share; -using MediatR; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; @@ -40,6 +39,6 @@ namespace IRaCIS.Core.Application.Image.QA Task VerifyCanQCPassedOrFailed(Guid subjectVisitId); - Task ForwardSVDicomImage(Guid[] subjectVisitIdList); + //Task ForwardSVDicomImage(Guid[] subjectVisitIdList); } } \ No newline at end of file diff --git a/IRaCIS.Core.Application/Service/QC/QCOperationService.cs b/IRaCIS.Core.Application/Service/QC/QCOperationService.cs index 3bccf5c80..515d153be 100644 --- a/IRaCIS.Core.Application/Service/QC/QCOperationService.cs +++ b/IRaCIS.Core.Application/Service/QC/QCOperationService.cs @@ -2,11 +2,9 @@ using IRaCIS.Core.Application.Contracts.DTO; using IRaCIS.Core.Application.Filter; using IRaCIS.Core.Domain.Share; -using MediatR; using Microsoft.AspNetCore.Mvc; using System.Data; using Microsoft.AspNetCore.Authorization; -using WinSCP; using Newtonsoft.Json; using IRaCIS.Core.Infrastructure; 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 ForwardSVDicomImage(Guid[] subjectVisitIdList) + //{ - [HttpPost("{trialId:guid}")] - //[Authorize(Policy = IRaCISPolicy.PM_APM)] - [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })] - public async Task ForwardSVDicomImage(Guid[] subjectVisitIdList) - { - - bool isSuccess = false; + // bool isSuccess = false; - foreach (var subjectVisitId in subjectVisitIdList) - { + // foreach (var subjectVisitId in subjectVisitIdList) + // { - var info = (await _subjectVisitRepository.Where(t => t.Id == subjectVisitId).ProjectTo(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException(); + // var info = (await _subjectVisitRepository.Where(t => t.Id == subjectVisitId).ProjectTo(_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 - { - // 主机及端口信息后面可以改到 配置文件 - SessionOptions sessionOptions = new SessionOptions - { - Protocol = Protocol.Sftp, - PortNumber = 8022, - HostName = "CS-690-sftp.mint-imaging.com", - UserName = "zdong", - Password = "Everest@2021", - SshHostKeyFingerprint = @"ecdsa-sha2-nistp384 384 59gkjJ5lMwv3jsB8Wz2B35tBAIor5pSd8PcJYtoamPo=" - }; + // try + // { + // // 主机及端口信息后面可以改到 配置文件 + // SessionOptions sessionOptions = new SessionOptions + // { + // Protocol = Protocol.Sftp, + // PortNumber = 8022, + // HostName = "CS-690-sftp.mint-imaging.com", + // UserName = "zdong", + // Password = "Everest@2021", + // SshHostKeyFingerprint = @"ecdsa-sha2-nistp384 384 59gkjJ5lMwv3jsB8Wz2B35tBAIor5pSd8PcJYtoamPo=" + // }; - using (Session session = new Session()) - { - var studyFolders = (new DirectoryInfo(path)).GetDirectories(); + // using (Session session = new Session()) + // { + // var studyFolders = (new DirectoryInfo(path)).GetDirectories(); - session.Open(sessionOptions); + // session.Open(sessionOptions); - if (!session.FileExists(targetPath)) - { - session.CreateDirectory(targetPath); - } + // if (!session.FileExists(targetPath)) + // { + // session.CreateDirectory(targetPath); + // } - foreach (var studyFolder in studyFolders) - { - var targetFolder = Path.Combine(targetPath, studyFolder.Name); + // foreach (var studyFolder in studyFolders) + // { + // var targetFolder = Path.Combine(targetPath, studyFolder.Name); - if (!session.FileExists(targetFolder)) - { - session.CreateDirectory(targetFolder); - } + // if (!session.FileExists(targetFolder)) + // { + // session.CreateDirectory(targetFolder); + // } - foreach (var file in studyFolder.GetFiles()) - { - if (file.Extension.Contains("dcm", StringComparison.OrdinalIgnoreCase)) - { - string remoteFilePath = - RemotePath.TranslateLocalPathToRemote(file.FullName, studyFolder.FullName, targetFolder); + // foreach (var file in studyFolder.GetFiles()) + // { + // if (file.Extension.Contains("dcm", StringComparison.OrdinalIgnoreCase)) + // { + // string remoteFilePath = + // 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) - { - await _subjectVisitRepository.BatchUpdateNoTrackingAsync(t => t.Id == subjectVisitId, - u => new SubjectVisit() { ForwardState = ForwardStateEnum.ForwardFailed }); + // if (!result.IsSuccess) + // { + // await _subjectVisitRepository.BatchUpdateNoTrackingAsync(t => t.Id == subjectVisitId, + // 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, - u => new SubjectVisit() { ForwardState = ForwardStateEnum.Forwarded, ForwardUserId = _userInfo.Id, ForwardTime = DateTime.Now }); + // } + // await _subjectVisitRepository.UpdatePartialFromQueryAsync(t => t.Id == subjectVisitId, + // 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, - u => new SubjectVisit() { ForwardState = ForwardStateEnum.ForwardFailed }); + // await _subjectVisitRepository.UpdatePartialFromQueryAsync(t => t.Id == subjectVisitId, + // 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"]); - } diff --git a/IRaCIS.Core.Application/Service/QC/_MapConfig.cs b/IRaCIS.Core.Application/Service/QC/_MapConfig.cs index b1bfd53c1..292e159cb 100644 --- a/IRaCIS.Core.Application/Service/QC/_MapConfig.cs +++ b/IRaCIS.Core.Application/Service/QC/_MapConfig.cs @@ -3,7 +3,7 @@ using AutoMapper.EquivalencyExpression; using IRaCIS.Application.Contracts; using IRaCIS.Core.Application.Contracts; using IRaCIS.Core.Application.Contracts.DTO; -using IRaCIS.Core.Application.MediatR.CommandAndQueries; +using IRaCIS.Core.Application.MassTransit.Command; using IRaCIS.Core.Domain.Share; using static IRaCIS.Core.Application.Contracts.SubjectProgressDto; diff --git a/IRaCIS.Core.Application/Service/TrialSiteUser/TrialDicomAEService.cs b/IRaCIS.Core.Application/Service/TrialSiteUser/TrialDicomAEService.cs index 9c59315b4..b1a455ff6 100644 --- a/IRaCIS.Core.Application/Service/TrialSiteUser/TrialDicomAEService.cs +++ b/IRaCIS.Core.Application/Service/TrialSiteUser/TrialDicomAEService.cs @@ -46,7 +46,7 @@ namespace IRaCIS.Core.Application.Service - var pageList = await dicomAEQueryable.ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, inQuery.SortField == string.Empty ? nameof(DicomAEView.CalledAE) : inQuery.SortField, inQuery.Asc); + var pageList = await dicomAEQueryable.ToPagedListAsync(inQuery); return ResponseOutput.Ok(pageList); diff --git a/IRaCIS.Core.Application/Service/TrialSiteUser/TrialService.cs b/IRaCIS.Core.Application/Service/TrialSiteUser/TrialService.cs index 9886bc91f..190511173 100644 --- a/IRaCIS.Core.Application/Service/TrialSiteUser/TrialService.cs +++ b/IRaCIS.Core.Application/Service/TrialSiteUser/TrialService.cs @@ -69,7 +69,7 @@ namespace IRaCIS.Application.Services } - var query = _trialRepository.AsQueryable().IgnoreQueryFilters() + var query = _trialRepository.AsQueryable() .WhereIf(!string.IsNullOrEmpty(searchParam.TrialStatusStr), o => o.TrialStatusStr.Contains(searchParam.TrialStatusStr)) .WhereIf(searchParam.SponsorId != null, o => o.SponsorId == searchParam.SponsorId) .WhereIf(searchParam.Expedited != null, o => o.Expedited == searchParam.Expedited) @@ -103,7 +103,7 @@ namespace IRaCIS.Application.Services //过滤废除的项目 public async Task> GetTrialSelect() { - return await _trialRepository.AsQueryable().IgnoreQueryFilters() + return await _trialRepository.AsQueryable() .WhereIf(_userInfo.UserTypeEnumInt != (int)UserTypeEnum.SuperAdmin && _userInfo.UserTypeEnumInt != (int)UserTypeEnum.Admin && _userInfo.UserTypeEnumInt != (int)UserTypeEnum.OP, t => t.TrialUserList.Any(t => t.UserId == _userInfo.Id) && t.IsDeleted == false) .ProjectTo(_mapper.ConfigurationProvider).ToListAsync(); @@ -119,7 +119,7 @@ namespace IRaCIS.Application.Services [HttpGet("{projectId:guid}")] public async Task GetTrialInfoAndLockState(Guid projectId) { - return (await _trialRepository.Where(o => o.Id == projectId).IgnoreQueryFilters().ProjectTo(_mapper.ConfigurationProvider, new {isEn_Us = _userInfo.IsEn_Us }).FirstOrDefaultAsync()).IfNullThrowException(); + return (await _trialRepository.Where(o => o.Id == projectId).ProjectTo(_mapper.ConfigurationProvider, new {isEn_Us = _userInfo.IsEn_Us }).FirstOrDefaultAsync()).IfNullThrowException(); } diff --git a/IRaCIS.Core.Application/Service/Visit/DTO/VisitPlanViewModel.cs b/IRaCIS.Core.Application/Service/Visit/DTO/VisitPlanViewModel.cs index 0742b40aa..b30eea9a4 100644 --- a/IRaCIS.Core.Application/Service/Visit/DTO/VisitPlanViewModel.cs +++ b/IRaCIS.Core.Application/Service/Visit/DTO/VisitPlanViewModel.cs @@ -1,4 +1,5 @@ using IRaCIS.Core.Infrastructure.Extention; +using MiniExcelLibs.Attributes; using System.ComponentModel.DataAnnotations; namespace IRaCIS.Application.Contracts @@ -103,5 +104,53 @@ namespace IRaCIS.Application.Contracts 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; } + } + + } diff --git a/IRaCIS.Core.Application/Service/Visit/VisitPlanService.cs b/IRaCIS.Core.Application/Service/Visit/VisitPlanService.cs index 29164fa24..28e7f55df 100644 --- a/IRaCIS.Core.Application/Service/Visit/VisitPlanService.cs +++ b/IRaCIS.Core.Application/Service/Visit/VisitPlanService.cs @@ -3,7 +3,6 @@ using IRaCIS.Application.Contracts; using IRaCIS.Core.Application.Filter; using Microsoft.AspNetCore.Mvc; using IRaCIS.Core.Domain.Share; -using IRaCIS.Core.Application.MediatR.CommandAndQueries; using IRaCIS.Core.Infrastructure; using Microsoft.AspNetCore.Authorization; using IRaCIS.Core.Application.Auth; diff --git a/IRaCIS.Core.Application/Service/Visit/_MapConfig.cs b/IRaCIS.Core.Application/Service/Visit/_MapConfig.cs index 9909f3eba..3d9d002e6 100644 --- a/IRaCIS.Core.Application/Service/Visit/_MapConfig.cs +++ b/IRaCIS.Core.Application/Service/Visit/_MapConfig.cs @@ -2,7 +2,6 @@ using IRaCIS.Application.Contracts; using IRaCIS.Core.Application.Contracts; using IRaCIS.Core.Application.Contracts.Dicom.DTO; -using IRaCIS.Core.Application.MediatR.CommandAndQueries; using IRaCIS.Core.Domain.Share; namespace IRaCIS.Core.Application.Service diff --git a/IRaCIS.Core.Application/_MediatR/CommandAndQueries/ConsistencyVerificationRequest.cs b/IRaCIS.Core.Application/_MediatR/CommandAndQueries/ConsistencyVerificationRequest.cs deleted file mode 100644 index 3bb3656d0..000000000 --- a/IRaCIS.Core.Application/_MediatR/CommandAndQueries/ConsistencyVerificationRequest.cs +++ /dev/null @@ -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 - { - public List ETCList { get; set; } = new List(); - - 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 Filter(ImportResult importResult) where T : class, new() - // { - // if (typeof(T).IsAssignableFrom(typeof(CheckViewModel))) - // { - // var data = (List)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 { { 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; } - } - -} diff --git a/IRaCIS.Core.Application/_MediatR/Handlers/AnonymizeCacheHandler.cs b/IRaCIS.Core.Application/_MediatR/Handlers/AnonymizeCacheHandler.cs deleted file mode 100644 index 6fb08a741..000000000 --- a/IRaCIS.Core.Application/_MediatR/Handlers/AnonymizeCacheHandler.cs +++ /dev/null @@ -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 - { - - } - public class AnonymizeCacheHandler : IRequestHandler - { - private readonly IRepository _repository; - - private readonly IEasyCachingProvider _provider; - - /// - /// 构造函数注入 - /// - public AnonymizeCacheHandler(IRepository repository, IEasyCachingProvider provider) - { - _repository = repository; - - _provider = provider; - } - - - public Task Handle(AnonymizeCacheRequest request, CancellationToken cancellationToken) - { - var systemAnonymizationList = _repository.Where(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); - } - } - - -} diff --git a/IRaCIS.Core.Application/_MediatR/Handlers/TrialStateCacheHandler.cs b/IRaCIS.Core.Application/_MediatR/Handlers/TrialStateCacheHandler.cs deleted file mode 100644 index 0f011158c..000000000 --- a/IRaCIS.Core.Application/_MediatR/Handlers/TrialStateCacheHandler.cs +++ /dev/null @@ -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 - { - - } - public class TrialStateCacheHandler : IRequestHandler - { - private readonly IRepository _trialRepository; - - private readonly IEasyCachingProvider _provider; - - /// - /// 构造函数注入 - /// - public TrialStateCacheHandler(IRepository trialRepository, IEasyCachingProvider provider) - { - _trialRepository = trialRepository; - - _provider = provider; - - } - - - public async Task 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; - } - } - - -} diff --git a/IRaCIS.Core.Domain/BaseModel/DomainEvent.cs b/IRaCIS.Core.Domain/BaseModel/DomainEvent.cs new file mode 100644 index 000000000..f645ebf3e --- /dev/null +++ b/IRaCIS.Core.Domain/BaseModel/DomainEvent.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace IRaCIS.Core.Domain.BaseModel +{ + /// + /// 领域实体事件基类 + /// + public abstract class DomainEvent + { + + } + + public class FailedDomainEvent + { + public Guid Id { get; set; } + public string EventType { get; set; } + public string EventData { get; set; } + public DateTime FailedAt { get; set; } + } +} diff --git a/IRaCIS.Core.Domain/BaseModel/Entity.cs b/IRaCIS.Core.Domain/BaseModel/Entity.cs index 8482a17d4..af38e8fd2 100644 --- a/IRaCIS.Core.Domain/BaseModel/Entity.cs +++ b/IRaCIS.Core.Domain/BaseModel/Entity.cs @@ -1,21 +1,59 @@ -using System; +using IRaCIS.Core.Domain.BaseModel; +using System; +using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; +using System.Security.Cryptography; namespace IRaCIS.Core.Domain.Models { + + + public interface IAggregateRoot; + public interface IEntity + { + abstract TKey Id { get; set; } + + } + public abstract class Entity : IEntity { [Key] [Required] [DatabaseGenerated(DatabaseGeneratedOption.None)] public Guid Id { get; set; } + + + #region 领域事件 仅仅允许通过提供的方法进行操作 + + //[NotMapped] + //private readonly List _domainEvents = []; + + //[NotMapped] + //public IReadOnlyCollection DomainEvents => _domainEvents.AsReadOnly(); + + + //public void AddDomainEvent(DomainEvent domainEvent) + //{ + // _domainEvents.Add(domainEvent); + //} + + //public void RemoveDomainEvent(DomainEvent domainEvent) + //{ + // _domainEvents.Remove(domainEvent); + //} + + //public void ClearDomainEvents() + //{ + // _domainEvents.Clear(); + //} + #endregion + + } - public interface IEntity - { - abstract TKey Id { get; set; } - } + + #region 减少实体属性,增加基类 diff --git a/IRaCIS.Core.Infra.EFCore/IRaCIS.Core.Infra.EFCore.csproj b/IRaCIS.Core.Infra.EFCore/IRaCIS.Core.Infra.EFCore.csproj index 9b2ef5d9c..bbedc4058 100644 --- a/IRaCIS.Core.Infra.EFCore/IRaCIS.Core.Infra.EFCore.csproj +++ b/IRaCIS.Core.Infra.EFCore/IRaCIS.Core.Infra.EFCore.csproj @@ -25,7 +25,6 @@ - diff --git a/IRaCIS.Core.Infra.EFCore/Interceptor/AuditEntityInterceptor.cs b/IRaCIS.Core.Infra.EFCore/Interceptor/AuditEntityInterceptor.cs index b2f99decd..b8235e0e8 100644 --- a/IRaCIS.Core.Infra.EFCore/Interceptor/AuditEntityInterceptor.cs +++ b/IRaCIS.Core.Infra.EFCore/Interceptor/AuditEntityInterceptor.cs @@ -12,13 +12,14 @@ namespace IRaCIS.Core.Infra.EFCore; public class AuditEntityInterceptor(IUserInfo _userInfo) : SaveChangesInterceptor { - public override InterceptionResult SavingChanges(DbContextEventData eventData, InterceptionResult result) - { - AuditEntities(eventData.Context); - - return base.SavingChanges(eventData, result); - } + /// + /// 在事务提交之前执行 + /// + /// + /// + /// + /// public override ValueTask> SavingChangesAsync(DbContextEventData eventData, InterceptionResult result, CancellationToken cancellationToken = default) { @@ -26,7 +27,12 @@ public class AuditEntityInterceptor(IUserInfo _userInfo) : SaveChangesIntercepto return base.SavingChangesAsync(eventData, result, cancellationToken); } + public override InterceptionResult SavingChanges(DbContextEventData eventData, InterceptionResult result) + { + AuditEntities(eventData.Context); + return base.SavingChanges(eventData, result); + } public void AuditEntities(DbContext? context) { if (context == null) return; diff --git a/IRaCIS.Core.Infra.EFCore/Interceptor/DispatchDomainEventsInterceptor.cs b/IRaCIS.Core.Infra.EFCore/Interceptor/DispatchDomainEventsInterceptor.cs new file mode 100644 index 000000000..87ce315a5 --- /dev/null +++ b/IRaCIS.Core.Infra.EFCore/Interceptor/DispatchDomainEventsInterceptor.cs @@ -0,0 +1,59 @@ +//using Microsoft.EntityFrameworkCore.Diagnostics; +//using Microsoft.EntityFrameworkCore; +//using System; +//using System.Collections.Generic; +//using System.Linq; +//using System.Text; +//using System.Threading; +//using System.Threading.Tasks; +//using IRaCIS.Core.Domain.Models; +//using MassTransit; + +//namespace IRaCIS.Core.Infra.EFCore.Interceptor +//{ +// public class DispatchDomainEventsInterceptor(IPublishEndpoint publishEndpoint) : SaveChangesInterceptor +// { + +// //领域事件通常与数据变更密切相关。如果在 SaveChanges 之前发布事件,有可能事件发布时的数据状态还没有被持久化到数据库。这可能导致事件消费者看到的是一个不一致的状态 + +// /// +// /// 在事务提交之后分发事件 +// /// +// /// +// /// +// /// +// /// +// public override async ValueTask SavedChangesAsync(SaveChangesCompletedEventData eventData, int result, +// CancellationToken cancellationToken = default) +// { +// await DispatchDomainEvents(eventData.Context); +// return await base.SavedChangesAsync(eventData, result, cancellationToken); +// } +// public override int SavedChanges(SaveChangesCompletedEventData eventData, int result) +// { +// DispatchDomainEvents(eventData.Context).GetAwaiter().GetResult(); +// return base.SavedChanges(eventData, result); +// } +// private async Task DispatchDomainEvents(DbContext? context) +// { +// if (context == null) return; + +// var entities = context.ChangeTracker +// .Entries() +// .Where(e => e.Entity.DomainEvents.Any()) +// .Select(e => e.Entity) +// .ToList(); + +// var domainEvents = entities +// .SelectMany(e => e.DomainEvents) +// .ToList(); + +// entities.ForEach(e => e.ClearDomainEvents()); + +// foreach (var domainEvent in domainEvents) +// { +// await publishEndpoint.Publish(domainEvent); +// } +// } +// } +//} diff --git a/IRaCIS.Core.Infrastructure/IRaCIS.Core.Infrastructure.csproj b/IRaCIS.Core.Infrastructure/IRaCIS.Core.Infrastructure.csproj index 324ac91a0..39d3b1d66 100644 --- a/IRaCIS.Core.Infrastructure/IRaCIS.Core.Infrastructure.csproj +++ b/IRaCIS.Core.Infrastructure/IRaCIS.Core.Infrastructure.csproj @@ -11,6 +11,7 @@ + diff --git a/IRaCIS.Core.Test/TT_Template/IRaCIS .Core.ServiceAsync.tt b/IRaCIS.Core.Test/TT_Template/IRaCIS .Core.ServiceAsync.tt index 4fcd115d0..ed77f287c 100644 --- a/IRaCIS.Core.Test/TT_Template/IRaCIS .Core.ServiceAsync.tt +++ b/IRaCIS.Core.Test/TT_Template/IRaCIS .Core.ServiceAsync.tt @@ -74,7 +74,7 @@ namespace IRaCIS.Core.Application.Service _<#=char.ToLower(tableName[0]) + tableName.Substring(1)#>Repository .ProjectTo<<#=tableName#>View>(_mapper.ConfigurationProvider); - var pageList= await <#=char.ToLower(tableName[0]) + tableName.Substring(1)#>Queryable.ToPagedListAsync(<#=tableName#>Query); + var pageList= await <#=char.ToLower(tableName[0]) + tableName.Substring(1)#>Queryable.ToPagedListAsync(inQuery); return pageList; }