diff --git a/IRaCIS.Core.API/IRaCIS.Core.API.csproj b/IRaCIS.Core.API/IRaCIS.Core.API.csproj index ba3a2d4e0..a6bbf319e 100644 --- a/IRaCIS.Core.API/IRaCIS.Core.API.csproj +++ b/IRaCIS.Core.API/IRaCIS.Core.API.csproj @@ -70,8 +70,8 @@ - - + + diff --git a/IRaCIS.Core.API/Startup.cs b/IRaCIS.Core.API/Startup.cs index 2d5f19e41..c157a1d94 100644 --- a/IRaCIS.Core.API/Startup.cs +++ b/IRaCIS.Core.API/Startup.cs @@ -110,7 +110,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/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 @@ -锘縰sing IRaCIS.Core.Application.Triggers; +锘縰sing 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.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 @@ 锘縰sing 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/_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 => { 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 ece94b800..7a5d93102 100644 --- a/IRaCIS.Core.Application/IRaCIS.Core.Application.csproj +++ b/IRaCIS.Core.Application/IRaCIS.Core.Application.csproj @@ -68,9 +68,12 @@ - + + + + true @@ -87,7 +90,6 @@ - true @@ -97,7 +99,6 @@ true - diff --git a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml index 56def288d..01b3b1464 100644 --- a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml +++ b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml @@ -1976,6 +1976,13 @@ + + + 鏄惁瀛樺湪PET + + + + 褰卞儚瀛︽暣浣撹偪鐦よ瘎浼 @@ -10348,11 +10355,6 @@ TrialSiteUserSurveyAddOrEdit 鍒楄〃鏌ヨ鍙傛暟妯″瀷 - - - 瀹炴祴 鏍囨敞鍦ㄦ湇鍔℃柟娉曚笂 娌$敤 - - TrialSiteEquipmentSurveyService 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 5f6e58120..7fac78714 100644 --- a/IRaCIS.Core.Application/Service/Common/MailService.cs +++ b/IRaCIS.Core.Application/Service/Common/MailService.cs @@ -6,8 +6,8 @@ using Microsoft.AspNetCore.Hosting; using IRaCIS.Core.Application.Auth; using AutoMapper; using IRaCIS.Application.Contracts; -using Nito.AsyncEx; using Microsoft.Extensions.Options; +using Medallion.Threading; namespace IRaCIS.Application.Services { @@ -54,8 +54,7 @@ namespace IRaCIS.Application.Services private readonly IRepository _userTypeRepository; private readonly IRepository _doctorTypeRepository; - - private readonly AsyncLock _mutex = new AsyncLock(); + private readonly IDistributedLockProvider _distributedLockProvider; private readonly SystemEmailSendConfig _systemEmailConfig; @@ -69,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; @@ -85,7 +84,7 @@ namespace IRaCIS.Application.Services _userTypeRepository = userTypeRepository; _doctorTypeRepository = doctorTypeRepository; - + _distributedLockProvider = distributedLockProvider; } //閲嶇疆閭 @@ -606,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/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 //姝e父淇濆瓨 涓嶅仛澶勭悊 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銆丆T") + if (modality == "PT銆丆T") { 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/ReadingCalculate/LuganoCalculateService.cs b/IRaCIS.Core.Application/Service/ReadingCalculate/LuganoCalculateService.cs index 2a1e48f84..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) { @@ -959,7 +968,7 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate FirstAddTaskId=x.FirstAddTaskId, QuestionId=x.QuestionId, QuestionType=x.QuestionType, - + OrderMarkName=x.OrderMarkName, }).ToListAsync(); questionMarkList.ForEach(x => { @@ -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/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 @@ -锘縰sing 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" - } - }; - } - } - - -} diff --git a/IRaCIS.Core.Application/Service/SiteSurvey/TrialSiteSurveyService.cs b/IRaCIS.Core.Application/Service/SiteSurvey/TrialSiteSurveyService.cs index 09a8225d9..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,24 +33,25 @@ 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; } - private object lockObj { get; set; } = new object(); /// /// 鍙戦侀獙璇佺爜 @@ -801,7 +803,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); @@ -902,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 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) + { + //---姝e紡绫诲瀷 銆佸煿璁被鍨嬬殑椤圭洰 涓嶅厑璁稿姞鍏ユ祴璇曠敤鎴 + 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) { - //---姝e紡绫诲瀷 銆佸煿璁被鍨嬬殑椤圭洰 涓嶅厑璁稿姞鍏ユ祴璇曠敤鎴 - 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 { 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 diff --git a/IRaCIS.Core.Application/TestService.cs b/IRaCIS.Core.Application/TestService.cs index c3e953a73..46153bca6 100644 --- a/IRaCIS.Core.Application/TestService.cs +++ b/IRaCIS.Core.Application/TestService.cs @@ -3,13 +3,17 @@ 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; using Microsoft.Extensions.Caching.Distributed; +using Microsoft.Extensions.Logging; 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 +24,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 +36,13 @@ namespace IRaCIS.Application.Services private readonly IOptionsMonitor _basicConfig; private readonly IRepository _visitTaskRepositoryy; + private readonly IDistributedLockProvider _distributedLockProvider; - public TestService(IRepository dicRepository, IRepository trialRepository/*, IDistributedCache cache*/ + private readonly ILogger _logger; - , IOptionsMonitor systemEmailConfig, IOptionsMonitor basicConfig, IRepository visitTaskRepository) + public TestService(IRepository dicRepository, IRepository trialRepository,ILogger logger + + , IOptionsMonitor systemEmailConfig, IOptionsMonitor basicConfig, IRepository visitTaskRepository, IDistributedLockProvider distributedLockProvider) { _visitTaskRepositoryy = visitTaskRepository; @@ -42,11 +51,35 @@ namespace IRaCIS.Application.Services _dicRepository = dicRepository; _trialRepository = trialRepository; + + _distributedLockProvider= distributedLockProvider; + + _logger= logger; //_cache = cache; } + [AllowAnonymous] + public async Task TestDistributedLock( ) + { + Console.WriteLine($"鎴戣繘鏉ヤ簡褰撳墠鍊兼槸锛" + IntValue); + _logger.LogWarning($"鎴戣繘鏉ヤ簡褰撳墠鍊兼槸锛" + IntValue); + + var @lock = _distributedLockProvider.CreateLock($"UserAccount"); + + using (await @lock.AcquireAsync()) + { + await Task.Delay(4); + IntValue--; + + _logger.LogWarning( IntValue.ToString()); + Console.WriteLine(IntValue); + } + + return ResponseOutput.Ok(IntValue); + } + [AllowAnonymous] public async Task InternationazitionInit()