Compare commits
139 Commits
Test_IRC_N
...
Temp_Uat_I
| Author | SHA1 | Date |
|---|---|---|
|
|
8580c64ef7 | |
|
|
64c657d233 | |
|
|
73b7aae6c0 | |
|
|
14e212c4a8 | |
|
|
344146a46e | |
|
|
cd5a1fcbb7 | |
|
|
424448db2f | |
|
|
629116cb6a | |
|
|
64c3d96807 | |
|
|
d607018832 | |
|
|
0d65625caa | |
|
|
2b82044213 | |
|
|
2769cf7efd | |
|
|
1c84a374a1 | |
|
|
2a59cfe3b5 | |
|
|
0dff3d6e4b | |
|
|
1d6731e3a4 | |
|
|
224318e0c4 | |
|
|
7096062d76 | |
|
|
a0b06fbc28 | |
|
|
4a76705ec7 | |
|
|
7676e3cc4d | |
|
|
234a5706a8 | |
|
|
956e214632 | |
|
|
974adb4367 | |
|
|
00189b992f | |
|
|
f192219621 | |
|
|
4b0d6fe8b9 | |
|
|
bb6dc19924 | |
|
|
ec9af97742 | |
|
|
a5472e1509 | |
|
|
a1bb730cfe | |
|
|
1aa411c0f8 | |
|
|
10de82132d | |
|
|
db11656862 | |
|
|
a47ac76729 | |
|
|
f86a88332c | |
|
|
f6be5e4355 | |
|
|
8deeb0290a | |
|
|
fb6231373b | |
|
|
a407313a95 | |
|
|
b1806d2eff | |
|
|
19351f34e1 | |
|
|
e0f708082d | |
|
|
44464a809d | |
|
|
c7c01b7ba3 | |
|
|
38b71d5267 | |
|
|
3950a3453a | |
|
|
7aa59da586 | |
|
|
9b2fbdb13f | |
|
|
c98b9e1bd4 | |
|
|
9522461508 | |
|
|
5bb99180b6 | |
|
|
62ec1e4955 | |
|
|
58e1af24c9 | |
|
|
a7394e7119 | |
|
|
a93d81de0d | |
|
|
6aafe02c6c | |
|
|
1511ef1608 | |
|
|
1141439c8e | |
|
|
559663082b | |
|
|
3a298518f9 | |
|
|
7f20232401 | |
|
|
20b0849b40 | |
|
|
db951e9195 | |
|
|
d5d78a99d2 | |
|
|
1609a7a88a | |
|
|
289831fce8 | |
|
|
dde058be18 | |
|
|
be8b730ee4 | |
|
|
28360861aa | |
|
|
3e097fa42b | |
|
|
b8a7cd6ebc | |
|
|
a9aefaf240 | |
|
|
266a0c5dd5 | |
|
|
54822ae038 | |
|
|
05203d6716 | |
|
|
2ce8edde80 | |
|
|
3c30f5dc14 | |
|
|
e4ad1c0653 | |
|
|
84df49ca07 | |
|
|
400edd0b70 | |
|
|
c4add1ecc8 | |
|
|
d5879e28d7 | |
|
|
37e083face | |
|
|
290506a060 | |
|
|
1b4bc3690a | |
|
|
6374781d26 | |
|
|
b28013a02f | |
|
|
fe429d2bdc | |
|
|
d63af2ed20 | |
|
|
cebf9875b1 | |
|
|
131681a0b3 | |
|
|
f833adc710 | |
|
|
df80d1e551 | |
|
|
82dc092247 | |
|
|
44894fcaa9 | |
|
|
083bebdc03 | |
|
|
e808764dd6 | |
|
|
77d198cb09 | |
|
|
180b02b28c | |
|
|
c49a74d742 | |
|
|
c76fc8f052 | |
|
|
14875dfacc | |
|
|
0a68788c0f | |
|
|
b17e5d9ff3 | |
|
|
05ce4b7155 | |
|
|
c8bbb3da48 | |
|
|
65de108ecd | |
|
|
d20c306219 | |
|
|
e69991ae37 | |
|
|
e1e2544ee3 | |
|
|
318333bae4 | |
|
|
d569de4dfe | |
|
|
05627ff126 | |
|
|
627618c854 | |
|
|
2711c5eb04 | |
|
|
a6982f79c3 | |
|
|
2a542949cd | |
|
|
a8ccbce76f | |
|
|
df7cf30aed | |
|
|
0664fbdfb7 | |
|
|
0a6ee05417 | |
|
|
f9bd8c3f5c | |
|
|
cb83c2a737 | |
|
|
fdd9afd4f0 | |
|
|
53d26c0445 | |
|
|
40d035e7a7 | |
|
|
a13807ae5f | |
|
|
9d5aaf1e26 | |
|
|
c347d08e2b | |
|
|
87f2d0e429 | |
|
|
89d009fcbf | |
|
|
7d65cf5051 | |
|
|
e74427c45c | |
|
|
e8825c7efa | |
|
|
628e0ad034 | |
|
|
2f3f639918 | |
|
|
87caf24dd1 |
|
|
@ -1116,6 +1116,14 @@
|
|||
<param name="trialId"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<!-- Badly formed XML comment ignored for member "M:IRaCIS.Core.Application.Service.TrialImageDownloadService.TrialImageAddExtralField(System.Guid,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.DicomInstance},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.DicomStudy},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.DicomSeries})" -->
|
||||
<member name="M:IRaCIS.Core.Application.Service.TrialImageDownloadService.DownloadDeleteTrialImage(System.Guid)">
|
||||
<summary>
|
||||
下载已经删除的影像
|
||||
</summary>
|
||||
<param name="trialId"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:IRaCIS.Core.Application.Service.TrialImageDownloadService.WriteTrialNeedDealData(IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.DicomInstance},System.Guid)">
|
||||
<summary>
|
||||
读取该项目的数据,进行维护
|
||||
|
|
@ -10546,6 +10554,11 @@
|
|||
影像标记
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:IRaCIS.Core.Application.Service.Reading.Dto.ReadingTableQuestionTrialAddOrEdit.IsPreinstall">
|
||||
<summary>
|
||||
是否预设
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:IRaCIS.Core.Application.Service.Reading.Dto.ReadingTableQuestionTrialAddOrEdit.ImageTool">
|
||||
<summary>
|
||||
影像工具
|
||||
|
|
@ -10689,6 +10702,11 @@
|
|||
数值类型
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:IRaCIS.Core.Application.Service.Reading.Dto.ReadingTableQuestionSystemAddOrEdit.IsPreinstall">
|
||||
<summary>
|
||||
是否预设
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:IRaCIS.Core.Application.Service.Reading.Dto.ReadingTableQuestionSystemAddOrEdit.ClassifyType">
|
||||
<summary>
|
||||
分类问题类型
|
||||
|
|
|
|||
|
|
@ -1619,7 +1619,6 @@ namespace IRaCIS.Core.Application.Service.Common
|
|||
|
||||
exportInfo.CurrentTime = ExportExcelConverterDate.DateTimeInternationalToString(DateTime.Now, _userInfo.TimeZoneId);
|
||||
|
||||
|
||||
if (inQuery.IsRandomOrderList == true)
|
||||
{
|
||||
list = list.OrderBy(t => t.RandomOrder).ToList();
|
||||
|
|
|
|||
|
|
@ -55,6 +55,8 @@ namespace IRaCIS.Core.Application.Contracts
|
|||
public string Modality { get; set; } = string.Empty;
|
||||
public DateTime ImageDate { get; set; }
|
||||
public string ModifyReason { get; set; }
|
||||
|
||||
public string BodyPartForEditOther { get; set; }
|
||||
}
|
||||
|
||||
///<summary> NoneDicomStudyAddOrEdit 列表查询参数模型</summary>
|
||||
|
|
|
|||
|
|
@ -21,6 +21,8 @@ namespace IRaCIS.Core.Application.Contracts.DTO
|
|||
public string BodyPart { get; set; } = String.Empty;
|
||||
|
||||
public string ModifyReason { get; set; }
|
||||
|
||||
public string BodyPartForEditOther { get; set; }
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1050,11 +1050,15 @@ namespace IRaCIS.Core.Application.Image.QA
|
|||
}
|
||||
else
|
||||
{
|
||||
if (await _subjectVisitRepository.AnyAsync(t => t.Id == updateModalityCommand.SubjectVisitId && t.SubmitState == SubmitStateEnum.Submitted && !t.QCChallengeList.Any(c => c.ReuploadEnum == QCChanllengeReuploadEnum.QCAgreeUpload)))
|
||||
if (!_dicomStudyRepository.Where(t => t.Id == updateModalityCommand.Id).Any(t => t.CreateTime > t.SubjectVisit.SubmitTime))
|
||||
{
|
||||
//---提交之后,不允许修改!
|
||||
throw new BusinessValidationFailedException(_localizer["QCOperation_NoModifyAfterSubmit"]);
|
||||
if (await _subjectVisitRepository.AnyAsync(t => t.Id == updateModalityCommand.SubjectVisitId && t.SubmitState == SubmitStateEnum.Submitted && !t.QCChallengeList.Any(c => c.ReuploadEnum == QCChanllengeReuploadEnum.QCAgreeUpload)))
|
||||
{
|
||||
//---提交之后,不允许修改!
|
||||
throw new BusinessValidationFailedException(_localizer["QCOperation_NoModifyAfterSubmit"]);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1128,13 +1132,19 @@ namespace IRaCIS.Core.Application.Image.QA
|
|||
public async Task<IResponseOutput> DeleteStudyList(Guid[] ids, Guid subjectVisitId, Guid trialId)
|
||||
{
|
||||
|
||||
//提交了 但是IQC同意的时候 是可以删除的 | 普通提交后也不能删除
|
||||
if (await _subjectVisitRepository.AnyAsync(t => t.Id == subjectVisitId && t.SubmitState == SubmitStateEnum.Submitted &&
|
||||
(!t.QCChallengeList.Any(u => u.ReuploadEnum == QCChanllengeReuploadEnum.QCAgreeUpload))))
|
||||
if (!_dicomStudyRepository.Where(t => ids.Contains(t.Id)).All(t => t.CreateTime > t.SubjectVisit.SubmitTime))
|
||||
{
|
||||
//---CRC已经提交,不允许删除。
|
||||
return ResponseOutput.NotOk(_localizer["QCOperation_CrcNoDelete"]);
|
||||
//提交了 但是IQC同意的时候 是可以删除的 | 普通提交后也不能删除
|
||||
if (await _subjectVisitRepository.AnyAsync(t => t.Id == subjectVisitId && t.SubmitState == SubmitStateEnum.Submitted &&
|
||||
(!t.QCChallengeList.Any(u => u.ReuploadEnum == QCChanllengeReuploadEnum.QCAgreeUpload))))
|
||||
{
|
||||
//---CRC已经提交,不允许删除。
|
||||
return ResponseOutput.NotOk(_localizer["QCOperation_CrcNoDelete"]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
var waitDeleteStudyList = await _dicomStudyRepository.Where(x => ids.Contains(x.Id), false, true).ToListAsync();
|
||||
|
||||
foreach (var item in waitDeleteStudyList)
|
||||
|
|
|
|||
|
|
@ -1005,6 +1005,10 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto
|
|||
|
||||
public int? PageShowOrder { get; set; }
|
||||
|
||||
public bool IsPreinstall { get {
|
||||
return this.TableQuestions.Questions.Any(x => x.IsPreinstall);
|
||||
} }
|
||||
|
||||
|
||||
|
||||
public List<TrialReadQuestionData> Childrens { get; set; }
|
||||
|
|
|
|||
|
|
@ -324,6 +324,12 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto
|
|||
/// </summary>
|
||||
public ImageMark? ImageMarkEnum { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 是否预设
|
||||
/// </summary>
|
||||
public bool IsPreinstall { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// 影像工具
|
||||
/// </summary>
|
||||
|
|
@ -513,6 +519,11 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto
|
|||
/// </summary>
|
||||
public ValueOfType? ValueType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否预设
|
||||
/// </summary>
|
||||
public bool IsPreinstall { get; set; } = false;
|
||||
|
||||
public bool IsCopy { get; set; } = false;
|
||||
|
||||
|
||||
|
|
@ -1692,6 +1703,7 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto
|
|||
{
|
||||
public Guid QuestionId { get; set; }
|
||||
|
||||
|
||||
public string QuestionName { get; set; }
|
||||
|
||||
[NotMapped]
|
||||
|
|
|
|||
|
|
@ -847,7 +847,7 @@ namespace IRaCIS.Core.Application.Service
|
|||
|
||||
|
||||
/// <summary>
|
||||
/// 新增修改想想项目表格问题
|
||||
/// 新增修改项目表格问题
|
||||
/// </summary>
|
||||
/// <param name="indto"></param>
|
||||
/// <returns></returns>
|
||||
|
|
@ -861,6 +861,13 @@ namespace IRaCIS.Core.Application.Service
|
|||
//---问题编号重复
|
||||
throw new BusinessValidationFailedException(_localizer["ReadingQuestion_IdDup"]);
|
||||
}
|
||||
if (indto.IsPreinstall)
|
||||
{
|
||||
if (await _readingTableQuestionTrialRepository.AnyAsync(x => x.ReadingQuestionId == indto.ReadingQuestionId && x.Id != indto.Id && x.IsPreinstall))
|
||||
{
|
||||
throw new BusinessValidationFailedException(_localizer["ReadingQuestion_OnlyOnePreinstall"]);
|
||||
}
|
||||
}
|
||||
|
||||
indto.ParentTriggerValue = string.Join(',', indto.ParentTriggerValueList);
|
||||
indto.RelevanceValue = string.Join(',', indto.RelevanceValueList);
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
using IRaCIS.Core.Application.Service.Reading.Dto;
|
||||
using DocumentFormat.OpenXml.EMMA;
|
||||
using IRaCIS.Core.Application.Service.Reading.Dto;
|
||||
using IRaCIS.Core.Application.ViewModel;
|
||||
using IRaCIS.Core.Domain.Share;
|
||||
using IRaCIS.Core.Infra.EFCore.Common;
|
||||
|
|
@ -366,6 +367,8 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate
|
|||
var isReadingTaskViewInOrder = await _readingQuestionCriterionTrialRepository.Where(x => x.Id == taskinfo.TrialReadingCriterionId).Select(x => x.IsReadingTaskViewInOrder).FirstOrDefaultAsync();
|
||||
var baseLineVisitId = await _subjectVisitRepository.Where(x => x.SubjectId == taskinfo.SubjectId && x.IsBaseLine).Select(x => x.Id).FirstOrDefaultAsync();
|
||||
|
||||
List<ReadingTableAnswerRowInfo> addRowList = new List<ReadingTableAnswerRowInfo>();
|
||||
List<ReadingTableQuestionAnswer> addTableQuestionAnswerList = new List<ReadingTableQuestionAnswer>();
|
||||
// 判断当前任务是否是基线
|
||||
if (taskinfo.SourceSubjectVisitId != baseLineVisitId && isReadingTaskViewInOrder == ReadingOrder.InOrder)
|
||||
{
|
||||
|
|
@ -434,13 +437,64 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate
|
|||
|
||||
var addList = _mapper.Map<List<ReadingTableAnswerRowInfo>>(tableRowAnswers);
|
||||
|
||||
await _readingTableAnswerRowInfoRepository.AddRangeAsync(addList);
|
||||
await _readingTableQuestionAnswerRepository.AddRangeAsync(tableAnswers);
|
||||
await _readingTableQuestionAnswerRepository.SaveChangesAsync();
|
||||
addRowList.AddRange(addList);
|
||||
addTableQuestionAnswerList.AddRange(tableAnswers);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// 添加 是否预设
|
||||
var tableQuestionList = await _readingTableQuestionTrialRepository.Where(x => x.ReadingQuestionTrial.ReadingQuestionCriterionTrialId == taskinfo.TrialReadingCriterionId && x.IsPreinstall).Include(x=>x.ReadingQuestionTrial).ToListAsync();
|
||||
if (tableQuestionList.Count() > 0)
|
||||
{
|
||||
|
||||
foreach (var tableQuestion in tableQuestionList)
|
||||
{
|
||||
var thisTableQuestionList=await _readingTableQuestionTrialRepository.Where(x => x.ReadingQuestionId == tableQuestion.ReadingQuestionId).ToListAsync();
|
||||
|
||||
decimal index = 1;
|
||||
|
||||
foreach (var item in tableQuestion.TypeValue.Split('|'))
|
||||
{
|
||||
var newRowId = NewId.NextGuid();
|
||||
addRowList.Add(new ReadingTableAnswerRowInfo()
|
||||
{
|
||||
Id = newRowId,
|
||||
QuestionId = tableQuestion.ReadingQuestionId,
|
||||
VisitTaskId = taskinfo.Id,
|
||||
TrialId = taskinfo.TrialId,
|
||||
RowIndex = index,
|
||||
IsCurrentTaskAdd = true,
|
||||
BlindName = taskinfo.TaskBlindName,
|
||||
OrderMark = tableQuestion.ReadingQuestionTrial.OrderMark,
|
||||
FristAddTaskId = taskinfo.Id,
|
||||
RowMark = tableQuestion.ReadingQuestionTrial.OrderMark + decimal.Parse(index.ToString()).GetLesionMark()
|
||||
|
||||
});
|
||||
|
||||
foreach (var thisTableQuestion in thisTableQuestionList)
|
||||
{
|
||||
addTableQuestionAnswerList.Add(new ReadingTableQuestionAnswer()
|
||||
{
|
||||
Answer = thisTableQuestion.Id== tableQuestion.Id? item:string.Empty,
|
||||
QuestionId = tableQuestion.ReadingQuestionId,
|
||||
TrialId = taskinfo.TrialId,
|
||||
VisitTaskId = taskinfo.Id,
|
||||
RowId = newRowId,
|
||||
RowIndex = index,
|
||||
TableQuestionId = thisTableQuestion.Id,
|
||||
});
|
||||
}
|
||||
index++;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
await _readingTableAnswerRowInfoRepository.AddRangeAsync(addRowList);
|
||||
await _readingTableQuestionAnswerRepository.AddRangeAsync(addTableQuestionAnswerList);
|
||||
await _readingTableQuestionAnswerRepository.SaveChangesAsync();
|
||||
return new AddTaskLesionAnswerFromLastTaskOutDto()
|
||||
{
|
||||
|
||||
|
|
|
|||
|
|
@ -441,6 +441,308 @@ namespace IRaCIS.Core.Application.Service
|
|||
|
||||
|
||||
|
||||
[AllowAnonymous]
|
||||
public async Task<IResponseOutput> RestoreDBOSSDate(
|
||||
[FromServices] IOSSService _oSSService, [FromServices] IWebHostEnvironment _hostEnvironment, [FromServices] IRepository<DicomStudy> _studyRepository)
|
||||
{
|
||||
var folder = FileStoreHelper.GetIRaCISRootDataFolder(_hostEnvironment);
|
||||
|
||||
var outputFile = Path.Combine(folder, $"{Guid.NewGuid()}_deleteKey_info.txt");
|
||||
var outputFile2 = Path.Combine(folder, $"{Guid.NewGuid()}_deleteKeyExport_info.txt");
|
||||
|
||||
var outputErrorFile = Path.Combine(folder, $"{Guid.NewGuid()}_deleteKeyerror.txt");
|
||||
var outputErrorFile2 = Path.Combine(folder, $"{Guid.NewGuid()}_deleteKeyerrorStudy.txt");
|
||||
|
||||
|
||||
var aliConfig = _oSSService.ObjectStoreServiceOptions.AliyunOSS;
|
||||
|
||||
var tempToken = _oSSService.GetObjectStoreTempToken();
|
||||
|
||||
var _ossClient = new OssClient(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? aliConfig.EndPoint : aliConfig.InternalEndpoint,
|
||||
tempToken.AliyunOSS.AccessKeyId,
|
||||
tempToken.AliyunOSS.AccessKeySecret,
|
||||
tempToken.AliyunOSS.SecurityToken);
|
||||
|
||||
|
||||
var allVersions = new List<ObjectVersionSummary>();
|
||||
var allDeleteMarkers = new List<DeleteMarkerSummary>();
|
||||
|
||||
var request = new ListObjectVersionsRequest(tempToken.AliyunOSS.BucketName)
|
||||
{
|
||||
Prefix = "01000000-ac13-0242-6397-08dcd2d2a091/Image",
|
||||
//Prefix = "01000000-ac13-0242-6397-08dcd2d2a091/Image/08dd9c04-c1b2-c2da-0242-ac1301000000/01000000-ac13-0242-235b-08dd9c04c1b3",
|
||||
MaxKeys = 1000,
|
||||
};
|
||||
|
||||
ObjectVersionList result;
|
||||
do
|
||||
{
|
||||
|
||||
result = _ossClient.ListObjectVersions(request);
|
||||
|
||||
if (result.ObjectVersionSummaries != null)
|
||||
allVersions.AddRange(result.ObjectVersionSummaries);
|
||||
|
||||
if (result.DeleteMarkerSummaries != null)
|
||||
allDeleteMarkers.AddRange(result.DeleteMarkerSummaries);
|
||||
|
||||
request.KeyMarker = result.NextKeyMarker;
|
||||
request.VersionIdMarker = result.NextVersionIdMarker;
|
||||
|
||||
} while (result.IsTruncated);
|
||||
|
||||
Console.WriteLine($"共找到 {allDeleteMarkers.Count} 个删除标记");
|
||||
|
||||
|
||||
|
||||
int total = allDeleteMarkers.Count;
|
||||
|
||||
int processed = 0;
|
||||
double lastPercent = 0;
|
||||
|
||||
|
||||
// 按 Key 分组,找每个删除标记前的最近版本
|
||||
var versionsByKey = allVersions
|
||||
.GroupBy(v => v.Key)
|
||||
.ToDictionary(g => g.Key, g => g.OrderByDescending(x => x.LastModified).ToList());
|
||||
|
||||
foreach (var del in allDeleteMarkers)
|
||||
{
|
||||
#region 防止阿里云过期
|
||||
if (tempToken.AliyunOSS.Expiration.AddSeconds(10) <= DateTime.Now)
|
||||
{
|
||||
tempToken = _oSSService.GetObjectStoreTempToken();
|
||||
|
||||
_ossClient = new OssClient(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? aliConfig.EndPoint : aliConfig.InternalEndpoint,
|
||||
tempToken.AliyunOSS.AccessKeyId,
|
||||
tempToken.AliyunOSS.AccessKeySecret,
|
||||
tempToken.AliyunOSS.SecurityToken);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
if (!versionsByKey.TryGetValue(del.Key, out var versions))
|
||||
continue; // 没有历史版本无法恢复
|
||||
|
||||
var prevVersion = versions.FirstOrDefault(v => v.LastModified < del.LastModified);
|
||||
if (prevVersion == null)
|
||||
continue; // 没找到可恢复版本
|
||||
|
||||
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
await File.AppendAllTextAsync(outputFile, $"{prevVersion.Key},{prevVersion.VersionId}" + Environment.NewLine);
|
||||
|
||||
var getReq = new GetObjectRequest(tempToken.AliyunOSS.BucketName, prevVersion.Key)
|
||||
{
|
||||
VersionId = prevVersion.VersionId
|
||||
};
|
||||
|
||||
using (var getResult = _ossClient.GetObject(getReq))
|
||||
using (var memStream = new MemoryStream())
|
||||
{
|
||||
// 先把 OSS 流复制到内存流
|
||||
getResult.Content.CopyTo(memStream);
|
||||
memStream.Position = 0;
|
||||
|
||||
// 读取 DICOM 信息
|
||||
var dicomFile = DicomFile.Open(memStream);
|
||||
var studyInstanceUID = dicomFile.Dataset.GetString(DicomTag.StudyInstanceUID);
|
||||
|
||||
var findInfo = await _studyRepository.Where(t => t.StudyInstanceUid == studyInstanceUID && t.TrialId == Guid.Parse("01000000-ac13-0242-6397-08dcd2d2a091"))
|
||||
.Select(t => new { t.StudyInstanceUid, t.Subject.Code, t.SubjectVisit.VisitName, t.SubjectId, t.SubjectVisitId }).FirstOrDefaultAsync();
|
||||
|
||||
if (findInfo != null)
|
||||
{
|
||||
|
||||
// 再保存到另一个路径(可以使用 fo-dicom 保存)
|
||||
|
||||
var fileName = Path.GetFileNameWithoutExtension(prevVersion.Key);
|
||||
var anotherPath = Path.Combine(folder, findInfo.Code, findInfo.VisitName, studyInstanceUID, fileName);
|
||||
// 去掉 folder 部分,得到相对路径
|
||||
var relativePath = Path.GetRelativePath(folder, anotherPath);
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(anotherPath));
|
||||
dicomFile.Save(anotherPath);
|
||||
|
||||
await File.AppendAllTextAsync(outputFile2, $"{findInfo.SubjectId},{findInfo.SubjectVisitId},{prevVersion.Key},{prevVersion.VersionId},{relativePath},{findInfo.Code},{findInfo.VisitName},{findInfo.StudyInstanceUid},{fileName}" + Environment.NewLine);
|
||||
}
|
||||
else
|
||||
{
|
||||
await File.AppendAllTextAsync(outputErrorFile2, $"{studyInstanceUID},{prevVersion.Key},{prevVersion.VersionId}" + Environment.NewLine);
|
||||
}
|
||||
|
||||
//Console.WriteLine($"读取到 studyInstanceUID: {studyInstanceUID}");
|
||||
|
||||
//var localPath = Path.Combine(folder, prevVersion.Key.Trim('/').Replace('/', Path.DirectorySeparatorChar));
|
||||
//Directory.CreateDirectory(Path.GetDirectoryName(localPath));
|
||||
//// 保存到原本路径
|
||||
//memStream.Position = 0;
|
||||
//using (var fs = File.Create(localPath))
|
||||
//{
|
||||
// memStream.CopyTo(fs);
|
||||
//}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
//Console.WriteLine($"✅ 下载成功: {prevVersion.Key} (version={prevVersion.VersionId})");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"❌ 下载失败: {prevVersion.Key}, 错误: {ex.Message}");
|
||||
|
||||
await File.AppendAllTextAsync(outputErrorFile, $"{prevVersion.Key},{prevVersion.VersionId}" + Environment.NewLine);
|
||||
}
|
||||
finally
|
||||
{
|
||||
processed++;
|
||||
double percent = processed * 100.0 / total;
|
||||
|
||||
// 每提升 5% 或完成时输出
|
||||
if (percent - lastPercent >= 2.0 || processed == total)
|
||||
{
|
||||
lastPercent = percent;
|
||||
Console.WriteLine($"{DateTime.Now} 进度: {processed}/{total} ({percent:F2}%)");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 使用 CopyObject 把历史版本拷贝为最新版本(恢复)
|
||||
//var copyReq = new CopyObjectRequest
|
||||
//{
|
||||
// Bucket = bucketName,
|
||||
// Key = prevVersion.Key,
|
||||
// SourceBucket = bucketName,
|
||||
// SourceKey = prevVersion.Key,
|
||||
// SourceVersionId = prevVersion.VersionId
|
||||
//};
|
||||
|
||||
//try
|
||||
//{
|
||||
// var copyResult = client.CopyObject(copyReq);
|
||||
// Console.WriteLine($"✅ 恢复成功: {prevVersion.Key} -> newVersionId={copyResult.VersionId}");
|
||||
//}
|
||||
//catch (Exception ex)
|
||||
//{
|
||||
// Console.WriteLine($"❌ 恢复失败: {prevVersion.Key}, 错误: {ex.Message}");
|
||||
//}
|
||||
}
|
||||
|
||||
|
||||
|
||||
return ResponseOutput.Ok();
|
||||
}
|
||||
|
||||
|
||||
|
||||
public async Task<IResponseOutput> OSSDeleteReStorre([FromServices] IOSSService _oSSService, [FromServices] IWebHostEnvironment _hostEnvironment)
|
||||
{
|
||||
var aliConfig = _oSSService.ObjectStoreServiceOptions.AliyunOSS;
|
||||
|
||||
var tempToken = _oSSService.GetObjectStoreTempToken();
|
||||
|
||||
var _ossClient = new OssClient(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? aliConfig.EndPoint : aliConfig.InternalEndpoint,
|
||||
tempToken.AliyunOSS.AccessKeyId,
|
||||
tempToken.AliyunOSS.AccessKeySecret,
|
||||
tempToken.AliyunOSS.SecurityToken);
|
||||
|
||||
|
||||
var allVersions = new List<ObjectVersionSummary>();
|
||||
var allDeleteMarkers = new List<DeleteMarkerSummary>();
|
||||
|
||||
var request = new ListObjectVersionsRequest(tempToken.AliyunOSS.BucketName)
|
||||
{
|
||||
Prefix = "test-delete-restore",
|
||||
//Prefix = "01000000-ac13-0242-6397-08dcd2d2a091/Image/08dd9c04-c1b2-c2da-0242-ac1301000000/01000000-ac13-0242-235b-08dd9c04c1b3",
|
||||
MaxKeys = 1000,
|
||||
};
|
||||
|
||||
ObjectVersionList result;
|
||||
do
|
||||
{
|
||||
|
||||
result = _ossClient.ListObjectVersions(request);
|
||||
|
||||
if (result.ObjectVersionSummaries != null)
|
||||
allVersions.AddRange(result.ObjectVersionSummaries);
|
||||
|
||||
if (result.DeleteMarkerSummaries != null)
|
||||
allDeleteMarkers.AddRange(result.DeleteMarkerSummaries);
|
||||
|
||||
request.KeyMarker = result.NextKeyMarker;
|
||||
request.VersionIdMarker = result.NextVersionIdMarker;
|
||||
|
||||
} while (result.IsTruncated);
|
||||
|
||||
Console.WriteLine($"共找到 {allDeleteMarkers.Count} 个删除标记");
|
||||
|
||||
var versionsByKey = allVersions
|
||||
.GroupBy(v => v.Key)
|
||||
.ToDictionary(g => g.Key, g => g.OrderByDescending(x => x.LastModified).ToList());
|
||||
|
||||
|
||||
foreach (var del in allDeleteMarkers)
|
||||
{
|
||||
#region 防止阿里云过期
|
||||
if (tempToken.AliyunOSS.Expiration.AddSeconds(10) <= DateTime.Now)
|
||||
{
|
||||
tempToken = _oSSService.GetObjectStoreTempToken();
|
||||
|
||||
_ossClient = new OssClient(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? aliConfig.EndPoint : aliConfig.InternalEndpoint,
|
||||
tempToken.AliyunOSS.AccessKeyId,
|
||||
tempToken.AliyunOSS.AccessKeySecret,
|
||||
tempToken.AliyunOSS.SecurityToken);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
if (!versionsByKey.TryGetValue(del.Key, out var versions))
|
||||
continue; // 没有历史版本无法恢复
|
||||
|
||||
var prevVersion = versions.FirstOrDefault(v => v.LastModified < del.LastModified);
|
||||
if (prevVersion == null)
|
||||
continue; // 没找到可恢复版本
|
||||
|
||||
|
||||
|
||||
|
||||
// 创建 CopyObject 请求
|
||||
// 先用构造函数指定源和目标
|
||||
var copyReq = new CopyObjectRequest(
|
||||
sourceBucketName: tempToken.AliyunOSS.BucketName,
|
||||
sourceKey: prevVersion.Key,
|
||||
destinationBucketName: tempToken.AliyunOSS.BucketName,
|
||||
destinationKey: prevVersion.Key // 覆盖到同名 Key,达到“恢复”的效果
|
||||
);
|
||||
|
||||
// 再设置版本号
|
||||
copyReq.SourceVersionId = prevVersion.VersionId;
|
||||
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
var copyResult = _ossClient.CopyObject(copyReq);
|
||||
Console.WriteLine($"✅ 恢复成功: {prevVersion.Key}, 新版本ID={copyResult.VersionId}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"❌ 恢复失败: {prevVersion.Key}, 错误: {ex.Message}");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
return ResponseOutput.Ok();
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
[AllowAnonymous]
|
||||
public async Task<IResponseOutput> UserCreateSourceDeal([FromServices] IRepository<IdentityUser> _identityUserRepository,
|
||||
[FromServices] IRepository<TrialUserRole> _trialUserRoleRepository)
|
||||
|
|
|
|||
|
|
@ -167,6 +167,12 @@ public class ReadingTableQuestionSystem : BaseAddAuditEntity
|
|||
[Comment("导出结果")]
|
||||
public string ExportResultStr { get; set; } = "[]";
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 是否预设
|
||||
/// </summary>
|
||||
public bool IsPreinstall { get; set; } = false;
|
||||
|
||||
[NotMapped]
|
||||
public List<ExportResult> ExportResult
|
||||
{
|
||||
|
|
|
|||
|
|
@ -192,6 +192,11 @@ public class ReadingTableQuestionTrial : BaseAddAuditEntity
|
|||
/// </summary>
|
||||
public string ImageTool { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 是否预设
|
||||
/// </summary>
|
||||
public bool IsPreinstall { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// 影像工具属性
|
||||
/// </summary>
|
||||
|
|
|
|||
|
|
@ -3860,8 +3860,6 @@ namespace IRaCIS.Core.Infra.EFCore.Common
|
|||
entity.RowMark = entity.OrderMark+ entity.RowIndex.GetLesionMark();
|
||||
|
||||
|
||||
|
||||
|
||||
string extraIdentification = string.Empty;
|
||||
|
||||
var readingQuestion = await _dbContext.ReadingQuestionTrial.Where(t => t.Id == entity.QuestionId).Include(x => x.ReadingQuestionCriterionTrial).FirstNotNullAsync();
|
||||
|
|
@ -3869,7 +3867,7 @@ namespace IRaCIS.Core.Infra.EFCore.Common
|
|||
{
|
||||
extraIdentification = "/Nontumorous";
|
||||
}
|
||||
|
||||
|
||||
if (readingQuestion.ReadingQuestionCriterionTrial.CriterionType == CriterionType.SelfDefine)
|
||||
{
|
||||
extraIdentification = "/SelfDefine";
|
||||
|
|
|
|||
20344
IRaCIS.Core.Infra.EFCore/Migrations/20251010074451_IsPreinstall.Designer.cs
generated
Normal file
20344
IRaCIS.Core.Infra.EFCore/Migrations/20251010074451_IsPreinstall.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,40 @@
|
|||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace IRaCIS.Core.Infra.EFCore.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class IsPreinstall : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<bool>(
|
||||
name: "IsPreinstall",
|
||||
table: "ReadingTableQuestionTrial",
|
||||
type: "bit",
|
||||
nullable: false,
|
||||
defaultValue: false);
|
||||
|
||||
migrationBuilder.AddColumn<bool>(
|
||||
name: "IsPreinstall",
|
||||
table: "ReadingTableQuestionSystem",
|
||||
type: "bit",
|
||||
nullable: false,
|
||||
defaultValue: false);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "IsPreinstall",
|
||||
table: "ReadingTableQuestionTrial");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "IsPreinstall",
|
||||
table: "ReadingTableQuestionSystem");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -7105,6 +7105,9 @@ namespace IRaCIS.Core.Infra.EFCore.Migrations
|
|||
.HasColumnType("bit")
|
||||
.HasComment("是否启用");
|
||||
|
||||
b.Property<bool>("IsPreinstall")
|
||||
.HasColumnType("bit");
|
||||
|
||||
b.Property<int>("IsRequired")
|
||||
.HasColumnType("int");
|
||||
|
||||
|
|
@ -7337,6 +7340,9 @@ namespace IRaCIS.Core.Infra.EFCore.Migrations
|
|||
b.Property<bool>("IsEnable")
|
||||
.HasColumnType("bit");
|
||||
|
||||
b.Property<bool>("IsPreinstall")
|
||||
.HasColumnType("bit");
|
||||
|
||||
b.Property<int>("IsRequired")
|
||||
.HasColumnType("int");
|
||||
|
||||
|
|
@ -15450,7 +15456,7 @@ namespace IRaCIS.Core.Infra.EFCore.Migrations
|
|||
.IsRequired();
|
||||
|
||||
b.HasOne("IRaCIS.Core.Domain.Models.IdentityUser", "IdentityUser")
|
||||
.WithMany()
|
||||
.WithMany("AuditRecordList")
|
||||
.HasForeignKey("IdentityUserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
|
@ -19951,6 +19957,8 @@ namespace IRaCIS.Core.Infra.EFCore.Migrations
|
|||
|
||||
modelBuilder.Entity("IRaCIS.Core.Domain.Models.IdentityUser", b =>
|
||||
{
|
||||
b.Navigation("AuditRecordList");
|
||||
|
||||
b.Navigation("SystemDocConfirmedList");
|
||||
|
||||
b.Navigation("UserRoleList");
|
||||
|
|
|
|||
Loading…
Reference in New Issue