From 7739652e21f043d92d79b5a9f0fc604705d3b5ad Mon Sep 17 00:00:00 2001 From: he <10978375@qq.com> Date: Mon, 9 Oct 2023 10:47:31 +0800 Subject: [PATCH 01/11] =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Service/ReadingCalculate/LuganoCalculateService.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/IRaCIS.Core.Application/Service/ReadingCalculate/LuganoCalculateService.cs b/IRaCIS.Core.Application/Service/ReadingCalculate/LuganoCalculateService.cs index 2a1e48f84..af8f88bf5 100644 --- a/IRaCIS.Core.Application/Service/ReadingCalculate/LuganoCalculateService.cs +++ b/IRaCIS.Core.Application/Service/ReadingCalculate/LuganoCalculateService.cs @@ -959,7 +959,7 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate FirstAddTaskId=x.FirstAddTaskId, QuestionId=x.QuestionId, QuestionType=x.QuestionType, - + OrderMarkName=x.OrderMarkName, }).ToListAsync(); questionMarkList.ForEach(x => { From 2c82cf525a008405868bad3a9bf6f55e3628966d Mon Sep 17 00:00:00 2001 From: he <10978375@qq.com> Date: Wed, 11 Oct 2023 15:52:56 +0800 Subject: [PATCH 02/11] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../IRaCIS.Core.Application.xml | 7 +++++ .../LuganoCalculateService.cs | 30 +++++++++++++++++-- .../Visit/Interface/ISubjectVisitService.cs | 2 ++ 3 files changed, 37 insertions(+), 2 deletions(-) diff --git a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml index 5b5d1d667..ce7fb263e 100644 --- a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml +++ b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml @@ -1934,6 +1934,13 @@ + + + 是否存在PET + + + + 影像学整体肿瘤评估 diff --git a/IRaCIS.Core.Application/Service/ReadingCalculate/LuganoCalculateService.cs b/IRaCIS.Core.Application/Service/ReadingCalculate/LuganoCalculateService.cs index af8f88bf5..5e816b314 100644 --- a/IRaCIS.Core.Application/Service/ReadingCalculate/LuganoCalculateService.cs +++ b/IRaCIS.Core.Application/Service/ReadingCalculate/LuganoCalculateService.cs @@ -29,6 +29,7 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate private readonly IRepository _organInfoRepository; private readonly IRepository _subjectVisitRepository; private readonly IRepository _tumorAssessmentRepository; + private readonly ISubjectVisitService _subjectVisitService; private readonly IGeneralCalculateService _generalCalculateService; private readonly IRepository _readingTaskQuestionAnswerRepository; @@ -43,6 +44,7 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate IRepository organInfoRepository, IRepository subjectVisitRepository, IRepository tumorAssessmentRepository, + ISubjectVisitService subjectVisitService, IGeneralCalculateService generalCalculateService, IRepository readingTaskQuestionAnswerRepository ) @@ -57,6 +59,7 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate this._organInfoRepository = organInfoRepository; this._subjectVisitRepository = subjectVisitRepository; this._tumorAssessmentRepository = tumorAssessmentRepository; + this._subjectVisitService = subjectVisitService; this._generalCalculateService = generalCalculateService; this._readingTaskQuestionAnswerRepository = readingTaskQuestionAnswerRepository; } @@ -502,12 +505,13 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate new ReadingCalculateData (){QuestionType=QuestionType.UptakeChange,GetStringFun=GetUptakeChange}, // FDG-PET 评估结果 - new ReadingCalculateData (){QuestionType=QuestionType.UptakeChange,GetStringFun=GetFDGPETOverallAssessment}, + new ReadingCalculateData (){QuestionType=QuestionType.FDGPET,GetStringFun=GetFDGPETOverallAssessment}, // 影像学整体肿瘤评估 new ReadingCalculateData (){QuestionType=QuestionType.ImgOncology,GetStringFun=GetImgOncology}, - + // 是否存在Pet + new ReadingCalculateData (){QuestionType=QuestionType.ExistPET,GetStringFun=GetExistPET}, //SUVmax new ReadingCalculateData (){QuestionType=QuestionType.SUVmax,GetDecimalFun=GetSuvMax}, @@ -835,6 +839,11 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate var baseLineVisitId = await _subjectVisitRepository.Where(x => x.SubjectId == taskinfo.SubjectId && x.IsBaseLine).Select(x => x.Id).FirstOrDefaultAsync(); + + ReadingCalculateDto readingData = await _generalCalculateService.GetReadingCalculateDto(visitTaskId); + await ReadingCalculate(readingData, new List() { QuestionType.ExistPET }); + + // 判断当前任务是否是基线 if (taskinfo.SourceSubjectVisitId != baseLineVisitId) { @@ -2020,6 +2029,23 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate } #endregion + /// + /// 是否存在PET + /// + /// + /// + public async Task GetExistPET(ReadingCalculateDto inDto) + { + var studyList = await this._subjectVisitService.GetReadingVisitStudyList(new Contracts.GetReadingVisitStudyListIndto() + { + TrialId = inDto.TrialId, + SujectVisitId = inDto.SubjectVisitId, + VisitTaskId=inDto.VisitTaskId, + }); + + return studyList.Any(x => x.Modalities.Contains("CT")) ? ReadingYesOrNo.Yes.GetEnumInt() : ReadingYesOrNo.No.GetEnumInt(); + } + #region 影像学整体肿瘤评估 /// /// 影像学整体肿瘤评估 diff --git a/IRaCIS.Core.Application/Service/Visit/Interface/ISubjectVisitService.cs b/IRaCIS.Core.Application/Service/Visit/Interface/ISubjectVisitService.cs index 67be25a04..91e782963 100644 --- a/IRaCIS.Core.Application/Service/Visit/Interface/ISubjectVisitService.cs +++ b/IRaCIS.Core.Application/Service/Visit/Interface/ISubjectVisitService.cs @@ -10,5 +10,7 @@ namespace IRaCIS.Core.Application.Interfaces Task SetSVExecuted(Guid subjectVisitId); Task SetSubjectVisitUrgent(Guid subjectVisitId, bool isUrgent); + + Task> GetReadingVisitStudyList(GetReadingVisitStudyListIndto indto); } } \ No newline at end of file From ba3319d0cd7b9d66d2bf8fe3ba8d815626ec652e Mon Sep 17 00:00:00 2001 From: he <10978375@qq.com> Date: Wed, 11 Oct 2023 16:11:04 +0800 Subject: [PATCH 03/11] =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Service/ReadingCalculate/LuganoCalculateService.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/IRaCIS.Core.Application/Service/ReadingCalculate/LuganoCalculateService.cs b/IRaCIS.Core.Application/Service/ReadingCalculate/LuganoCalculateService.cs index 5e816b314..ccfb0e7d0 100644 --- a/IRaCIS.Core.Application/Service/ReadingCalculate/LuganoCalculateService.cs +++ b/IRaCIS.Core.Application/Service/ReadingCalculate/LuganoCalculateService.cs @@ -2043,6 +2043,7 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate VisitTaskId=inDto.VisitTaskId, }); + return studyList.Any(x => x.Modalities.Contains("CT")) ? ReadingYesOrNo.Yes.GetEnumInt() : ReadingYesOrNo.No.GetEnumInt(); } From 3de5142a5b66b4eec8a832ca645300be20d3055e Mon Sep 17 00:00:00 2001 From: he <10978375@qq.com> Date: Wed, 11 Oct 2023 16:42:17 +0800 Subject: [PATCH 04/11] =?UTF-8?q?=E6=B5=8B=E8=AF=95=E8=BF=81=E7=A7=BB?= =?UTF-8?q?=E5=8F=91=E5=B8=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Service/ReadingCalculate/LuganoCalculateService.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/IRaCIS.Core.Application/Service/ReadingCalculate/LuganoCalculateService.cs b/IRaCIS.Core.Application/Service/ReadingCalculate/LuganoCalculateService.cs index ccfb0e7d0..5e816b314 100644 --- a/IRaCIS.Core.Application/Service/ReadingCalculate/LuganoCalculateService.cs +++ b/IRaCIS.Core.Application/Service/ReadingCalculate/LuganoCalculateService.cs @@ -2043,7 +2043,6 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate VisitTaskId=inDto.VisitTaskId, }); - return studyList.Any(x => x.Modalities.Contains("CT")) ? ReadingYesOrNo.Yes.GetEnumInt() : ReadingYesOrNo.No.GetEnumInt(); } From 9ade3a7c3930604cff70e239b3cfc206409bc43f Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Thu, 12 Oct 2023 09:40:00 +0800 Subject: [PATCH 05/11] =?UTF-8?q?=E5=BC=95=E5=85=A5=E5=88=86=E5=B8=83?= =?UTF-8?q?=E5=BC=8F=E9=94=81=E7=BB=84=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.Application/IRaCIS.Core.Application.csproj | 2 ++ 1 file changed, 2 insertions(+) diff --git a/IRaCIS.Core.Application/IRaCIS.Core.Application.csproj b/IRaCIS.Core.Application/IRaCIS.Core.Application.csproj index 247ed6016..7e0318c0f 100644 --- a/IRaCIS.Core.Application/IRaCIS.Core.Application.csproj +++ b/IRaCIS.Core.Application/IRaCIS.Core.Application.csproj @@ -70,6 +70,8 @@ + + true From 3218be613d81576835d7a2f06ff7a43f70fae981 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Wed, 11 Oct 2023 17:38:34 +0800 Subject: [PATCH 06/11] =?UTF-8?q?=E5=88=86=E5=B8=83=E5=BC=8F=E9=94=81=20?= =?UTF-8?q?=20sqlserver=20=E6=B5=8B=E8=AF=95=2003?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.API/_ServiceExtensions/EFSetup.cs | 13 ++++++++- IRaCIS.Core.Application/TestService.cs | 27 ++++++++++++++++++- 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/IRaCIS.Core.API/_ServiceExtensions/EFSetup.cs b/IRaCIS.Core.API/_ServiceExtensions/EFSetup.cs index c1d2c31cc..3a7df5742 100644 --- a/IRaCIS.Core.API/_ServiceExtensions/EFSetup.cs +++ b/IRaCIS.Core.API/_ServiceExtensions/EFSetup.cs @@ -1,8 +1,12 @@ -using IRaCIS.Core.Application.Triggers; +using Hangfire.SqlServer; +using IRaCIS.Core.Application.Triggers; using IRaCIS.Core.Infra.EFCore; +using Medallion.Threading; +using Medallion.Threading.SqlServer; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; +using StackExchange.Redis; namespace IRaCIS.Core.API { @@ -55,6 +59,13 @@ namespace IRaCIS.Core.API }); + //注意区分 easy caching 也有 IDistributedLockProvider + services.AddSingleton(sp => + { + //var connection = ConnectionMultiplexer.Connect(configuration["Redis:Configuration"]!); + + return new SqlDistributedSynchronizationProvider(configuration.GetSection("ConnectionStrings:RemoteNew").Value); + }); //services.AddAssemblyTriggers(typeof(SubjectVisitImageDateTrigger).Assembly); } diff --git a/IRaCIS.Core.Application/TestService.cs b/IRaCIS.Core.Application/TestService.cs index c3e953a73..b72556137 100644 --- a/IRaCIS.Core.Application/TestService.cs +++ b/IRaCIS.Core.Application/TestService.cs @@ -3,6 +3,8 @@ using IRaCIS.Core.Application.Service; using IRaCIS.Core.Application.ViewModel; using IRaCIS.Core.Domain.Share; using IRaCIS.Core.Infrastructure; +using MassTransit; +using Medallion.Threading; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Mvc; @@ -10,6 +12,7 @@ using Microsoft.Extensions.Caching.Distributed; using Microsoft.Extensions.Options; using MiniExcelLibs; using System.Linq.Expressions; +using System.Reflection.Metadata; using System.Security.Cryptography; using System.Text; using System.Text.RegularExpressions; @@ -20,6 +23,8 @@ namespace IRaCIS.Application.Services [ApiExplorerSettings(GroupName = "Institution")] public class TestService : BaseService { + + public static int IntValue = 100; private readonly IRepository _dicRepository; private readonly IRepository _trialRepository; @@ -30,10 +35,11 @@ namespace IRaCIS.Application.Services private readonly IOptionsMonitor _basicConfig; private readonly IRepository _visitTaskRepositoryy; + private readonly IDistributedLockProvider _distributedLockProvider; public TestService(IRepository dicRepository, IRepository trialRepository/*, IDistributedCache cache*/ - , IOptionsMonitor systemEmailConfig, IOptionsMonitor basicConfig, IRepository visitTaskRepository) + , IOptionsMonitor systemEmailConfig, IOptionsMonitor basicConfig, IRepository visitTaskRepository, IDistributedLockProvider distributedLockProvider) { _visitTaskRepositoryy = visitTaskRepository; @@ -42,11 +48,30 @@ namespace IRaCIS.Application.Services _dicRepository = dicRepository; _trialRepository = trialRepository; + + _distributedLockProvider= distributedLockProvider; //_cache = cache; } + [AllowAnonymous] + public async Task TestDistributedLock( ) + { + Console.WriteLine($"我进来了当前值是:" + IntValue); + + var @lock = _distributedLockProvider.CreateLock($"UserAccount"); + + using (await @lock.AcquireAsync()) + { + await Task.Delay(3); + IntValue--; + Console.WriteLine(IntValue); + } + + return ResponseOutput.Ok(IntValue); + } + [AllowAnonymous] public async Task InternationazitionInit() From 5d7beb71e6467e176c440dd14711d80c967a24f9 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Wed, 11 Oct 2023 17:44:13 +0800 Subject: [PATCH 07/11] =?UTF-8?q?=E5=88=86=E5=B8=83=E5=BC=8F=E9=94=81=20?= =?UTF-8?q?=20sqlserver=20=E6=B5=8B=E8=AF=95=2004=20=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E6=97=A5=E5=BF=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.Application/TestService.cs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/IRaCIS.Core.Application/TestService.cs b/IRaCIS.Core.Application/TestService.cs index b72556137..46153bca6 100644 --- a/IRaCIS.Core.Application/TestService.cs +++ b/IRaCIS.Core.Application/TestService.cs @@ -9,6 +9,7 @@ using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Caching.Distributed; +using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using MiniExcelLibs; using System.Linq.Expressions; @@ -37,7 +38,9 @@ namespace IRaCIS.Application.Services private readonly IDistributedLockProvider _distributedLockProvider; - public TestService(IRepository dicRepository, IRepository trialRepository/*, IDistributedCache cache*/ + private readonly ILogger _logger; + + public TestService(IRepository dicRepository, IRepository trialRepository,ILogger logger , IOptionsMonitor systemEmailConfig, IOptionsMonitor basicConfig, IRepository visitTaskRepository, IDistributedLockProvider distributedLockProvider) { @@ -50,6 +53,8 @@ namespace IRaCIS.Application.Services _trialRepository = trialRepository; _distributedLockProvider= distributedLockProvider; + + _logger= logger; //_cache = cache; } @@ -59,13 +64,16 @@ namespace IRaCIS.Application.Services public async Task TestDistributedLock( ) { Console.WriteLine($"我进来了当前值是:" + IntValue); + _logger.LogWarning($"我进来了当前值是:" + IntValue); var @lock = _distributedLockProvider.CreateLock($"UserAccount"); using (await @lock.AcquireAsync()) { - await Task.Delay(3); + await Task.Delay(4); IntValue--; + + _logger.LogWarning( IntValue.ToString()); Console.WriteLine(IntValue); } From a565282a94f2ca7c5af81399c44b346ec830ab1e Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Thu, 12 Oct 2023 09:34:09 +0800 Subject: [PATCH 08/11] =?UTF-8?q?=E5=88=86=E5=B8=83=E5=BC=8F=E9=94=81=20?= =?UTF-8?q?=20sqlserver=2005=20=E9=A1=B9=E7=9B=AE=E8=BF=81=E7=A7=BB?= =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../IRaCIS.Core.Application.csproj | 1 - .../Service/Common/MailService.cs | 2 - .../ImageAndDoc/DicomArchiveService.cs | 25 ++- .../Service/ImageAndDoc/StudyService.cs | 32 +-- .../Service/Institution/SiteService.cs | 14 +- .../Service/Management/UserService.cs | 42 ++-- .../Service/QC/NoneDicomStudyService.cs | 12 +- .../Service/QC/QCOperationService.cs | 13 +- .../SiteSurvey/TrialSiteSurveyService.cs | 5 +- .../TrialSiteUser/TrialExternalUserService.cs | 196 +++++++++--------- 10 files changed, 181 insertions(+), 161 deletions(-) diff --git a/IRaCIS.Core.Application/IRaCIS.Core.Application.csproj b/IRaCIS.Core.Application/IRaCIS.Core.Application.csproj index 7e0318c0f..4f74c24fb 100644 --- a/IRaCIS.Core.Application/IRaCIS.Core.Application.csproj +++ b/IRaCIS.Core.Application/IRaCIS.Core.Application.csproj @@ -101,7 +101,6 @@ true - diff --git a/IRaCIS.Core.Application/Service/Common/MailService.cs b/IRaCIS.Core.Application/Service/Common/MailService.cs index 5f6e58120..bf195994b 100644 --- a/IRaCIS.Core.Application/Service/Common/MailService.cs +++ b/IRaCIS.Core.Application/Service/Common/MailService.cs @@ -6,7 +6,6 @@ using Microsoft.AspNetCore.Hosting; using IRaCIS.Core.Application.Auth; using AutoMapper; using IRaCIS.Application.Contracts; -using Nito.AsyncEx; using Microsoft.Extensions.Options; namespace IRaCIS.Application.Services @@ -55,7 +54,6 @@ namespace IRaCIS.Application.Services private readonly IRepository _doctorTypeRepository; - private readonly AsyncLock _mutex = new AsyncLock(); private readonly SystemEmailSendConfig _systemEmailConfig; diff --git a/IRaCIS.Core.Application/Service/ImageAndDoc/DicomArchiveService.cs b/IRaCIS.Core.Application/Service/ImageAndDoc/DicomArchiveService.cs index f797c8ca4..9b990c306 100644 --- a/IRaCIS.Core.Application/Service/ImageAndDoc/DicomArchiveService.cs +++ b/IRaCIS.Core.Application/Service/ImageAndDoc/DicomArchiveService.cs @@ -8,10 +8,11 @@ using IRaCIS.Core.Application.Contracts; using IRaCIS.Core.Application.Helper; using Microsoft.AspNetCore.Hosting; using IRaCIS.Core.Infrastructure; +using Medallion.Threading; namespace IRaCIS.Core.Application.Services { - public class DicomArchiveService :BaseService, IDicomArchiveService + public class DicomArchiveService : BaseService, IDicomArchiveService { private readonly IRepository _studyRepository; private readonly IRepository _seriesRepository; @@ -21,7 +22,7 @@ namespace IRaCIS.Core.Application.Services private readonly IWebHostEnvironment _hostEnvironment; - private static object lockCodeGenerate = new object(); + private readonly IDistributedLockProvider _distributedLockProvider; private List _instanceIdList = new List(); @@ -31,8 +32,9 @@ namespace IRaCIS.Core.Application.Services IRepository instanceRepository, IWebHostEnvironment hostEnvironment, IRepository dictionaryRepository, - IEasyCachingProvider provider) + IEasyCachingProvider provider, IDistributedLockProvider distributedLockProvider) { + _distributedLockProvider = distributedLockProvider; _hostEnvironment = hostEnvironment; _studyRepository = studyRepository; @@ -50,7 +52,7 @@ namespace IRaCIS.Core.Application.Services return success; } - + public async Task<(Guid StudyId, string StudyCode)> ArchiveDicomStreamAsync(Stream dicomStream, @@ -129,7 +131,7 @@ namespace IRaCIS.Core.Application.Services DicomStudy dicomStudy = CreateDicomStudy(dataset, addtionalInfo, out bool isStudyNeedAdd); DicomSeries dicomSeries = CreateDicomSeries(dataset, dicomStudy, out bool isSeriesNeedAdd); - DicomInstance dicomInstance = CreateDicomInstance(dataset, dicomStudy, dicomSeries,out bool isInstanceNeedAdd); + DicomInstance dicomInstance = CreateDicomInstance(dataset, dicomStudy, dicomSeries, out bool isInstanceNeedAdd); dicomSeries.DicomStudy = dicomStudy; @@ -183,7 +185,7 @@ namespace IRaCIS.Core.Application.Services //正常保存 不做处理 await dicomFile.SaveAsync(physicalPath); } - else + else { //RLELossless 保存 await dicomFile.Clone(DicomTransferSyntax.RLELossless).SaveAsync(physicalPath); //RLELossless @@ -235,7 +237,7 @@ namespace IRaCIS.Core.Application.Services { modalityForEdit = "PET"; } - if(modality== "PT、CT") + if (modality == "PT、CT") { modalityForEdit = "PET-CT"; } @@ -282,9 +284,10 @@ namespace IRaCIS.Core.Application.Services dicomStudy.PatientBirthDate = $"{dicomStudy.PatientBirthDate[0]}{dicomStudy.PatientBirthDate[1]}{dicomStudy.PatientBirthDate[2]}{dicomStudy.PatientBirthDate[3]}-{dicomStudy.PatientBirthDate[4]}{dicomStudy.PatientBirthDate[5]}-{dicomStudy.PatientBirthDate[6]}{dicomStudy.PatientBirthDate[7]}"; } - lock (lockCodeGenerate) - { + var @lock = _distributedLockProvider.CreateLock($"StudyCode"); + using (@lock.Acquire()) + { //查询数据库获取最大的Code 没有记录则为0 var dbStudyCodeIntMax = _studyRepository.Where(s => s.TrialId == addtionalInfo.TrialId).Select(t => t.Code).DefaultIfEmpty().Max(); @@ -298,9 +301,9 @@ namespace IRaCIS.Core.Application.Services dicomStudy.StudyCode = AppSettings.GetCodeStr(currentNextCodeInt, nameof(DicomStudy)); _provider.Set($"{addtionalInfo.TrialId}_{StaticData.CacheKey.StudyMaxCode}", dicomStudy.Code, TimeSpan.FromMinutes(30)); - } + #region Setting Code old //var studyCode = _studyRepository.Where(s => s.TrialId == addtionalInfo.TrialId).Select(t => t.StudyCode).OrderByDescending(c => c).FirstOrDefault(); @@ -468,7 +471,7 @@ namespace IRaCIS.Core.Application.Services _instanceIdList.Add(instanceId); } - + return dicomInstance; } diff --git a/IRaCIS.Core.Application/Service/ImageAndDoc/StudyService.cs b/IRaCIS.Core.Application/Service/ImageAndDoc/StudyService.cs index 0e3e5c184..adb1f224a 100644 --- a/IRaCIS.Core.Application/Service/ImageAndDoc/StudyService.cs +++ b/IRaCIS.Core.Application/Service/ImageAndDoc/StudyService.cs @@ -14,16 +14,13 @@ using IRaCIS.Core.Application.MediatR.Handlers; using Microsoft.AspNetCore.Http; using Newtonsoft.Json; using System.Threading; -using Nito.AsyncEx; +using Medallion.Threading; namespace IRaCIS.Core.Application.Service.ImageAndDoc { [ApiExplorerSettings(GroupName = "Image")] public class StudyService : BaseService, IStudyService { - private static object lockObj = new object(); - private static readonly AsyncLock _mutex = new AsyncLock(); - private static readonly AsyncLock _mutex2 = new AsyncLock(); private readonly IEasyCachingProvider _provider; @@ -35,12 +32,12 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc private readonly IRepository _dictionaryRepository; private readonly IRepository _studyMonitorRepository; - + private readonly IDistributedLockProvider _distributedLockProvider; public StudyService(IEasyCachingProvider provider , IRepository subjectVisitRepository, IRepository dicomInstanceRepository, - IRepository dicomSeriesRepository, IRepository dicomstudyRepository, IRepository dictionaryRepository, IRepository studyMonitorRepository) + IRepository dicomSeriesRepository, IRepository dicomstudyRepository, IRepository dictionaryRepository, IRepository studyMonitorRepository, IDistributedLockProvider distributedLockProvider) { _provider = provider; _subjectVisitRepository = subjectVisitRepository; @@ -49,6 +46,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc _dicomstudyRepository = dicomstudyRepository; _dictionaryRepository = dictionaryRepository; _studyMonitorRepository = studyMonitorRepository; + _distributedLockProvider = distributedLockProvider; } @@ -160,7 +158,9 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc { var study = _mapper.Map(incommand.Study); - using (await _mutex.LockAsync()) + var @lock = _distributedLockProvider.CreateLock($"StudyCode"); + + using (await @lock.AcquireAsync()) { //查询数据库获取最大的Code 没有记录则为0 var dbStudyCodeIntMax = _dicomstudyRepository.Where(s => s.TrialId == trialId).Select(t => t.Code).DefaultIfEmpty().Max(); @@ -306,11 +306,11 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc } - using (await _mutex2.LockAsync()) + var @lock2 = _distributedLockProvider.CreateLock($"StudyCommit"); + + using (await @lock2.AcquireAsync()) { await _dicomInstanceRepository.SaveChangesAsync(); - - } } catch (Exception ex) @@ -826,22 +826,22 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc } result.StudyInstanceUid = studyInstanceUid; + var @lock = _distributedLockProvider.CreateLock($"StudyUpload"); - if (result.AllowReUpload || result.AllowUpload) + using (@lock.Acquire()) { - lock (lockObj) + if (result.AllowReUpload || result.AllowUpload) { _provider.Set($"StudyUid_{trialId}_{studyInstanceUid}", _userInfo.Id, TimeSpan.FromSeconds(30)); } - } - else - { - lock (lockObj) + else { _provider.Remove($"StudyUid_{trialId}_{studyInstanceUid}"); } } + + return result; } diff --git a/IRaCIS.Core.Application/Service/Institution/SiteService.cs b/IRaCIS.Core.Application/Service/Institution/SiteService.cs index ce240e222..b65b2379f 100644 --- a/IRaCIS.Core.Application/Service/Institution/SiteService.cs +++ b/IRaCIS.Core.Application/Service/Institution/SiteService.cs @@ -3,7 +3,7 @@ using IRaCIS.Application.Contracts; using IRaCIS.Core.Infra.EFCore; using Microsoft.AspNetCore.Mvc; using IRaCIS.Core.Domain.Share; -using Nito.AsyncEx; +using Medallion.Threading; namespace IRaCIS.Application.Services { @@ -12,13 +12,13 @@ namespace IRaCIS.Application.Services { private readonly IRepository _siteRepository; private readonly IRepository _trialSiteUserRepository; + private readonly IDistributedLockProvider _distributedLockProvider; - private readonly AsyncLock _mutex = new AsyncLock(); - - public SiteService(IRepository siteRepository, IRepository trialSiteUserRepository) + public SiteService(IRepository siteRepository, IRepository trialSiteUserRepository, IDistributedLockProvider distributedLockProvider) { _siteRepository = siteRepository; - this._trialSiteUserRepository = trialSiteUserRepository; + _trialSiteUserRepository = trialSiteUserRepository; + _distributedLockProvider = distributedLockProvider; } /// 分页获取研究中心列表 @@ -58,7 +58,9 @@ namespace IRaCIS.Application.Services VerifyMsg = _localizer["Site_DupName"] }; - using (await _mutex.LockAsync()) + var @lock = _distributedLockProvider.CreateLock($"SiteAdd"); + + using (await @lock.AcquireAsync()) { if (siteCommand.Id == null) { diff --git a/IRaCIS.Core.Application/Service/Management/UserService.cs b/IRaCIS.Core.Application/Service/Management/UserService.cs index ef581d115..8b6b968e3 100644 --- a/IRaCIS.Core.Application/Service/Management/UserService.cs +++ b/IRaCIS.Core.Application/Service/Management/UserService.cs @@ -12,6 +12,7 @@ using IRaCIS.Core.Infra.Common.Cache; using Microsoft.Identity.Client; using static IRaCIS.Core.Domain.Share.StaticData; using IRaCIS.Core.Application.ViewModel; +using Medallion.Threading; namespace IRaCIS.Application.Services { @@ -25,7 +26,7 @@ namespace IRaCIS.Application.Services private readonly IRepository _userTrialRepository; private readonly IRepository _userLogRepository; - + private readonly IDistributedLockProvider _distributedLockProvider; private readonly IMemoryCache _cache; private readonly IOptionsMonitor _verifyConfig; @@ -40,7 +41,8 @@ namespace IRaCIS.Application.Services IRepository userTrialRepository, IOptionsMonitor verifyConfig, IRepository userLogRepository - ) +, + IDistributedLockProvider distributedLockProvider) { _userLogRepository = userLogRepository; @@ -52,6 +54,7 @@ namespace IRaCIS.Application.Services _doctorRepository = doctorRepository; _userTrialRepository = userTrialRepository; _userLogRepository = userLogRepository; + _distributedLockProvider = distributedLockProvider; } @@ -504,29 +507,32 @@ namespace IRaCIS.Application.Services var saveItem = _mapper.Map(userAddModel); - saveItem.Code = await _userRepository.Select(t => t.Code).DefaultIfEmpty().MaxAsync() + 1; + var @lock = _distributedLockProvider.CreateLock($"UserAccount"); - saveItem.UserCode = AppSettings.GetCodeStr(saveItem.Code, nameof(User)); - - if (saveItem.IsZhiZhun) + using (await @lock.AcquireAsync()) { - saveItem.OrganizationName = AppSettings.DefaultInternalOrganizationName; + saveItem.Code = await _userRepository.Select(t => t.Code).DefaultIfEmpty().MaxAsync() + 1; + + saveItem.UserCode = AppSettings.GetCodeStr(saveItem.Code, nameof(User)); + + if (saveItem.IsZhiZhun) + { + saveItem.OrganizationName = AppSettings.DefaultInternalOrganizationName; + } + + + saveItem.Password = MD5Helper.Md5("123456"); + + await _userRepository.AddAsync(saveItem); + + var success = await _userRepository.SaveChangesAsync(); } - - saveItem.Password = MD5Helper.Md5("123456"); - - await _userRepository.AddAsync(saveItem); - - var success = await _userRepository.SaveChangesAsync(); - - + await _mailVerificationService.AddUserSendEmailAsync(saveItem.Id, userAddModel.BaseUrl, userAddModel.RouteUrl); - - - return ResponseOutput.Result(success, new UserAddedReturnDTO { Id = saveItem.Id, UserCode = saveItem.UserCode }); + return ResponseOutput.Ok( new UserAddedReturnDTO { Id = saveItem.Id, UserCode = saveItem.UserCode }); } diff --git a/IRaCIS.Core.Application/Service/QC/NoneDicomStudyService.cs b/IRaCIS.Core.Application/Service/QC/NoneDicomStudyService.cs index fa912838f..e6a40c3bf 100644 --- a/IRaCIS.Core.Application/Service/QC/NoneDicomStudyService.cs +++ b/IRaCIS.Core.Application/Service/QC/NoneDicomStudyService.cs @@ -5,10 +5,10 @@ //-------------------------------------------------------------------- using Microsoft.AspNetCore.Mvc; using IRaCIS.Core.Application.Filter; -using Nito.AsyncEx; using System.ComponentModel.DataAnnotations; using IRaCIS.Core.Application.Service; using IRaCIS.Core.Domain.Share; +using Medallion.Threading; namespace IRaCIS.Core.Application.Contracts { @@ -20,19 +20,19 @@ namespace IRaCIS.Core.Application.Contracts { private readonly IRepository _noneDicomStudyRepository; private readonly IRepository _noneDicomStudyFileRepository; - private readonly AsyncLock _mutex = new AsyncLock(); + private readonly IDistributedLockProvider _distributedLockProvider; private readonly QCCommon _qCCommon; public NoneDicomStudyService(IRepository noneDicomStudyRepository, QCCommon qCCommon, - IRepository noneDicomStudyFileRepository) + IRepository noneDicomStudyFileRepository, IDistributedLockProvider distributedLockProvider) { _qCCommon = qCCommon; _noneDicomStudyRepository = noneDicomStudyRepository; _noneDicomStudyFileRepository = noneDicomStudyFileRepository; - + _distributedLockProvider = distributedLockProvider; } @@ -62,7 +62,9 @@ namespace IRaCIS.Core.Application.Contracts } NoneDicomStudy? optEntity = null; - using (await _mutex.LockAsync()) + var @lock = _distributedLockProvider.CreateLock($"NoneDicomCode"); + + using (await @lock.AcquireAsync()) { if (addOrEditNoneDicomStudy.Id == Guid.Empty || addOrEditNoneDicomStudy.Id == null) { diff --git a/IRaCIS.Core.Application/Service/QC/QCOperationService.cs b/IRaCIS.Core.Application/Service/QC/QCOperationService.cs index 207e9c30c..b714730ae 100644 --- a/IRaCIS.Core.Application/Service/QC/QCOperationService.cs +++ b/IRaCIS.Core.Application/Service/QC/QCOperationService.cs @@ -10,13 +10,13 @@ using WinSCP; using Newtonsoft.Json; using IRaCIS.Core.Infrastructure; using IRaCIS.Core.Application.Service.Inspection.DTO; -using Nito.AsyncEx; using System.ComponentModel.DataAnnotations; using IRaCIS.Core.Application.Auth; using IRaCIS.Core.Application.Helper; using IRaCIS.Core.Application.ViewModel; using IRaCIS.Core.Domain.Models; using IRaCIS.Core.Application.Service; +using Medallion.Threading; namespace IRaCIS.Core.Application.Image.QA { @@ -35,8 +35,7 @@ namespace IRaCIS.Core.Application.Image.QA private readonly IRepository _trialRepository; private readonly IRepository _visitTaskRepository; private readonly IVisitTaskHelpeService _IVisitTaskHelpeService; - - private readonly AsyncLock _mutex = new AsyncLock(); + private readonly IDistributedLockProvider _distributedLockProvider; public QCOperationService(IRepository subjectVisitRepository, IRepository qcChallengeRepository, @@ -48,7 +47,8 @@ namespace IRaCIS.Core.Application.Image.QA IRepository readingClinicalDataRepository, IRepository qCChallengeDialogrepository, IRepository checkChallengeDialogrepository, - IVisitTaskHelpeService visitTaskHelpeService + IVisitTaskHelpeService visitTaskHelpeService, + IDistributedLockProvider distributedLockProvider ) { _subjectVisitRepository = subjectVisitRepository; @@ -62,6 +62,7 @@ namespace IRaCIS.Core.Application.Image.QA _trialRepository = trialRepository; this._visitTaskRepository = visitTaskRepository; _IVisitTaskHelpeService = visitTaskHelpeService; + _distributedLockProvider = distributedLockProvider; } #region QC质疑 以及回复 关闭 @@ -108,9 +109,9 @@ namespace IRaCIS.Core.Application.Image.QA var trialConfig = (await _trialRepository.Where(t => t.Id == trialId).Select(t => new { TrialId = t.Id, t.QCProcessEnum, t.IsImageConsistencyVerification }).FirstOrDefaultAsync()).IfNullThrowException(); + var @lock = _distributedLockProvider.CreateLock($"QCChallengeCode"); - - using (await _mutex.LockAsync()) + using (await @lock.AcquireAsync()) { //获取编号 var code = _qcChallengeRepository.Where(t => t.TrialId == trialId).Select(t => t.Code).DefaultIfEmpty().Max(); diff --git a/IRaCIS.Core.Application/Service/SiteSurvey/TrialSiteSurveyService.cs b/IRaCIS.Core.Application/Service/SiteSurvey/TrialSiteSurveyService.cs index 09a8225d9..2c6e899d9 100644 --- a/IRaCIS.Core.Application/Service/SiteSurvey/TrialSiteSurveyService.cs +++ b/IRaCIS.Core.Application/Service/SiteSurvey/TrialSiteSurveyService.cs @@ -49,7 +49,6 @@ namespace IRaCIS.Core.Application.Contracts _mailVerificationService = mailVerificationService; } - private object lockObj { get; set; } = new object(); /// /// 发送验证码 @@ -801,7 +800,9 @@ namespace IRaCIS.Core.Application.Contracts if (sysUserInfo == null) { - lock (lockObj) + var @lock = _distributedLockProvider.CreateLock($"UserCode"); + + using (await @lock.AcquireAsync()) { var saveItem = _mapper.Map(item); diff --git a/IRaCIS.Core.Application/Service/TrialSiteUser/TrialExternalUserService.cs b/IRaCIS.Core.Application/Service/TrialSiteUser/TrialExternalUserService.cs index 94bb318c3..309cbdd1d 100644 --- a/IRaCIS.Core.Application/Service/TrialSiteUser/TrialExternalUserService.cs +++ b/IRaCIS.Core.Application/Service/TrialSiteUser/TrialExternalUserService.cs @@ -16,6 +16,7 @@ using Panda.DynamicWebApi.Attributes; using IRaCIS.Core.Application.Auth; using IRaCIS.Application.Services; using IRaCIS.Core.Application.Filter; +using Medallion.Threading; namespace IRaCIS.Core.Application.Service { @@ -31,10 +32,11 @@ namespace IRaCIS.Core.Application.Service private readonly IRepository _trialSiteSurveyUserRepository; private readonly IRepository _trialSiteUserRepository; private readonly IMailVerificationService _mailVerificationService; + private readonly IDistributedLockProvider _distributedLockProvider; public TrialExternalUserService(IRepository trialExternalUseRepository, IRepository userRepository, IRepository trialUserRepository, IRepository trialSiteSurveyUserRepository, IRepository trialSiteUserRepository, - IMailVerificationService mailVerificationService) + IMailVerificationService mailVerificationService, IDistributedLockProvider distributedLockProvider) { _trialExternalUseRepository = trialExternalUseRepository; _userRepository = userRepository; @@ -43,6 +45,7 @@ namespace IRaCIS.Core.Application.Service _trialSiteUserRepository = trialSiteUserRepository; _mailVerificationService = mailVerificationService; + _distributedLockProvider = distributedLockProvider; } @@ -75,121 +78,125 @@ namespace IRaCIS.Core.Application.Service if (addOrEditTrialExternalUser.Id == null) { - var existSysUser = await _userRepository.FirstOrDefaultAsync(t => t.EMail == addOrEditTrialExternalUser.Email && t.UserTypeId == addOrEditTrialExternalUser.UserTypeId); + var @lock = _distributedLockProvider.CreateLock($"UserCode"); - if (existSysUser != null) + using (await @lock.AcquireAsync()) { - if (existSysUser.LastName != addOrEditTrialExternalUser.LastName || existSysUser.FirstName != addOrEditTrialExternalUser.FirstName) + var existSysUser = await _userRepository.FirstOrDefaultAsync(t => t.EMail == addOrEditTrialExternalUser.Email && t.UserTypeId == addOrEditTrialExternalUser.UserTypeId); + + if (existSysUser != null) { - //$"该用户在系统中的用户名为:{existSysUser.LastName + " / " + existSysUser.FirstName} 电话:{existSysUser.Phone},与填写信息存在不一致项, 请将界面信息修改为与系统一致,再进行保存", - return ResponseOutput.NotOk(_localizer["TrialExternalUser_Inconsistency", existSysUser.LastName + " / " + existSysUser.FirstName, existSysUser.Phone], new { existSysUser.LastName, existSysUser.FirstName, existSysUser.Phone, existSysUser.IsZhiZhun, existSysUser.IsTestUser }, ApiResponseCodeEnum.NeedTips); + if (existSysUser.LastName != addOrEditTrialExternalUser.LastName || existSysUser.FirstName != addOrEditTrialExternalUser.FirstName) + { + //$"该用户在系统中的用户名为:{existSysUser.LastName + " / " + existSysUser.FirstName} 电话:{existSysUser.Phone},与填写信息存在不一致项, 请将界面信息修改为与系统一致,再进行保存", + return ResponseOutput.NotOk(_localizer["TrialExternalUser_Inconsistency", existSysUser.LastName + " / " + existSysUser.FirstName, existSysUser.Phone], new { existSysUser.LastName, existSysUser.FirstName, existSysUser.Phone, existSysUser.IsZhiZhun, existSysUser.IsTestUser }, ApiResponseCodeEnum.NeedTips); + } + } - } + //处理 生成账户 - //处理 生成账户 - - if (await _trialExternalUseRepository.AnyAsync(t => - t.Email == addOrEditTrialExternalUser.Email && - t.UserTypeId == addOrEditTrialExternalUser.UserTypeId && t.TrialId == addOrEditTrialExternalUser.TrialId)) - { - //---系统已经存在与列表中填写的邮箱和用户类型相同的账户,请确认。 - return ResponseOutput.NotOk(_localizer["TrialExternalUser_EmailTypeDuplicate"]); - } + if (await _trialExternalUseRepository.AnyAsync(t => + t.Email == addOrEditTrialExternalUser.Email && + t.UserTypeId == addOrEditTrialExternalUser.UserTypeId && t.TrialId == addOrEditTrialExternalUser.TrialId)) + { + //---系统已经存在与列表中填写的邮箱和用户类型相同的账户,请确认。 + return ResponseOutput.NotOk(_localizer["TrialExternalUser_EmailTypeDuplicate"]); + } - var addEntity = _mapper.Map(addOrEditTrialExternalUser); + var addEntity = _mapper.Map(addOrEditTrialExternalUser); - await _trialExternalUseRepository.AddAsync(addEntity); + await _trialExternalUseRepository.AddAsync(addEntity); - var existUser = await _userRepository.FirstOrDefaultAsync(t => t.EMail == addOrEditTrialExternalUser.Email && t.UserTypeId == addOrEditTrialExternalUser.UserTypeId); - var trialType = await _repository.Where(t => t.Id == addOrEditTrialExternalUser.TrialId).Select(t => t.TrialType).FirstOrDefaultAsync(); + var existUser = await _userRepository.FirstOrDefaultAsync(t => t.EMail == addOrEditTrialExternalUser.Email && t.UserTypeId == addOrEditTrialExternalUser.UserTypeId); + var trialType = await _repository.Where(t => t.Id == addOrEditTrialExternalUser.TrialId).Select(t => t.TrialType).FirstOrDefaultAsync(); - if (existUser != null) - { - addEntity.IsSystemUser = true; - addEntity.SystemUserId = existUser.Id; + if (existUser != null) + { + addEntity.IsSystemUser = true; + addEntity.SystemUserId = existUser.Id; - } - else - { + } + else + { - //生成账户 并插入 + //生成账户 并插入 - var generateUser = _mapper.Map(addOrEditTrialExternalUser); + var generateUser = _mapper.Map(addOrEditTrialExternalUser); + + if (trialType == TrialType.NoneOfficial) + { + generateUser.IsTestUser = true; + } + + // 外部人员生成账号 都是外部的 + generateUser.IsZhiZhun = false; + + generateUser.Code = _userRepository.Select(t => t.Code).DefaultIfEmpty().Max() + 1; + + + generateUser.UserCode = AppSettings.GetCodeStr(generateUser.Code, nameof(User)); + + generateUser.UserName = generateUser.UserCode; + + generateUser.UserTypeEnum = _repository.Where(t => t.Id == generateUser.UserTypeId).Select(t => t.UserTypeEnum).First(); + + generateUser.Password = MD5Helper.Md5("123456"); + + generateUser.Status = UserStateEnum.Disable; + + var newAddUser = await _repository.AddAsync(generateUser); + + + addEntity.IsSystemUser = false; + addEntity.SystemUserId = newAddUser.Id; + + + existUser = newAddUser; + + } + + #region 验证用户 能否加入 + + if (trialType == TrialType.OfficialTrial || trialType == TrialType.Training) + { + + if (existUser.IsTestUser) + { + //---正式类型 、培训类型的项目 不允许加入测试用户 + throw new BusinessValidationFailedException(_localizer["TrialExternalUser_TestUserNotAllowed"]); + + } + } if (trialType == TrialType.NoneOfficial) { - generateUser.IsTestUser = true; + + if (existUser.IsTestUser == false) + { + //---测试项目 不允许加入正式用户 + throw new BusinessValidationFailedException(_localizer["TrialExternalUser_FormalUserNotAllowed"]); + } } - // 外部人员生成账号 都是外部的 - generateUser.IsZhiZhun = false; - - generateUser.Code = _userRepository.Select(t => t.Code).DefaultIfEmpty().Max() + 1; + #endregion - generateUser.UserCode = AppSettings.GetCodeStr(generateUser.Code, nameof(User)); - - generateUser.UserName = generateUser.UserCode; - - generateUser.UserTypeEnum = _repository.Where(t => t.Id == generateUser.UserTypeId).Select(t => t.UserTypeEnum).First(); - - generateUser.Password = MD5Helper.Md5("123456"); - - generateUser.Status = UserStateEnum.Disable; - - var newAddUser = await _repository.AddAsync(generateUser); + await _trialExternalUseRepository.SaveChangesAsync(); - addEntity.IsSystemUser = false; - addEntity.SystemUserId = newAddUser.Id; - - - existUser = newAddUser; - - } - - #region 验证用户 能否加入 - - if (trialType == TrialType.OfficialTrial || trialType == TrialType.Training) - { - - if (existUser.IsTestUser) + //添加的时候就发邮件 现在省略 + if (addOrEditTrialExternalUser.IsSendEmail) { - //---正式类型 、培训类型的项目 不允许加入测试用户 - throw new BusinessValidationFailedException(_localizer["TrialExternalUser_TestUserNotAllowed"]); - - } - } - - if (trialType == TrialType.NoneOfficial) - { - - if (existUser.IsTestUser == false ) - { - //---测试项目 不允许加入正式用户 - throw new BusinessValidationFailedException(_localizer["TrialExternalUser_FormalUserNotAllowed"]); - } - } - - #endregion - - - await _trialExternalUseRepository.SaveChangesAsync(); - - - //添加的时候就发邮件 现在省略 - if (addOrEditTrialExternalUser.IsSendEmail) - { - await SendExternalUserJoinEmail(new TrialExternalUserSendEmail() - { - BaseUrl = addOrEditTrialExternalUser.BaseUrl, - RouteUrl = addOrEditTrialExternalUser.RouteUrl, - TrialId = addOrEditTrialExternalUser.TrialId, - SendUsers = new List() + await SendExternalUserJoinEmail(new TrialExternalUserSendEmail() + { + BaseUrl = addOrEditTrialExternalUser.BaseUrl, + RouteUrl = addOrEditTrialExternalUser.RouteUrl, + TrialId = addOrEditTrialExternalUser.TrialId, + SendUsers = new List() { new UserEmail() { @@ -199,12 +206,13 @@ namespace IRaCIS.Core.Application.Service SystemUserId=addEntity.SystemUserId } } - }); + }); + } + + + return ResponseOutput.Ok(addEntity.Id.ToString()); } - - return ResponseOutput.Ok(addEntity.Id.ToString()); - } else { From 8436a319f83905fec306e8c874874fb49d94da1a Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Thu, 12 Oct 2023 09:59:06 +0800 Subject: [PATCH 09/11] =?UTF-8?q?=E5=88=86=E5=B8=83=E5=BC=8F=E9=94=81?= =?UTF-8?q?=E9=A1=B9=E7=9B=AE=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Allocation/TaskConsistentRuleService.cs | 15 ++- .../Service/Common/MailService.cs | 11 +- .../SiteSurvey/TrialSiteSurveyService.cs | 118 +----------------- 3 files changed, 22 insertions(+), 122 deletions(-) diff --git a/IRaCIS.Core.Application/Service/Allocation/TaskConsistentRuleService.cs b/IRaCIS.Core.Application/Service/Allocation/TaskConsistentRuleService.cs index 1f8480a21..14ded501a 100644 --- a/IRaCIS.Core.Application/Service/Allocation/TaskConsistentRuleService.cs +++ b/IRaCIS.Core.Application/Service/Allocation/TaskConsistentRuleService.cs @@ -13,9 +13,9 @@ using IRaCIS.Core.Domain.Share; using System.Linq.Expressions; using IRaCIS.Core.Infra.EFCore.Common; using System.Linq; -using Nito.AsyncEx; using IRaCIS.Core.Application.Contracts; using IRaCIS.Core.Application.Filter; +using Medallion.Threading; namespace IRaCIS.Core.Application.Service { @@ -31,16 +31,17 @@ namespace IRaCIS.Core.Application.Service private readonly IRepository _subjectUserRepository; private readonly IRepository _subjectRepository; private readonly IRepository _enrollRepository; + private readonly IDistributedLockProvider _distributedLockProvider; - private readonly AsyncLock _mutex = new AsyncLock(); - public TaskConsistentRuleService(IRepository visitTaskRepository, IRepository enrollRepository, IRepository taskConsistentRuleRepository, IRepository subjectUserRepository, IRepository subjectRepository) + public TaskConsistentRuleService(IRepository visitTaskRepository, IRepository enrollRepository, IRepository taskConsistentRuleRepository, IRepository subjectUserRepository, IRepository subjectRepository, IDistributedLockProvider distributedLockProvider) { _taskConsistentRuleRepository = taskConsistentRuleRepository; _visitTaskRepository = visitTaskRepository; _subjectUserRepository = subjectUserRepository; _subjectRepository = subjectRepository; _enrollRepository = enrollRepository; + _distributedLockProvider = distributedLockProvider; } /// @@ -142,7 +143,9 @@ namespace IRaCIS.Core.Application.Service //var list = query.OrderByDescending(t => t.IsHaveGeneratedTask).ToList(); - using (await _mutex.LockAsync()) + var @lock = _distributedLockProvider.CreateLock($"VisitTaskCode"); + + using (await @lock.AcquireAsync()) { int maxCodeInt = 0; @@ -293,7 +296,9 @@ namespace IRaCIS.Core.Application.Service var configDoctorUserIdList = await doctorUserIdQuery.ToListAsync(); - using (await _mutex.LockAsync()) + var @lock = _distributedLockProvider.CreateLock($"VisitTaskCode"); + + using (await @lock.AcquireAsync()) { int maxCodeInt = 0; diff --git a/IRaCIS.Core.Application/Service/Common/MailService.cs b/IRaCIS.Core.Application/Service/Common/MailService.cs index bf195994b..7fac78714 100644 --- a/IRaCIS.Core.Application/Service/Common/MailService.cs +++ b/IRaCIS.Core.Application/Service/Common/MailService.cs @@ -7,6 +7,7 @@ using IRaCIS.Core.Application.Auth; using AutoMapper; using IRaCIS.Application.Contracts; using Microsoft.Extensions.Options; +using Medallion.Threading; namespace IRaCIS.Application.Services { @@ -53,7 +54,7 @@ namespace IRaCIS.Application.Services private readonly IRepository _userTypeRepository; private readonly IRepository _doctorTypeRepository; - + private readonly IDistributedLockProvider _distributedLockProvider; private readonly SystemEmailSendConfig _systemEmailConfig; @@ -67,7 +68,7 @@ namespace IRaCIS.Application.Services IRepository trialRepository, IRepository userTypeRepository, IRepository doctorTypeRepository, - IMapper mapper, IOptionsMonitor systemEmailConfig) + IMapper mapper, IOptionsMonitor systemEmailConfig, IDistributedLockProvider distributedLockProvider) { _systemEmailConfig = systemEmailConfig.CurrentValue; _verificationCodeRepository = verificationCodeRepository; @@ -83,7 +84,7 @@ namespace IRaCIS.Application.Services _userTypeRepository = userTypeRepository; _doctorTypeRepository = doctorTypeRepository; - + _distributedLockProvider = distributedLockProvider; } //重置邮箱 @@ -604,7 +605,9 @@ namespace IRaCIS.Application.Services var userType = await _userTypeRepository.FirstAsync(t => t.UserTypeEnum == UserTypeEnum.IndependentReviewer); - using (await _mutex.LockAsync()) + var @lock = _distributedLockProvider.CreateLock($"UserCode"); + + using (await @lock.AcquireAsync()) { var isDoctorHaveAccount = await _userRepository.AnyAsync(t => t.DoctorId == doctorId); diff --git a/IRaCIS.Core.Application/Service/SiteSurvey/TrialSiteSurveyService.cs b/IRaCIS.Core.Application/Service/SiteSurvey/TrialSiteSurveyService.cs index 2c6e899d9..522885748 100644 --- a/IRaCIS.Core.Application/Service/SiteSurvey/TrialSiteSurveyService.cs +++ b/IRaCIS.Core.Application/Service/SiteSurvey/TrialSiteSurveyService.cs @@ -15,6 +15,7 @@ using MailKit.Security; using MimeKit; using IRaCIS.Core.Application.Helper; using IRaCIS.Core.Application.Filter; +using Medallion.Threading; namespace IRaCIS.Core.Application.Contracts { @@ -32,21 +33,23 @@ namespace IRaCIS.Core.Application.Contracts private readonly IRepository _trialUserRepository; private readonly ITokenService _tokenService; private readonly IMailVerificationService _mailVerificationService; + private readonly IDistributedLockProvider _distributedLockProvider; public TrialSiteSurveyService(IRepository trialSiteSurveyRepository, IRepository trialUserRepository, IRepository trialSiteUserSurveyRepository, IRepository userRepository, IRepository trialSiteRepository, IRepository doctorRepository, ITokenService tokenService, - IMailVerificationService mailVerificationService) + IMailVerificationService mailVerificationService, IDistributedLockProvider distributedLockProvider) { _trialSiteSurveyRepository = trialSiteSurveyRepository; _trialSiteUserSurveyRepository = trialSiteUserSurveyRepository; _userRepository = userRepository; _trialUserRepository = trialUserRepository; _trialSiteRepository = trialSiteRepository; - this._doctorRepository = doctorRepository; + _doctorRepository = doctorRepository; _tokenService = tokenService; _mailVerificationService = mailVerificationService; + _distributedLockProvider = distributedLockProvider; } @@ -903,118 +906,7 @@ namespace IRaCIS.Core.Application.Contracts - #region 废弃 - //Site 调研邀请 - public async Task SendInviteEmail(InviteEmailCommand inviteEmailCommand) - { - var trialInfo = await _repository.FirstOrDefaultAsync(t => t.Id == inviteEmailCommand.TrialId); - - - foreach (var item in inviteEmailCommand.UserList) - { - - var messageToSend = new MimeMessage(); - //发件地址 - messageToSend.From.Add(new MailboxAddress("GRR", "iracis_grr@163.com")); - //收件地址 - messageToSend.To.Add(new MailboxAddress(String.Empty, item.Email)); - //主题 - //$"[来自展影IRC] [{trialInfo.ResearchProgramNo}] 邀请信"; - messageToSend.Subject = _localizer["TrialSiteSurvey_IRCInvitation", trialInfo.ResearchProgramNo]; - - var builder = new BodyBuilder(); - - //找下系统中是否存在该用户类型的 并且邮箱 或者手机的账户 - var sysUserInfo = await _userRepository.Where(t => t.UserTypeId == item.UserTypeId && t.EMail == item.Email).Include(t => t.UserTypeRole).FirstOrDefaultAsync(); - - //int verificationCode = new Random().Next(100000, 1000000); - - //var baseApiUrl = baseUrl.Remove(baseUrl.IndexOf("#")) + "api"; - - - if (sysUserInfo == null) - { - - lock (lockObj) - { - var saveItem = _mapper.Map(item); - - saveItem.Code = _userRepository.Select(t => t.Code).DefaultIfEmpty().Max() + 1; - - saveItem.UserCode = AppSettings.GetCodeStr(saveItem.Code, nameof(User)); ; - - saveItem.UserName = saveItem.UserCode; - - saveItem.UserTypeEnum = _repository.Where(t => t.Id == saveItem.UserTypeId).Select(t => t.UserTypeEnum).First(); - - //saveItem.Password = MD5Helper.Md5(verificationCode.ToString()); - - _ = _repository.AddAsync(saveItem).Result; - - _ = _repository.SaveChangesAsync().Result; - - - sysUserInfo = saveItem; - } - - } - - - - builder.HtmlBody = @$" -
-
-
- {sysUserInfo.LastName + "/" + sysUserInfo.FirstName}: -
-
- {_localizer["TrialSiteSurvey_IRCInvitationContent", trialInfo.ResearchProgramNo]} -
- - - 查看并确认 - -
-
- "; - - - - messageToSend.Body = builder.ToMessageBody(); - - using (var smtp = new MailKit.Net.Smtp.SmtpClient()) - { - - smtp.ServerCertificateValidationCallback = (s, c, h, e) => true; - - smtp.MessageSent += (sender, args) => - { - - _ = _trialSiteUserSurveyRepository.BatchUpdateNoTrackingAsync(t => t.Id == item.Id, u => new TrialSiteUserSurvey() { IsGenerateSuccess = true, InviteState = TrialSiteUserStateEnum.HasSend, ConfirmTime = null, RejectReason = String.Empty, SystemUserId = sysUserInfo.Id, ExpireTime = DateTime.Now.AddDays(7) }).Result; - - }; - - - await smtp.ConnectAsync("smtp.163.com", 465, SecureSocketOptions.StartTls); - - - await smtp.AuthenticateAsync("iracis_grr@163.com", "XLWVQKZAEKLDWOAH"); - - - await smtp.SendAsync(messageToSend); - - - await smtp.DisconnectAsync(true); - } - - } - - - return ResponseOutput.Ok(); - } - - #endregion From 86a486b0605ebfca35e04e6963dc46ee8c14d9db Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Thu, 12 Oct 2023 10:09:32 +0800 Subject: [PATCH 10/11] =?UTF-8?q?=E5=88=86=E5=B8=83=E5=BC=8F=E7=BC=93?= =?UTF-8?q?=E5=AD=98=E7=BB=84=E4=BB=B6=E5=87=86=E5=A4=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.API/IRaCIS.Core.API.csproj | 3 +- IRaCIS.Core.API/Startup.cs | 2 +- .../_ServiceExtensions/EasyCachingSetup.cs | 13 ++++- IRaCIS.Core.API/appsettings.json | 20 ++++++++ .../IRaCIS.Core.Application.csproj | 4 +- .../IRaCIS.Core.Application.xml | 5 -- .../Interface/JsonPatchUserRequestExample.cs | 51 ------------------- 7 files changed, 36 insertions(+), 62 deletions(-) delete mode 100644 IRaCIS.Core.Application/Service/SiteSurvey/Interface/JsonPatchUserRequestExample.cs diff --git a/IRaCIS.Core.API/IRaCIS.Core.API.csproj b/IRaCIS.Core.API/IRaCIS.Core.API.csproj index c6af611a4..dbda38d25 100644 --- a/IRaCIS.Core.API/IRaCIS.Core.API.csproj +++ b/IRaCIS.Core.API/IRaCIS.Core.API.csproj @@ -70,7 +70,8 @@ - + + diff --git a/IRaCIS.Core.API/Startup.cs b/IRaCIS.Core.API/Startup.cs index 886e443fc..f8aca4e66 100644 --- a/IRaCIS.Core.API/Startup.cs +++ b/IRaCIS.Core.API/Startup.cs @@ -109,7 +109,7 @@ namespace IRaCIS.Core.API // MediatR Ϣ ¼ ӳ עhandlerӦϵ services.AddMediatR(typeof(ConsistencyVerificationHandler).Assembly); // EasyCaching - services.AddEasyCachingSetup(); + services.AddEasyCachingSetup(_configuration); //services.AddDistributedMemoryCache(); diff --git a/IRaCIS.Core.API/_ServiceExtensions/EasyCachingSetup.cs b/IRaCIS.Core.API/_ServiceExtensions/EasyCachingSetup.cs index 7d7a28c6a..6f9e53bcc 100644 --- a/IRaCIS.Core.API/_ServiceExtensions/EasyCachingSetup.cs +++ b/IRaCIS.Core.API/_ServiceExtensions/EasyCachingSetup.cs @@ -1,17 +1,26 @@ using EasyCaching.Core; +using EasyCaching.Core.Configurations; using EasyCaching.Interceptor.Castle; +using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; namespace IRaCIS.Core.API { - public static class EasyCachingSetup + public static class EasyCachingSetup { - public static void AddEasyCachingSetup(this IServiceCollection services) + public static void AddEasyCachingSetup(this IServiceCollection services, IConfiguration configuration) { services.AddEasyCaching(options => { options.UseInMemory(); + + //options.UseRedis(configuration, EasyCachingConstValue.DefaultRedisName).WithMessagePack(EasyCachingConstValue.DefaultRedisName); + + }); + + //services.ConfigureCastleInterceptor(options => options.CacheProviderName = EasyCachingConstValue.DefaultRedisName); + services.ConfigureCastleInterceptor(options => options.CacheProviderName = EasyCachingConstValue.DefaultInMemoryName); } } diff --git a/IRaCIS.Core.API/appsettings.json b/IRaCIS.Core.API/appsettings.json index f142d1f51..242ea4da5 100644 --- a/IRaCIS.Core.API/appsettings.json +++ b/IRaCIS.Core.API/appsettings.json @@ -55,6 +55,26 @@ "EnableReadDeepClone": true, "EnableWriteDeepClone": false } + }, + "redis": { + "MaxRdSecond": 120, + "EnableLogging": false, + "LockMs": 5000, + "SleepMs": 300, + "dbconfig": { + "Password": "xc@123456", + "IsSsl": false, + "SslHost": null, + "ConnectionTimeout": 5000, + "AllowAdmin": true, + "Endpoints": [ + { + "Host": "47.117.164.182", + "Port": 6379 + } + ], + "Database": 0 + } } }, "IRaCISImageStore": { diff --git a/IRaCIS.Core.Application/IRaCIS.Core.Application.csproj b/IRaCIS.Core.Application/IRaCIS.Core.Application.csproj index 4f74c24fb..1ea467582 100644 --- a/IRaCIS.Core.Application/IRaCIS.Core.Application.csproj +++ b/IRaCIS.Core.Application/IRaCIS.Core.Application.csproj @@ -67,7 +67,8 @@ - + + @@ -91,7 +92,6 @@ - true diff --git a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml index ce7fb263e..b510fcf9e 100644 --- a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml +++ b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml @@ -10274,11 +10274,6 @@ TrialSiteUserSurveyAddOrEdit 列表查询参数模型 - - - 实测 标注在服务方法上 没用 - - TrialSiteEquipmentSurveyService diff --git a/IRaCIS.Core.Application/Service/SiteSurvey/Interface/JsonPatchUserRequestExample.cs b/IRaCIS.Core.Application/Service/SiteSurvey/Interface/JsonPatchUserRequestExample.cs deleted file mode 100644 index 0fa6ff834..000000000 --- a/IRaCIS.Core.Application/Service/SiteSurvey/Interface/JsonPatchUserRequestExample.cs +++ /dev/null @@ -1,51 +0,0 @@ -using Microsoft.AspNetCore.JsonPatch.Operations; -using Swashbuckle.AspNetCore.Filters; - -namespace IRaCIS.Core.Application.Contracts -{ - /// - /// 实测 标注在服务方法上 没用 - /// - public class JsonPatchUserRequestExample : IExamplesProvider - { - public Operation[] GetExamples() - { - return new[] - { - new Operation - { - op = "replace", - path = "/name", - value = "Gordon" - }, - new Operation - { - op = "replace", - path = "/surname", - value = "Freeman" - } - }; - } - - object IExamplesProvider.GetExamples() - { - return new[] - { - new Operation - { - op = "replace", - path = "/name", - value = "Gordon" - }, - new Operation - { - op = "replace", - path = "/surname", - value = "Freeman" - } - }; - } - } - - -} From a1d8e2237cbef9e8c6d22d9796e7b03f3f392760 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Thu, 12 Oct 2023 10:12:22 +0800 Subject: [PATCH 11/11] =?UTF-8?q?=E5=88=A0=E9=99=A4JsonPatch?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.API/IRaCIS.Core.API.csproj | 1 - IRaCIS.Core.API/_ServiceExtensions/Swagger/SwaggerSetup.cs | 1 - 2 files changed, 2 deletions(-) diff --git a/IRaCIS.Core.API/IRaCIS.Core.API.csproj b/IRaCIS.Core.API/IRaCIS.Core.API.csproj index dbda38d25..ffbbb41b1 100644 --- a/IRaCIS.Core.API/IRaCIS.Core.API.csproj +++ b/IRaCIS.Core.API/IRaCIS.Core.API.csproj @@ -69,7 +69,6 @@ - diff --git a/IRaCIS.Core.API/_ServiceExtensions/Swagger/SwaggerSetup.cs b/IRaCIS.Core.API/_ServiceExtensions/Swagger/SwaggerSetup.cs index 4a16162e7..44bbb60f4 100644 --- a/IRaCIS.Core.API/_ServiceExtensions/Swagger/SwaggerSetup.cs +++ b/IRaCIS.Core.API/_ServiceExtensions/Swagger/SwaggerSetup.cs @@ -18,7 +18,6 @@ namespace IRaCIS.Core.API { public static void AddSwaggerSetup(this IServiceCollection services) { - services.AddSwaggerExamplesFromAssemblyOf(); services.AddSwaggerGen(options => {