diff --git a/IRaCIS.Core.API/Controllers/UploadDownLoadController.cs b/IRaCIS.Core.API/Controllers/UploadDownLoadController.cs index c1090ca..f98352d 100644 --- a/IRaCIS.Core.API/Controllers/UploadDownLoadController.cs +++ b/IRaCIS.Core.API/Controllers/UploadDownLoadController.cs @@ -2,8 +2,10 @@ using DocumentFormat.OpenXml.Drawing; using EasyCaching.Core; using ExcelDataReader; +using Hangfire; using IRaCIS.Application.Contracts; using IRaCIS.Application.Interfaces; +using IRaCIS.Application.Services.BackGroundJob; using IRaCIS.Core.Application.Auth; using IRaCIS.Core.Application.Contracts; using IRaCIS.Core.Application.Contracts.Dicom; @@ -424,7 +426,12 @@ namespace IRaCIS.Core.API.Controllers } - + /// + /// 创建zip包 + /// + /// + /// + /// [HttpPost, Route("Study/CreateImageZip")] public async Task CreateImageZipAsync(Guid visitTaskId, [FromServices] IHubContext _uploadHub) { @@ -452,22 +459,17 @@ namespace IRaCIS.Core.API.Controllers var relativePath = $"/{StaticData.Folder.IRaCISDataFolder}/{StaticData.Folder.TempFileFolder}/{zipFileName}"; - - await Task.Run(async () => - { - ZipFile.CreateFromDirectory(folderPath, zipFilePath); - await _repository.BatchUpdateAsync(t => t.Id == visitTaskId, u => new VisitTask() { PackState = PackState.Packed, PackRelativePath = relativePath }); - - }); - - - // 发送最终进度信息到客户端 - //await _uploadHub.Clients.User(_userInfo.Id.ToString()).CompressProgressAsync(visitTaskId, $"打包完成"); + BackgroundJob.Schedule(t => t.CreateImageZipTask(folderPath,zipFilePath,relativePath, visitTaskId), TimeSpan.FromSeconds(1)); return ResponseOutput.Ok(relativePath); } + /// + /// 下载压缩包 + /// + /// + /// [AllowAnonymous] [HttpGet("Study/DownloadImageZip")] public IActionResult DownloadImageZip(string relativePath) diff --git a/IRaCIS.Core.API/IRaCIS.Core.API.csproj b/IRaCIS.Core.API/IRaCIS.Core.API.csproj index 52062b3..b8b4d5f 100644 --- a/IRaCIS.Core.API/IRaCIS.Core.API.csproj +++ b/IRaCIS.Core.API/IRaCIS.Core.API.csproj @@ -1,5 +1,4 @@  - net6.0 false @@ -110,7 +109,8 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + + diff --git a/IRaCIS.Core.API/IRaCIS.Core.API.xml b/IRaCIS.Core.API/IRaCIS.Core.API.xml index 93e1867..036a355 100644 --- a/IRaCIS.Core.API/IRaCIS.Core.API.xml +++ b/IRaCIS.Core.API/IRaCIS.Core.API.xml @@ -229,6 +229,21 @@ Dicom 归档 + + + 创建zip包 + + + + + + + + 下载压缩包 + + + + 上传临床数据 多文件 diff --git a/IRaCIS.Core.API/Startup.cs b/IRaCIS.Core.API/Startup.cs index b086a99..9130032 100644 --- a/IRaCIS.Core.API/Startup.cs +++ b/IRaCIS.Core.API/Startup.cs @@ -84,8 +84,6 @@ namespace IRaCIS.Core.API options.Filters.Add(); } - - }) .AddNewtonsoftJsonSetup(); // NewtonsoftJson л @@ -115,7 +113,7 @@ namespace IRaCIS.Core.API //services.AddDistributedMemoryCache(); // hangfire ʱ н棬Ѻ~ - //services.AddhangfireSetup(_configuration); + services.AddhangfireSetup(_configuration); // QuartZ ʱ ʹhangfire ʱãҪԴ򿪣Ѿ services.AddQuartZSetup(_configuration); diff --git a/IRaCIS.Core.API/_PipelineExtensions/Hangfire/HangfireConfig.cs b/IRaCIS.Core.API/_PipelineExtensions/Hangfire/HangfireConfig.cs index 4842353..2c3badf 100644 --- a/IRaCIS.Core.API/_PipelineExtensions/Hangfire/HangfireConfig.cs +++ b/IRaCIS.Core.API/_PipelineExtensions/Hangfire/HangfireConfig.cs @@ -13,15 +13,15 @@ namespace IRaCIS.Core.API public static void UseHangfireConfig(this IApplicationBuilder app, IWebHostEnvironment env) { - app.UseHangfireDashboard("/api/hangfire", new DashboardOptions() - { - //直接访问,没有带token 获取不到用户身份信息,所以这种自定义授权暂时没法使用 - //Authorization = new[] { new hangfireAuthorizationFilter() } + //app.UseHangfireDashboard("/api/hangfire", new DashboardOptions() + //{ + // //直接访问,没有带token 获取不到用户身份信息,所以这种自定义授权暂时没法使用 + // //Authorization = new[] { new hangfireAuthorizationFilter() } - //本地请求 才能看 - Authorization = new[] { new LocalRequestsOnlyAuthorizationFilter() } + // //本地请求 才能看 + // Authorization = new[] { new LocalRequestsOnlyAuthorizationFilter() } - }); + //}); #region hangfire //// 延迟任务执行 1秒之后执行 有时启动没运行 换成添加到队列中 @@ -31,7 +31,7 @@ namespace IRaCIS.Core.API //周期性任务,1天执行一次 - RecurringJob.AddOrUpdate(t => t.ProjectStartCache(), Cron.Daily); + //RecurringJob.AddOrUpdate(t => t.ProjectStartCache(), Cron.Daily); #endregion diff --git a/IRaCIS.Core.API/_PipelineExtensions/Hangfire/hangfireAuthorizationFilter.cs b/IRaCIS.Core.API/_PipelineExtensions/Hangfire/hangfireAuthorizationFilter.cs index 707b552..fe909c6 100644 --- a/IRaCIS.Core.API/_PipelineExtensions/Hangfire/hangfireAuthorizationFilter.cs +++ b/IRaCIS.Core.API/_PipelineExtensions/Hangfire/hangfireAuthorizationFilter.cs @@ -6,10 +6,10 @@ namespace IRaCIS.Core.API.Filter { public bool Authorize(DashboardContext context) { - var httpContext = context.GetHttpContext(); + //var httpContext = context.GetHttpContext(); // Allow all authenticated users to see the Dashboard (potentially dangerous). - return httpContext.User.Identity.IsAuthenticated; + return true; //return true; } diff --git a/IRaCIS.Core.API/_ServiceExtensions/hangfireSetup.cs b/IRaCIS.Core.API/_ServiceExtensions/hangfireSetup.cs index a5dd1fc..c4fdb3c 100644 --- a/IRaCIS.Core.API/_ServiceExtensions/hangfireSetup.cs +++ b/IRaCIS.Core.API/_ServiceExtensions/hangfireSetup.cs @@ -1,6 +1,4 @@ using Hangfire; -using Hangfire.SqlServer; -using Hangfire.Tags.SqlServer; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using System; @@ -11,26 +9,10 @@ namespace IRaCIS.Core.API { public static void AddhangfireSetup(this IServiceCollection services, IConfiguration configuration) { - var hangFireConnStr = configuration.GetSection("ConnectionStrings:Hangfire").Value; - services.AddHangfire(hangFireConfig => - { - //指定存储介质 - hangFireConfig.UseSqlServerStorage(hangFireConnStr, new SqlServerStorageOptions() - { - SchemaName = "hangfire", - CommandBatchMaxTimeout = TimeSpan.FromMinutes(5), - SlidingInvisibilityTimeout = TimeSpan.FromMinutes(5), - QueuePollInterval = TimeSpan.Zero, - UseRecommendedIsolationLevel = true, - UsePageLocksOnDequeue = true, - DisableGlobalLocks = true - }); - hangFireConfig.UseTagsWithSql(); //nuget引入Hangfire.Tags.SqlServer - //.UseHangfireHttpJob(); - - }); + services.AddHangfire(configuration => configuration + .UseInMemoryStorage()); // 使用内存存储 services.AddHangfireServer(); diff --git a/IRaCIS.Core.Application/BackGroundJob/IRaCISCacheHangfireJob.cs b/IRaCIS.Core.Application/BackGroundJob/IRaCISCacheHangfireJob.cs index 80a3d16..e560fb0 100644 --- a/IRaCIS.Core.Application/BackGroundJob/IRaCISCacheHangfireJob.cs +++ b/IRaCIS.Core.Application/BackGroundJob/IRaCISCacheHangfireJob.cs @@ -2,6 +2,7 @@ using IRaCIS.Core.Domain.Share; using Microsoft.EntityFrameworkCore.SqlServer.Query.Internal; using Microsoft.Extensions.Logging; +using System.IO.Compression; namespace IRaCIS.Application.Services.BackGroundJob { @@ -15,10 +16,14 @@ namespace IRaCIS.Application.Services.BackGroundJob Task MemoryCacheAnonymizeData(); Task CacheUserTypePermission(Guid? cacheUserTypeId); + + + Task CreateImageZipTask(string folderPath, string zipPath, string relativePath, Guid visitTaskId); } public class IRaCISCacheHangfireJob: IIRaCISCacheHangfireJob { private readonly IRepository _trialRepository; + private readonly IRepository _VisitTaskRepository; private readonly IEasyCachingProvider _provider; private readonly ILogger _logger; private readonly IRepository _systemAnonymizationRepository; @@ -27,13 +32,14 @@ namespace IRaCIS.Application.Services.BackGroundJob public IRaCISCacheHangfireJob(IRepository trialRepository, IRepository systemAnonymizationRepository, IRepository userTypeMenuRepository, - IEasyCachingProvider provider,ILogger logger) + IEasyCachingProvider provider,ILogger logger, IRepository visitTaskRepository) { _trialRepository = trialRepository; _provider = provider; _logger = logger; _systemAnonymizationRepository = systemAnonymizationRepository; _userTypeMenuRepository = userTypeMenuRepository; + _VisitTaskRepository = visitTaskRepository; } @@ -67,11 +73,6 @@ namespace IRaCIS.Application.Services.BackGroundJob } - - - - - public async Task MemoryCacheAnonymizeData() { var systemAnonymizationList = await _systemAnonymizationRepository.Where(t => t.IsEnable).ToListAsync(); @@ -94,6 +95,10 @@ namespace IRaCIS.Application.Services.BackGroundJob } } - + public async Task CreateImageZipTask(string folderPath, string zipFilePath, string relativePath,Guid visitTaskId) + { + ZipFile.CreateFromDirectory(folderPath, zipFilePath); + await _VisitTaskRepository.BatchUpdateNoTrackingAsync(t => t.Id == visitTaskId, u => new VisitTask() { PackState = PackState.Packed, PackRelativePath = relativePath }); + } } } \ No newline at end of file diff --git a/IRaCIS.Core.Application/BusinessFilter/TrialResourceFilter.cs b/IRaCIS.Core.Application/BusinessFilter/TrialResourceFilter.cs index f2103ce..dbe10b7 100644 --- a/IRaCIS.Core.Application/BusinessFilter/TrialResourceFilter.cs +++ b/IRaCIS.Core.Application/BusinessFilter/TrialResourceFilter.cs @@ -3,6 +3,7 @@ using IRaCIS.Core.Domain.Share; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Filters; +using Microsoft.Extensions.Localization; using System.Text.RegularExpressions; using static IRaCIS.Core.Domain.Share.StaticData; @@ -15,17 +16,18 @@ namespace IRaCIS.Core.Application.Filter { private readonly IEasyCachingProvider _provider; private readonly IUserInfo _userInfo; + public IStringLocalizer _localizer; private readonly List _trialOptList=new List(); - public TrialResourceFilter(IEasyCachingProvider provider, IUserInfo userInfo, string trialOpt = null, string trialOpt2 = null, string trialOpt3 = null) + public TrialResourceFilter(IEasyCachingProvider provider, IStringLocalizer localizer, IUserInfo userInfo, string trialOpt = null, string trialOpt2 = null, string trialOpt3 = null) { _provider = provider; _userInfo = userInfo; //_trialOpt = trialOpt; - + _localizer = localizer; if (!string.IsNullOrWhiteSpace(trialOpt)) _trialOptList.Add(trialOpt.Trim()); if (!string.IsNullOrWhiteSpace(trialOpt2)) _trialOptList.Add(trialOpt2.Trim()); if (!string.IsNullOrWhiteSpace(trialOpt3)) _trialOptList.Add(trialOpt3.Trim()); @@ -184,7 +186,8 @@ namespace IRaCIS.Core.Application.Filter // 项目停止、或者完成 不允许操作 else { - context.Result = new JsonResult(ResponseOutput.NotOk("本次请求被配置规则拦截:项目状态处于进行中状态时,才允许操作。")); + //本次请求被配置规则拦截:项目状态处于进行中状态时,才允许操作。 + context.Result = new JsonResult(ResponseOutput.NotOk(_localizer["TrialResource_InterceptedProjectStatusRule"])); } diff --git a/IRaCIS.Core.Application/IRaCIS.Core.Application.csproj b/IRaCIS.Core.Application/IRaCIS.Core.Application.csproj index fa169fa..65056fa 100644 --- a/IRaCIS.Core.Application/IRaCIS.Core.Application.csproj +++ b/IRaCIS.Core.Application/IRaCIS.Core.Application.csproj @@ -96,9 +96,7 @@ - - true - + true diff --git a/IRaCIS.Core.Application/Resources/en-US.json b/IRaCIS.Core.Application/Resources/en-US.json index 0c0783e..2c42456 100644 --- a/IRaCIS.Core.Application/Resources/en-US.json +++ b/IRaCIS.Core.Application/Resources/en-US.json @@ -1,5 +1,4 @@ { - "test{0}{1}": "英文本地化{0}{1}", "RequiredAttribute": "{0} is required", // SiteSurvey 服务-------------------------------------------------------------------------------------------------------------------------- diff --git a/IRaCIS.Core.Application/Resources/zh-CN.json b/IRaCIS.Core.Application/Resources/zh-CN.json index 6408137..eadf714 100644 --- a/IRaCIS.Core.Application/Resources/zh-CN.json +++ b/IRaCIS.Core.Application/Resources/zh-CN.json @@ -1,5 +1,34 @@ { - "test{0}{1}": "中文本地化{0}{1}", + + // trial 服务-------------------------------------------------------------------------------------------------------------------------- + "TrialService_OnlyInInitOrProgress": "项目状态只有处于:初始化或者进行中时,才允许操作。", + "TrialService_ExistPN": "已经存在相同的项目编号", + + "SubjectService_ExistSubjectCode": "已存在具有相关患者编号的患者。", + "SubjectService_ExistImage": "该患者已经有检查批次已经上传影像,不允许删除。", + + "SubjectVisitServiece_ExistOtherInCurrent": "该患者的检查批次中,在选择的上一检查后已存在计划外的的检查批次,请重新选择上一检查。", + "SubjectVisitServiece_ExistName": "该患者的检查批次中已经包含一个具有相同名称的检查批次。", + "SubjectVisitServiece_ExistImage": "当前检查批次已经有影像上传,不允许删除。", + "SubjectVisitServiece_HaveSetBeforeBatch": "当前检查批次已经被设置为另一检查批次的上一检查批次,不允许删除。", + "TrialResource_InterceptedProjectStatusRule": null, + + + + + + + + + + + + + + + + + "RequiredAttribute": "{0} 字段是必须的", // SiteSurvey 服务-------------------------------------------------------------------------------------------------------------------------- diff --git a/IRaCIS.Core.Application/Service/TrialSiteUser/TrialService.cs b/IRaCIS.Core.Application/Service/TrialSiteUser/TrialService.cs index 02c95aa..b2a97d4 100644 --- a/IRaCIS.Core.Application/Service/TrialSiteUser/TrialService.cs +++ b/IRaCIS.Core.Application/Service/TrialSiteUser/TrialService.cs @@ -146,10 +146,7 @@ namespace IRaCIS.Application.Services if (trialAddModel.Id == Guid.Empty || trialAddModel.Id == null) { - if (await _trialRepository.AnyAsync(u => u.TrialCode == trialAddModel.TrialCode)) - { - throw new BusinessValidationFailedException("已经存在相同的项目编号。"); - } + var dbMaxCode = await _trialRepository.Where(t => t.CreateTime.Year == DateTime.Now.Year && t.TrialType == trialAddModel.TrialType).Select(t => t.Code).DefaultIfEmpty().MaxAsync(); @@ -275,13 +272,15 @@ namespace IRaCIS.Application.Services if (!await _repository.AnyAsync(u => u.Id == trialAddModel.Id && (u.TrialStatusStr == StaticData.TrialState.TrialInitializing || u.TrialStatusStr == StaticData.TrialState.TrialOngoing))) { - throw new BusinessValidationFailedException("项目状态只有处于:初始化或者进行中时,才允许操作。"); + //项目状态只有处于:初始化或者进行中时,才允许操作。 + throw new BusinessValidationFailedException(_localizer["TrialService_OnlyInInitOrProgress"]); } // 判断项目Id 是否已经存在 if (await _repository.AnyAsync(u => u.TrialCode == updateModel.TrialCode && u.Id != updateModel.Id)) { - throw new BusinessValidationFailedException("已经存在相同的项目编号。"); + //已经存在相同的项目编号。 + throw new BusinessValidationFailedException(_localizer["TrialService_ExistPN"]); } diff --git a/IRaCIS.Core.Application/Service/Visit/SubjectService.cs b/IRaCIS.Core.Application/Service/Visit/SubjectService.cs index a4c83fd..d94954f 100644 --- a/IRaCIS.Core.Application/Service/Visit/SubjectService.cs +++ b/IRaCIS.Core.Application/Service/Visit/SubjectService.cs @@ -39,7 +39,9 @@ namespace IRaCIS.Application.Services var verifyExp1 = new EntityVerifyExp() { VerifyExp = u => u.Code == subjectCommand.Code && u.TrialId == subjectCommand.TrialId, - VerifyMsg = "已存在具有相关患者编号的患者。" + + //"已存在具有相关患者编号的患者。" + VerifyMsg = _localizer["SubjectService_ExistSubjectCode"] }; @@ -88,7 +90,8 @@ namespace IRaCIS.Application.Services if (await _subjectVisitRepository.AnyAsync(u => u.SubjectId == id && u.VisitExecuted == VisitExecutedEnum.Executed)) { - return ResponseOutput.NotOk("该患者已经有检查批次已经上传影像,不允许删除。"); + //"该患者已经有检查批次已经上传影像,不允许删除。" + return ResponseOutput.NotOk(_localizer["SubjectService_ExistImage"] ); } await _subjectRepository.UpdatePartialFromQueryAsync(id, x => new Subject diff --git a/IRaCIS.Core.Application/Service/Visit/SubjectVisitService.cs b/IRaCIS.Core.Application/Service/Visit/SubjectVisitService.cs index 9a2d27c..2f0d176 100644 --- a/IRaCIS.Core.Application/Service/Visit/SubjectVisitService.cs +++ b/IRaCIS.Core.Application/Service/Visit/SubjectVisitService.cs @@ -68,12 +68,15 @@ namespace IRaCIS.Core.Application.Services var verifyExp1 = new EntityVerifyExp() { VerifyExp = t => t.VisitNum == svCommand.VisitNum && t.SubjectId == svCommand.SubjectId, - VerifyMsg = "该患者的检查批次中,在选择的上一检查后已存在计划外的的检查批次,请重新选择上一检查。" + + //"该患者的检查批次中,在选择的上一检查后已存在计划外的的检查批次,请重新选择上一检查。" + VerifyMsg = _localizer["SubjectVisitServiece_ExistOtherInCurrent"] }; var verifyExp2 = new EntityVerifyExp() { VerifyExp = t => t.SubjectId == svCommand.SubjectId && t.IsFinalVisit, + // VerifyMsg = "该患者已经有检查批次设置为末次检查批次,不允许将当前检查批次设置为末次检查批次。", IsVerify = svCommand.IsFinalVisit }; @@ -81,7 +84,9 @@ namespace IRaCIS.Core.Application.Services var verifyExp3 = new EntityVerifyExp() { VerifyExp = t => t.SubjectId == svCommand.SubjectId && t.VisitName == svCommand.VisitName, - VerifyMsg = "该患者的检查批次中已经包含一个具有相同名称的检查批次。" + + //"该患者的检查批次中已经包含一个具有相同名称的检查批次。" + VerifyMsg = _localizer["SubjectVisitServiece_ExistName"] }; @@ -197,7 +202,8 @@ namespace IRaCIS.Core.Application.Services { if (await _repository.AnyAsync(t => t.SubjectVisitId == id)) { - return ResponseOutput.NotOk("当前检查批次已经有影像上传,不允许删除。"); + //"当前检查批次已经有影像上传,不允许删除。" + return ResponseOutput.NotOk(_localizer["SubjectVisitServiece_ExistImage"]); } if (await _subjectVisitRepository.AnyAsync(t => t.Id == id && t.InPlan)) { @@ -205,7 +211,8 @@ namespace IRaCIS.Core.Application.Services } if (await _subjectVisitRepository.AnyAsync(t => t.OutPlanPreviousVisitId == id)) { - return ResponseOutput.NotOk("当前检查批次已经被设置为另一检查批次的上一检查批次,不允许删除。"); + //"当前检查批次已经被设置为另一检查批次的上一检查批次,不允许删除。" + return ResponseOutput.NotOk(_localizer["SubjectVisitServiece_HaveSetBeforeBatch"]); } await _subjectVisitRepository.DeleteFromQueryAsync(s => s.Id == id, true);