Compare commits

..

113 Commits

Author SHA1 Message Date
hang f192219621 合并问题
continuous-integration/drone/push Build is passing Details
2025-08-07 11:37:24 +08:00
hang 4b0d6fe8b9 Test 合并到Uat 冲突解决
continuous-integration/drone/push Build is failing Details
2025-08-07 11:30:37 +08:00
hang bb6dc19924 更新里面有添加bug
continuous-integration/drone/push Build is passing Details
2025-07-29 15:21:18 +08:00
hang ec9af97742 初审通过bug 修改
continuous-integration/drone/push Build is passing Details
2025-07-29 09:07:55 +08:00
hang a5472e1509 取tag 做判断
continuous-integration/drone/push Build is passing Details
2025-07-25 10:30:31 +08:00
hang a1bb730cfe Merge branch 'Uat_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Uat_IRC_Net8
continuous-integration/drone/push Build is passing Details
2025-07-23 15:00:27 +08:00
hang 1aa411c0f8 下一个任务不会跳复核任务 2025-07-23 15:00:25 +08:00
he 10de82132d Merge branch 'Uat_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Uat_IRC_Net8
continuous-integration/drone/push Build is passing Details
2025-07-23 13:34:56 +08:00
he db11656862 邮件修改 区分CRC与CRA 2025-07-23 13:34:54 +08:00
hang a47ac76729 复核指派bug修改
continuous-integration/drone/push Build is passing Details
2025-07-22 15:29:09 +08:00
hang f86a88332c 复核稽查修改016
continuous-integration/drone/push Build is passing Details
2025-07-18 13:15:23 +08:00
hang f6be5e4355 复核稽查修改015
continuous-integration/drone/push Build is failing Details
2025-07-18 13:04:58 +08:00
hang 8deeb0290a 复核稽查修改014
continuous-integration/drone/push Build is failing Details
2025-07-18 12:17:55 +08:00
hang fb6231373b 复核稽查修改013
continuous-integration/drone/push Build is passing Details
2025-07-18 11:34:13 +08:00
hang a407313a95 复核稽查修改012
continuous-integration/drone/push Build is passing Details
2025-07-18 09:25:56 +08:00
hang b1806d2eff 复核稽查修改011
continuous-integration/drone/push Build is passing Details
2025-07-17 17:25:45 +08:00
hang 19351f34e1 复核稽查修改010
continuous-integration/drone/push Build is passing Details
2025-07-17 17:10:06 +08:00
hang e0f708082d 复核稽查修改009
continuous-integration/drone/push Build is passing Details
2025-07-17 16:49:20 +08:00
hang 44464a809d 复核稽查修改008
continuous-integration/drone/push Build is passing Details
2025-07-17 15:26:28 +08:00
hang c7c01b7ba3 复核稽查修改007
continuous-integration/drone/push Build is passing Details
2025-07-17 15:08:11 +08:00
hang 38b71d5267 复核稽查修改006
continuous-integration/drone/push Build is passing Details
2025-07-17 14:00:03 +08:00
hang 3950a3453a 复核稽查修改005
continuous-integration/drone/push Build is passing Details
2025-07-17 13:26:44 +08:00
hang 7aa59da586 复核稽查修改004
continuous-integration/drone/push Build is passing Details
2025-07-17 11:51:41 +08:00
hang 9b2fbdb13f 复核稽查修改003
continuous-integration/drone/push Build is passing Details
2025-07-17 11:28:47 +08:00
hang c98b9e1bd4 复核稽查修改002
continuous-integration/drone/push Build is passing Details
2025-07-17 11:08:02 +08:00
hang 9522461508 复核稽查修改
continuous-integration/drone/push Build is passing Details
2025-07-17 10:34:15 +08:00
hang 5bb99180b6 修改复核-退回-003
continuous-integration/drone/push Build is passing Details
2025-07-16 17:59:42 +08:00
hang 62ec1e4955 修改复核查询接口-002
continuous-integration/drone/push Build is passing Details
2025-07-16 17:34:09 +08:00
hang 58e1af24c9 修改复核查询接口-001
continuous-integration/drone/push Build is passing Details
2025-07-16 16:30:03 +08:00
hang a7394e7119 指派其他质控-uat-13
continuous-integration/drone/push Build is passing Details
2025-07-16 10:30:55 +08:00
hang a93d81de0d 指派其他质控-uat-12 2025-07-16 10:30:51 +08:00
hang 6aafe02c6c 指派其他质控-uat-11 2025-07-16 10:30:48 +08:00
hang 1511ef1608 修改QC复核 -二次提交-uat-10 2025-07-16 10:30:43 +08:00
hang 1141439c8e 修改QC复核 -二次提交-uat-9 2025-07-16 10:30:32 +08:00
hang 559663082b 修改QC复核 -二次提交-uat-8 2025-07-16 10:26:30 +08:00
hang 3a298518f9 修改QC复核 -二次提交-uat-7 2025-07-16 10:26:25 +08:00
hang 7f20232401 修改QC复核 -二次提交-uat-6 2025-07-16 10:26:21 +08:00
hang 20b0849b40 修改QC复核 -二次提交-uat-5 2025-07-16 10:26:16 +08:00
hang db951e9195 修改QC复核 -二次提交-uat-4 2025-07-16 10:26:13 +08:00
hang d5d78a99d2 QC复核 -二次提交-uat-3 2025-07-16 10:26:08 +08:00
hang 1609a7a88a QC复核 -二次提交-uat-3 2025-07-16 10:26:03 +08:00
hang 289831fce8 QC复核 -二次提交-uat-2 2025-07-16 10:25:59 +08:00
hang dde058be18 QC 审核提交--迁移uat 2025-07-16 10:25:26 +08:00
hang be8b730ee4 返回文件大小
continuous-integration/drone/push Build is passing Details
2025-07-14 15:00:36 +08:00
hang 28360861aa 修改subject 随机阅片下载影像重阅bug
continuous-integration/drone/push Build is passing Details
2025-07-14 13:36:27 +08:00
hang 3e097fa42b uat 序列获取Instance 增加文件大小 2025-07-14 13:32:21 +08:00
hang b8a7cd6ebc 修改非dicom 设置删除,检查上的数量不变更 2025-07-14 13:32:16 +08:00
hang a9aefaf240 修改预览看到阅片影像 修改后受试者随机bug修改 4 2025-07-14 13:32:10 +08:00
hang 266a0c5dd5 修改后受试者随机bug修改 3 2025-07-14 13:32:05 +08:00
hang 54822ae038 修改后受试者随机bug修改 2 2025-07-14 13:31:07 +08:00
hang 05203d6716 受试者随机bug修改 2025-07-14 13:31:00 +08:00
hang 2ce8edde80 uat升级excel 组件测试
continuous-integration/drone/push Build is passing Details
2025-07-05 13:34:09 +08:00
hang 3c30f5dc14 完全随机跟下载关联
continuous-integration/drone/push Build is passing Details
2025-07-03 14:54:23 +08:00
hang e4ad1c0653 增加失访可读配置-uat
continuous-integration/drone/push Build is passing Details
2025-06-25 15:31:59 +08:00
he 84df49ca07 单位修改2
continuous-integration/drone/push Build is passing Details
2025-06-24 14:58:39 +08:00
he 400edd0b70 修改单位1 2025-06-24 14:58:37 +08:00
he c4add1ecc8 修改单位 2025-06-24 14:58:35 +08:00
he d5879e28d7 修改OCT计算触发逻辑
continuous-integration/drone/push Build is passing Details
2025-06-24 14:07:31 +08:00
he 37e083face 阅片标准默认值修改 2025-06-24 14:07:28 +08:00
he 290506a060 保存测量值
continuous-integration/drone/push Build is passing Details
2025-06-24 09:28:27 +08:00
he 1b4bc3690a 稽查保存Ivus和Oct 2025-06-24 09:28:25 +08:00
he 6374781d26 修改阅片期计划的排序
continuous-integration/drone/push Build is failing Details
2025-06-20 17:33:23 +08:00
he b28013a02f 阅片期计划可以选择基线 2025-06-20 17:32:07 +08:00
he fe429d2bdc 修改受试者内随机
continuous-integration/drone/push Build is passing Details
2025-06-20 09:37:48 +08:00
he d63af2ed20 修改稽查的单位翻译
continuous-integration/drone/push Build is passing Details
2025-06-19 17:16:42 +08:00
hang cebf9875b1 禁用人员系统查看文档
continuous-integration/drone/push Build is passing Details
2025-06-19 10:31:24 +08:00
hang 131681a0b3 完全随机触发系统盲态名称 2025-06-19 10:22:06 +08:00
hang f833adc710 修改有序阅片生成任务bug 2025-06-19 10:21:59 +08:00
hang df80d1e551 修改影像下载bug
continuous-integration/drone/push Build is passing Details
2025-06-18 10:36:26 +08:00
he 82dc092247 修改阅片期计划生成裁判的逻辑
continuous-integration/drone/push Build is passing Details
2025-06-17 16:42:47 +08:00
he 44894fcaa9 生成阅片期计划的时候 产生裁判
continuous-integration/drone/push Build is passing Details
2025-06-17 16:24:00 +08:00
hang 083bebdc03 真实随机阅片导表-1
continuous-integration/drone/push Build is passing Details
2025-06-17 10:06:41 +08:00
hang e808764dd6 随机阅片排序-5 2025-06-17 10:06:33 +08:00
hang 77d198cb09 随机阅片-NextTask-5 2025-06-17 10:05:55 +08:00
hang 180b02b28c 随机阅片NextTask-4 2025-06-17 10:04:26 +08:00
hang c49a74d742 Merge branch 'Uat_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Uat_IRC_Net8
continuous-integration/drone/push Build is passing Details
2025-06-17 10:02:34 +08:00
he c76fc8f052 修改阅片期选择访视下拉框的数据
continuous-integration/drone/push Build is running Details
2025-06-17 10:02:04 +08:00
he 14875dfacc 生成了裁判任务 阅片期不让删除和修改 2025-06-17 10:02:02 +08:00
hang 0a68788c0f 随机阅片序号3 2025-06-17 10:00:39 +08:00
hang b17e5d9ff3 随机阅片序号2 2025-06-17 10:00:34 +08:00
hang 05ce4b7155 随机阅片随机序号 2025-06-17 10:00:28 +08:00
he c8bbb3da48 Merge branch 'Uat_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Uat_IRC_Net8
continuous-integration/drone/push Build is passing Details
2025-06-16 15:16:20 +08:00
he 65de108ecd 添加阅片期 产生裁判 2025-06-16 15:16:19 +08:00
hang d20c306219 末次访视的展示+ 展示基线选择阅片期
continuous-integration/drone/push Build is passing Details
2025-06-16 14:50:23 +08:00
hang e69991ae37 修改重置阅片稽查3
continuous-integration/drone/push Build is passing Details
2025-06-13 09:57:33 +08:00
hang e1e2544ee3 修改阅片重置稽查 2025-06-13 09:57:30 +08:00
hang 318333bae4 修改重置阅片稽查 2025-06-13 09:57:26 +08:00
hang d569de4dfe 确认浏览临床数据
continuous-integration/drone/push Build is passing Details
2025-06-12 10:52:46 +08:00
hang 05627ff126 肿瘤学稽查修改
continuous-integration/drone/push Build is passing Details
2025-06-11 10:03:01 +08:00
hang 627618c854 增加进入阅片中稽查 2025-06-11 10:02:57 +08:00
hang 2711c5eb04 稽查 申请PM 重阅,有SPM 判断 2025-06-11 10:00:57 +08:00
hang a6982f79c3 稽查修改,区分标识 2025-06-11 10:00:53 +08:00
hang 2a542949cd 增加稽查标识 2025-06-11 10:00:49 +08:00
he a8ccbce76f 稽查添加
continuous-integration/drone/push Build is passing Details
2025-06-05 16:46:06 +08:00
he df7cf30aed 测量值可以为空
continuous-integration/drone/push Build is passing Details
2025-06-04 14:25:57 +08:00
he 0664fbdfb7 验证修改
continuous-integration/drone/push Build is passing Details
2025-06-04 09:57:08 +08:00
he 0a6ee05417 Merge branch 'Test_IRC_Net8' into Uat_IRC_Net8
continuous-integration/drone/push Build is passing Details
2025-05-22 18:01:11 +08:00
hang f9bd8c3f5c Merge branch 'Test_IRC_Net8' into Uat_IRC_Net8
continuous-integration/drone/push Build is passing Details
2025-05-21 15:16:26 +08:00
he cb83c2a737 Merge branch 'Test_IRC_Net8' into Uat_IRC_Net8
continuous-integration/drone/push Build is passing Details
2025-05-21 14:05:30 +08:00
he fdd9afd4f0 Merge branch 'Test_IRC_Net8' into Uat_IRC_Net8
continuous-integration/drone/push Build is passing Details
2025-05-20 15:46:24 +08:00
he 53d26c0445 Merge branch 'Test_IRC_Net8' into Uat_IRC_Net8
continuous-integration/drone/push Build is passing Details
2025-05-20 10:55:36 +08:00
he 40d035e7a7 解决合并的冲突
continuous-integration/drone/push Build is passing Details
2025-05-15 09:33:17 +08:00
he a13807ae5f 合并冲突修改
continuous-integration/drone/push Build is failing Details
2025-05-15 09:29:41 +08:00
he 9d5aaf1e26 Merge branch 'Test_IRC_Net8' into Uat_IRC_Net8
continuous-integration/drone/push Build is failing Details
2025-05-15 09:20:22 +08:00
he c347d08e2b 合并
continuous-integration/drone/push Build is failing Details
2025-05-15 09:14:10 +08:00
hang 87f2d0e429 非dicom 删除上传
continuous-integration/drone/push Build is passing Details
2025-04-15 13:27:33 +08:00
he 89d009fcbf Revert "修改"
continuous-integration/drone/push Build is passing Details
This reverts commit 7d65cf5051.
2025-04-09 11:00:45 +08:00
he 7d65cf5051 修改
continuous-integration/drone/push Build is passing Details
2025-04-09 09:45:49 +08:00
he e74427c45c 解决冲突
continuous-integration/drone/push Build is passing Details
2025-04-08 11:05:31 +08:00
he e8825c7efa 修改查询 2025-04-08 11:04:52 +08:00
hang 628e0ad034 修改异地登录bug 设置最后一次登录的iP
continuous-integration/drone/push Build is passing Details
2025-04-03 13:55:04 +08:00
hang 2f3f639918 修改异地登录ip逻辑 2025-04-03 13:55:00 +08:00
hang 87caf24dd1 验证环境生成缩略图测试ok提交
continuous-integration/drone/push Build is passing Details
2025-04-03 13:49:34 +08:00
31 changed files with 125 additions and 81058 deletions

View File

@ -7,10 +7,10 @@
}
},
"ConnectionStrings": {
"RemoteNew": "Server=101.132.193.237,1434;Database=Prod_IRC;User ID=sa;Password=zhanying@2021;TrustServerCertificate=true",
"Hangfire": "Server=101.132.193.237,1434;Database=Prod_IRC_Hangfire;User ID=sa;Password=zhanying@2021;TrustServerCertificate=true"
//"RemoteNew": "Server=prod_mssql_standard,1433;Database=Prod_IRC;User ID=sa;Password=zhanying@2021;TrustServerCertificate=true",
//"Hangfire": "Server=prod_mssql_standard,1433;Database=Prod_IRC_Hangfire;User ID=sa;Password=zhanying@2021;TrustServerCertificate=true"
//"RemoteNew": "Server=101.132.193.237,1434;Database=Prod_IRC;User ID=sa;Password=zhanying@2021;TrustServerCertificate=true",
//"Hangfire": "Server=101.132.193.237,1434;Database=Prod_IRC_Hangfire;User ID=sa;Password=zhanying@2021;TrustServerCertificate=true"
"RemoteNew": "Server=prod_mssql_standard,1433;Database=Prod_IRC;User ID=sa;Password=zhanying@2021;TrustServerCertificate=true",
"Hangfire": "Server=prod_mssql_standard,1433;Database=Prod_IRC_Hangfire;User ID=sa;Password=zhanying@2021;TrustServerCertificate=true"
},
"ObjectStoreService": {
"ObjectStoreUse": "AliyunOSS",

View File

@ -1,194 +0,0 @@
using FellowOakDicom;
using FellowOakDicom.Media;
using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace IRaCIS.Core.Application.Helper
{
public class StudyDIRInfo
{
public Guid SubjectVisitId { get; set; }
// Study
public Guid DicomStudyId { get; set; }
public string PatientId { get; set; }
public string PatientName { get; set; }
public string PatientBirthDate { get; set; }
public string PatientSex { get; set; }
public string StudyInstanceUid { get; set; }
public string StudyId { get; set; }
public string DicomStudyDate { get; set; }
public string DicomStudyTime { get; set; }
public string AccessionNumber { get; set; }
public string StudyDescription { get; set; }
// Series
public string SeriesInstanceUid { get; set; }
public string Modality { get; set; }
public string DicomSeriesDate { get; set; }
public string DicomSeriesTime { get; set; }
public int SeriesNumber { get; set; }
public string SeriesDescription { get; set; }
// Instance
public Guid InstanceId { get; set; }
public string SopInstanceUid { get; set; }
public string SOPClassUID { get; set; }
public int InstanceNumber { get; set; }
public string MediaStorageSOPClassUID { get; set; }
public string MediaStorageSOPInstanceUID { get; set; }
public string TransferSytaxUID { get; set; }
}
public static class DicomDIRHelper
{
public static async Task<Dictionary<string, string>> GenerateStudyDIRAndUploadAsync(List<StudyDIRInfo> list, string ossFolder, IOSSService _oSSService)
{
var dic = new Dictionary<string, string>();
var mappings = new List<string>();
int index = 1;
var dicomDir = new DicomDirectory();
foreach (var item in list.OrderBy(t => t.SeriesNumber).ThenBy(t => t.InstanceNumber))
{
var dicomUid = DicomUID.Enumerate().FirstOrDefault(uid => uid.UID == item.TransferSytaxUID);
if (dicomUid != null)
{
var ts = DicomTransferSyntax.Query(dicomUid);
var dataset = new DicomDataset(ts)
{
{ DicomTag.PatientID, item.PatientId ?? string.Empty },
{ DicomTag.PatientName, item.PatientName ?? string.Empty },
{ DicomTag.PatientBirthDate, item.PatientBirthDate ?? string.Empty },
{ DicomTag.PatientSex, item.PatientSex ?? string.Empty },
{ DicomTag.StudyInstanceUID, item.StudyInstanceUid ?? string.Empty },
{ DicomTag.StudyID, item.StudyId ?? string.Empty },
{ DicomTag.StudyDate, item.DicomStudyDate ?? string.Empty },
{ DicomTag.StudyTime, item.DicomStudyTime ?? string.Empty },
{ DicomTag.AccessionNumber, item.AccessionNumber ?? string.Empty },
{ DicomTag.StudyDescription, item.StudyDescription ?? string.Empty },
{ DicomTag.SeriesInstanceUID, item.SeriesInstanceUid ?? string.Empty },
{ DicomTag.Modality, item.Modality ?? string.Empty },
{ DicomTag.SeriesDate, item.DicomSeriesDate ?? string.Empty },
{ DicomTag.SeriesTime, item.DicomSeriesTime ?? string.Empty },
{ DicomTag.SeriesNumber, item.SeriesNumber.ToString() ?? string.Empty },
{ DicomTag.SeriesDescription, item.SeriesDescription ?? string.Empty },
{ DicomTag.SOPInstanceUID, item.SopInstanceUid ?? string.Empty },
{ DicomTag.SOPClassUID, item.SOPClassUID ?? string.Empty },
{ DicomTag.InstanceNumber, item.InstanceNumber.ToString() ?? string.Empty },
{ DicomTag.MediaStorageSOPClassUID, item.MediaStorageSOPClassUID ?? string.Empty },
{ DicomTag.MediaStorageSOPInstanceUID, item.MediaStorageSOPInstanceUID ?? string.Empty },
{ DicomTag.TransferSyntaxUID, item.TransferSytaxUID ?? string.Empty },
};
var dicomFile = new DicomFile(dataset);
// 文件名递增格式IM_00001, IM_00002, ...
string filename = $@"IMAGE/IM_{index:D5}"; // :D5 表示补足5位
mappings.Add($"{filename} => {item.InstanceId}");
dic.Add(item.InstanceId.ToString(), Path.GetFileName(filename));
dicomDir.AddFile(dicomFile, filename);
index++;
}
}
//有实际的文件
if (mappings.Count > 0)
{
#region 写入临时路径
var tempFilePath = Path.GetTempFileName();
// 保存 DICOMDIR 到临时文件 不能直接写入到流种
await dicomDir.SaveAsync(tempFilePath);
using (var memoryStream = new MemoryStream(File.ReadAllBytes(tempFilePath)))
{
// 重置流位置
memoryStream.Position = 0;
await _oSSService.UploadToOSSAsync(memoryStream, ossFolder, "DICOMDIR", false);
}
//清理临时文件
File.Delete(tempFilePath);
#endregion
#region 映射上传
// 将映射写入内存流
var mappingText = string.Join(Environment.NewLine, mappings);
await using var mappingStream = new MemoryStream(Encoding.UTF8.GetBytes(mappingText));
await _oSSService.UploadToOSSAsync(mappingStream, ossFolder, $"Download_{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}", false);
#endregion
}
return dic;
}
public static StudyDIRInfo ReadDicomDIRInfo(DicomFile dicomFile)
{
var dataset = dicomFile.Dataset;
var info = new StudyDIRInfo
{
PatientId = dataset.GetSingleValueOrDefault(DicomTag.PatientID, string.Empty),
PatientName = dataset.GetSingleValueOrDefault(DicomTag.PatientName, string.Empty),
PatientBirthDate = dataset.GetSingleValueOrDefault(DicomTag.PatientBirthDate, string.Empty),
PatientSex = dataset.GetSingleValueOrDefault(DicomTag.PatientSex, string.Empty),
StudyInstanceUid = dataset.GetSingleValueOrDefault(DicomTag.StudyInstanceUID, string.Empty),
StudyId = dataset.GetSingleValueOrDefault(DicomTag.StudyID, string.Empty),
DicomStudyDate = dataset.GetSingleValueOrDefault(DicomTag.StudyDate, string.Empty),
DicomStudyTime = dataset.GetSingleValueOrDefault(DicomTag.StudyTime, string.Empty),
AccessionNumber = dataset.GetSingleValueOrDefault(DicomTag.AccessionNumber, string.Empty),
StudyDescription = dataset.GetSingleValueOrDefault(DicomTag.StudyDescription, string.Empty),
SeriesInstanceUid = dataset.GetSingleValueOrDefault(DicomTag.SeriesInstanceUID, string.Empty),
Modality = dataset.GetSingleValueOrDefault(DicomTag.Modality, string.Empty),
DicomSeriesDate = dataset.GetSingleValueOrDefault(DicomTag.SeriesDate, string.Empty),
DicomSeriesTime = dataset.GetSingleValueOrDefault(DicomTag.SeriesTime, string.Empty),
SeriesNumber = dataset.GetSingleValueOrDefault(DicomTag.SeriesNumber, 1),
SeriesDescription = dataset.GetSingleValueOrDefault(DicomTag.SeriesDescription, string.Empty),
SopInstanceUid = dataset.GetSingleValueOrDefault(DicomTag.SOPInstanceUID, string.Empty),
SOPClassUID = dataset.GetSingleValueOrDefault(DicomTag.SOPClassUID, string.Empty),
InstanceNumber = dataset.GetSingleValueOrDefault(DicomTag.InstanceNumber, 1),
MediaStorageSOPClassUID = dicomFile.FileMetaInfo.GetSingleValueOrDefault(DicomTag.MediaStorageSOPClassUID, string.Empty),
MediaStorageSOPInstanceUID = dicomFile.FileMetaInfo.GetSingleValueOrDefault(DicomTag.MediaStorageSOPInstanceUID, string.Empty),
TransferSytaxUID = dicomFile.FileMetaInfo.GetSingleValueOrDefault(DicomTag.TransferSyntaxUID, string.Empty)
};
return info;
}
}
}

View File

@ -112,8 +112,6 @@ public class AliyunOSSTempToken
public string PreviewEndpoint { get; set; }
public string DownloadEndPoint => EndPoint.Insert(EndPoint.IndexOf("//") + 2, BucketName + ".");
}
[LowerCamelCaseJson]
@ -147,8 +145,6 @@ public interface IOSSService
public Task DownLoadFromOSSAsync(string ossRelativePath, string localFilePath);
public Task<Stream> GetStreamFromOSSAsync(string ossRelativePath);
public ObjectStoreServiceOptions ObjectStoreServiceOptions { get; set; }
public Task<string> GetSignedUrl(string ossRelativePath);
@ -194,7 +190,7 @@ public class OSSService : IOSSService
/// <returns></returns>
public async Task<string> UploadToOSSAsync(Stream fileStream, string oosFolderPath, string fileRealName, bool isFileNameAddGuid = true)
{
BackBatchGetToken();
GetObjectStoreTempToken();
var ossRelativePath = isFileNameAddGuid ? $"{oosFolderPath}/{Guid.NewGuid()}_{fileRealName}" : $"{oosFolderPath}/{fileRealName}";
@ -284,37 +280,6 @@ public class OSSService : IOSSService
}
//后端批量上传 或者下载不每个文件获取临时token
private void BackBatchGetToken()
{
if (ObjectStoreServiceOptions.ObjectStoreUse == "AliyunOSS")
{
if (AliyunOSSTempToken == null)
{
GetObjectStoreTempToken();
}
//token 过期了
else if (AliyunOSSTempToken.Expiration.AddSeconds(10) <= DateTime.Now)
{
GetObjectStoreTempToken();
}
}
else if (ObjectStoreServiceOptions.ObjectStoreUse == "AWS")
{
if (AWSTempToken == null)
{
GetObjectStoreTempToken();
}
//token 过期了
else if (AWSTempToken.Expiration?.AddSeconds(10) <= DateTime.Now)
{
GetObjectStoreTempToken();
}
}
}
/// <summary>
/// oosFolderPath 不要 "/ "开头 应该: TempFolder/ChildFolder
@ -326,7 +291,7 @@ public class OSSService : IOSSService
/// <exception cref="BusinessValidationFailedException"></exception>
public async Task<string> UploadToOSSAsync(string localFilePath, string oosFolderPath, bool isFileNameAddGuid = true)
{
BackBatchGetToken();
GetObjectStoreTempToken();
var localFileName = Path.GetFileName(localFilePath);
@ -396,7 +361,11 @@ public class OSSService : IOSSService
public async Task DownLoadFromOSSAsync(string ossRelativePath, string localFilePath)
{
BackBatchGetToken();
if (isFirstCall)
{
GetObjectStoreTempToken();
isFirstCall = false;
}
ossRelativePath = ossRelativePath.TrimStart('/');
try
@ -409,12 +378,14 @@ public class OSSService : IOSSService
var _ossClient = new OssClient(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? aliConfig.EndPoint : aliConfig.InternalEndpoint, AliyunOSSTempToken.AccessKeyId, AliyunOSSTempToken.AccessKeySecret, AliyunOSSTempToken.SecurityToken);
// 上传文件
var result = _ossClient.GetObject(aliConfig.BucketName, ossRelativePath);
// 将下载的文件流保存到本地文件
using (var fs = File.OpenWrite(localFilePath))
{
await result.Content.CopyToAsync(fs);
result.Content.CopyTo(fs);
fs.Close();
}
}
@ -478,96 +449,6 @@ public class OSSService : IOSSService
}
public async Task<Stream> GetStreamFromOSSAsync(string ossRelativePath)
{
BackBatchGetToken();
ossRelativePath = ossRelativePath.TrimStart('/');
try
{
if (ObjectStoreServiceOptions.ObjectStoreUse == "AliyunOSS")
{
var aliConfig = ObjectStoreServiceOptions.AliyunOSS;
var _ossClient = new OssClient(
RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? aliConfig.EndPoint : aliConfig.InternalEndpoint,
AliyunOSSTempToken.AccessKeyId,
AliyunOSSTempToken.AccessKeySecret,
AliyunOSSTempToken.SecurityToken
);
var result = _ossClient.GetObject(aliConfig.BucketName, ossRelativePath);
// 将OSS返回的流复制到内存流中并返回
var memoryStream = new MemoryStream();
await result.Content.CopyToAsync(memoryStream);
memoryStream.Position = 0; // 重置位置以便读取
return memoryStream;
}
else if (ObjectStoreServiceOptions.ObjectStoreUse == "MinIO")
{
var minIOConfig = ObjectStoreServiceOptions.MinIO;
var minioClient = new MinioClient()
.WithEndpoint($"{minIOConfig.EndPoint}:{minIOConfig.Port}")
.WithCredentials(minIOConfig.AccessKeyId, minIOConfig.SecretAccessKey)
.WithSSL(minIOConfig.UseSSL)
.Build();
var memoryStream = new MemoryStream();
var getObjectArgs = new GetObjectArgs()
.WithBucket(minIOConfig.BucketName)
.WithObject(ossRelativePath)
.WithCallbackStream(stream => stream.CopyToAsync(memoryStream));
await minioClient.GetObjectAsync(getObjectArgs);
memoryStream.Position = 0;
return memoryStream;
}
else if (ObjectStoreServiceOptions.ObjectStoreUse == "AWS")
{
var awsConfig = ObjectStoreServiceOptions.AWS;
var credentials = new SessionAWSCredentials(
AWSTempToken.AccessKeyId,
AWSTempToken.SecretAccessKey,
AWSTempToken.SessionToken
);
var clientConfig = new AmazonS3Config
{
RegionEndpoint = RegionEndpoint.USEast1,
UseHttp = true,
};
var amazonS3Client = new AmazonS3Client(credentials, clientConfig);
var getObjectRequest = new Amazon.S3.Model.GetObjectRequest
{
BucketName = awsConfig.BucketName,
Key = ossRelativePath
};
var response = await amazonS3Client.GetObjectAsync(getObjectRequest);
var memoryStream = new MemoryStream();
await response.ResponseStream.CopyToAsync(memoryStream);
memoryStream.Position = 0;
return memoryStream;
}
else
{
throw new BusinessValidationFailedException("未定义的存储介质类型");
}
}
catch (Exception ex)
{
throw new BusinessValidationFailedException("oss流获取失败! " + ex.Message);
}
}
public async Task<string> GetSignedUrl(string ossRelativePath)
{
GetObjectStoreTempToken();
@ -1124,9 +1005,14 @@ public class OSSService : IOSSService
}
}
private bool isFirstCall = true;
public async Task<long> GetObjectSizeAsync(string sourcePath)
{
BackBatchGetToken();
if (isFirstCall)
{
GetObjectStoreTempToken();
isFirstCall = false;
}
var objectkey = sourcePath.Trim('/');
@ -1140,7 +1026,7 @@ public class OSSService : IOSSService
var key = HttpUtility.UrlDecode(objectkey);
var metadata = _ossClient.GetObjectMetadata(aliConfig.BucketName, key);
long fileSize = metadata?.ContentLength ?? 0; // 文件大小(字节)
long fileSize = metadata?.ContentLength??0; // 文件大小(字节)
return fileSize;
}

View File

@ -1,41 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
namespace IRaCIS.Core.Application.Helper
{
public static class SafeBussinessHelper
{
public static async Task<bool> RunAsync(Func<Task> func, [CallerMemberName] string caller = "", string errorMsgTitle = "")
{
try
{
await func();
return true;
}
catch (Exception ex)
{
Log.Logger.Error($"【{errorMsgTitle}失败 - {caller}】: {ex.Message}");
return false;
}
}
public static async Task<(bool Success, T? Result)> RunAsync<T>(Func<Task<T>> func, [CallerMemberName] string caller = "", string errorMsgTitle = "")
{
try
{
var result = await func();
return (true, result);
}
catch (Exception ex)
{
Log.Logger.Error($"【{errorMsgTitle}失败 - {caller}】: {ex.Message}");
return (false, default);
}
}
}
}

View File

@ -1111,13 +1111,6 @@
<param name="trialId"></param>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.Application.Service.TrialImageDownloadService.DownloadAndUploadTrialData(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})">
<summary>
下载影像 维护dir信息 并回传到OSS
</summary>
<param name="trialId"></param>
<returns></returns>
</member>
<member name="T:IRaCIS.Core.Application.Service.AttachmentService">
<summary>
医生文档关联关系维护
@ -10923,11 +10916,6 @@
Parent字典code
</summary>
</member>
<member name="P:IRaCIS.Core.Application.Service.Reading.Dto.ReadingQuestionTrialView.ExcludeShowVisitList">
<summary>
排除显示的访视名称
</summary>
</member>
<member name="P:IRaCIS.Core.Application.Service.Reading.Dto.ReadingQuestionTrialView.ReadingQuestionCriterionTrialId">
<summary>
系统标准Id
@ -11798,11 +11786,6 @@
分类显示类型 是否显示
</summary>
</member>
<member name="P:IRaCIS.Core.Application.Service.Reading.Dto.AddOrUpdateReadingQuestionTrialInDto.ExcludeShowVisitList">
<summary>
排除显示的访视名称
</summary>
</member>
<member name="P:IRaCIS.Core.Application.Service.Reading.Dto.AddOrUpdateReadingQuestionTrialInDto.HighlightAnswer">
<summary>
高亮问题的答案
@ -14108,13 +14091,6 @@
计划外访视 获取受试者选择下拉框列表
</summary>
</member>
<member name="M:IRaCIS.Core.Application.Service.VisitPlanService.GetVisitStage(IRaCIS.Application.Contracts.GetVisitStageInDto)">
<summary>
获取项目访视计划
</summary>
<param name="inDto"></param>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.Application.Service.VisitPlanService.GetTrialVisitStageList(IRaCIS.Application.Contracts.VisitPlanQueryDTO)">
暂时不用
<summary> 获取项目访视计划</summary>

View File

@ -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();

View File

@ -1,14 +1,10 @@
using DocumentFormat.OpenXml.EMMA;
using FellowOakDicom;
using FellowOakDicom.Imaging;
using FellowOakDicom.Imaging.Render;
using FellowOakDicom.IO.Buffer;
using IRaCIS.Core.Application.Helper;
using MassTransit;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using SharpCompress.Common;
using System;
using System.Collections.Generic;
using System.Linq;
@ -45,14 +41,12 @@ namespace IRaCIS.Core.Application.Service
[AllowAnonymous]
public async Task<IResponseOutput> DownloadTrialImage(Guid trialId)
{
//var subjectCodeList = new List<string>() { "05002", "07006", "07026" };
var subjectCodeList = new List<string>() { "05002", "07006", "07026" };
var downloadInfo = _trialRepository.Where(t => t.Id == trialId).Select(t => new
{
t.ResearchProgramNo,
VisitList = t.SubjectVisitList
//.Where(t=>subjectCodeList.Contains(t.Subject.Code))
.Select(sv => new
VisitList = t.SubjectVisitList.Where(t=>subjectCodeList.Contains(t.Subject.Code)).Select(sv => new
{
TrialSiteCode = sv.TrialSite.TrialSiteCode,
SubjectCode = sv.Subject.Code,
@ -63,11 +57,11 @@ namespace IRaCIS.Core.Application.Service
u.StudyTime,
u.StudyCode,
SeriesList = u.SeriesList.Where(t => t.IsReading).Select(z => new
SeriesList = u.SeriesList.Select(z => new
{
z.Modality,
InstancePathList = z.DicomInstanceList.Where(t => t.IsReading).Select(k => new
InstancePathList = z.DicomInstanceList.Select(k => new
{
k.Path
}).ToList()
@ -75,13 +69,13 @@ namespace IRaCIS.Core.Application.Service
}).ToList(),
NoneDicomStudyList = sv.NoneDicomStudyList.Where(t => t.IsReading).Select(nd => new
NoneDicomStudyList = sv.NoneDicomStudyList.Select(nd => new
{
nd.Modality,
nd.StudyCode,
nd.ImageDate,
FileList = nd.NoneDicomFileList.Where(t => t.IsReading).Select(file => new
FileList = nd.NoneDicomFileList.Select(file => new
{
file.FileName,
file.Path,
@ -94,17 +88,12 @@ namespace IRaCIS.Core.Application.Service
var count = downloadInfo.VisitList.SelectMany(t => t.NoneDicomStudyList).SelectMany(t => t.FileList).Count();
var count2 = downloadInfo.VisitList.SelectMany(t => t.StudyList).SelectMany(t => t.SeriesList).SelectMany(t => t.InstancePathList).Count();
Console.WriteLine($"下载总数量:{count}+{count2}={count + count2}");
var count2 = downloadInfo.VisitList.SelectMany(t => t.StudyList).SelectMany(t => t.SeriesList).SelectMany(t=>t.InstancePathList).Count();
if (downloadInfo != null)
{
var downloadJobs = new List<Func<Task>>();
var rootFolder = @"E:\DownloadImage";
//var rootFolder = FileStoreHelper.GetDonwnloadImageFolder(_hostEnvironment);
var rootFolder = FileStoreHelper.GetDonwnloadImageFolder(_hostEnvironment);
// 获取无效字符(系统定义的)
string invalidChars = new string(Path.GetInvalidFileNameChars()) + new string(Path.GetInvalidPathChars());
@ -152,16 +141,12 @@ namespace IRaCIS.Core.Application.Service
// 复制文件到相应的文件夹
string destinationPath = Path.Combine(studyDicomFolderPath, Path.GetFileName(instanceInfo.Path));
//加入到下载任务里
downloadJobs.Add(() => _oSSService.DownLoadFromOSSAsync(instanceInfo.Path, destinationPath));
//下载到当前目录
//await _oSSService.DownLoadFromOSSAsync(instanceInfo.Path, destinationPath);
await _oSSService.DownLoadFromOSSAsync(instanceInfo.Path, destinationPath);
}
}
}
foreach (var noneDicomStudy in visitItem.NoneDicomStudyList)
@ -174,59 +159,15 @@ namespace IRaCIS.Core.Application.Service
{
string destinationPath = Path.Combine(studyNoneDicomFolderPath, Path.GetFileName(file.FileName));
//加入到下载任务里
downloadJobs.Add(() => _oSSService.DownLoadFromOSSAsync(HttpUtility.UrlDecode(file.Path), destinationPath));
//下载到当前目录
//await _oSSService.DownLoadFromOSSAsync(HttpUtility.UrlDecode(file.Path), destinationPath);
await _oSSService.DownLoadFromOSSAsync(HttpUtility.UrlDecode(file.Path), destinationPath);
}
}
}
#region 异步方式处理
int totalCount = downloadJobs.Count;
int downloadedCount = 0;
foreach (var job in downloadJobs)
{
try
{
await job();
}
catch (Exception ex)
{
Console.WriteLine($"下载失败: {ex.Message}");
}
downloadedCount++;
// 每处理50个输出一次进度或最后一个时也输出
if (downloadedCount % 50 == 0 || downloadedCount == totalCount)
{
Console.WriteLine($"已下载 {downloadedCount} / {totalCount} 个文件,完成 {(downloadedCount * 100.0 / totalCount):F2}%");
}
}
#endregion
#region 多线程测试
//const int batchSize = 15;
//int totalCount = downloadJobs.Count;
//int downloadedCount = 0;
//for (int i = 0; i < downloadJobs.Count; i += batchSize)
//{
// var batch = downloadJobs.Skip(i).Take(batchSize).Select(job => job());
// await Task.WhenAll(batch);
// downloadedCount += batch.Count();
// Console.WriteLine($"已下载 {downloadedCount} / {totalCount} 个文件,完成 {(downloadedCount * 100.0 / totalCount):F2}%");
//}
#endregion
}
@ -235,105 +176,6 @@ namespace IRaCIS.Core.Application.Service
}
/// <summary>
/// 下载影像 维护dir信息 并回传到OSS
/// </summary>
/// <param name="trialId"></param>
/// <returns></returns>
[HttpGet]
[AllowAnonymous]
public async Task<IResponseOutput> DownloadAndUploadTrialData(Guid trialId, [FromServices] IRepository<DicomInstance> _instanceRepository,
[FromServices] IRepository<DicomStudy> _studyRepository,
[FromServices] IRepository<DicomSeries> _seriesRepository)
{
var list = await _instanceRepository.Where(t => t.TrialId == trialId && t.SubjectVisitId == Guid.Parse("01000000-0a00-0242-bd20-08dcce543ded" ) && t.DicomStudy.ModalityForEdit == "IVUS")
.Select(t => new { t.SeriesId, t.StudyId, t.Id, t.Path }).ToListAsync();
int totalCount = list.Count;
int dealCount = 0;
foreach (var item in list)
{
var stream = await _oSSService.GetStreamFromOSSAsync(item.Path);
var dicomFile = DicomFile.Open(stream);
// 获取 Pixel Data 标签
var pixelData = DicomPixelData.Create(dicomFile.Dataset);
//获取像素是否为封装形式
var syntax = dicomFile.Dataset.InternalTransferSyntax;
//对于封装像素的文件做转换
if (syntax.IsEncapsulated)
{
// 创建一个新的片段序列
var newFragments = new DicomOtherByteFragment(DicomTag.PixelData);
// 获取每帧数据并封装为单独的片段
for (int n = 0; n < pixelData.NumberOfFrames; n++)
{
var frameData = pixelData.GetFrame(n);
newFragments.Fragments.Add(new MemoryByteBuffer(frameData.Data));
}
// 替换原有的片段序列
dicomFile.Dataset.AddOrUpdate(newFragments);
}
#region 获取dir信息 维护数据库三个表数据
var dirInfo = DicomDIRHelper.ReadDicomDIRInfo(dicomFile);
await _instanceRepository.BatchUpdateNoTrackingAsync(t => t.Id == item.Id,
u => new DicomInstance()
{
IsEncapsulated= syntax.IsEncapsulated,
TransferSytaxUID = dirInfo.TransferSytaxUID,
SOPClassUID = dirInfo.SOPClassUID,
MediaStorageSOPClassUID = dirInfo.MediaStorageSOPClassUID,
MediaStorageSOPInstanceUID = dirInfo.MediaStorageSOPInstanceUID
}, false);
await _seriesRepository.BatchUpdateNoTrackingAsync(t => t.Id == item.SeriesId,
u => new DicomSeries()
{
DicomSeriesDate = dirInfo.DicomSeriesDate,
DicomSeriesTime = dirInfo.DicomSeriesTime,
}, false);
await _studyRepository.BatchUpdateNoTrackingAsync(t => t.Id == item.StudyId,
u => new DicomStudy()
{
DicomStudyDate = dirInfo.DicomStudyDate,
DicomStudyTime = dirInfo.DicomStudyTime
}, false);
#endregion
//保存到内存流
using var memoryStream = new MemoryStream();
dicomFile.Save(memoryStream);
memoryStream.Position = 0;
//获取原始目录 和文件名
var folder = item.Path.Substring(0, item.Path.LastIndexOf('/')).TrimStart('/');
var fileName = Path.GetFileName(item.Path);
//dicomFile.Save($"download_{Guid.NewGuid()}");
await _oSSService.UploadToOSSAsync(memoryStream, folder, fileName, false);
dealCount++;
Console.WriteLine($"{DateTime.Now}已下载 {dealCount} / {totalCount} 个文件,完成 {(dealCount * 100.0 / totalCount):F2}%");
}
return ResponseOutput.Ok();
}
}
}

View File

@ -1,5 +1,4 @@
using FellowOakDicom;
using IRaCIS.Core.Application.Service.ImageAndDoc.DTO;
using IRaCIS.Core.Application.Service.ImageAndDoc.DTO;
using IRaCIS.Core.Domain.Share;
using Newtonsoft.Json;
using System.ComponentModel.DataAnnotations;
@ -324,14 +323,9 @@ namespace IRaCIS.Core.Application.Contracts
public string BodyPartExamined { get; set; } = string.Empty;
public string DicomStudyDate { get; set; }
public string DicomStudyTime { get; set; }
public List<AddOrUpdateSeriesDto> SeriesList { get; set; }
}
public class AddOrUpdateSeriesDto
@ -357,12 +351,6 @@ namespace IRaCIS.Core.Application.Contracts
public string TriggerTime { get; set; } = string.Empty;
public string ImageResizePath { get; set; } = string.Empty;
public string DicomSeriesDate { get; set; }
public string DicomSeriesTime { get; set; }
public List<AddInstanceDto> InstanceList { get; set; }
public Guid? VisitTaskId { get; set; }
@ -397,17 +385,6 @@ namespace IRaCIS.Core.Application.Contracts
public string HtmlPath { get; set; } = string.Empty;
public long FileSize { get; set; }
public string SOPClassUID { get; set; }
public string MediaStorageSOPClassUID { get; set; }
public string TransferSytaxUID { get; set; }
public string MediaStorageSOPInstanceUID { get; set; }
public bool IsEncapsulated => DicomTransferSyntax.Lookup(DicomUID.Parse(TransferSytaxUID)).IsEncapsulated;
}
public class CRCUploadTaskQuery
@ -525,68 +502,7 @@ namespace IRaCIS.Core.Application.Contracts
}
#region 下载重新生成名字
public class ImageDownloadDto
{
public Guid TrialId { get; set; }
public Guid SubjectId { get; set; }
public string SubjectCode { get; set; }
public string TrialSiteCode { get; set; }
public string VisitName { get; set; }
public string TaskBlindName { get; set; }
public Guid VisitId { get; set; }
public List<DownloadDicomStudyDto> StudyList { get; set; }
public List<DownloadNoneDicomStudyDto> NoneDicomStudyList { get; set; }
}
public class DownloadDicomStudyDto
{
public string PatientId { get; set; }
public DateTime? StudyTime { get; set; }
public string StudyCode { get; set; }
public string StudyInstanceUid { get; set; }
public string StudyDIRPath { get; set; }
public List<DownloadDicomSeriesDto> SeriesList { get; set; }
}
public class DownloadDicomSeriesDto
{
public string Modality { get; set; }
public List<DownloadDicomInstanceDto> InstanceList { get; set; }
}
public class DownloadDicomInstanceDto
{
public Guid InstanceId { get; set; }
public string FileName { get; set; }
public string Path { get; set; }
public long? FileSize { get; set; }
}
public class DownloadNoneDicomStudyDto
{
public string Modality { get; set; }
public string StudyCode { get; set; }
public DateTime? ImageDate { get; set; }
public List<DownloadNoneDicomFileDto> FileList { get; set; } = new();
}
public class DownloadNoneDicomFileDto
{
public string FileName { get; set; }
public string Path { get; set; }
public string FileType { get; set; }
public long? FileSize { get; set; }
}
#endregion
public class CRCUploadedStudyQuqry
{
@ -678,9 +594,6 @@ namespace IRaCIS.Core.Application.Contracts
public bool IsKeyImage { get; set; }
// true 导出阅片null 就是所有影像
public bool? IsExportReading { get; set; }
}
@ -724,16 +637,10 @@ namespace IRaCIS.Core.Application.Contracts
public long? TotalImageSize { get; set; }
public long? TotalReadingImageSize { get; set; }
public string TotalImageSizeStr => TotalImageSize.HasValue
? $"{TotalImageSize.Value / 1024d / 1024d:F3} MB"
: "0.000 MB";
public string TotalReadingImageSizeStr => TotalReadingImageSize.HasValue
? $"{TotalReadingImageSize.Value / 1024d / 1024d:F3} MB"
: "0.000 MB";
public string ImageTypeStr => $"{(IsHaveDicom ? "DICOM" : "")}{(IsHaveNoneDicom&&IsHaveDicom?" , ":"")}{(IsHaveNoneDicom ? "Non-DICOM" : "")}";
public bool IsHaveDicom { get; set; }
@ -785,22 +692,6 @@ namespace IRaCIS.Core.Application.Contracts
? $"{TotalImageSize.Value / SubjectVisitCount / 1024d / 1024d:F3} MB"
: "0.000 MB";
public long? TotalReadingImageSize { get; set; }
public string TotalReadingImageSizeStr => TotalReadingImageSize.HasValue
? $"{TotalReadingImageSize.Value / 1024d / 1024d:F3} MB"
: "0.000 MB";
public string SubjectReadingImageAVGSizeStr => TotalReadingImageSize.HasValue
? $"{TotalReadingImageSize.Value / SubjectCount / 1024d / 1024d:F3} MB"
: "0.000 MB";
public string SubjectVisitReadingImageAVGSizeStr => TotalReadingImageSize.HasValue
? $"{TotalReadingImageSize.Value / SubjectVisitCount / 1024d / 1024d:F3} MB"
: "0.000 MB";
}
public class TrialImageDownloadView

View File

@ -1,6 +1,5 @@
using DocumentFormat.OpenXml.EMMA;
using FellowOakDicom;
using FellowOakDicom.Media;
using IRaCIS.Core.Application.Contracts;
using IRaCIS.Core.Application.Contracts.Dicom.DTO;
using IRaCIS.Core.Application.Filter;
@ -15,11 +14,9 @@ using MassTransit;
using MassTransit.Initializers;
using Medallion.Threading;
using Microsoft.AspNetCore.Mvc;
using NetTopologySuite.Mathematics;
using Newtonsoft.Json;
using NPOI.SS.Formula.Functions;
using System.Data;
using System.IO;
using System.IO.Compression;
using System.Text;
using System.Web;
@ -35,7 +32,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
}
[ApiExplorerSettings(GroupName = "Trial")]
public class DownloadAndUploadService(IRepository<SystemAnonymization> _systemAnonymizationRepository, IRepository<DicomStudy> _dicomStudyRepository,
public class DownloadAndUploadService(IRepository<SystemAnonymization> _systemAnonymizationRepository,
IRepository<VisitTask> _visitTaskRepository,
IRepository<SubjectVisit> _subjectVisitRepository,
IOSSService _oSSService,
@ -782,137 +779,58 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
var imageType = (isQueryDicom && isQueryNoneDicom) ? ImageType.DicomAndNoneDicom : (isQueryDicom ? ImageType.Dicom : ImageType.NoneDicom);
var dirDic = new Dictionary<string, string>();
#region DIR处理导出文件名并将对应关系上传到OSS里面存储
//有传输语法值的导出 才生成DIR
if (_subjectVisitRepository.Any(t => t.Id == inQuery.SubjectVisitId && t.StudyList.SelectMany(t => t.InstanceList).Any(c => c.TransferSytaxUID != string.Empty)))
{
var list = _subjectVisitRepository.Where(t => t.Id == inQuery.SubjectVisitId).SelectMany(t => t.StudyList)
.Where(t => isQueryDicom ? inQuery.DicomStudyIdList.Contains(t.Id) : false)
.SelectMany(t => t.InstanceList)
.Select(t => new StudyDIRInfo()
{
DicomStudyId = t.DicomStudy.Id,
PatientId = t.DicomStudy.PatientId,
PatientName = t.DicomStudy.PatientName,
PatientBirthDate = t.DicomStudy.PatientBirthDate,
PatientSex = t.DicomStudy.PatientSex,
StudyInstanceUid = t.StudyInstanceUid,
StudyId = t.DicomStudy.StudyId,
DicomStudyDate = t.DicomStudy.DicomStudyDate,
DicomStudyTime = t.DicomStudy.DicomStudyTime,
AccessionNumber = t.DicomStudy.AccessionNumber,
StudyDescription = t.DicomStudy.Description,
SeriesInstanceUid = t.DicomSerie.SeriesInstanceUid,
Modality = t.DicomSerie.Modality,
DicomSeriesDate = t.DicomSerie.DicomSeriesDate,
DicomSeriesTime = t.DicomSerie.DicomSeriesTime,
SeriesNumber = t.DicomSerie.SeriesNumber,
SeriesDescription = t.DicomSerie.Description,
InstanceId = t.Id,
SopInstanceUid = t.SopInstanceUid,
SOPClassUID = t.SOPClassUID,
InstanceNumber = t.InstanceNumber,
MediaStorageSOPClassUID = t.MediaStorageSOPClassUID,
MediaStorageSOPInstanceUID = t.MediaStorageSOPInstanceUID,
TransferSytaxUID = t.TransferSytaxUID,
}).ToList();
var pathInfo = await _subjectVisitRepository.Where(t => t.Id == inQuery.SubjectVisitId).Select(t => new { t.TrialId, t.SubjectId, VisitId = t.Id }).FirstNotNullAsync();
foreach (var item in list.GroupBy(t => new { t.StudyInstanceUid, t.DicomStudyId }))
{
var ossFolder = $"{pathInfo.TrialId}/Image/{pathInfo.SubjectId}/{pathInfo.VisitId}/{item.Key.StudyInstanceUid}";
var (isSucess, dic) = await SafeBussinessHelper.RunAsync(async () => await DicomDIRHelper.GenerateStudyDIRAndUploadAsync(item.ToList(), ossFolder, _oSSService));
dirDic = dic;
if (isSucess)
{
await _dicomStudyRepository.BatchUpdateNoTrackingAsync(t => t.Id == item.Key.DicomStudyId, u => new DicomStudy() { StudyDIRPath = $"/{ossFolder}/DICOMDIR" });
}
}
}
#endregion
var query = from sv in _subjectVisitRepository.Where(t => t.Id == inQuery.SubjectVisitId)
select new ImageDownloadDto()
select new
{
TrialId = sv.TrialId,
SubjectId = sv.SubjectId,
SubjectCode = sv.Subject.Code,
TrialSiteCode = sv.TrialSite.TrialSiteCode,
VisitName = sv.VisitName,
VisitId = sv.Id,
StudyList = sv.StudyList.Where(t => isQueryDicom ? inQuery.DicomStudyIdList.Contains(t.Id) : false)
.Select(u => new DownloadDicomStudyDto()
.Select(u => new
{
PatientId = u.PatientId,
StudyTime = u.StudyTime,
StudyCode = u.StudyCode,
StudyInstanceUid = u.StudyInstanceUid,
StudyDIRPath = u.StudyDIRPath,
u.PatientId,
u.StudyTime,
u.StudyCode,
SeriesList = u.SeriesList.Select(z => new DownloadDicomSeriesDto()
SeriesList = u.SeriesList.Select(z => new
{
Modality = z.Modality,
z.Modality,
InstanceList = z.DicomInstanceList.Select(k => new DownloadDicomInstanceDto()
InstanceList = z.DicomInstanceList.Select(k => new
{
InstanceId = k.Id,
FileName = string.Empty,
Path = k.Path,
FileSize = k.FileSize
}).ToList()
}).ToList()
k.Path,
k.FileSize
})
})
}).ToList(),
NoneDicomStudyList = sv.NoneDicomStudyList.Where(t => isQueryNoneDicom ? inQuery.NoneDicomStudyIdList.Contains(t.Id) : false)
.Select(nd => new DownloadNoneDicomStudyDto()
.Select(nd => new
{
Modality = nd.Modality,
StudyCode = nd.StudyCode,
ImageDate = nd.ImageDate,
nd.Modality,
nd.StudyCode,
nd.ImageDate,
FileList = nd.NoneDicomFileList.Select(file => new DownloadNoneDicomFileDto()
FileList = nd.NoneDicomFileList.Select(file => new
{
FileName = file.FileName,
Path = file.Path,
FileType = file.FileType,
FileSize = file.FileSize
}).ToList()
file.FileName,
file.Path,
file.FileType,
file.FileSize,
})
}).ToList()
};
var result = query.FirstOrDefault();
foreach (var item in result.StudyList.SelectMany(t => t.SeriesList).SelectMany(t => t.InstanceList))
{
var key = item.InstanceId.ToString();
if (dirDic.ContainsKey(key))
{
item.FileName = dirDic[key];
}
}
var preDownloadInfo = new TrialImageDownload()
{
Id = NewId.NextSequentialGuid(),
@ -1086,143 +1004,59 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
var trialSiteCode = _visitTaskRepository.Where(t => t.Id == taskIdList.FirstOrDefault()).Select(t => t.IsAnalysisCreate ? t.BlindTrialSiteCode : t.Subject.TrialSite.TrialSiteCode).FirstOrDefault() ?? string.Empty;
var dirDic = new Dictionary<string, string>();
#region 在下载前先处理DIR文件
//有传输语法值的导出 才生成DIR
if (_subjectVisitRepository.Any(t => t.SubjectId == inQuery.SubjectId && t.StudyList.SelectMany(t => t.InstanceList).Any(c => c.TransferSytaxUID != string.Empty)))
{
var dirInfolist = _subjectRepository.Where(t => t.Id == inQuery.SubjectId).SelectMany(t => t.SubjectVisitList.Where(t => subjectVisitIdList.Contains(t.Id))).SelectMany(t => t.StudyList)
.Where(t => isQueryDicom ? inQuery.DicomStudyIdList.Contains(t.Id) : false)
.Where(t => info.IsImageFilter ? ("|" + info.CriterionModalitys + "|").Contains("|" + t.ModalityForEdit + "|") : true)
.SelectMany(t => t.InstanceList.Where(t => t.IsReading && t.DicomSerie.IsReading))
.Select(t => new StudyDIRInfo()
{
SubjectVisitId = t.SubjectVisitId,
DicomStudyId = t.DicomStudy.Id,
PatientId = t.DicomStudy.PatientId,
PatientName = t.DicomStudy.PatientName,
PatientBirthDate = t.DicomStudy.PatientBirthDate,
PatientSex = t.DicomStudy.PatientSex,
StudyInstanceUid = t.StudyInstanceUid,
StudyId = t.DicomStudy.StudyId,
DicomStudyDate = t.DicomStudy.DicomStudyDate,
DicomStudyTime = t.DicomStudy.DicomStudyTime,
AccessionNumber = t.DicomStudy.AccessionNumber,
StudyDescription = t.DicomStudy.Description,
SeriesInstanceUid = t.DicomSerie.SeriesInstanceUid,
Modality = t.DicomSerie.Modality,
DicomSeriesDate = t.DicomSerie.DicomSeriesDate,
DicomSeriesTime = t.DicomSerie.DicomSeriesTime,
SeriesNumber = t.DicomSerie.SeriesNumber,
SeriesDescription = t.DicomSerie.Description,
InstanceId = t.Id,
SopInstanceUid = t.SopInstanceUid,
SOPClassUID = t.SOPClassUID,
InstanceNumber = t.InstanceNumber,
MediaStorageSOPClassUID = t.MediaStorageSOPClassUID,
MediaStorageSOPInstanceUID = t.MediaStorageSOPInstanceUID,
TransferSytaxUID = t.TransferSytaxUID,
}).ToList();
var pathInfo = await _subjectRepository.Where(t => t.Id == inQuery.SubjectId).Select(t => new { t.TrialId, SubjectId = t.Id }).FirstNotNullAsync();
foreach (var item in dirInfolist.GroupBy(t => new { t.StudyInstanceUid, t.DicomStudyId }))
{
var visitId = item.First().SubjectVisitId;
var ossFolder = $"{pathInfo.TrialId}/Image/{pathInfo.SubjectId}/{visitId}/{item.Key.StudyInstanceUid}";
var (isSucess, dic) = await SafeBussinessHelper.RunAsync(async () => await DicomDIRHelper.GenerateStudyDIRAndUploadAsync(item.ToList(), ossFolder, _oSSService));
dirDic = dic;
if (isSucess)
{
await _dicomStudyRepository.BatchUpdateNoTrackingAsync(t => t.Id == item.Key.DicomStudyId, u => new DicomStudy() { StudyDIRPath = $"/{ossFolder}/DICOMDIR" });
}
}
}
#endregion
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 => taskIdList.Contains(t.Id))
on sv.Id equals visitTask.SourceSubjectVisitId
select new ImageDownloadDto()
select new
{
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 DownloadDicomStudyDto()
.Select(u => new
{
PatientId = u.PatientId,
StudyTime = u.StudyTime,
StudyCode = u.StudyCode,
StudyInstanceUid = u.StudyInstanceUid,
StudyDIRPath = u.StudyDIRPath,
u.PatientId,
u.StudyTime,
u.StudyCode,
SeriesList = u.SeriesList.Where(t => t.IsReading).Select(z => new DownloadDicomSeriesDto()
SeriesList = u.SeriesList.Where(t => t.IsReading).Select(z => new
{
Modality = z.Modality,
z.Modality,
InstanceList = z.DicomInstanceList.Where(t => t.IsReading).Select(k => new DownloadDicomInstanceDto()
InstancePathList = z.DicomInstanceList.Where(t => t.IsReading).Select(k => new
{
InstanceId = k.Id,
FileName = string.Empty,
Path = k.Path,
FileSize = k.FileSize
}).ToList()
}).ToList()
}).ToList(),
k.Path,
k.FileSize
})
})
}),
NoneDicomStudyList = sv.NoneDicomStudyList.Where(t => isQueryNoneDicom ? inQuery.NoneDicomStudyIdList.Contains(t.Id) : false)
.Where(t => info.IsImageFilter ? ("|" + info.CriterionModalitys + "|").Contains("|" + t.Modality + "|") : true)
.Where(t => t.IsReading)
.Select(nd => new DownloadNoneDicomStudyDto()
{
Modality = nd.Modality,
StudyCode = nd.StudyCode,
ImageDate = nd.ImageDate,
.Select(nd => new
{
nd.Modality,
nd.StudyCode,
nd.ImageDate,
FileList = nd.NoneDicomFileList.Where(t => t.IsReading).Select(file => new DownloadNoneDicomFileDto()
{
FileName = file.FileName,
Path = file.Path,
FileType = file.FileType,
FileSize = file.FileSize
}).ToList()
}).ToList()
FileList = nd.NoneDicomFileList.Where(t => t.IsReading).Select(file => new
{
file.FileName,
file.Path,
file.FileType,
file.FileSize
})
})
};
var list = await query.ToListAsync();
foreach (var result in list)
{
foreach (var item in result.StudyList.SelectMany(t => t.SeriesList).SelectMany(t => t.InstanceList))
{
var key = item.InstanceId.ToString();
if (dirDic.ContainsKey(key))
{
item.FileName = dirDic[key];
}
}
}
var result = await query.ToListAsync();
@ -1237,17 +1071,17 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
DownloadStartTime = DateTime.Now,
IsSuccess = false,
ImageType = imageType,
VisitName = string.Join(" | ", list.Select(t => t.VisitName).OrderBy(t => t).ToList()),
NoneDicomStudyCount = list.Sum(t => t.NoneDicomStudyList.Count()),
DicomStudyCount = list.Sum(t => t.StudyList.Count()),
ImageCount = list.Sum(t => t.StudyList.Sum(s => s.SeriesList.Sum(s => s.InstanceList.Count())) + t.NoneDicomStudyList.Sum(s => s.FileList.Count())),
ImageSize = list.Sum(t => t.StudyList.Sum(t => t.SeriesList.Sum(s => s.InstanceList.Sum(i => i.FileSize))) + t.NoneDicomStudyList.Sum(t => t.FileList.Sum(s => s.FileSize))
VisitName = string.Join(" | ", result.Select(t => t.VisitName).OrderBy(t => t).ToList()),
NoneDicomStudyCount = result.Sum(t => t.NoneDicomStudyList.Count()),
DicomStudyCount = result.Sum(t => t.StudyList.Count()),
ImageCount = result.Sum(t => t.StudyList.Sum(s => s.SeriesList.Sum(s => s.InstancePathList.Count())) + t.NoneDicomStudyList.Sum(s => s.FileList.Count())),
ImageSize = result.Sum(t => t.StudyList.Sum(t => t.SeriesList.Sum(s => s.InstancePathList.Sum(i => i.FileSize))) + t.NoneDicomStudyList.Sum(t => t.FileList.Sum(s => s.FileSize))
) ?? 0
};
await _trialImageDownloadRepository.AddAsync(preDownloadInfo, true);
return ResponseOutput.Ok(list, new { PreDownloadId = preDownloadInfo.Id, info.IsReadingTaskViewInOrder });
return ResponseOutput.Ok(result, new { PreDownloadId = preDownloadInfo.Id, info.IsReadingTaskViewInOrder });
}
/// <summary>
@ -1384,9 +1218,6 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
TotalImageSize = t.StudyList.SelectMany(t => t.InstanceList).Sum(t => t.FileSize) + t.NoneDicomStudyList.SelectMany(t => t.NoneDicomFileList).Sum(t => t.FileSize),
TotalReadingImageSize = t.StudyList.SelectMany(t => t.InstanceList.Where(t => t.IsReading && t.DicomSerie.IsReading)).Sum(t => t.FileSize)
+ t.NoneDicomStudyList.Where(t => t.IsReading).SelectMany(t => t.NoneDicomFileList.Where(t => t.IsReading)).Sum(t => t.FileSize),
//DicomStudyCount = t.StudyList.Count(),
//NoneDicomStudyCount = t.NoneDicomStudyList.Count(),
@ -1418,10 +1249,6 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
{
SubjectId = g.Key,
VisitCount = g.Count(),
ReadingImageSize = g.SelectMany(t => t.NoneDicomStudyList.Where(t => t.IsReading)).SelectMany(t => t.NoneDicomFileList.Where(t => t.IsReading)).Sum(t => t.FileSize)
+ g.SelectMany(t => t.StudyList).SelectMany(t => t.InstanceList.Where(t => t.IsReading && t.DicomSerie.IsReading)).Sum(t => t.FileSize),
ImageSize = g.SelectMany(t => t.NoneDicomStudyList).SelectMany(t => t.NoneDicomFileList).Sum(t => t.FileSize)
+ g.SelectMany(t => t.StudyList).SelectMany(t => t.InstanceList).Sum(t => t.FileSize)
@ -1434,9 +1261,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
var totalImageSize = subjectImageList.Sum(t => t.ImageSize);
var totalReadingImageSize = subjectImageList.Sum(t => t.ReadingImageSize);
return ResponseOutput.Ok(new TrialImageStatInfo { SubjectCount = subjectCount, SubjectVisitCount = subjectVisitCount, TotalImageSize = totalImageSize, TotalReadingImageSize = totalReadingImageSize });
return ResponseOutput.Ok(new TrialImageStatInfo { SubjectCount = subjectCount, SubjectVisitCount = subjectVisitCount, TotalImageSize = totalImageSize });
}
@ -1450,8 +1275,6 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
public async Task<IResponseOutput> GetExportSubjectVisitImageList(TrialExportImageCommand inCommand)
{
var isExportReading = inCommand.IsExportReading == true;
if (inCommand.IsKeyImage)
{
var downloadInfoList = _visitTaskRepository.Where(t => t.TrialId == inCommand.TrialId && (t.ReadingCategory == ReadingCategory.Visit || t.ReadingCategory == ReadingCategory.Global)
@ -1715,11 +1538,11 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
u.StudyTime,
u.StudyCode,
SeriesList = u.SeriesList.Where(t => isExportReading ? t.IsReading : true).Select(z => new
SeriesList = u.SeriesList.Select(z => new
{
z.Modality,
InstancePathList = z.DicomInstanceList.Where(t => isExportReading ? t.IsReading : true).Select(k => new
InstancePathList = z.DicomInstanceList.Select(k => new
{
k.Path
})
@ -1727,13 +1550,13 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
}),
NoneDicomStudyList = sv.NoneDicomStudyList.Where(t => isExportReading ? t.IsReading : true).Select(nd => new
NoneDicomStudyList = sv.NoneDicomStudyList.Select(nd => new
{
nd.Modality,
nd.StudyCode,
nd.ImageDate,
FileList = nd.NoneDicomFileList.Where(t => isExportReading ? t.IsReading : true).Select(file => new
FileList = nd.NoneDicomFileList.Select(file => new
{
file.FileName,
file.Path,

View File

@ -1040,10 +1040,7 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto
public List<string> HighlightAnswerList { get; set; } = new List<string>();
/// <summary>
/// 排除显示的访视名称
/// </summary>
public List<decimal> ExcludeShowVisitList { get; set; } = new List<decimal>() { };
/// <summary>
/// 系统标准Id
@ -2424,13 +2421,9 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto
public string ExportResultStr { get; set; } = "[]";
public List<ExportResult> ExportResult { get; set; } = new List<ExportResult>();
/// <summary>
/// 排除显示的访视名称
/// </summary>
public List<decimal> ExcludeShowVisitList { get; set; } = new List<decimal>() { };
public bool IsAdditional { get; set; }
/// <summary>

View File

@ -1062,17 +1062,16 @@ namespace IRaCIS.Core.Application.Service
var taskinfo = await _visitTaskRepository.Where(x => x.Id == visitTaskId).ProjectTo<VisitTaskDto>(_mapper.ConfigurationProvider).FirstNotNullAsync();
if (taskInfo.VisitTaskNum == 0)
if (taskinfo.VisitTaskNum == 0)
{
questions = questions.Where(x => (x.LimitShow == LimitShow.AllShow || x.LimitShow == LimitShow.BaseLineShow) || (x.LimitShow == LimitShow.ExcludeSomeVisits && !x.ExcludeShowVisitList.Contains(taskInfo.VisitTaskNum))).ToList();
questions = questions.Where(x => x.LimitShow == LimitShow.AllShow || x.LimitShow == LimitShow.BaseLineShow).ToList();
}
else
{
questions = questions.Where(x => (x.LimitShow == LimitShow.AllShow || x.LimitShow == LimitShow.FollowShow) || (x.LimitShow == LimitShow.ExcludeSomeVisits && !x.ExcludeShowVisitList.Contains(taskInfo.VisitTaskNum))).ToList();
questions = questions.Where(x => x.LimitShow == LimitShow.AllShow || x.LimitShow == LimitShow.FollowShow).ToList();
}
questions.ForEach(x =>
{
x.CrterionDictionaryGroup = ReadingCommon.GetCrterionDictionaryGroup(taskinfo.IsConvertedTask);
@ -1343,12 +1342,12 @@ namespace IRaCIS.Core.Application.Service
taskInfo = await _visitTaskRepository.Where(x => x.Id == inDto.TaskId).ProjectTo<VisitTaskDto>(_mapper.ConfigurationProvider).FirstNotNullAsync();
if (taskInfo.VisitTaskNum == 0)
{
qusetionList = qusetionList.Where(x => (x.LimitShow == LimitShow.AllShow || x.LimitShow == LimitShow.BaseLineShow) || (x.LimitShow == LimitShow.ExcludeSomeVisits&&!x.ExcludeShowVisitList.Contains(taskInfo.VisitTaskNum))).ToList();
qusetionList = qusetionList.Where(x => x.LimitShow == LimitShow.AllShow || x.LimitShow == LimitShow.BaseLineShow).ToList();
}
else
{
qusetionList = qusetionList.Where(x => (x.LimitShow == LimitShow.AllShow || x.LimitShow == LimitShow.FollowShow) || (x.LimitShow == LimitShow.ExcludeSomeVisits && !x.ExcludeShowVisitList.Contains(taskInfo.VisitTaskNum))).ToList();
qusetionList = qusetionList.Where(x => x.LimitShow == LimitShow.AllShow || x.LimitShow == LimitShow.FollowShow).ToList();
}

View File

@ -88,10 +88,7 @@ namespace IRaCIS.Application.Contracts
public bool IsDeleted { get; set; }
}
public class GetVisitStageInDto
{
public Guid TrialId { get; set; } = Guid.Empty;
}
public class VisitPlanQueryDTO : PageInput
{
public Guid TrialId { get; set; } = Guid.Empty;

View File

@ -1,5 +1,4 @@
using DocumentFormat.OpenXml.Office2010.ExcelAc;
using IRaCIS.Application.Contracts;
using IRaCIS.Application.Contracts;
using IRaCIS.Application.Interfaces;
using IRaCIS.Core.Application.Filter;
using IRaCIS.Core.Domain.Share;
@ -19,18 +18,7 @@ namespace IRaCIS.Core.Application.Service
IRepository<VisitPlanInfluenceStat> _visitPlanInfluenceStatRepository, IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer) : BaseService, IVisitPlanService
{
/// <summary>
/// 获取项目访视计划
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
[HttpPost]
public async Task<List<VisitStageDTO>> GetVisitStage(GetVisitStageInDto inDto)
{
var visitStageList = await _visitStageRepository.Where(x => x.TrialId == inDto.TrialId).ProjectTo<VisitStageDTO>(_mapper.ConfigurationProvider).OrderBy(x => x.VisitNum).ToListAsync(); ;
return visitStageList;
}
///暂时不用
/// <summary> 获取项目访视计划</summary>

View File

@ -3074,14 +3074,7 @@ public enum PET5PSScore
/// </summary>
FollowShow = 2,
/// <summary>
/// 排除部分访视
/// </summary>
ExcludeSomeVisits = 3,
}
}
/// <summary>
/// 限制编辑

View File

@ -32,7 +32,7 @@ public class DicomInstance : BaseFullDeleteAuditEntity, IEntitySeqId
public int ImageRows { get; set; }
public string ImagerPixelSpacing { get; set; } = null!;
public int InstanceNumber { get; set; }
@ -44,7 +44,7 @@ public class DicomInstance : BaseFullDeleteAuditEntity, IEntitySeqId
[StringLength(1000)]
public string Path { get; set; } = null!;
public string PixelSpacing { get; set; } = null!;
public Guid SeqId { get; set; }
@ -55,7 +55,7 @@ public class DicomInstance : BaseFullDeleteAuditEntity, IEntitySeqId
public int SliceLocation { get; set; }
public string SliceThickness { get; set; } = null!;
public string SopInstanceUid { get; set; } = null!;
@ -70,27 +70,11 @@ public class DicomInstance : BaseFullDeleteAuditEntity, IEntitySeqId
public Guid TrialId { get; set; }
public string WindowCenter { get; set; } = null!;
public string WindowWidth { get; set; } = null!;
public bool IsReading { get; set; } = true;
#region DIR 增加
public string SOPClassUID { get; set; }
public string MediaStorageSOPClassUID { get; set; }
public string TransferSytaxUID { get; set; }
public string MediaStorageSOPInstanceUID { get; set; }
public bool IsEncapsulated { get; set; }
#endregion
}

View File

@ -73,12 +73,5 @@ public class DicomSeries : BaseFullDeleteAuditEntity, IEntitySeqId
public string TriggerTime { get; set; } = null!;
public Guid? VisitTaskId { get; set; }
#region DIR 增加
public string DicomSeriesDate { get; set; }
public string DicomSeriesTime { get; set; }
#endregion
}

View File

@ -102,14 +102,4 @@ public class DicomStudy : BaseFullDeleteAuditEntity, IEntitySeqId
public string Uploader { get; set; } = null!;
public string ModifyReason { get; set; }
#region DIR 增加字段
public string DicomStudyDate { get; set; }
public string DicomStudyTime { get; set; }
public string StudyDIRPath { get; set; }
#endregion
}

View File

@ -226,11 +226,6 @@ public class ReadingQuestionTrial : BaseAddAuditEntity
[Comment("限制显示")]
public LimitShow LimitShow { get; set; } = LimitShow.AllShow;
/// <summary>
/// 排除显示的访视名称
/// </summary>
public List<decimal> ExcludeShowVisitList { get; set; } = new List<decimal>() { };
[MaxLength]
[Comment("自定义计算标记")]
public string CalculateQuestions { get; set; } = "[]";

View File

@ -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";

View File

@ -1,29 +0,0 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace IRaCIS.Core.Infra.EFCore.Migrations
{
/// <inheritdoc />
public partial class ExcludeShowVisitList : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<string>(
name: "ExcludeShowVisitList",
table: "ReadingQuestionTrial",
type: "nvarchar(max)",
nullable: false,
defaultValue: "[]");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "ExcludeShowVisitList",
table: "ReadingQuestionTrial");
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,114 +0,0 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace IRaCIS.Core.Infra.EFCore.Migrations
{
/// <inheritdoc />
public partial class dir : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<string>(
name: "DicomStudyDate",
table: "DicomStudy",
type: "nvarchar(400)",
maxLength: 400,
nullable: false,
defaultValue: "");
migrationBuilder.AddColumn<string>(
name: "DicomStudyTime",
table: "DicomStudy",
type: "nvarchar(400)",
maxLength: 400,
nullable: false,
defaultValue: "");
migrationBuilder.AddColumn<string>(
name: "DicomSeriesDate",
table: "DicomSeries",
type: "nvarchar(400)",
maxLength: 400,
nullable: false,
defaultValue: "");
migrationBuilder.AddColumn<string>(
name: "DicomSeriesTime",
table: "DicomSeries",
type: "nvarchar(400)",
maxLength: 400,
nullable: false,
defaultValue: "");
migrationBuilder.AddColumn<string>(
name: "MediaStorageSOPClassUID",
table: "DicomInstance",
type: "nvarchar(400)",
maxLength: 400,
nullable: false,
defaultValue: "");
migrationBuilder.AddColumn<string>(
name: "MediaStorageSOPInstanceUID",
table: "DicomInstance",
type: "nvarchar(400)",
maxLength: 400,
nullable: false,
defaultValue: "");
migrationBuilder.AddColumn<string>(
name: "SOPClassUID",
table: "DicomInstance",
type: "nvarchar(400)",
maxLength: 400,
nullable: false,
defaultValue: "");
migrationBuilder.AddColumn<string>(
name: "TransferSytaxUID",
table: "DicomInstance",
type: "nvarchar(400)",
maxLength: 400,
nullable: false,
defaultValue: "");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "DicomStudyDate",
table: "DicomStudy");
migrationBuilder.DropColumn(
name: "DicomStudyTime",
table: "DicomStudy");
migrationBuilder.DropColumn(
name: "DicomSeriesDate",
table: "DicomSeries");
migrationBuilder.DropColumn(
name: "DicomSeriesTime",
table: "DicomSeries");
migrationBuilder.DropColumn(
name: "MediaStorageSOPClassUID",
table: "DicomInstance");
migrationBuilder.DropColumn(
name: "MediaStorageSOPInstanceUID",
table: "DicomInstance");
migrationBuilder.DropColumn(
name: "SOPClassUID",
table: "DicomInstance");
migrationBuilder.DropColumn(
name: "TransferSytaxUID",
table: "DicomInstance");
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,30 +0,0 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace IRaCIS.Core.Infra.EFCore.Migrations
{
/// <inheritdoc />
public partial class dir2 : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<string>(
name: "StudyDIRPath",
table: "DicomStudy",
type: "nvarchar(400)",
maxLength: 400,
nullable: false,
defaultValue: "");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "StudyDIRPath",
table: "DicomStudy");
}
}
}

View File

@ -1,29 +0,0 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace IRaCIS.Core.Infra.EFCore.Migrations
{
/// <inheritdoc />
public partial class addIsEncapsulated : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<bool>(
name: "IsEncapsulated",
table: "DicomInstance",
type: "bit",
nullable: false,
defaultValue: false);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "IsEncapsulated",
table: "DicomInstance");
}
}
}

View File

@ -930,22 +930,9 @@ namespace IRaCIS.Core.Infra.EFCore.Migrations
b.Property<bool>("IsDeleted")
.HasColumnType("bit");
b.Property<bool>("IsEncapsulated")
.HasColumnType("bit");
b.Property<bool>("IsReading")
.HasColumnType("bit");
b.Property<string>("MediaStorageSOPClassUID")
.IsRequired()
.HasMaxLength(400)
.HasColumnType("nvarchar(400)");
b.Property<string>("MediaStorageSOPInstanceUID")
.IsRequired()
.HasMaxLength(400)
.HasColumnType("nvarchar(400)");
b.Property<int>("NumberOfFrames")
.HasColumnType("int");
@ -959,11 +946,6 @@ namespace IRaCIS.Core.Infra.EFCore.Migrations
.HasMaxLength(400)
.HasColumnType("nvarchar(400)");
b.Property<string>("SOPClassUID")
.IsRequired()
.HasMaxLength(400)
.HasColumnType("nvarchar(400)");
b.Property<Guid>("SeriesId")
.HasColumnType("uniqueidentifier");
@ -999,11 +981,6 @@ namespace IRaCIS.Core.Infra.EFCore.Migrations
b.Property<Guid>("SubjectVisitId")
.HasColumnType("uniqueidentifier");
b.Property<string>("TransferSytaxUID")
.IsRequired()
.HasMaxLength(400)
.HasColumnType("nvarchar(400)");
b.Property<Guid>("TrialId")
.HasColumnType("uniqueidentifier");
@ -1080,16 +1057,6 @@ namespace IRaCIS.Core.Infra.EFCore.Migrations
.HasMaxLength(400)
.HasColumnType("nvarchar(400)");
b.Property<string>("DicomSeriesDate")
.IsRequired()
.HasMaxLength(400)
.HasColumnType("nvarchar(400)");
b.Property<string>("DicomSeriesTime")
.IsRequired()
.HasMaxLength(400)
.HasColumnType("nvarchar(400)");
b.Property<Guid>("Id")
.HasColumnType("uniqueidentifier");
@ -1250,16 +1217,6 @@ namespace IRaCIS.Core.Infra.EFCore.Migrations
.HasMaxLength(400)
.HasColumnType("nvarchar(400)");
b.Property<string>("DicomStudyDate")
.IsRequired()
.HasMaxLength(400)
.HasColumnType("nvarchar(400)");
b.Property<string>("DicomStudyTime")
.IsRequired()
.HasMaxLength(400)
.HasColumnType("nvarchar(400)");
b.Property<Guid>("Id")
.HasColumnType("uniqueidentifier");
@ -1328,11 +1285,6 @@ namespace IRaCIS.Core.Infra.EFCore.Migrations
.HasMaxLength(400)
.HasColumnType("nvarchar(400)");
b.Property<string>("StudyDIRPath")
.IsRequired()
.HasMaxLength(400)
.HasColumnType("nvarchar(400)");
b.Property<string>("StudyId")
.IsRequired()
.HasMaxLength(400)
@ -6322,10 +6274,6 @@ namespace IRaCIS.Core.Infra.EFCore.Migrations
.HasColumnType("nvarchar(400)")
.HasComment("字典code");
b.Property<string>("ExcludeShowVisitList")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("ExportResultStr")
.IsRequired()
.HasMaxLength(400)

View File

@ -58,7 +58,7 @@ namespace IRaCIS.Core.Infra.EFCore
Task<bool> BatchDeleteNoTrackingAsync(Expression<Func<TEntity, bool>> deleteFilter);
/// <summary>批量更新相当于原生sql 没用EF跟踪方式所有查询出来再更新 浪费性能)</summary>
Task<bool> BatchUpdateNoTrackingAsync(Expression<Func<TEntity, bool>> where, Expression<Func<TEntity, TEntity>> updateFactory, bool isAutoIncludeTimeAndUser = true);
Task<bool> BatchUpdateNoTrackingAsync(Expression<Func<TEntity, bool>> where, Expression<Func<TEntity, TEntity>> updateFactory);
Task<bool> ExecuteUpdateAsync(Expression<Func<TEntity, bool>> where, Expression<Func<SetPropertyCalls<TEntity>, SetPropertyCalls<TEntity>>> setPropertyCalls);
@ -77,7 +77,7 @@ namespace IRaCIS.Core.Infra.EFCore
#endregion
void MarkAsModified<TFrom>(TFrom entity, string propertyName);
void MarkAsModified<TFrom>(TFrom entity, string propertyName);
}

View File

@ -157,7 +157,7 @@ namespace IRaCIS.Core.Infra.EFCore
/// <summary>批量更新相当于原生sql 没用EF跟踪方式所有查询出来再更新 浪费性能)</summary>
public static async Task<bool> BatchUpdateNoTrackingAsync<T>(this IRaCISDBContext _dbContext, Expression<Func<T, bool>> where, Expression<Func<T, T>> updateFactory, Guid updateUserId, bool isAutoIncludeTimeAndUser = true) where T : Entity
public static async Task<bool> BatchUpdateNoTrackingAsync<T>(this IRaCISDBContext _dbContext, Expression<Func<T, bool>> where, Expression<Func<T, T>> updateFactory, Guid updateUserId) where T : Entity
{
if (where == null) throw new ArgumentNullException(nameof(where));
@ -202,17 +202,15 @@ namespace IRaCIS.Core.Infra.EFCore
if (typeof(IAuditUpdate).IsAssignableFrom(typeof(T)))
{
if (isAutoIncludeTimeAndUser)
{
if (!hasPropNameList.Contains(nameof(IAuditUpdate.UpdateTime)))
{
fieldValues.Add(nameof(IAuditUpdate.UpdateTime), DateTime.Now);
}
if (!hasPropNameList.Contains(nameof(IAuditUpdate.UpdateUserId)))
{
fieldValues.Add(nameof(IAuditUpdate.UpdateUserId), updateUserId);
}
if (!hasPropNameList.Contains(nameof(IAuditUpdate.UpdateTime)))
{
fieldValues.Add(nameof(IAuditUpdate.UpdateTime), DateTime.Now);
}
if (!hasPropNameList.Contains(nameof(IAuditUpdate.UpdateUserId)))
{
fieldValues.Add(nameof(IAuditUpdate.UpdateUserId), updateUserId);
}
}

View File

@ -297,10 +297,10 @@ namespace IRaCIS.Core.Infra.EFCore
/// <summary>批量更新相当于原生sql 没用EF跟踪方式所有查询出来再更新 浪费性能)</summary>
public async Task<bool> BatchUpdateNoTrackingAsync(Expression<Func<TEntity, bool>> where,
Expression<Func<TEntity, TEntity>> updateFactory ,bool isAutoIncludeTimeAndUser = true)
Expression<Func<TEntity, TEntity>> updateFactory)
{
return await _dbContext.BatchUpdateNoTrackingAsync(where, updateFactory, _userInfo.UserRoleId, isAutoIncludeTimeAndUser);
return await _dbContext.BatchUpdateNoTrackingAsync(where, updateFactory, _userInfo.UserRoleId);
}