上传 心跳包处理
parent
43ef5bcdd9
commit
8875595012
|
@ -178,6 +178,8 @@ namespace IRaCIS.Core.Application.Contracts
|
||||||
|
|
||||||
public class PreArchiveDicomStudyCommand
|
public class PreArchiveDicomStudyCommand
|
||||||
{
|
{
|
||||||
|
//public string StudyInstanceUid { get; set; }
|
||||||
|
|
||||||
[NotDefault]
|
[NotDefault]
|
||||||
public Guid TrialId { get; set; }
|
public Guid TrialId { get; set; }
|
||||||
[NotDefault]
|
[NotDefault]
|
||||||
|
|
|
@ -21,7 +21,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
||||||
[ApiExplorerSettings(GroupName = "Image")]
|
[ApiExplorerSettings(GroupName = "Image")]
|
||||||
public class StudyService : BaseService, IStudyService
|
public class StudyService : BaseService, IStudyService
|
||||||
{
|
{
|
||||||
private static object lockCodeGenerate = new object();
|
private static object lockObj = new object();
|
||||||
private static readonly AsyncLock _mutex = new AsyncLock();
|
private static readonly AsyncLock _mutex = new AsyncLock();
|
||||||
private static readonly AsyncLock _mutex2 = new AsyncLock();
|
private static readonly AsyncLock _mutex2 = new AsyncLock();
|
||||||
|
|
||||||
|
@ -93,8 +93,18 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
||||||
public async Task<IResponseOutput> PreArchiveDicomStudy(PreArchiveDicomStudyCommand preArchiveStudyCommand)
|
public async Task<IResponseOutput> PreArchiveDicomStudy(PreArchiveDicomStudyCommand preArchiveStudyCommand)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
//lock (lockObj)
|
||||||
|
//{
|
||||||
|
// if (_provider.Exists($"StudyUid_{preArchiveStudyCommand.TrialId}_{preArchiveStudyCommand.StudyInstanceUid}"))
|
||||||
|
// {
|
||||||
|
// //---当前已有人正在上传和归档该检查!
|
||||||
|
// return ResponseOutput.NotOk(StaticData.International("UploadDownLoad_ArchiveInProgress"));
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// _provider.Set($"StudyUid_{preArchiveStudyCommand.TrialId}_{preArchiveStudyCommand.StudyInstanceUid}", _userInfo.Id, TimeSpan.FromSeconds(30));
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
var studyMonitor = new StudyMonitor()
|
var studyMonitor = new StudyMonitor()
|
||||||
{
|
{
|
||||||
|
@ -111,7 +121,6 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
||||||
IsDicomReUpload = preArchiveStudyCommand.IsDicomReUpload,
|
IsDicomReUpload = preArchiveStudyCommand.IsDicomReUpload,
|
||||||
FileSize = preArchiveStudyCommand.FileSize,
|
FileSize = preArchiveStudyCommand.FileSize,
|
||||||
FileCount = preArchiveStudyCommand.FileCount,
|
FileCount = preArchiveStudyCommand.FileCount,
|
||||||
//FailedFileCount = preArchiveStudyCommand.FailedFileCount,
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -123,123 +132,76 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public IResponseOutput DicomUploadInprogress(Guid trialId, string studyInstanceUid)
|
||||||
|
{
|
||||||
|
_provider.Set($"StudyUid_{trialId}_{studyInstanceUid}", _userInfo.Id, TimeSpan.FromSeconds(30));
|
||||||
|
|
||||||
|
return ResponseOutput.Ok();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
|
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
|
||||||
public async Task<IResponseOutput> AddOrUpdateArchiveStudy(NewArchiveStudyCommand incommand)
|
public async Task<IResponseOutput> AddOrUpdateArchiveStudy(NewArchiveStudyCommand incommand)
|
||||||
{
|
{
|
||||||
var trialId = incommand.TrialId;
|
try
|
||||||
|
|
||||||
var studyMonitor = await _studyMonitorRepository.FirstOrDefaultAsync(t => t.Id == incommand.StudyMonitorId);
|
|
||||||
studyMonitor.UploadFinishedTime = DateTime.Now;
|
|
||||||
studyMonitor.ArchiveFinishedTime = DateTime.Now;
|
|
||||||
studyMonitor.FailedFileCount = incommand.FailedFileCount;
|
|
||||||
studyMonitor.IsSuccess = true;
|
|
||||||
|
|
||||||
//上传
|
|
||||||
if (studyMonitor.IsDicomReUpload == false)
|
|
||||||
{
|
{
|
||||||
var study = _mapper.Map<DicomStudy>(incommand.Study);
|
var trialId = incommand.TrialId;
|
||||||
|
|
||||||
using (await _mutex.LockAsync())
|
var studyMonitor = await _studyMonitorRepository.FirstOrDefaultAsync(t => t.Id == incommand.StudyMonitorId);
|
||||||
|
studyMonitor.UploadFinishedTime = DateTime.Now;
|
||||||
|
studyMonitor.ArchiveFinishedTime = DateTime.Now;
|
||||||
|
studyMonitor.FailedFileCount = incommand.FailedFileCount;
|
||||||
|
studyMonitor.IsSuccess = true;
|
||||||
|
|
||||||
|
//上传
|
||||||
|
if (studyMonitor.IsDicomReUpload == false)
|
||||||
{
|
{
|
||||||
//查询数据库获取最大的Code 没有记录则为0
|
var study = _mapper.Map<DicomStudy>(incommand.Study);
|
||||||
var dbStudyCodeIntMax = _dicomstudyRepository.Where(s => s.TrialId == trialId).Select(t => t.Code).DefaultIfEmpty().Max();
|
|
||||||
|
|
||||||
//获取缓存中的值 并发的时候,需要记录,已被占用的值 这样其他线程在此占用的最大的值上递增
|
using (await _mutex.LockAsync())
|
||||||
var cacheMaxCodeInt = _provider.Get<int>($"{trialId}_{StaticData.CacheKey.StudyMaxCode}").Value;
|
|
||||||
|
|
||||||
int currentNextCodeInt = cacheMaxCodeInt > dbStudyCodeIntMax ? cacheMaxCodeInt + 1 : dbStudyCodeIntMax + 1;
|
|
||||||
|
|
||||||
study.Code = currentNextCodeInt;
|
|
||||||
|
|
||||||
study.StudyCode = AppSettings.GetCodeStr(currentNextCodeInt, nameof(DicomStudy));
|
|
||||||
|
|
||||||
_provider.Set<int>($"{trialId}_{StaticData.CacheKey.StudyMaxCode}", study.Code, TimeSpan.FromMinutes(30));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
study.Id = IdentifierHelper.CreateGuid(incommand.Study.StudyInstanceUid, incommand.TrialId.ToString());
|
|
||||||
study.TrialId = incommand.TrialId;
|
|
||||||
study.SiteId = incommand.SiteId;
|
|
||||||
study.SubjectId = incommand.SubjectId;
|
|
||||||
study.SubjectVisitId = incommand.SubjectVisitId;
|
|
||||||
|
|
||||||
|
|
||||||
//特殊处理逻辑
|
|
||||||
study.Modalities = string.Join("、", incommand.Study.SeriesList.Select(t => t.Modality).Distinct());
|
|
||||||
SpecialArchiveStudyDeal(study);
|
|
||||||
|
|
||||||
await _dicomstudyRepository.AddAsync(study);
|
|
||||||
|
|
||||||
|
|
||||||
studyMonitor.StudyId = study.Id;
|
|
||||||
studyMonitor.StudyCode = study.StudyCode;
|
|
||||||
|
|
||||||
|
|
||||||
foreach (var seriesItem in incommand.Study.SeriesList)
|
|
||||||
{
|
|
||||||
var series = _mapper.Map<DicomSeries>(seriesItem);
|
|
||||||
|
|
||||||
series.Id = IdentifierHelper.CreateGuid(seriesItem.SeriesInstanceUid, incommand.TrialId.ToString());
|
|
||||||
series.StudyId = study.Id;
|
|
||||||
|
|
||||||
series.TrialId = incommand.TrialId;
|
|
||||||
series.SiteId = incommand.SiteId;
|
|
||||||
series.SubjectId = incommand.SubjectId;
|
|
||||||
series.SubjectVisitId = incommand.SubjectVisitId;
|
|
||||||
|
|
||||||
await _dicomSeriesRepository.AddAsync(series);
|
|
||||||
|
|
||||||
foreach (var instanceItem in seriesItem.InstanceList)
|
|
||||||
{
|
{
|
||||||
var isntance = _mapper.Map<DicomInstance>(instanceItem);
|
//查询数据库获取最大的Code 没有记录则为0
|
||||||
isntance.StudyId = study.Id;
|
var dbStudyCodeIntMax = _dicomstudyRepository.Where(s => s.TrialId == trialId).Select(t => t.Code).DefaultIfEmpty().Max();
|
||||||
isntance.SeriesId = series.Id;
|
|
||||||
|
|
||||||
isntance.TrialId = incommand.TrialId;
|
//获取缓存中的值 并发的时候,需要记录,已被占用的值 这样其他线程在此占用的最大的值上递增
|
||||||
isntance.SiteId = incommand.SiteId;
|
var cacheMaxCodeInt = _provider.Get<int>($"{trialId}_{StaticData.CacheKey.StudyMaxCode}").Value;
|
||||||
isntance.SubjectId = incommand.SubjectId;
|
|
||||||
isntance.SubjectVisitId = incommand.SubjectVisitId;
|
int currentNextCodeInt = cacheMaxCodeInt > dbStudyCodeIntMax ? cacheMaxCodeInt + 1 : dbStudyCodeIntMax + 1;
|
||||||
|
|
||||||
|
study.Code = currentNextCodeInt;
|
||||||
|
|
||||||
|
study.StudyCode = AppSettings.GetCodeStr(currentNextCodeInt, nameof(DicomStudy));
|
||||||
|
|
||||||
|
_provider.Set<int>($"{trialId}_{StaticData.CacheKey.StudyMaxCode}", study.Code, TimeSpan.FromMinutes(30));
|
||||||
|
|
||||||
await _dicomInstanceRepository.AddAsync(isntance);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
study.Id = IdentifierHelper.CreateGuid(incommand.Study.StudyInstanceUid, incommand.TrialId.ToString());
|
||||||
|
study.TrialId = incommand.TrialId;
|
||||||
|
study.SiteId = incommand.SiteId;
|
||||||
|
study.SubjectId = incommand.SubjectId;
|
||||||
|
study.SubjectVisitId = incommand.SubjectVisitId;
|
||||||
|
|
||||||
|
|
||||||
}
|
//特殊处理逻辑
|
||||||
else
|
study.Modalities = string.Join("、", incommand.Study.SeriesList.Select(t => t.Modality).Distinct());
|
||||||
{
|
SpecialArchiveStudyDeal(study);
|
||||||
|
|
||||||
var studyId = IdentifierHelper.CreateGuid(incommand.Study.StudyInstanceUid, incommand.TrialId.ToString()); ;
|
await _dicomstudyRepository.AddAsync(study);
|
||||||
|
|
||||||
var study = await _dicomstudyRepository.FirstOrDefaultAsync(t => t.Id == studyId);
|
|
||||||
|
|
||||||
//_mapper.Map(incommand.Study, study);
|
|
||||||
|
|
||||||
//特殊处理逻辑
|
|
||||||
study.Modalities = string.Join("、", incommand.Study.SeriesList.Select(t => t.Modality).Union(study.Modalities.Split("、", StringSplitOptions.RemoveEmptyEntries)).Distinct());
|
|
||||||
SpecialArchiveStudyDeal(study);
|
|
||||||
|
|
||||||
|
|
||||||
|
studyMonitor.StudyId = study.Id;
|
||||||
|
studyMonitor.StudyCode = study.StudyCode;
|
||||||
|
|
||||||
// 少了整个序列
|
|
||||||
|
|
||||||
//某个序列下少了instance
|
foreach (var seriesItem in incommand.Study.SeriesList)
|
||||||
foreach (var seriesItem in incommand.Study.SeriesList)
|
|
||||||
{
|
|
||||||
var seriesId = IdentifierHelper.CreateGuid(seriesItem.StudyInstanceUid, seriesItem.SeriesInstanceUid, trialId.ToString());
|
|
||||||
|
|
||||||
DicomSeries dicomSeries = await _dicomSeriesRepository.FirstOrDefaultAsync(t => t.Id == seriesId);
|
|
||||||
|
|
||||||
//判断重复
|
|
||||||
if (dicomSeries == null)
|
|
||||||
{
|
{
|
||||||
var series = _mapper.Map<DicomSeries>(seriesItem);
|
var series = _mapper.Map<DicomSeries>(seriesItem);
|
||||||
|
|
||||||
series.Id = seriesId;
|
series.Id = IdentifierHelper.CreateGuid(seriesItem.SeriesInstanceUid, incommand.TrialId.ToString());
|
||||||
series.StudyId = study.Id;
|
series.StudyId = study.Id;
|
||||||
|
|
||||||
series.TrialId = incommand.TrialId;
|
series.TrialId = incommand.TrialId;
|
||||||
|
@ -247,49 +209,120 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
||||||
series.SubjectId = incommand.SubjectId;
|
series.SubjectId = incommand.SubjectId;
|
||||||
series.SubjectVisitId = incommand.SubjectVisitId;
|
series.SubjectVisitId = incommand.SubjectVisitId;
|
||||||
|
|
||||||
|
await _dicomSeriesRepository.AddAsync(series);
|
||||||
|
|
||||||
dicomSeries = await _dicomSeriesRepository.AddAsync(series);
|
foreach (var instanceItem in seriesItem.InstanceList)
|
||||||
|
{
|
||||||
|
var isntance = _mapper.Map<DicomInstance>(instanceItem);
|
||||||
|
isntance.StudyId = study.Id;
|
||||||
|
isntance.SeriesId = series.Id;
|
||||||
|
|
||||||
//新的序列 那么 检查的序列数量+1
|
isntance.TrialId = incommand.TrialId;
|
||||||
study.SeriesCount += 1;
|
isntance.SiteId = incommand.SiteId;
|
||||||
|
isntance.SubjectId = incommand.SubjectId;
|
||||||
|
isntance.SubjectVisitId = incommand.SubjectVisitId;
|
||||||
|
|
||||||
|
await _dicomInstanceRepository.AddAsync(isntance);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
|
var studyId = IdentifierHelper.CreateGuid(incommand.Study.StudyInstanceUid, incommand.TrialId.ToString()); ;
|
||||||
|
|
||||||
|
var study = await _dicomstudyRepository.FirstOrDefaultAsync(t => t.Id == studyId);
|
||||||
|
|
||||||
|
//_mapper.Map(incommand.Study, study);
|
||||||
|
|
||||||
|
//特殊处理逻辑
|
||||||
|
study.Modalities = string.Join("、", incommand.Study.SeriesList.Select(t => t.Modality).Union(study.Modalities.Split("、", StringSplitOptions.RemoveEmptyEntries)).Distinct());
|
||||||
|
SpecialArchiveStudyDeal(study);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// 少了整个序列
|
||||||
|
|
||||||
|
//某个序列下少了instance
|
||||||
|
foreach (var seriesItem in incommand.Study.SeriesList)
|
||||||
{
|
{
|
||||||
//该序列掉了instance
|
var seriesId = IdentifierHelper.CreateGuid(seriesItem.StudyInstanceUid, seriesItem.SeriesInstanceUid, trialId.ToString());
|
||||||
dicomSeries.InstanceCount += seriesItem.InstanceCount;
|
|
||||||
|
DicomSeries dicomSeries = await _dicomSeriesRepository.FirstOrDefaultAsync(t => t.Id == seriesId);
|
||||||
|
|
||||||
|
//判断重复
|
||||||
|
if (dicomSeries == null)
|
||||||
|
{
|
||||||
|
var series = _mapper.Map<DicomSeries>(seriesItem);
|
||||||
|
|
||||||
|
series.Id = seriesId;
|
||||||
|
series.StudyId = study.Id;
|
||||||
|
|
||||||
|
series.TrialId = incommand.TrialId;
|
||||||
|
series.SiteId = incommand.SiteId;
|
||||||
|
series.SubjectId = incommand.SubjectId;
|
||||||
|
series.SubjectVisitId = incommand.SubjectVisitId;
|
||||||
|
|
||||||
|
|
||||||
|
dicomSeries = await _dicomSeriesRepository.AddAsync(series);
|
||||||
|
|
||||||
|
//新的序列 那么 检查的序列数量+1
|
||||||
|
study.SeriesCount += 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//该序列掉了instance
|
||||||
|
dicomSeries.InstanceCount += seriesItem.InstanceCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
dicomSeries.IamgeResizePath = seriesItem.IamgeResizePath;
|
||||||
|
|
||||||
|
foreach (var instanceItem in seriesItem.InstanceList)
|
||||||
|
{
|
||||||
|
var insntance = _mapper.Map<DicomInstance>(instanceItem);
|
||||||
|
insntance.Id = IdentifierHelper.CreateGuid(insntance.StudyInstanceUid, insntance.SeriesInstanceUid, insntance.SopInstanceUid, trialId.ToString());
|
||||||
|
insntance.StudyId = study.Id;
|
||||||
|
insntance.SeriesId = dicomSeries.Id;
|
||||||
|
|
||||||
|
insntance.TrialId = incommand.TrialId;
|
||||||
|
insntance.SiteId = incommand.SiteId;
|
||||||
|
insntance.SubjectId = incommand.SubjectId;
|
||||||
|
insntance.SubjectVisitId = incommand.SubjectVisitId;
|
||||||
|
|
||||||
|
await _dicomInstanceRepository.AddAsync(insntance);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 不管是新的序列 还是 该序列 掉了Instance 重传的时候 检查的instance 数量都会增加
|
||||||
|
study.InstanceCount += seriesItem.InstanceCount;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dicomSeries.IamgeResizePath = seriesItem.IamgeResizePath;
|
|
||||||
|
|
||||||
foreach (var instanceItem in seriesItem.InstanceList)
|
|
||||||
{
|
|
||||||
var insntance = _mapper.Map<DicomInstance>(instanceItem);
|
|
||||||
insntance.Id = IdentifierHelper.CreateGuid(insntance.StudyInstanceUid, insntance.SeriesInstanceUid, insntance.SopInstanceUid, trialId.ToString());
|
|
||||||
insntance.StudyId = study.Id;
|
|
||||||
insntance.SeriesId = dicomSeries.Id;
|
|
||||||
|
|
||||||
insntance.TrialId = incommand.TrialId;
|
|
||||||
insntance.SiteId = incommand.SiteId;
|
|
||||||
insntance.SubjectId = incommand.SubjectId;
|
|
||||||
insntance.SubjectVisitId = incommand.SubjectVisitId;
|
|
||||||
|
|
||||||
await _dicomInstanceRepository.AddAsync(insntance);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// 不管是新的序列 还是 该序列 掉了Instance 重传的时候 检查的instance 数量都会增加
|
|
||||||
study.InstanceCount += seriesItem.InstanceCount;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
using (await _mutex2.LockAsync())
|
||||||
|
{
|
||||||
|
await _dicomInstanceRepository.SaveChangesAsync();
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
catch (Exception ex)
|
||||||
using (await _mutex2.LockAsync())
|
|
||||||
{
|
{
|
||||||
await _dicomInstanceRepository.SaveChangesAsync();
|
|
||||||
|
|
||||||
|
return ResponseOutput.NotOk(ex.Message);
|
||||||
}
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_provider.Remove($"StudyUid_{incommand.TrialId}_{incommand.Study.StudyInstanceUid}");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -729,7 +762,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
||||||
|
|
||||||
var result = new VerifyStudyUploadResult();
|
var result = new VerifyStudyUploadResult();
|
||||||
|
|
||||||
if (_provider.Exists("StudyUid_" + studyInstanceUid))
|
if (_provider.Exists($"StudyUid_{trialId}_{studyInstanceUid}"))
|
||||||
{
|
{
|
||||||
result.AllowUpload = false;
|
result.AllowUpload = false;
|
||||||
|
|
||||||
|
@ -790,6 +823,16 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
result.StudyInstanceUid = studyInstanceUid;
|
result.StudyInstanceUid = studyInstanceUid;
|
||||||
|
|
||||||
|
|
||||||
|
if (result.AllowReUpload || result.AllowUpload)
|
||||||
|
{
|
||||||
|
lock (lockObj)
|
||||||
|
{
|
||||||
|
_provider.Set($"StudyUid_{trialId}_{studyInstanceUid}", _userInfo.Id, TimeSpan.FromMinutes(30));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue