Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is failing Details

IRC_NewDev
hang 2024-08-21 17:26:18 +08:00
commit 9356e6ed7e
13 changed files with 176 additions and 136 deletions

View File

@ -9,6 +9,7 @@ using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using SharpCompress.Common;
using ZiggyCreatures.Caching.Fusion;
namespace IRaCIS.Application.Services.BackGroundJob
{
@ -21,77 +22,45 @@ namespace IRaCIS.Application.Services.BackGroundJob
Task InitHangfireJobTaskAsync();
}
public class IRaCISCHangfireJob : IIRaCISHangfireJob
public class IRaCISCHangfireJob(IRepository<Trial> _trialRepository,
IEasyCachingProvider _provider,
ILogger<IRaCISCHangfireJob> _logger,
IRepository<SystemAnonymization> _systemAnonymizationRepository,
IRepository<Internationalization> _internationalizationRepository,
IRepository<TrialEmailNoticeConfig> _trialEmailNoticeConfigRepository
) : IIRaCISHangfireJob
{
public static string JsonFileFolder = Path.Combine(AppContext.BaseDirectory, StaticData.Folder.Resources);
private readonly IRepository<Trial> _trialRepository;
private readonly IEasyCachingProvider _provider;
private readonly ILogger<IRaCISCHangfireJob> _logger;
private readonly IRepository<SystemAnonymization> _systemAnonymizationRepository;
private readonly IRepository<TrialEmailNoticeConfig> _trialEmailNoticeConfigRepository;
private readonly IRepository<Internationalization> _internationalizationRepository;
public IRaCISCHangfireJob(IRepository<Trial> trialRepository, ILogger<IRaCISCHangfireJob> logger, IEasyCachingProvider provider, IRepository<TrialEmailNoticeConfig> trialEmailNoticeConfigRepository, IRepository<Internationalization> internationalizationRepository, IRepository<SystemAnonymization> systemAnonymizationRepository)
{
_trialRepository = trialRepository;
_provider = provider;
_logger = logger;
_trialEmailNoticeConfigRepository = trialEmailNoticeConfigRepository;
_internationalizationRepository = internationalizationRepository;
_systemAnonymizationRepository = systemAnonymizationRepository;
}
public async Task InitHangfireJobTaskAsync()
{
_logger.LogInformation("项目启动 hangfire 任务初始化 执行开始~");
//项目状态 立即加载到缓存中
await MemoryCacheTrialStatusAsync();
await MemoryCacheAnonymizeData();
//创建项目缓存 定时任务
HangfireJobHelper.AddOrUpdateInitCronJob<IIRaCISHangfireJob>("RecurringJob_Cache_TrialState", t => t.MemoryCacheTrialStatusAsync(), Cron.Daily());
//初始化
//初始化国际化
await InternationalizationHelper.InitInternationlizationDataAndWatchJsonFileAsync(_internationalizationRepository);
//创建邮件定时任务
await InitSysAndTrialCronJobAsync();
#region 废弃
////项目状态 立即加载到缓存中
//await MemoryCacheTrialStatusAsync();
////await MemoryCacheAnonymizeData();
////创建项目缓存 定时任务
//HangfireJobHelper.AddOrUpdateInitCronJob<IIRaCISHangfireJob>("RecurringJob_Cache_TrialState", t => t.MemoryCacheTrialStatusAsync(), Cron.Daily());
#endregion
_logger.LogInformation("项目启动 hangfire 任务初始化 执行结束");
}
/// <summary>
/// 缓存项目状态
/// </summary>
/// <returns></returns>
public async Task MemoryCacheTrialStatusAsync()
{
var list = await _trialRepository.Select(t => new { TrialId = t.Id, TrialStatusStr = t.TrialStatusStr })
.ToListAsync();
list.ForEach(t => _provider.Set(t.TrialId.ToString(), t.TrialStatusStr, TimeSpan.FromDays(7)));
}
public async Task MemoryCacheAnonymizeData()
{
var systemAnonymizationList = await _systemAnonymizationRepository.Where(t => t.IsEnable).ToListAsync();
_provider.Set(StaticData.Anonymize.Anonymize_AddFixedFiled, systemAnonymizationList.Where(t => t.IsAdd && t.IsFixed).ToList(), TimeSpan.FromDays(7));
_provider.Set(StaticData.Anonymize.Anonymize_AddIRCInfoFiled, systemAnonymizationList.Where(t => t.IsAdd && t.IsFixed == false).ToList(), TimeSpan.FromDays(7));
_provider.Set(StaticData.Anonymize.Anonymize_FixedField, systemAnonymizationList.Where(t => t.IsAdd == false && t.IsFixed).ToList(), TimeSpan.FromDays(7));
_provider.Set(StaticData.Anonymize.Anonymize_IRCInfoField, systemAnonymizationList.Where(t => t.IsAdd == false && t.IsFixed == false).ToList(), TimeSpan.FromDays(7));
}
@ -136,6 +105,36 @@ namespace IRaCIS.Application.Services.BackGroundJob
}
#region 废弃 前端上传的时候获取
/// <summary>
/// 缓存项目状态--之前是启动的时候就获取所有的项目进行缓存,加上定时任务刷新,现在的话,改为是按照需要进行缓存请求数据库
/// </summary>
/// <returns></returns>
public async Task MemoryCacheTrialStatusAsync()
{
var list = await _trialRepository.Select(t => new { TrialId = t.Id, TrialStatusStr = t.TrialStatusStr })
.ToListAsync();
list.ForEach(t => _provider.Set(t.TrialId.ToString(), t.TrialStatusStr, TimeSpan.FromDays(7)));
}
public async Task MemoryCacheAnonymizeData()
{
var systemAnonymizationList = await _systemAnonymizationRepository.Where(t => t.IsEnable).ToListAsync();
_provider.Set(StaticData.Anonymize.Anonymize_AddFixedFiled, systemAnonymizationList.Where(t => t.IsAdd && t.IsFixed).ToList(), TimeSpan.FromDays(7));
_provider.Set(StaticData.Anonymize.Anonymize_AddIRCInfoFiled, systemAnonymizationList.Where(t => t.IsAdd && t.IsFixed == false).ToList(), TimeSpan.FromDays(7));
_provider.Set(StaticData.Anonymize.Anonymize_FixedField, systemAnonymizationList.Where(t => t.IsAdd == false && t.IsFixed).ToList(), TimeSpan.FromDays(7));
_provider.Set(StaticData.Anonymize.Anonymize_IRCInfoField, systemAnonymizationList.Where(t => t.IsAdd == false && t.IsFixed == false).ToList(), TimeSpan.FromDays(7));
}
#endregion
}

View File

@ -9,6 +9,7 @@ using Panda.DynamicWebApi.Attributes;
using System.Diagnostics.CodeAnalysis;
using IRaCIS.Core.Domain.Share;
using Microsoft.AspNetCore.Mvc;
using ZiggyCreatures.Caching.Fusion;
namespace IRaCIS.Core.Application
{
@ -32,7 +33,7 @@ namespace IRaCIS.Core.Application
public IWebHostEnvironment _hostEnvironment { get; set; }
public IFusionCache _fusionCache { get; set; }
public static IResponseOutput Null404NotFound<TEntity>(TEntity? businessObject) where TEntity : class
@ -60,6 +61,9 @@ namespace IRaCIS.Core.Application
[MemberNotNull(nameof(_hostEnvironment))]
public IWebHostEnvironment _hostEnvironment { get; set; }
[MemberNotNull(nameof(_fusionCache))]
public IFusionCache _fusionCache { get; set; }
}
#endregion
@ -81,8 +85,9 @@ namespace IRaCIS.Core.Application
[MemberNotNull(nameof(_localizer))]
public IStringLocalizer _localizer { get; set; }
[MemberNotNull(nameof(_fusionCache))]
public IFusionCache _fusionCache { get; set; }
}
[TypeFilter(typeof(UnifiedApiResultFilter))]
@ -97,6 +102,8 @@ namespace IRaCIS.Core.Application
public IStringLocalizer _localizer { get; set; }
public IFusionCache _fusionCache { get; set; }
public static IResponseOutput Null404NotFound<TEntity>(TEntity? businessObject) where TEntity : class
{
return new ResponseOutput<string>()

View File

@ -1,10 +1,12 @@
using EasyCaching.Core;
using IRaCIS.Core.Application.Helper;
using IRaCIS.Core.Domain.Share;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.Localization;
using System.Text.RegularExpressions;
using ZiggyCreatures.Caching.Fusion;
using static IRaCIS.Core.Domain.Share.StaticData;
namespace IRaCIS.Core.Application.Filter
@ -16,47 +18,36 @@ namespace IRaCIS.Core.Application.Filter
{
private readonly IEasyCachingProvider _provider;
private readonly IUserInfo _userInfo;
private readonly IFusionCache _fusionCache;
public IStringLocalizer _localizer;
private readonly List<string> _trialOptList=new List<string>();
private readonly IRepository<Trial> _trialRepository;
private readonly List<string> _trialOptList = new List<string>();
public TrialResourceFilter(IEasyCachingProvider provider, IStringLocalizer localizer , IUserInfo userInfo, string trialOpt = null, string trialOpt2 = null, string trialOpt3 = null)
public TrialResourceFilter(IFusionCache fusionCache, IRepository<Trial> trialRepository, IEasyCachingProvider provider, IStringLocalizer localizer, IUserInfo userInfo, string trialOpt = null, string trialOpt2 = null, string trialOpt3 = null)
{
_fusionCache = fusionCache;
_provider = provider;
_userInfo = userInfo;
_localizer = localizer;
//_trialOpt = trialOpt;
_trialRepository = trialRepository;
if (!string.IsNullOrWhiteSpace(trialOpt)) _trialOptList.Add(trialOpt.Trim());
if (!string.IsNullOrWhiteSpace(trialOpt)) _trialOptList.Add(trialOpt.Trim());
if (!string.IsNullOrWhiteSpace(trialOpt2)) _trialOptList.Add(trialOpt2.Trim());
if (!string.IsNullOrWhiteSpace(trialOpt3)) _trialOptList.Add(trialOpt3.Trim());
}
//public TrialResourceFilter(IEasyCachingProvider provider, IUserInfo userInfo)
//{
// _provider = provider;
// _userInfo = userInfo;
//}
//优先选择异步的方法
public async Task OnResourceExecutionAsync(ResourceExecutingContext context, ResourceExecutionDelegate next)
{
// var typeFilter = context.ActionDescriptor.EndpointMetadata.Where(t => t.GetType() == typeof(TypeFilterAttribute)).Select(t => (TypeFilterAttribute)t).ToList().FirstOrDefault();
//var _trialOptList= typeFilter.Arguments.Select(t => t.ToString()).ToList();
// var typeFilter = context.ActionDescriptor.EndpointMetadata.Where(t => t.GetType() == typeof(TypeFilterAttribute)).Select(t => (TypeFilterAttribute)t).ToList().FirstOrDefault();
//var _trialOptList= typeFilter.Arguments.Select(t => t.ToString()).ToList();
#region 处理新的用户类型,不能操作项目相关接口
// 后期列举出具体的类型,其他任何用户类型,都不允许操作
if (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.CRA && _userInfo.RequestUrl.ToLower()!= "TrialDocument/userConfirm".ToLower())
if (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.CRA && _userInfo.RequestUrl.ToLower() != "TrialDocument/userConfirm".ToLower())
{
//---对不起,您的账户没有操作权限。
context.Result = new JsonResult(ResponseOutput.NotOk(_localizer["TrialResource_NoAccessPermission"]));
@ -97,7 +88,7 @@ namespace IRaCIS.Core.Application.Filter
}
else
{
//---正则取请求Refer 中trialId 失败,请联系开发人员核查
//---正则取请求Refer 中trialId 失败,请联系开发人员核查
context.Result = new JsonResult(ResponseOutput.NotOk(_localizer["TrialResource_ReferTrialIdFailed"]));
}
@ -128,20 +119,20 @@ namespace IRaCIS.Core.Application.Filter
if (matchResult.Success)
{
//有可能匹配错误 "trialId":"","documentId":"b8180000-3e2c-0016-9fe0-08da33f96236" 从缓存里面验证下
var cacheResultDic = _provider.GetAll<string>(new[] { matchResult.Value });
var trialStatusStr = cacheResultDic[matchResult.Value.ToLower()].Value;
trialIdStr = matchResult.Value;
if (!string.IsNullOrWhiteSpace(trialStatusStr))
var trialStatusStr = await _fusionCache.GetOrSetAsync(CacheKeys.Trial(trialIdStr), _ => CacheHelper.GetTrialStatusAsync(Guid.Parse(trialIdStr), _trialRepository), TimeSpan.FromDays(7));
if (string.IsNullOrWhiteSpace(trialStatusStr))
{
trialIdStr = matchResult.Value;
//数据库 检查该项目Id不对
context.Result = new JsonResult(ResponseOutput.NotOk(_localizer["TrialResource_ReferTrialIdFailed"]));
}
}
else
{
//---正则取请求Refer 中trialId 失败,请联系开发人员核查
//---正则取请求Refer 中trialId 失败,请联系开发人员核查
context.Result = new JsonResult(ResponseOutput.NotOk(_localizer["TrialResource_ReferTrialIdFailed"]));
}
@ -153,34 +144,12 @@ namespace IRaCIS.Core.Application.Filter
}
//通过path 或者body 找到trialId 了
if ( !string.IsNullOrWhiteSpace(trialIdStr))
if (!string.IsNullOrWhiteSpace(trialIdStr))
{
//如果没缓存数据,可能定时任务没执行或者缓存丢失 在此重新缓存
if (_provider.GetCount() == 0)
{
var _trialRepository = context.HttpContext.RequestServices.GetService(typeof(IRepository<Trial>)) as IRepository<Trial>;
var list = _trialRepository.IfNullThrowException().Select(t => new { TrialId = t.Id, TrialStatusStr = t.TrialStatusStr })
.ToList();
list.ForEach(t => _provider.Set(t.TrialId.ToString(), t.TrialStatusStr, TimeSpan.FromDays(7)));
}
var cacheResultDic = _provider.GetAll<string>(new[] { trialIdStr });
var trialStatusStr = cacheResultDic[trialIdStr].Value;
//意外 导致缓存过期,调整服务器时间,测试不想重启程序
if (string.IsNullOrWhiteSpace(trialStatusStr))
{
var trialRepository = context.HttpContext.RequestServices.GetService(typeof(IRepository<Trial>)) as IRepository<Trial>;
trialStatusStr = trialRepository?.Where(t => t.Id == Guid.Parse(trialIdStr)).Select(t => t.TrialStatusStr).FirstOrDefault();
}
var trialStatusStr = await _fusionCache.GetOrSetAsync(CacheKeys.Trial(trialIdStr), _ => CacheHelper.GetTrialStatusAsync(Guid.Parse(trialIdStr), _trialRepository), TimeSpan.FromDays(7));
// 这里是统一拦截 项目有关的操作允许情况(特殊的地方比如项目配置有的在多种状态初始化ongoing都可以操作有的仅仅在Initializing还有 项目添加和更新,不走这里,特殊处理,不然在这里显得很乱,判断是哪个接口)
if (trialStatusStr == StaticData.TrialState.TrialOngoing || _trialOptList.Any(t=>t== TrialOpt.BeforeOngoingCantOpt) )
if (trialStatusStr == StaticData.TrialState.TrialOngoing || _trialOptList.Any(t => t == TrialOpt.BeforeOngoingCantOpt))
{
await next.Invoke();
@ -189,14 +158,14 @@ namespace IRaCIS.Core.Application.Filter
// 项目停止、或者完成 不允许操作
else
{
//---本次请求被配置规则拦截:项目状态处于进行中时,才允许操作,若此处逻辑有误,请联系开发人员修改
//---本次请求被配置规则拦截:项目状态处于进行中时,才允许操作,若此处逻辑有误,请联系开发人员修改
context.Result = new JsonResult(ResponseOutput.NotOk(_localizer["TrialResource_InterceptedProjectStatusRule"]));
}
}
//添加项目 签名系统文档的时候 不做拦截 但是更新项目 签名项目文档的时候需要拦截
else if (_trialOptList.Any(t => t == TrialOpt.AddOrUpdateTrial ||t ==TrialOpt.SignSystemDocNoTrialId))
else if (_trialOptList.Any(t => t == TrialOpt.AddOrUpdateTrial || t == TrialOpt.SignSystemDocNoTrialId))
{
await next.Invoke();
}

View File

@ -0,0 +1,27 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace IRaCIS.Core.Application.Helper
{
public static class CacheKeys
{
public static string Trial(string trialIdStr) => $"TrialId:{trialIdStr}";
// 你可以为其他实体和模块定义更多的键
}
public static class CacheHelper
{
public static async Task<string?> GetTrialStatusAsync(Guid trialId, IRepository<Trial> _trialRepository)
{
var statusStr = await _trialRepository.Where(t => t.Id == trialId, ignoreQueryFilters: true).Select(t => t.TrialStatusStr).FirstOrDefaultAsync();
return statusStr;
}
}
}

View File

@ -13315,7 +13315,7 @@
</member>
<member name="M:IRaCIS.Application.Services.BackGroundJob.IRaCISCHangfireJob.MemoryCacheTrialStatusAsync">
<summary>
缓存项目状态
缓存项目状态--之前是启动的时候就获取所有的项目进行缓存,加上定时任务刷新,现在的话,改为是按照需要进行缓存请求数据库
</summary>
<returns></returns>
</member>

View File

@ -33,7 +33,10 @@ namespace IRaCIS.Core.Application.ViewModel
public class TaskConsistentRuleBasic : TaskConsistentRuleAddOrEdit
{
/// <summary>
/// 任务展示访视 读片任务显示是否顺序
/// </summary>
public ReadingOrder IsReadingTaskViewInOrder { get; set; } = ReadingOrder.InOrder;
}
public class SubjectGeneratedTask

View File

@ -17,6 +17,7 @@ using IRaCIS.Core.Infra.EFCore.Common;
using System.Linq.Expressions;
using IRaCIS.Core.Domain.Share.Reading;
using IRaCIS.Core.Application.Service.Reading.Dto;
using System.Runtime.InteropServices;
namespace IRaCIS.Core.Application.Service
{
@ -26,7 +27,7 @@ namespace IRaCIS.Core.Application.Service
/// 访视读片任务
/// </summary>
[ApiExplorerSettings(GroupName = "Trial")]
public class VisitTaskHelpeService : IVisitTaskHelpeService
public class VisitTaskHelpeService : BaseService, IVisitTaskHelpeService
{
private readonly IRepository<VisitTask> _visitTaskRepository;
@ -450,6 +451,19 @@ namespace IRaCIS.Core.Application.Service
}
/// <summary>
/// 获取GetIsClinicalDataSignTest
/// </summary>
/// <param name="visitTask"></param>
/// <returns></returns>
public async Task<bool> GetIsClinicalDataSignTest(Guid visitTask)
{
var taskinfo = await _visitTaskRepository.Where(x => x.Id == visitTask).FirstNotNullAsync();
var clinicalDataConfirmList = _trialClinicalDataSetRepository.Where(t => t.TrialId == taskinfo.TrialId && t.IsConfirm).Include(t => t.TrialClinicalDataSetCriteriaList).ToList();
Guid readingid = taskinfo.SourceSubjectVisitId == null ? taskinfo.SouceReadModuleId!.Value : taskinfo.SourceSubjectVisitId.Value;
return IsClinicalDataSign(taskinfo.ReadingCategory, taskinfo.VisitTaskNum == 0m, taskinfo.TrialReadingCriterionId, clinicalDataConfirmList, readingid, taskinfo.TrialId); ;
}
// 有可能在任务生成之前 就签名完了临床数据
private bool IsClinicalDataSign(ReadingCategory readingCategory, bool isbaseLine, Guid trialReadingCriterionId, List<ClinicalDataTrialSet> trialClinicalDataSetList, Guid readingId, Guid trialId)
@ -468,7 +482,9 @@ namespace IRaCIS.Core.Application.Service
//CRC 的自动签名 不用管 只用处理PM的就好
var haveSignedCount = _readingClinicalDataRepository
.Where(t => t.TrialId == trialId && t.IsSign && t.ReadingClinicalDataState == ReadingClinicalDataStatus.HaveSigned && t.ReadingId == readingId && t.ClinicalDataTrialSet.UploadRole == UploadRole.PM).Count();
.Where(t => t.TrialId == trialId && t.IsSign
&& t.ClinicalDataTrialSet.TrialClinicalDataSetCriteriaList.Any(x=>x.TrialReadingCriterionId== trialReadingCriterionId)
&& t.ReadingClinicalDataState == ReadingClinicalDataStatus.HaveSigned && t.ReadingId == readingId && t.ClinicalDataTrialSet.UploadRole == UploadRole.PM).Count();
var readModule = _readModuleRepository.Where(t => t.Id == readingId).FirstOrDefault();
@ -1415,6 +1431,7 @@ namespace IRaCIS.Core.Application.Service
case GenerateTaskCategory.SelfConsistent:
var readingCriterionId = generateTaskCommand.GenerataConsistentTaskList.First().TrialReadingCriterionId;
var isReadingTaskViewInOrder = await _trialReadingCriterionRepository.Where(t => t.Id == readingCriterionId).Select(x => x.IsReadingTaskViewInOrder).FirstNotNullAsync();
var subjectId = generateTaskCommand.GenerataConsistentTaskList.First().SubjectId;
//var trialReadingCriterion=_trialReadingCriterionRepository.Where(t=>t.Id== trialReadingCriterionId).FirstOrDefault();
@ -1457,7 +1474,11 @@ namespace IRaCIS.Core.Application.Service
foreach (var task in generateTaskCommand.GenerataConsistentTaskList)
{
var exsitPDF = await _readingClinicalDataRepository.AnyAsync(t => t.TrialId == trialId &&
var exsitPDF = await _readingClinicalDataRepository
.WhereIf(isReadingTaskViewInOrder== ReadingOrder.Random,t=>t.ReadingId== task.SouceReadModuleId|| t.ReadingId == task.SourceSubjectVisitId)
.AnyAsync(t => t.TrialId == trialId &&
t.SubjectId== task.SubjectId&&
t.ClinicalDataTrialSet.TrialClinicalDataSetCriteriaList.Any(c => c.TrialReadingCriterionId == readingCriterionId)

View File

@ -293,7 +293,8 @@ namespace IRaCIS.Core.Application.Service
//CreateMap<TaskConsistentRule, TaskConsistentRuleView>()
// .ForMember(o => o.GeneratedSubjectCount, t => t.MapFrom(u => u.DoctorVisitTaskList.Where(t => t.IsAnalysisCreate && t.TaskConsistentRuleId == u.Id).Select(t => t.SubjectId).Distinct().Count())) ;
CreateMap<TaskConsistentRule, TaskConsistentRuleBasic>();
CreateMap<TaskConsistentRule, TaskConsistentRuleBasic>()
.ForMember(o => o.IsReadingTaskViewInOrder, t => t.MapFrom(u => u.TrialReadingCriterion.IsReadingTaskViewInOrder));
CreateMap<TaskConsistentRuleAddOrEdit, TaskConsistentRule>();

View File

@ -398,7 +398,7 @@ namespace IRaCIS.Core.Application.Contracts
var result = await _trialSiteSurveyRepository.Where(t => t.Id == trialSiteSurveyId && t.TrialId == trialId).IgnoreQueryFilters()
.ProjectTo<LoginReturnDTO>(_mapper.ConfigurationProvider, new { isEn_Us = _userInfo.IsEn_Us }).FirstOrDefaultAsync().IfNullThrowException();
var siteSurveryConfig = _trialSiteSurveyRepository.Where(t => t.Id == trialSiteSurveyId).Select(t => t.Trial.TrialExtraConfigJsonStr).FirstOrDefault()??string.Empty;
var siteSurveryConfig = _trialSiteSurveyRepository.Where(t => t.Id == trialSiteSurveyId).IgnoreQueryFilters().Select(t => t.Trial.TrialExtraConfigJsonStr).FirstOrDefault()??string.Empty;
result.SiteSurveyFiledConfig = JsonConvert.DeserializeObject<TrialExtraConfig>(siteSurveryConfig) ?? new TrialExtraConfig();
return result;

View File

@ -23,6 +23,8 @@ using IRaCIS.Application.Contracts;
using SixLabors.ImageSharp.Formats.Tiff.Compression.Decompressors;
using Newtonsoft.Json;
using Microsoft.Extensions.Options;
using IRaCIS.Core.Application.Helper;
using ZiggyCreatures.Caching.Fusion;
namespace IRaCIS.Core.Application
{
@ -1239,8 +1241,8 @@ namespace IRaCIS.Core.Application
}
await _provider.SetAsync(trialId.ToString(), trialStatusStr, TimeSpan.FromDays(7));
await _fusionCache.SetAsync(CacheKeys.Trial(trial.Id.ToString()), trialStatusStr, TimeSpan.FromDays(7));
await _repository.SaveChangesAsync();
return ResponseOutput.Ok();
@ -1390,7 +1392,7 @@ namespace IRaCIS.Core.Application
{
var trialCode = await _trialRepository.Where(t => t.Id == trialId).Select(t => t.TrialCode).FirstOrDefaultAsync();
return new TrialPacsInfo() { Ip=optionsMonitor.CurrentValue.IP,Port=optionsMonitor.CurrentValue.Port,TrialCalledAE=$"EI{trialCode}" };
return new TrialPacsInfo() { Ip = optionsMonitor.CurrentValue.IP, Port = optionsMonitor.CurrentValue.Port, TrialCalledAE = $"EI{trialCode}" };
}
}
}

View File

@ -12,6 +12,8 @@ using Microsoft.AspNetCore.Authorization;
using System.Linq.Expressions;
using System.Linq;
using IRaCIS.Core.Domain.Models;
using IRaCIS.Core.Application.Helper;
using ZiggyCreatures.Caching.Fusion;
namespace IRaCIS.Application.Services
{
@ -93,7 +95,7 @@ namespace IRaCIS.Application.Services
.WhereIf(multiCriteriaSelectCount > 0, t => t.TrialDicList.Count(t => t.KeyName == StaticData.Criterion) == multiCriteriaSelectCount)
.WhereIf(multiReviewTypeSelectCount > 0, t => t.TrialDicList.Count(t => t.KeyName == StaticData.ReviewType) == multiReviewTypeSelectCount)
.WhereIf(_userInfo.UserTypeEnumInt != (int)UserTypeEnum.SuperAdmin, t => t.TrialUserList.Any(t => t.UserId == _userInfo.Id && t.IsDeleted == false) && t.IsDeleted == false)
.ProjectTo<TrialDetailDTO>(_mapper.ConfigurationProvider, new { userTypeEnumInt = _userInfo.UserTypeEnumInt, userId = _userInfo.Id , isEn_Us= _userInfo.IsEn_Us });
.ProjectTo<TrialDetailDTO>(_mapper.ConfigurationProvider, new { userTypeEnumInt = _userInfo.UserTypeEnumInt, userId = _userInfo.Id, isEn_Us = _userInfo.IsEn_Us });
return await query.ToPagedListAsync(searchParam.PageIndex, searchParam.PageSize, string.IsNullOrWhiteSpace(searchParam.SortField) ? "CreateTime" : searchParam.SortField, searchParam.Asc);
@ -119,7 +121,7 @@ namespace IRaCIS.Application.Services
[HttpGet("{projectId:guid}")]
public async Task<TrialDetailDTO> GetTrialInfoAndLockState(Guid projectId)
{
return (await _trialRepository.Where(o => o.Id == projectId).ProjectTo<TrialDetailDTO>(_mapper.ConfigurationProvider, new {isEn_Us = _userInfo.IsEn_Us }).FirstOrDefaultAsync()).IfNullThrowException();
return (await _trialRepository.Where(o => o.Id == projectId).ProjectTo<TrialDetailDTO>(_mapper.ConfigurationProvider, new { isEn_Us = _userInfo.IsEn_Us }).FirstOrDefaultAsync()).IfNullThrowException();
}
@ -216,7 +218,7 @@ namespace IRaCIS.Application.Services
await _repository.AddAsync(new TrialPaymentPrice() { TrialId = trial.Id });
//添加访视
await _repository.AddAsync(new VisitStage { TrialId = trial.Id, VisitNum = 0, BlindName = "B" + 0.ToString("D3"), VisitDay = 0, VisitName = "Baseline", IsBaseLine = true,VisitWindowLeft=-28,VisitWindowRight=0 });
await _repository.AddAsync(new VisitStage { TrialId = trial.Id, VisitNum = 0, BlindName = "B" + 0.ToString("D3"), VisitDay = 0, VisitName = "Baseline", IsBaseLine = true, VisitWindowLeft = -28, VisitWindowRight = 0 });
await _repository.AddAsync(new VisitStage { TrialId = trial.Id, VisitNum = 1, BlindName = "B" + 10.ToString("D3"), VisitDay = 30, VisitName = "Visit 1", VisitWindowLeft = -5, VisitWindowRight = 5 });
@ -234,12 +236,11 @@ namespace IRaCIS.Application.Services
{
item.TrialId = trial.Id;
}
await _repository.AddRangeAsync(needAddBodyPartList,true);
_provider.Set(trial.Id.ToString(), StaticData.TrialState.TrialInitializing, TimeSpan.FromDays(7));
await _repository.AddRangeAsync(needAddBodyPartList, true);
await _fusionCache.SetAsync(CacheKeys.Trial(trial.Id.ToString()), StaticData.TrialState.TrialInitializing, TimeSpan.FromDays(7));
return ResponseOutput.Ok(trial);
}
@ -589,7 +590,7 @@ namespace IRaCIS.Application.Services
await _repository.BatchDeleteAsync<VisitTaskReReading>(t => t.OriginalReReadingTask.TrialId == trialId);
await _repository.BatchDeleteAsync<VisitTask>(t => t.TrialId == trialId);
await _repository.BatchDeleteAsync<TrialStateChange>(t => t.TrialId == trialId) ;
await _repository.BatchDeleteAsync<TrialStateChange>(t => t.TrialId == trialId);
return ResponseOutput.Ok();
@ -650,7 +651,7 @@ namespace IRaCIS.Application.Services
.WhereIf(!string.IsNullOrEmpty(searchModel.Code), o => o.TrialCode.Contains(searchModel.Code))
.WhereIf(!string.IsNullOrWhiteSpace(searchModel.Indication), o => o.Indication.Contains(searchModel.Indication))
.WhereIf(_userInfo.UserTypeEnumInt != (int)UserTypeEnum.SuperAdmin, t => t.TrialUserList.Any(t => t.UserId == _userInfo.Id))
.ProjectTo<TrialDetailDTO>(_mapper.ConfigurationProvider, new { userTypeEnumInt = _userInfo.UserTypeEnumInt, userId = _userInfo.Id ,isEn_Us = _userInfo.IsEn_Us });
.ProjectTo<TrialDetailDTO>(_mapper.ConfigurationProvider, new { userTypeEnumInt = _userInfo.UserTypeEnumInt, userId = _userInfo.Id, isEn_Us = _userInfo.IsEn_Us });
return await query.ToPagedListAsync(searchModel.PageIndex, searchModel.PageSize, string.IsNullOrWhiteSpace(searchModel.SortField) ? "CreateTime" : searchModel.SortField, searchModel.Asc);

View File

@ -340,6 +340,7 @@ namespace IRaCIS.Application.Services
foreach (var waitUploadItem in scpStudyList)
{
if (isVerifyVisitImageDate)
{
//小于当前访视 最近的最晚拍片
@ -349,7 +350,8 @@ namespace IRaCIS.Application.Services
{
// $"当前访视检查时间{waitUploadItem.StudyDate?.ToString("yyyy-MM-dd")}不能早于前序访视检查时间{before?.ToString("yyyy-MM-dd")},请核对检查数据是否有误",
result.Add(new VerifySCPStudyUploadResult() { ErrorMesseage = _localizer["Study_VisitBeforePrevError", waitUploadItem.StudyDate?.ToString("yyyy-MM-dd")!, before?.ToString("yyyy-MM-dd")!] });
result.Add(new VerifySCPStudyUploadResult() { SCPStudyId = waitUploadItem.Id, ErrorMesseage = _localizer["Study_VisitBeforePrevError", waitUploadItem.StudyDate?.ToString("yyyy-MM-dd")!, before?.ToString("yyyy-MM-dd")!] });
continue; // 跳过当前迭代
}
//大于当前访视 最近的最早拍片日期
@ -358,13 +360,15 @@ namespace IRaCIS.Application.Services
if (after != null && waitUploadItem.StudyDate != null && after < waitUploadItem.StudyDate)
{
// $"当前访视检查时间{waitUploadItem.StudyDate?.ToString("yyyy-MM-dd")}不能晚于该访视之后的检查时间{after?.ToString("yyyy-MM-dd")},请核对检查数据是否有误"
result.Add(new VerifySCPStudyUploadResult() { ErrorMesseage = _localizer["Study_VisitAfterSubseqError", waitUploadItem.StudyDate?.ToString("yyyy-MM-dd")!, after?.ToString("yyyy-MM-dd")!]});
result.Add(new VerifySCPStudyUploadResult() { SCPStudyId = waitUploadItem.Id, ErrorMesseage = _localizer["Study_VisitAfterSubseqError", waitUploadItem.StudyDate?.ToString("yyyy-MM-dd")!, after?.ToString("yyyy-MM-dd")!] });
continue; // 跳过当前迭代
}
}
var verifyStudyInfo = _repository.Where<DicomStudy>(t => t.TrialId == trialId && t.Id == waitUploadItem.Id).ProjectTo<VerifyStudyDto>(_mapper.ConfigurationProvider).FirstOrDefault();
var currentStudyResult = new VerifyStudyUploadResult();
var currentStudyResult = new VerifySCPStudyUploadResult() { SCPStudyId = waitUploadItem.Id };
//数据库不存在该检查 允许上传
if (verifyStudyInfo == null)
@ -391,6 +395,8 @@ namespace IRaCIS.Application.Services
currentStudyResult.ErrorMesseage = _localizer["Study_ImgAlreadyUploaded", verifyStudyInfo.SubjectCode, verifyStudyInfo.VisitName];
}
}
result.Add(currentStudyResult);
}
@ -413,7 +419,7 @@ namespace IRaCIS.Application.Services
[UnitOfWork]
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
public async Task<IResponseOutput> SubmitVisitStudyBinding(SubmitVisitStudyBindingCommand inCommand,
[FromServices]IRepository<DicomStudy> _dicomstudyRepository,
[FromServices] IRepository<DicomStudy> _dicomstudyRepository,
[FromServices] IRepository<DicomSeries> _dicomSeriesRepository,
[FromServices] IRepository<DicomInstance> _dicomInstanceRepository)
{
@ -427,7 +433,7 @@ namespace IRaCIS.Application.Services
var allowUploadList = verifyResult.Where(u => u.AllowUpload == true).Select(t => t.SCPStudyId).ToList();
var allowReUploadList = verifyResult.Where(u => u.AllowReUpload == true).Select(t => t.SCPStudyId).ToList();
if (inCommand.SCPStudyIdList.All(t => allowUploadList.Contains(t)) && inCommand.ReUploadSCPStudyIdList.All(t => allowReUploadList.Contains(t)))
if (!(inCommand.SCPStudyIdList.All(t => allowUploadList.Contains(t)) && inCommand.ReUploadSCPStudyIdList.All(t => allowReUploadList.Contains(t))))
{
throw new BusinessValidationFailedException("对接提示: 前端提交的检查有不能上传的,请刷新页面调用验证接口重试!");
}
@ -505,7 +511,7 @@ namespace IRaCIS.Application.Services
var instanceIdList = _dicomInstanceRepository.Where(t => t.Id == scpStudyId).Select(t => t.Id).ToList();
var scpStudy = _scpStudyRepository.Where(t => t.Id == scpStudyId).Include(t=>t.SeriesList).ThenInclude(t=>t.SCPInstanceList).FirstOrDefault();
var scpStudy = _scpStudyRepository.Where(t => t.Id == scpStudyId).Include(t => t.SeriesList).ThenInclude(t => t.SCPInstanceList).FirstOrDefault();
//以最后一次为准
study.IsFromPACS = true;

View File

@ -15,6 +15,7 @@ public static class StaticData
public static Dictionary<string, string> Log_Locoalize_Dic = new Dictionary<string, string>();
#region 国际化
public static readonly string En_US_Json = "en-US.json";
public static readonly string Zh_CN_Json = "zh-CN.json";
@ -70,9 +71,11 @@ public static class StaticData
}
#endregion
#region 字典表项固定值
public static readonly string Title = "Title";
#region 字典表项固定值
public static readonly string Title = "Title";
public static readonly string ReadingType = "ReadingType";
public static readonly string Subspeciality = "Subspeciality";
@ -80,6 +83,7 @@ public static class StaticData
public static readonly string Criterion = "Criterion";
public static readonly string ReviewType = "ReviewType";
public static readonly string ReadingStandard = "ReadingStandard";
#endregion