Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
commit
5b420a453b
|
@ -12,16 +12,19 @@ namespace IRaCIS.Core.Application.Helper
|
||||||
{
|
{
|
||||||
public static string Trial(string trialIdStr) => $"TrialId:{trialIdStr}";
|
public static string Trial(string trialIdStr) => $"TrialId:{trialIdStr}";
|
||||||
|
|
||||||
|
//检查编号递增锁
|
||||||
public static string TrialStudyMaxCode(Guid trialId) => $"TrialStudyMaxCode:{trialId}";
|
public static string TrialStudyMaxCode(Guid trialId) => $"TrialStudyMaxCode:{trialId}";
|
||||||
|
|
||||||
public static string TrialStudyUidUploading(Guid trialId, string studyUid) => $"TrialStudyUid:{trialId}_{studyUid}";
|
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 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 SystemAnonymization => $"SystemAnonymization";
|
||||||
|
//前端国际化
|
||||||
public static string FrontInternational => $"FrontInternationalList";
|
public static string FrontInternational => $"FrontInternationalList";
|
||||||
|
|
||||||
//登录挤账号
|
//登录挤账号
|
||||||
|
|
|
@ -5,6 +5,9 @@ using Microsoft.AspNetCore.Mvc;
|
||||||
using IRaCIS.Core.Domain.Share;
|
using IRaCIS.Core.Domain.Share;
|
||||||
using IRaCIS.Core.Application.Contracts;
|
using IRaCIS.Core.Application.Contracts;
|
||||||
using IRaCIS.Core.Infra.EFCore.Common;
|
using IRaCIS.Core.Infra.EFCore.Common;
|
||||||
|
using IP2Region.Net.XDB;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
namespace IRaCIS.Application.Services
|
namespace IRaCIS.Application.Services
|
||||||
{
|
{
|
||||||
|
@ -29,6 +32,32 @@ namespace IRaCIS.Application.Services
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
|
public async Task<IResponseOutput> GenerateEnumDefine(string code)
|
||||||
|
{
|
||||||
|
var searchList = await _dicRepository.Where(t => t.Parent.Code == code && t.ParentId != null && t.IsEnable).ProjectTo<BasicDicSelect>(_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);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 添加bool
|
/// 添加bool
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -541,11 +541,19 @@ namespace IRaCIS.Core.Application.Contracts
|
||||||
[NotDefault]
|
[NotDefault]
|
||||||
public string SubjectCode { get; set; }
|
public string SubjectCode { get; set; }
|
||||||
|
|
||||||
public List<Guid> SubjectVisitIdList { get; set; }
|
public List<SubjectVisitTaskInfo> SubjectVisitTaskList { get; set; }
|
||||||
|
|
||||||
public List<Guid> DicomStudyIdList { get; set; }
|
public List<Guid> DicomStudyIdList { get; set; }
|
||||||
|
|
||||||
public List<Guid> NoneDicomStudyIdList { get; set; }
|
public List<Guid> NoneDicomStudyIdList { get; set; }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public class SubjectVisitTaskInfo
|
||||||
|
{
|
||||||
|
public Guid SubjectVisitId { get; set; }
|
||||||
|
|
||||||
|
public Guid VisitTaskId { get; set; }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
using FellowOakDicom;
|
using Amazon.Runtime.EventStreams.Internal;
|
||||||
|
using DocumentFormat.OpenXml.EMMA;
|
||||||
|
using FellowOakDicom;
|
||||||
using IRaCIS.Application.Contracts;
|
using IRaCIS.Application.Contracts;
|
||||||
using IRaCIS.Core.Application.Contracts;
|
using IRaCIS.Core.Application.Contracts;
|
||||||
using IRaCIS.Core.Application.Contracts.Dicom.DTO;
|
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
|
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");
|
&& t.ReadingTaskState != ReadingTaskState.HaveSigned && t.ReadingCategory == ReadingCategory.Visit && t.TaskBlindName != "Timepoint").Select(t => new { t.TaskBlindName, t.SourceSubjectVisitId, t.SouceReadModuleId }).ToListAsync();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//随机赋值编号 比如要处理5个任务,实例化一个包含1-5的数组,每次随机取出一个
|
//随机赋值编号 比如要处理5个任务,实例化一个包含1-5的数组,每次随机取出一个
|
||||||
List<int> availableNumbers = Enumerable.Range(haveDealedTaskCount + haveFinishedTaskCount + 1, needDealTaskList.Count).ToList();
|
List<int> availableNumbers = Enumerable.Range(haveDealedTaskList.Count + haveFinishedTaskCount + 1, needDealTaskList.Count).ToList();
|
||||||
Random rng = new Random();
|
Random rng = new Random();
|
||||||
foreach (var visitTask in needDealTaskList)
|
foreach (var visitTask in needDealTaskList)
|
||||||
{
|
{
|
||||||
int randomIndex = rng.Next(availableNumbers.Count);
|
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);
|
availableNumbers.RemoveAt(randomIndex);
|
||||||
}
|
}
|
||||||
|
@ -324,7 +335,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
||||||
|
|
||||||
using (await @uploadLock.AcquireAsync())
|
using (await @uploadLock.AcquireAsync())
|
||||||
{
|
{
|
||||||
if (_fusionCache.GetOrDefault<Guid>(CacheKeys.TrialStudyUidDBLock(incommand.TrialId, incommand.Study.StudyInstanceUid)) != Guid.Empty)
|
if (_fusionCache.GetOrDefault<Guid>(CacheKeys.TrialTaskStudyUidDBLock(incommand.TrialId, incommand.VisitTaskId, incommand.Study.StudyInstanceUid)) != Guid.Empty)
|
||||||
{
|
{
|
||||||
//---当前已有人正在上传和归档该检查!
|
//---当前已有人正在上传和归档该检查!
|
||||||
return ResponseOutput.NotOk(StaticData.International("UploadDownLoad_ArchiveInProgress"));
|
return ResponseOutput.NotOk(StaticData.International("UploadDownLoad_ArchiveInProgress"));
|
||||||
|
@ -332,7 +343,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
||||||
else
|
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 (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 _taskStudyRepository.BatchDeleteNoTrackingAsync(t => t.VisitTaskId == visiTaskId);
|
||||||
await _taskSeriesRepository.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);
|
await _taskInstanceRepository.AddAsync(isntance);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -533,7 +540,8 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
||||||
}
|
}
|
||||||
finally
|
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
|
else
|
||||||
{
|
{
|
||||||
await _taskStudyRepository.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 _taskSeriesRepository.BatchDeleteNoTrackingAsync(t => t.VisitTaskId == visitTaskId && t.Id == dicomStudyId);
|
||||||
await _taskInstanceRepository.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();
|
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 将任务级别转为检查级别
|
#region 将任务级别转为检查级别
|
||||||
|
|
||||||
var result = new List<SubjectCRCImageUploadedStudyDto>();
|
var result = new List<SubjectCRCImageUploadedStudyDto>();
|
||||||
|
@ -783,13 +801,18 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
||||||
var isQueryDicom = inQuery.DicomStudyIdList.Count > 0;
|
var isQueryDicom = inQuery.DicomStudyIdList.Count > 0;
|
||||||
var isQueryNoneDicom = inQuery.NoneDicomStudyIdList.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
|
select new
|
||||||
{
|
{
|
||||||
SubjectCode = sv.Subject.Code,
|
SubjectCode = inQuery.SubjectCode,
|
||||||
VisitName = sv.VisitName,
|
VisitName = sv.VisitName,
|
||||||
|
TaskBlindName = visitTask.TaskBlindName,
|
||||||
StudyList = sv.StudyList.Where(t => isQueryDicom ? inQuery.DicomStudyIdList.Contains(t.Id) : false)
|
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
|
.Select(u => new
|
||||||
{
|
{
|
||||||
u.PatientId,
|
u.PatientId,
|
||||||
|
@ -809,6 +832,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
||||||
}),
|
}),
|
||||||
|
|
||||||
NoneDicomStudyList = sv.NoneDicomStudyList.Where(t => isQueryNoneDicom ? inQuery.NoneDicomStudyIdList.Contains(t.Id) : false)
|
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
|
.Select(nd => new
|
||||||
{
|
{
|
||||||
nd.Modality,
|
nd.Modality,
|
||||||
|
@ -828,6 +852,8 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
||||||
|
|
||||||
var result = await query.ToListAsync();
|
var result = await query.ToListAsync();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return ResponseOutput.Ok(result);
|
return ResponseOutput.Ok(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -103,9 +103,27 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
public async Task<IResponseOutput> DicomUploadInProgress(Guid trialId, string studyInstanceUid)
|
public async Task<IResponseOutput> 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<Guid>(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();
|
return ResponseOutput.Ok();
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using AutoMapper;
|
using AutoMapper;
|
||||||
|
using DocumentFormat.OpenXml.EMMA;
|
||||||
using IRaCIS.Application.Contracts;
|
using IRaCIS.Application.Contracts;
|
||||||
using IRaCIS.Core.Application.Contracts;
|
using IRaCIS.Core.Application.Contracts;
|
||||||
using IRaCIS.Core.Application.Contracts.Dicom.DTO;
|
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.IsImageFilter, u => u.MapFrom(s => s.TrialReadingCriterion.IsImageFilter))
|
||||||
.ForMember(d => d.CriterionModalitys, u => u.MapFrom(s => s.TrialReadingCriterion.CriterionModalitys))
|
.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.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))
|
.ForMember(d => d.NoneDicomStudyList, u => u.MapFrom(s => s.SourceSubjectVisit.NoneDicomStudyList))
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue