diff --git a/IRaCIS.Core.Application/Helper/CacheHelper.cs b/IRaCIS.Core.Application/Helper/CacheHelper.cs index f2135ea9b..f3cf0cf51 100644 --- a/IRaCIS.Core.Application/Helper/CacheHelper.cs +++ b/IRaCIS.Core.Application/Helper/CacheHelper.cs @@ -12,16 +12,19 @@ namespace IRaCIS.Core.Application.Helper { public static string Trial(string trialIdStr) => $"TrialId:{trialIdStr}"; + //检查编号递增锁 public static string TrialStudyMaxCode(Guid trialId) => $"TrialStudyMaxCode:{trialId}"; public static string TrialStudyUidUploading(Guid trialId, string studyUid) => $"TrialStudyUid:{trialId}_{studyUid}"; - + //CRC上传影像提交锁key public static string TrialStudyUidDBLock(Guid trialId, string studyUid) => $"TrialStudyUidDBLock:{trialId}_{studyUid}"; - - + public static string TrialTaskStudyUidUploading(Guid trialId, Guid visiTaskId, string studyUid) => $"TrialStudyUid:{trialId}_{visiTaskId}_{studyUid}"; + //影像后处理上传提交锁key + public static string TrialTaskStudyUidDBLock(Guid trialId, Guid visiTaskId, string studyUid) => $"TrialTaskStudyUidDBLock:{trialId}_{visiTaskId}_{studyUid}"; + //系统匿名化 public static string SystemAnonymization => $"SystemAnonymization"; - + //前端国际化 public static string FrontInternational => $"FrontInternationalList"; //登录挤账号 diff --git a/IRaCIS.Core.Application/Service/Common/DictionaryService.cs b/IRaCIS.Core.Application/Service/Common/DictionaryService.cs index 0174ee41d..57fe7ac1c 100644 --- a/IRaCIS.Core.Application/Service/Common/DictionaryService.cs +++ b/IRaCIS.Core.Application/Service/Common/DictionaryService.cs @@ -5,6 +5,9 @@ using Microsoft.AspNetCore.Mvc; using IRaCIS.Core.Domain.Share; using IRaCIS.Core.Application.Contracts; using IRaCIS.Core.Infra.EFCore.Common; +using IP2Region.Net.XDB; +using System.Collections; +using System.Text; namespace IRaCIS.Application.Services { @@ -29,6 +32,32 @@ namespace IRaCIS.Application.Services { + public async Task GenerateEnumDefine(string code) + { + var searchList = await _dicRepository.Where(t => t.Parent.Code == code && t.ParentId != null && t.IsEnable).ProjectTo(_mapper.ConfigurationProvider).ToListAsync(); + + // StringBuilder 用于构建枚举代码字符串 + var enumCode = new StringBuilder(); + + // 生成枚举定义 + enumCode.AppendLine($"public enum {code}"); + enumCode.AppendLine("{"); + + foreach (var item in searchList) + { + // 每个枚举值生成 + enumCode.AppendLine($" {item.Code} = {item.ValueCN},"); + } + + enumCode.AppendLine("}"); + + // 返回生成的枚举代码 + var enumStr= enumCode.ToString(); + + return ResponseOutput.Ok(enumStr); + + } + /// /// 添加bool /// diff --git a/IRaCIS.Core.Application/Service/ImageAndDoc/DTO/UnionStudyViewDodel.cs b/IRaCIS.Core.Application/Service/ImageAndDoc/DTO/UnionStudyViewDodel.cs index 25856ce22..088c77ef3 100644 --- a/IRaCIS.Core.Application/Service/ImageAndDoc/DTO/UnionStudyViewDodel.cs +++ b/IRaCIS.Core.Application/Service/ImageAndDoc/DTO/UnionStudyViewDodel.cs @@ -541,11 +541,19 @@ namespace IRaCIS.Core.Application.Contracts [NotDefault] public string SubjectCode { get; set; } - public List SubjectVisitIdList { get; set; } + public List SubjectVisitTaskList { get; set; } public List DicomStudyIdList { get; set; } public List NoneDicomStudyIdList { get; set; } } + + + public class SubjectVisitTaskInfo + { + public Guid SubjectVisitId { get; set; } + + public Guid VisitTaskId { get; set; } + } } diff --git a/IRaCIS.Core.Application/Service/ImageAndDoc/DownloadAndUploadService.cs b/IRaCIS.Core.Application/Service/ImageAndDoc/DownloadAndUploadService.cs index 1de05482f..b59a3e043 100644 --- a/IRaCIS.Core.Application/Service/ImageAndDoc/DownloadAndUploadService.cs +++ b/IRaCIS.Core.Application/Service/ImageAndDoc/DownloadAndUploadService.cs @@ -1,4 +1,6 @@ -using FellowOakDicom; +using Amazon.Runtime.EventStreams.Internal; +using DocumentFormat.OpenXml.EMMA; +using FellowOakDicom; using IRaCIS.Application.Contracts; using IRaCIS.Core.Application.Contracts; using IRaCIS.Core.Application.Contracts.Dicom.DTO; @@ -77,19 +79,28 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc //已经处理过的任务名称的数量 - var haveDealedTaskCount = await _visitTaskRepository.CountAsync(t => t.SubjectId == subjectId && t.TrialReadingCriterionId == trialReadingCriterionId && t.IsAnalysisCreate == false && t.DoctorUserId == _userInfo.Id - && t.ReadingTaskState != ReadingTaskState.HaveSigned && t.ReadingCategory == ReadingCategory.Visit && t.TaskBlindName != "Timepoint"); + var haveDealedTaskList = await _visitTaskRepository.Where(t => t.SubjectId == subjectId && t.TrialReadingCriterionId == trialReadingCriterionId && t.IsAnalysisCreate == false && t.DoctorUserId == _userInfo.Id + && t.ReadingTaskState != ReadingTaskState.HaveSigned && t.ReadingCategory == ReadingCategory.Visit && t.TaskBlindName != "Timepoint").Select(t => new { t.TaskBlindName, t.SourceSubjectVisitId, t.SouceReadModuleId }).ToListAsync(); //随机赋值编号 比如要处理5个任务,实例化一个包含1-5的数组,每次随机取出一个 - List availableNumbers = Enumerable.Range(haveDealedTaskCount + haveFinishedTaskCount + 1, needDealTaskList.Count).ToList(); + List availableNumbers = Enumerable.Range(haveDealedTaskList.Count + haveFinishedTaskCount + 1, needDealTaskList.Count).ToList(); Random rng = new Random(); foreach (var visitTask in needDealTaskList) { int randomIndex = rng.Next(availableNumbers.Count); - visitTask.TaskBlindName = $"Timepoint Ran {availableNumbers[randomIndex]}"; + var findOldTask = haveDealedTaskList.Where(t => t.SourceSubjectVisitId == visitTask.SourceSubjectVisitId && t.SouceReadModuleId == visitTask.SouceReadModuleId).FirstOrDefault(); + + if (findOldTask != null) + { + visitTask.TaskBlindName = findOldTask.TaskBlindName; + } + else + { + visitTask.TaskBlindName = $"Timepoint Ran {availableNumbers[randomIndex]}"; + } availableNumbers.RemoveAt(randomIndex); } @@ -324,7 +335,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc using (await @uploadLock.AcquireAsync()) { - if (_fusionCache.GetOrDefault(CacheKeys.TrialStudyUidDBLock(incommand.TrialId, incommand.Study.StudyInstanceUid)) != Guid.Empty) + if (_fusionCache.GetOrDefault(CacheKeys.TrialTaskStudyUidDBLock(incommand.TrialId, incommand.VisitTaskId, incommand.Study.StudyInstanceUid)) != Guid.Empty) { //---当前已有人正在上传和归档该检查! return ResponseOutput.NotOk(StaticData.International("UploadDownLoad_ArchiveInProgress")); @@ -332,7 +343,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc else { //在事务未完成前 防止前端重复提交 - await _fusionCache.SetAsync(CacheKeys.TrialStudyUidDBLock(incommand.TrialId, incommand.Study.StudyInstanceUid), _userInfo.Id, TimeSpan.FromMinutes(3)); + await _fusionCache.SetAsync(CacheKeys.TrialTaskStudyUidDBLock(incommand.TrialId, incommand.VisitTaskId, incommand.Study.StudyInstanceUid), _userInfo.Id, TimeSpan.FromMinutes(1)); } } @@ -356,7 +367,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc if (studyMonitor.IsDicomReUpload == false) { //目前不考虑重传的问题,后面的直接覆盖前面的,全部删除 - if(_taskStudyRepository.Any(t=>t.VisitTaskId==visiTaskId && t.StudyInstanceUid == incommand.Study.StudyInstanceUid)) + if (_taskStudyRepository.Any(t => t.VisitTaskId == visiTaskId && t.StudyInstanceUid == incommand.Study.StudyInstanceUid)) { await _taskStudyRepository.BatchDeleteNoTrackingAsync(t => t.VisitTaskId == visiTaskId); await _taskSeriesRepository.BatchDeleteNoTrackingAsync(t => t.VisitTaskId == visiTaskId); @@ -440,10 +451,6 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc await _taskInstanceRepository.AddAsync(isntance); } } - - - - } else { @@ -533,7 +540,8 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc } finally { - await _fusionCache.RemoveAsync(CacheKeys.TrialStudyUidUploading(incommand.TrialId, incommand.Study.StudyInstanceUid)); + await _fusionCache.RemoveAsync(CacheKeys.TrialTaskStudyUidDBLock(incommand.TrialId, incommand.VisitTaskId, incommand.Study.StudyInstanceUid)); + await _fusionCache.RemoveAsync(CacheKeys.TrialTaskStudyUidUploading(incommand.TrialId, incommand.VisitTaskId, incommand.Study.StudyInstanceUid)); } @@ -559,8 +567,8 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc } else { - await _taskStudyRepository.BatchDeleteNoTrackingAsync(t => t.VisitTaskId == visitTaskId && t.Id== dicomStudyId); - await _taskSeriesRepository.BatchDeleteNoTrackingAsync(t => t.VisitTaskId == visitTaskId && t.Id== dicomStudyId); + await _taskStudyRepository.BatchDeleteNoTrackingAsync(t => t.VisitTaskId == visitTaskId && t.Id == dicomStudyId); + await _taskSeriesRepository.BatchDeleteNoTrackingAsync(t => t.VisitTaskId == visitTaskId && t.Id == dicomStudyId); await _taskInstanceRepository.BatchDeleteNoTrackingAsync(t => t.VisitTaskId == visitTaskId && t.Id == dicomStudyId); } } @@ -723,6 +731,16 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc var list = await query.Where(t => t.SubjectCode == inQuery.SubjectCode).ToListAsync(); + foreach (var item in list) + { + if (item.IsImageFilter) + { + item.DicomStudyList = item.DicomStudyList.Where(t => ("|" + item.CriterionModalitys + "|").Contains("|" + t.ModalityForEdit + "|")).ToList(); + item.NoneDicomStudyList = item.NoneDicomStudyList.Where(t => ("|" + item.CriterionModalitys + "|").Contains("|" + t.Modality + "|")).ToList(); + } + } + + #region 将任务级别转为检查级别 var result = new List(); @@ -783,13 +801,18 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc var isQueryDicom = inQuery.DicomStudyIdList.Count > 0; var isQueryNoneDicom = inQuery.NoneDicomStudyIdList.Count > 0; - var query = from sv in _subjectRepository.Where(t => t.Id == inQuery.SubjectId).SelectMany(t => t.SubjectVisitList.Where(t => inQuery.SubjectVisitIdList.Contains(t.Id))) + var subjectVisitIdList = inQuery.SubjectVisitTaskList.Select(t => t.SubjectVisitId).ToList(); + var query = from sv in _subjectRepository.Where(t => t.Id == inQuery.SubjectId).SelectMany(t => t.SubjectVisitList.Where(t => subjectVisitIdList.Contains(t.Id))) + join visitTask in _visitTaskRepository.Where(t => t.TaskState == TaskState.Effect && t.DoctorUserId == _userInfo.Id && t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId) + on sv.Id equals visitTask.SourceSubjectVisitId select new { - SubjectCode = sv.Subject.Code, + SubjectCode = inQuery.SubjectCode, VisitName = sv.VisitName, + TaskBlindName = visitTask.TaskBlindName, StudyList = sv.StudyList.Where(t => isQueryDicom ? inQuery.DicomStudyIdList.Contains(t.Id) : false) + .Where(t => info.IsImageFilter ? ("|" + info.CriterionModalitys + "|").Contains("|" + t.ModalityForEdit + "|") : true) .Select(u => new { u.PatientId, @@ -809,6 +832,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc }), NoneDicomStudyList = sv.NoneDicomStudyList.Where(t => isQueryNoneDicom ? inQuery.NoneDicomStudyIdList.Contains(t.Id) : false) + .Where(t => info.IsImageFilter ? ("|" + info.CriterionModalitys + "|").Contains("|" + t.Modality + "|") : true) .Select(nd => new { nd.Modality, @@ -828,6 +852,8 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc var result = await query.ToListAsync(); + + return ResponseOutput.Ok(result); } diff --git a/IRaCIS.Core.Application/Service/ImageAndDoc/StudyService.cs b/IRaCIS.Core.Application/Service/ImageAndDoc/StudyService.cs index ef6d6c0c9..9c7bc702c 100644 --- a/IRaCIS.Core.Application/Service/ImageAndDoc/StudyService.cs +++ b/IRaCIS.Core.Application/Service/ImageAndDoc/StudyService.cs @@ -103,9 +103,27 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc } [HttpGet] - public async Task DicomUploadInProgress(Guid trialId, string studyInstanceUid) + public async Task DicomUploadInProgress(Guid trialId, string studyInstanceUid,Guid? visitTaskId) { - await _fusionCache.SetAsync(CacheKeys.TrialStudyUidUploading(trialId, studyInstanceUid), _userInfo.Id, TimeSpan.FromSeconds(15)); + if(visitTaskId != null) + { + var cacheValue = _fusionCache.GetOrDefault(CacheKeys.TrialTaskStudyUidUploading(trialId, visitTaskId.Value, studyInstanceUid)); + if (cacheValue != Guid.Empty && cacheValue !=_userInfo.Id) + { + //---当前已有人正在上传和归档该检查! + return ResponseOutput.NotOk(StaticData.International("UploadDownLoad_ArchiveInProgress")); + } + else + { + await _fusionCache.SetAsync(CacheKeys.TrialTaskStudyUidUploading(trialId, visitTaskId.Value, studyInstanceUid), _userInfo.Id, TimeSpan.FromSeconds(15)); + + } + } + else + { + await _fusionCache.SetAsync(CacheKeys.TrialStudyUidUploading(trialId, studyInstanceUid), _userInfo.Id, TimeSpan.FromSeconds(15)); + + } return ResponseOutput.Ok(); diff --git a/IRaCIS.Core.Application/Service/ImageAndDoc/_MapConfig.cs b/IRaCIS.Core.Application/Service/ImageAndDoc/_MapConfig.cs index d6fb7d319..78b0c12ea 100644 --- a/IRaCIS.Core.Application/Service/ImageAndDoc/_MapConfig.cs +++ b/IRaCIS.Core.Application/Service/ImageAndDoc/_MapConfig.cs @@ -1,4 +1,5 @@ using AutoMapper; +using DocumentFormat.OpenXml.EMMA; using IRaCIS.Application.Contracts; using IRaCIS.Core.Application.Contracts; using IRaCIS.Core.Application.Contracts.Dicom.DTO; @@ -138,7 +139,7 @@ namespace IRaCIS.Core.Application.Service .ForMember(d => d.IsImageFilter, u => u.MapFrom(s => s.TrialReadingCriterion.IsImageFilter)) .ForMember(d => d.CriterionModalitys, u => u.MapFrom(s => s.TrialReadingCriterion.CriterionModalitys)) .ForMember(d => d.SubjectCode, u => u.MapFrom(u => u.IsSelfAnalysis == true ? u.BlindSubjectCode : u.Subject.Code)) - .ForMember(d => d.DicomStudyList, u => u.MapFrom(s => s.SourceSubjectVisit.StudyList)) + .ForMember(d => d.DicomStudyList, u => u.MapFrom(s => s.SourceSubjectVisit.StudyList)) .ForMember(d => d.NoneDicomStudyList, u => u.MapFrom(s => s.SourceSubjectVisit.NoneDicomStudyList)) ;