From 56b94a97fd2e7b8c1a4f0f33f9238beb8de9598f Mon Sep 17 00:00:00 2001
From: wangxiaoshuang <825034831@qq.com>
Date: Fri, 24 May 2024 16:47:35 +0800
Subject: [PATCH] =?UTF-8?q?=E4=B8=8A=E4=BC=A0=E3=80=81=E4=B8=8B=E8=BD=BD?=
=?UTF-8?q?=E5=BD=B1=E5=83=8F?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/api/load.js | 9 +
src/components/uploadImage/index.vue | 499 +++++++++++++++++++--------
src/utils/parseDicom.js | 18 +-
3 files changed, 384 insertions(+), 142 deletions(-)
diff --git a/src/api/load.js b/src/api/load.js
index 34cd3179..cc23cc40 100644
--- a/src/api/load.js
+++ b/src/api/load.js
@@ -30,4 +30,13 @@ export function addOrUpdateArchiveTaskStudy(data) {
method: 'post',
data
})
+}
+
+// 删除上传文件
+export function deleteTaskStudy(params) {
+ return request({
+ url: '/DownloadAndUpload/deleteTaskStudy',
+ method: 'delete',
+ params
+ })
}
\ No newline at end of file
diff --git a/src/components/uploadImage/index.vue b/src/components/uploadImage/index.vue
index 01e91807..3b7b79b2 100644
--- a/src/components/uploadImage/index.vue
+++ b/src/components/uploadImage/index.vue
@@ -7,6 +7,10 @@
:before-close="beforeClose"
>
{{ $t("trials:uploadImage:title:uploadImages") }}
+ {{
+ $t("trials:uploadImage:button:uploadTableTitle1")
+ }}
+
- {{
- scope.row.OrginalStudyList &&
- Array.isArray(scope.row.OrginalStudyList)
- ? scope.row.OrginalStudyList.length
- : 0
- }}
+
+
+ {{ scope.row.OrginalStudyList.length }}
+
+ 0
+
-
{{ $t("trials:uploadImage:button:uploadTableTitle") }}
+ {{
+ $t("trials:uploadImage:button:uploadTableTitle")
+ }}
-
+
+
+ {{ $t("trials:uploadImage:button:selectFolder") }}
+
+
-
-
-
-
+
+
+
+
+
+
+ {{ $t("trials:uploadImage:table:studyDetail1") }}
+ {{ $t("trials:uploadImage:table:studyDetail2") }}
+ {{ $t("trials:uploadedDicoms:table:studyDate") }}
+
+ {{ $t("trials:uploadImage:table:studyInfo") }}
+
+
+
+
+
+
+
+ Acc:
+ {{ scope.row.dicomInfo.AccessionNumber || "N/A" }}
+
+
+
+
+ {{ scope.row.dicomInfo.Modalities.join("、") }},
+
+ N/A,
+
+
+ {{ scope.row.SeriesInstanceUidList.length }} Series,
+
+ N/A,
+
+
+ {{ scope.row.count }} Instances
+
+ N/A
+
+
+
+
+
+
+ {{ scope.row.dicomInfo.seriesBodyPartExamined }},
+
+ N/A,
+
+
+
+ {{ scope.row.dicomInfo.StudyDescription }}
+ N/A
+
+
+
+ {{ scope.row.dicomInfo.StudyTime }}
+
+
+
+
+
+
+
+
+
+ {{ $t("trials:uploadImage:table:pId") }}
+ {{ $t("trials:uploadImage:table:patientName") }}
+ {{ $t("trials:uploadImage:table:pInfo") }}
+
+ {{ $t("trials:uploadImage:table:patientInfo") }}
+
+
+
+
+
+ PID: {{ scope.row.dicomInfo.PatientId }}
+ N/A
+
+
+
+ {{ scope.row.dicomInfo.PatientName || "N/A" }}
+
+
+
+
+ {{ scope.row.dicomInfo.PatientSex || "N/A" }},
+
+
+
+ {{ scope.row.dicomInfo.PatientAge || "N/A" }},
+
+
+
+ {{ scope.row.dicomInfo.PatientBirthDate || "N/A" }}
+
+
+
+
+
{
data.SopInstanceUidList &&
this.SopInstanceUidList.push(...data.SopInstanceUidList);
});
@@ -235,7 +389,32 @@ export default {
}
},
// 删除
- remove(item) {},
+ async remove(item) {
+ try {
+ let confirm = await this.$confirm(
+ this.$t("trials:uploadImage:confirm:delMessage"),
+ {
+ type: "warning",
+ distinguishCancelAndClose: true,
+ confirmButtonText: this.$t("common:button:confirm"),
+ cancelButtonText: this.$t("common:button:cancel"),
+ }
+ );
+ if (confirm !== "confirm") return;
+ let params = {
+ VisitTaskId: item.VisitTaskId,
+ };
+ let res = await deleteTaskStudy(params);
+ if (res.IsSuccess) {
+ this.getList();
+ this.$message.success(
+ this.$t("trials:uploadImage:message:delSuccess")
+ );
+ }
+ } catch (err) {
+ console.log(err);
+ }
+ },
// 打包下载
async downloadImage(item) {
try {
@@ -248,11 +427,23 @@ export default {
}
},
// 预上传
- async preArchiveDicomStudy(post) {
+ async preArchiveDicomStudy(post, index) {
try {
let res = await preArchiveDicomStudy(post);
if (res.IsSuccess) {
- return res.Result;
+ let item = this.uploadList[index];
+ item.StudyMonitorId = res.Result;
+ let arr = this.dicomList.filter(
+ (dicom) => dicom.StudyInstanceUid === item.StudyInstanceUid
+ );
+ let num = arr.length > this.requestNum ? this.requestNum : arr.length;
+ let funArr = [];
+ for (let i = 0; i < num; i++) {
+ funArr.push(this.handleUploadTask(arr, i));
+ }
+ if (funArr.length > 0) {
+ let res = await Promise.all(funArr);
+ }
} else {
return false;
}
@@ -275,8 +466,23 @@ export default {
!dicom ||
!has ||
this.SopInstanceUidList.includes(dicom.SopInstanceUid)
- )
+ ) {
+ if (i === files.length - 1 && this.dicomList.length <= 0) {
+ let confirm = await this.$confirm(
+ this.$t("trials:uploadImage:confirmMessage:failSubject"),
+ {
+ type: "warning",
+ distinguishCancelAndClose: true,
+ confirmButtonText: this.$t("common:button:confirm"),
+ cancelButtonText: this.$t("common:button:cancel"),
+ }
+ );
+ if (confirm !== "confirm") continue;
+ this.$refs.file.click();
+ }
continue;
+ }
+ this.isLoad = true;
dicom.file = files[i];
dicom.isUpload = 0;
this.StudyInstanceUidList.some((item) => {
@@ -287,33 +493,54 @@ export default {
VisitTaskId: item.VisitTaskId,
SourceSubjectVisitId: item.SourceSubjectVisitId,
};
- let uploadHas = this.uploadList.some(
- (uploadData, uploadIndex) => {
- if (uploadData.StudyInstanceUid === dicom.StudyInstanceUid) {
- if (uploadData.status > 0) {
- uploadData.count = 1;
- uploadData.successCount = 0;
- uploadData.failCount = 0;
- uploadData.schedule = 0;
- uploadData.status = 0;
- uploadData.FileSize = dicom.file.size;
- uploadData.IsDicomReUpload = false;
- } else {
- uploadData.FileSize += dicom.file.size;
- uploadData.count++;
- }
- if (
- item.SopInstanceUidList &&
- item.SopInstanceUidList.length > 0
- ) {
- uploadData.IsDicomReUpload = true;
- }
- dicom.uploadIndex = uploadIndex;
+ let uploadHas = this.uploadList.some((uploadData) => {
+ if (uploadData.StudyInstanceUid === dicom.StudyInstanceUid) {
+ if (uploadData.status > 0) {
+ uploadData.count = 1;
+ uploadData.successCount = 0;
+ uploadData.failCount = 0;
+ uploadData.schedule = 0;
+ uploadData.status = 0;
+ uploadData.FileSize = dicom.file.size;
+ uploadData.IsDicomReUpload = false;
+ uploadData.SeriesInstanceUidList = [
+ dicom.SeriesInstanceUid,
+ ];
+ uploadData.dicomInfo = {
+ AccessionNumber: dicom.AccessionNumber,
+ Modalities: dicom.Modalities,
+ seriesBodyPartExamined: dicom.seriesBodyPartExamined,
+ StudyDescription: dicom.StudyDescription,
+ StudyTime: this.getTime(dicom.StudyDate, dicom.StudyTime),
+ PatientName: dicom.PatientName,
+ PatientId: dicom.PatientId,
+ PatientAge: dicom.PatientAge,
+ PatientSex: dicom.PatientSex,
+ PatientBirthDate: dicom.PatientBirthDate,
+ };
+ } else {
+ uploadData.FileSize += dicom.file.size;
+ uploadData.count++;
+ }
+ if (
+ !uploadData.SeriesInstanceUidList.includes(
+ dicom.SeriesInstanceUid
+ )
+ ) {
+ uploadData.SeriesInstanceUidList.push(
+ dicom.SeriesInstanceUid
+ );
+ }
+ if (
+ item.SopInstanceUidList &&
+ item.SopInstanceUidList.length > 0
+ ) {
+ uploadData.IsDicomReUpload = true;
}
-
- return uploadData.StudyInstanceUid === dicom.StudyInstanceUid;
}
- );
+
+ return uploadData.StudyInstanceUid === dicom.StudyInstanceUid;
+ });
if (!uploadHas) {
let uploadData = {
TrialId: this.$route.query.trialId,
@@ -327,7 +554,20 @@ export default {
failCount: 0,
schedule: 0,
status: 0,
+ SeriesInstanceUidList: [dicom.SeriesInstanceUid],
IsDicomReUpload: false,
+ dicomInfo: {
+ AccessionNumber: dicom.AccessionNumber,
+ Modalities: dicom.Modalities,
+ seriesBodyPartExamined: dicom.seriesBodyPartExamined,
+ StudyDescription: dicom.StudyDescription,
+ StudyTime: this.getTime(dicom.StudyDate, dicom.StudyTime),
+ PatientName: dicom.PatientName,
+ PatientId: dicom.PatientId,
+ PatientAge: dicom.PatientAge,
+ PatientSex: dicom.PatientSex,
+ PatientBirthDate: dicom.PatientBirthDate,
+ },
};
if (
item.SopInstanceUidList &&
@@ -336,13 +576,13 @@ export default {
uploadData.IsDicomReUpload = true;
}
this.uploadList.push(uploadData);
- dicom.uploadIndex = this.uploadList.length - 1;
}
}
return item.StudyInstanceUid === dicom.StudyInstanceUid;
});
this.dicomList.push(dicom);
}
+ let funArr = [];
for (let i = 0; i < this.uploadList.length; i++) {
let item = this.uploadList[i];
let data = {
@@ -353,20 +593,10 @@ export default {
IsDicomReUpload: item.IsDicomReUpload,
FileCount: item.count,
};
- let res = await this.preArchiveDicomStudy(data);
- if (res) {
- item.StudyMonitorId = res;
- let arr = this.dicomList.filter((dicom) => dicom.uploadIndex === i);
- let num =
- arr.length > this.requestNum ? this.requestNum : arr.length;
- let funArr = [];
- for (let i = 0; i < num; i++) {
- funArr.push(this.handleUploadTask(arr, i));
- }
- if (funArr.length > 0) {
- let res = await Promise.all(funArr);
- }
- }
+ funArr.push(this.preArchiveDicomStudy(data, i));
+ }
+ if (funArr && funArr.length > 0) {
+ let res = await Promise.all(funArr);
}
} catch (err) {
console.log(err);
@@ -375,42 +605,58 @@ export default {
// 并发上传
async handleUploadTask(arr, index) {
arr[index].isUpload = 1;
- let res = await this.dicomToOSS(
- arr[index].file,
- arr[index].params,
- arr[index]
- );
+ let path = `/${arr[index].params.TrialId}/TaskImage/${
+ arr[index].params.SubjectId
+ }/${arr[index].params.VisitTaskId}/${
+ arr[index].StudyInstanceUid
+ }/${this.getGuid(
+ arr[index].StudyInstanceUid +
+ arr[index].SeriesInstanceUid +
+ arr[index].SOPInstanceUid +
+ arr[index].params.TrialId +
+ arr[index].params.VisitTaskId
+ )}`;
+ let uploadDicom = this.uploadList.filter(
+ (item) => item.StudyInstanceUid === arr[index].StudyInstanceUid
+ )[0];
+ let res = await dicomToOSS(arr[index].file, path);
if (res) {
arr[index].path = res;
- this.uploadList[arr[index].uploadIndex].successCount++;
+ uploadDicom.successCount++;
arr[index].isUpload = 2;
} else {
- this.uploadList[arr[index].uploadIndex].status = 2;
- this.uploadList[arr[index].uploadIndex].failCount++;
+ uploadDicom.status = 2;
+ uploadDicom.failCount++;
arr[index].isUpload = 3;
}
- this.uploadList[arr[index].uploadIndex].schedule = Math.floor(
- ((this.uploadList[arr[index].uploadIndex].successCount +
- this.uploadList[arr[index].uploadIndex].failCount) /
- this.uploadList[arr[index].uploadIndex].count) *
+ uploadDicom.schedule = Math.floor(
+ ((uploadDicom.successCount + uploadDicom.failCount) /
+ uploadDicom.count) *
100
);
if (
- this.uploadList[arr[index].uploadIndex].schedule >= 100 &&
- this.uploadList[arr[index].uploadIndex].successCount ===
- this.uploadList[arr[index].uploadIndex].count
+ uploadDicom.schedule >= 100 &&
+ uploadDicom.successCount === uploadDicom.count
) {
- this.uploadList[arr[index].uploadIndex].status = 1;
- let res = await this.formatDicom(arr, arr[index].uploadIndex);
+ uploadDicom.status = 1;
+ let res = await this.formatDicom(arr, arr[index].StudyInstanceUid);
if (res) {
- this.uploadList[arr[index].uploadIndex].Study =
- res[arr[index].StudyId];
- this.uploadList[arr[index].uploadIndex].status = 3;
- res = await addOrUpdateArchiveTaskStudy(
- this.uploadList[arr[index].uploadIndex]
- );
- if (res.IsSuccess) {
- this.getList();
+ uploadDicom.Study = res[arr[index].StudyId];
+ uploadDicom.status = 3;
+ try {
+ res = await addOrUpdateArchiveTaskStudy(uploadDicom);
+ if (res.IsSuccess) {
+ uploadDicom.status = 4;
+ this.getList();
+ } else {
+ uploadDicom.status = 5;
+ }
+ let flag = this.uploadList.every((item) => item.status > 3);
+ if (flag) this.isLoad = false;
+ } catch (err) {
+ uploadDicom.status = 5;
+ let flag = this.uploadList.every((item) => item.status > 3);
+ if (flag) this.isLoad = false;
}
}
}
@@ -422,11 +668,12 @@ export default {
}
},
// 数据整理
- async formatDicom(arr, index) {
+ async formatDicom(arr, StudyInstanceUid) {
let studyObj = {};
for (let i = 0; i < arr.length; i++) {
let dicom = arr[i];
- if (dicom.uploadIndex !== index) continue;
+ if (dicom.StudyInstanceUid !== StudyInstanceUid) continue;
+ let thumbnailPath = `/${dicom.params.TrialId}/TaskImage/${dicom.params.SubjectId}/${dicom.params.VisitTaskId}/${dicom.StudyInstanceUid}/${dicom.SeriesInstanceUid}.png`;
if (!studyObj[dicom.StudyId]) {
studyObj[dicom.StudyId] = {
StudyId: dicom.StudyId,
@@ -468,7 +715,7 @@ export default {
TriggerTime: dicom.TriggerTime,
ImageResizePath: await getThumbnail(
dicom.file,
- dicom.params,
+ thumbnailPath,
dicom
),
InstanceList: [
@@ -505,12 +752,12 @@ export default {
let instance = {
StudyInstanceUid: dicom.StudyInstanceUid,
SeriesInstanceUid: dicom.SeriesInstanceUid,
- SopInstanceUid: dicom.SopInstanceUid,
- InstanceNumber: dicom.ImageOrInstanceNumber,
- InstanceTime: this.getTime(
- dicom.ContentDate,
- dicom.ContentTime
- ),
+ SopInstanceUid: dicom.SopInstanceUid,
+ InstanceNumber: dicom.ImageOrInstanceNumber,
+ InstanceTime: this.getTime(
+ dicom.ContentDate,
+ dicom.ContentTime
+ ),
ImageRows: dicom.Rows || 0,
ImageColumns: dicom.Columns || 0,
SliceLocation: dicom.SliceLocation,
@@ -550,19 +797,19 @@ export default {
TriggerTime: dicom.TriggerTime,
ImageResizePath: await getThumbnail(
dicom.file,
- dicom.params,
+ thumbnailPath,
dicom
),
InstanceList: [
{
StudyInstanceUid: dicom.StudyInstanceUid,
SeriesInstanceUid: dicom.SeriesInstanceUid,
- SopInstanceUid: dicom.SopInstanceUid,
- InstanceNumber: dicom.ImageOrInstanceNumber,
- InstanceTime: this.getTime(
- dicom.ContentDate,
- dicom.ContentTime
- ),
+ SopInstanceUid: dicom.SopInstanceUid,
+ InstanceNumber: dicom.ImageOrInstanceNumber,
+ InstanceTime: this.getTime(
+ dicom.ContentDate,
+ dicom.ContentTime
+ ),
ImageRows: dicom.Rows || 0,
ImageColumns: dicom.Columns || 0,
SliceLocation: dicom.SliceLocation,
@@ -606,26 +853,6 @@ export default {
}
return studyTime;
},
- // 影像上传
- async dicomToOSS(file, params, dicomInfo) {
- let path = `/${params.TrialId}/TaskImage/${params.SubjectId}/${
- params.VisitTaskId
- }/${dicomInfo.StudyInstanceUid}/${this.getGuid(
- dicomInfo.StudyInstanceUid +
- dicomInfo.SeriesInstanceUid +
- dicomInfo.SOPInstanceUid +
- params.TrialId +
- params.VisitTaskId
- )}`;
- try {
- let res = await dcmUpload(path, file);
- if (!res || !res.url) return false;
- return this.$getObjectName(res.url);
- } catch (err) {
- console.log(err);
- return false;
- }
- },
},
};
@@ -633,18 +860,12 @@ export default {
label {
cursor: pointer;
}
-.line {
- width: 100%;
- display: flex;
- align-items: center;
- justify-content: space-between;
- margin: 20px 0;
- &::after {
- display: block;
- content: "";
- flex: 1;
- height: 1px;
- border-top: 1px solid #ddd;
+::v-deep .el-dialog {
+ .el-dialog__header {
+ padding-top: 15px;
}
}
+.colorOfRed {
+ color: #f44336;
+}
\ No newline at end of file
diff --git a/src/utils/parseDicom.js b/src/utils/parseDicom.js
index f913cb81..4535eb6a 100644
--- a/src/utils/parseDicom.js
+++ b/src/utils/parseDicom.js
@@ -5,6 +5,7 @@ cornerstoneWADOImageLoader.external.dicomParser = dicomParser;
cornerstoneWADOImageLoader.external.cornerstone = cornerstone;
import { convertBytes } from "@/utils/dicom-character-set";
import Vue from 'vue';
+import { dcmUpload } from "@/utils/dcmUpload/dcmUpload";
let dicom = {
PatientName: "x00100010", // 患者姓名
PatientId: "x00100020", // 患者ID
@@ -133,8 +134,20 @@ export const parseDicom = (file, name = false) => {
reader.readAsArrayBuffer(file);
});
};
+// 影像上传
+// 影像上传
+export const dicomToOSS = async (file, path) => {
+ try {
+ let res = await dcmUpload(path, file);
+ if (!res || !res.url) return false;
+ return Vue.prototype.$getObjectName(res.url);
+ } catch (err) {
+ console.log(err);
+ return false;
+ }
+};
// 获取缩略图
-export const getThumbnail = async (file, params, dicomInfo) => {
+export const getThumbnail = async (file, ossPath, dicomInfo) => {
try {
if (dicomInfo.modality !== "SR") {
let fileId = cornerstoneWADOImageLoader.wadouri.fileManager.add(file);
@@ -144,9 +157,8 @@ export const getThumbnail = async (file, params, dicomInfo) => {
dicomInfo.Rows
);
if (!blob) return "";
- let thumbnailPath = `/${params.TrialId}/TaskImage/${params.SubjectId}/${params.VisitTaskId}/${dicomInfo.StudyInstanceUid}/${dicomInfo.SeriesInstanceUid}.png`;
let OSSclient = Vue.prototype.OSSclient;
- let seriesRes = await OSSclient.put(thumbnailPath, blob);
+ let seriesRes = await OSSclient.put(ossPath, blob);
if (seriesRes && seriesRes.url) {
return Vue.prototype.$getObjectName(seriesRes.url);
} else {