From 6712cad721524edf83129570478886ee30fc16d9 Mon Sep 17 00:00:00 2001 From: "DESKTOP-6C3NK6N\\WXS" <815034831@qq.com> Date: Tue, 3 Sep 2024 17:48:24 +0800 Subject: [PATCH] =?UTF-8?q?ir=E4=BB=BB=E5=8A=A1=E5=88=97=E8=A1=A8=E4=B8=8B?= =?UTF-8?q?=E8=BD=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/load.js | 16 + .../downloadDicomAndNonedicom/index.vue | 382 ++++++++++++++++++ .../uploadDicomAndNonedicom/study-view.vue | 131 ++++++ src/components/uploadImage/index.vue | 3 +- src/utils/stream.js | 13 +- src/utils/uploadZip.js | 168 -------- .../reading/reading-task/index.vue | 96 +++-- .../reading-period/components/AddOrEditCD.vue | 200 +++++---- .../qc-check/components/qualityAssurance.vue | 28 +- 9 files changed, 721 insertions(+), 316 deletions(-) create mode 100644 src/components/downloadDicomAndNonedicom/index.vue create mode 100644 src/components/uploadDicomAndNonedicom/study-view.vue delete mode 100644 src/utils/uploadZip.js diff --git a/src/api/load.js b/src/api/load.js index ff9e6b8d..3bc426ca 100644 --- a/src/api/load.js +++ b/src/api/load.js @@ -47,4 +47,20 @@ export function getCRCUploadedStudyInfo(data) { method: 'post', data }) +} +// 获取ir阅片和任务列表 +export function getSubjectImageDownloadSelectList(data) { + return request({ + url: '/DownloadAndUpload/getSubjectImageDownloadSelectList', + method: 'post', + data + }) +} +// 获取ir阅片和任务下载文件信息 +export function getIRReadingDownloadStudyInfo(data) { + return request({ + url: '/DownloadAndUpload/getIRReadingDownloadStudyInfo', + method: 'post', + data + }) } \ No newline at end of file diff --git a/src/components/downloadDicomAndNonedicom/index.vue b/src/components/downloadDicomAndNonedicom/index.vue new file mode 100644 index 00000000..500dbc9a --- /dev/null +++ b/src/components/downloadDicomAndNonedicom/index.vue @@ -0,0 +1,382 @@ + + + \ No newline at end of file diff --git a/src/components/uploadDicomAndNonedicom/study-view.vue b/src/components/uploadDicomAndNonedicom/study-view.vue new file mode 100644 index 00000000..92f06b67 --- /dev/null +++ b/src/components/uploadDicomAndNonedicom/study-view.vue @@ -0,0 +1,131 @@ + + + \ No newline at end of file diff --git a/src/components/uploadImage/index.vue b/src/components/uploadImage/index.vue index 1d6d6067..d00de1f0 100644 --- a/src/components/uploadImage/index.vue +++ b/src/components/uploadImage/index.vue @@ -102,7 +102,6 @@ import uploadList from "./components/upload-list.vue"; import studyView from "./components/study-view.vue"; import { getSubjectImageUploadList, deleteTaskStudy } from "@/api/load.js"; -import { downloadImage } from "@/utils/uploadZip.js"; import store from "@/store"; export default { name: "uploadImage", @@ -591,7 +590,7 @@ export default { files.push(obj); } store.dispatch("trials/setUnLock", true); - let res = await downloadImage(zipName, files); + // let res = await downloadImage(zipName, files); store.dispatch("trials/setUnLock", false); }, }, diff --git a/src/utils/stream.js b/src/utils/stream.js index a812b259..1c74b6d3 100644 --- a/src/utils/stream.js +++ b/src/utils/stream.js @@ -1,9 +1,10 @@ import streamSaver from "streamsaver"; import "streamsaver/examples/zip-stream.js"; - +import store from '@/store' // 下载文件并压缩 function zipFiles(zipName, files) { console.log("同步下载打包开始时间:" + new Date()); + store.dispatch('trials/setUnLock', true) // 创建压缩文件输出流 const zipFileOutputStream = streamSaver.createWriteStream(zipName); // 创建下载文件流 @@ -28,15 +29,21 @@ function zipFiles(zipName, files) { // 开始下载 readableZipStream .pipeTo(zipFileOutputStream) - .then(() => console.log("同步下载打包结束时间:" + new Date())); + .then(() => { + console.log("同步下载打包结束时间:" + new Date()); + store.dispatch('trials/setUnLock', false) + }); } } // 下载文件并修改名称 async function updateFile(file, name) { try { + store.dispatch('trials/setUnLock', true) const fileOutputStream = streamSaver.createWriteStream(name); let res = await fetch(file); - res.body.pipeTo(fileOutputStream); + res.body.pipeTo(fileOutputStream).then(() => { + store.dispatch('trials/setUnLock', true) + }); } catch (err) { console.log(err) } diff --git a/src/utils/uploadZip.js b/src/utils/uploadZip.js deleted file mode 100644 index 71f813b9..00000000 --- a/src/utils/uploadZip.js +++ /dev/null @@ -1,168 +0,0 @@ -import Vue from 'vue'; -import store from "@/store"; -import { - requestPackageAndAnonymizImage, -} from "@/api/load.js"; -import streamSaver from "streamsaver"; -import "streamsaver/examples/zip-stream.js" -let flag = {}; -export const resetFlag = () => { - flag = {}; - store.state.trials.uploadTip = null; - if (store.state.trials.timer) { - clearInterval(store.state.trials.timer); - store.state.trials.timer = null; - } - store.dispatch("trials/setUnLock", false); -} -export const downloadImage = async (id, id2, IsDicom = true) => { - // if (flag[`${id2}_${IsDicom}`]) return Vue.prototype.$message.warning(Vue.prototype.$t('trials:upload:tip:uploading')); - if (flag[`${id2}_${IsDicom}`]) return false; - flag[`${id2}_${IsDicom}`] = true - try { - let params = { - TrialId: id, - SubjectVisitId: id2, - IsDicom: IsDicom - } - store.dispatch("trials/setUnLock", true); - let res = await requestPackageAndAnonymizImage(params); - if (res.IsSuccess) { - if (!res.Result) { - flag[`${id2}_${IsDicom}`] = false; - // Vue.prototype.$message.warning(Vue.prototype.$t("trials:upload:message:not")) - let message = Vue.prototype.$t('trials:upload:tip:uploading').replace("xxx", res.OtherInfo.FileName); - store.state.trials.uploadTip = message; - if (!store.state.trials.timer) { - store.state.trials.timer = setInterval(() => { - downloadImage(id, id2, IsDicom); - }, 2000); - } - return false; - } - if (store.state.trials.timer) { - clearInterval(store.state.trials.timer); - store.state.trials.timer = null; - } - let fileName = res.Result.split("/").pop(); - let href = Vue.prototype.OSSclientConfig.basePath + res.Result; - if (fileName !== res.OtherInfo.FileName) { - let message = Vue.prototype.$t('trials:upload:tip:uploading').replace("xxx", res.OtherInfo.FileName); - store.state.trials.uploadTip = message; - // Vue.prototype.$message.success(Vue.prototype.$t("trials:upload:message:startUpload")); - return download(href, res.OtherInfo.FileName, { id2, IsDicom }); - - } - let a = document.createElement("a"); - a.download = res.OtherInfo.FileName; - a.href = href; - a.click(); - URL.revokeObjectURL(href); - let timer = setTimeout(() => { - a = null; - href = null; - timer = null; - }, 500) - store.state.trials.uploadTip = null; - return true; - } else { - flag[`${id2}_${IsDicom}`] = false; - return false; - } - } catch (err) { - flag[`${id2}_${IsDicom}`] = false; - console.log(err); - } -}; -export const fileDownload = (content, filename) => { - const eleLink = document.createElement("a"); - eleLink.download = filename; - eleLink.style.display = "none"; - const blob = new Blob([content]); - eleLink.href = URL.createObjectURL(blob); - document.body.appendChild(eleLink); - eleLink.click(); - document.body.removeChild(eleLink); -}; -let download = async (downloadUrl, downloadFileName, res) => { - const blob = await getBlob(downloadUrl); - flag[`${res.id2}_${res.IsDicom}`] = false; - store.state.trials.uploadTip = null; - store.dispatch("trials/setUnLock", false); - saveAsB(blob, downloadFileName); - return true; -} - -let getBlob = (url) => { - return new Promise((resolve, reject) => { - const xhr = new XMLHttpRequest(); - - xhr.open('GET', url, true); - xhr.responseType = 'blob'; - xhr.onload = () => { - if (xhr.status === 200) { - resolve(xhr.response); - } else { - reject(new Error(`Request failed with status ${xhr.status}`)); - } - }; - xhr.onerror = () => { - reject(new Error('Request failed')); - }; - - xhr.send(); - }); -} - -let saveAsB = (blob, filename) => { - const link = document.createElement('a'); - const body = document.body; - - link.href = window.URL.createObjectURL(blob); - link.download = filename; - - // hide the link - link.style.display = 'none'; - body.appendChild(link); - - link.click(); - body.removeChild(link); - - window.URL.revokeObjectURL(link.href); -} - -// 前端流式打包下载 -const handleBatchDown = async (item, zip) => { - return new Promise((resolve) => { - console.log("同步下载打包开始时间:" + new Date()); - // 创建压缩文件输出流 - const zipFileOutputStream = streamSaver.createWriteStream(zipName); - // 创建下载文件流 - const fileIterator = files.values(); - const readableZipStream = new window.ZIP({ - async pull(ctrl) { - const fileInfo = fileIterator.next(); - if (fileInfo.done) {//迭代终止 - ctrl.close(); - } else { - const { name, url } = fileInfo.value; - return fetch(url).then(res => { - ctrl.enqueue({ - name, - stream: () => res.body - }) - }) - } - } - }); - if (window.WritableStream && readableZipStream.pipeTo) { - // 开始下载 - readableZipStream - .pipeTo(zipFileOutputStream) - .then(() => { console.log("同步下载打包结束时间:" + new Date()); resolve(true) }) - } else { - resolve(false); - } - }) - -}; diff --git a/src/views/trials/trials-panel/reading/reading-task/index.vue b/src/views/trials/trials-panel/reading/reading-task/index.vue index 1c828c19..f3564d0e 100644 --- a/src/views/trials/trials-panel/reading/reading-task/index.vue +++ b/src/views/trials/trials-panel/reading/reading-task/index.vue @@ -18,7 +18,7 @@ v-if=" (isReadingTaskViewInOrder === 1 || isReadingTaskViewInOrder === 2) && - TrialReadingCriterionId === item.TrialReadingCriterionId + TrialReadingCriterionId === item.TrialReadingCriterionId " >
@@ -41,7 +41,7 @@ icon="el-icon-search" @click="handleSearch" > - {{ $t("common:button:search") }} + {{ $t('common:button:search') }} - {{ $t("common:button:reset") }} + {{ $t('common:button:reset') }} @@ -75,10 +75,11 @@ scope.row.UrgentColor === 1 ? 'danger' : scope.row.UrgentColor === 2 - ? 'warning' - : 'primary' + ? 'warning' + : 'primary' " - >{{ $fd("YesOrNo", scope.row.IsUrgent) }} + >{{ $fd('YesOrNo', scope.row.IsUrgent) }} @@ -113,10 +114,11 @@ scope.row.UrgentColor === 1 ? '#F56C6C' : scope.row.UrgentColor === 2 - ? '#E6A23C' - : '#409EFF', + ? '#E6A23C' + : '#409EFF', }" - >{{ scope.row.UrgentCount }} + >{{ scope.row.UrgentCount }} @@ -130,7 +132,7 @@ sortable="custom" > @@ -248,48 +250,64 @@ :disabled=" randomReadInfo.UnReadTaskCount + randomReadInfo.UnReadJudgeTaskCount === - 0 + 0 " @click="handleOutOfOrderReading" > - {{ $t("trials:pendingReadingTasks:button:beginRandomReview") }} + {{ $t('trials:pendingReadingTasks:button:beginRandomReview') }}
- --> + + diff --git a/src/views/trials/trials-panel/subject/reading-period/components/AddOrEditCD.vue b/src/views/trials/trials-panel/subject/reading-period/components/AddOrEditCD.vue index 8d920ac1..2c87a977 100644 --- a/src/views/trials/trials-panel/subject/reading-period/components/AddOrEditCD.vue +++ b/src/views/trials/trials-panel/subject/reading-period/components/AddOrEditCD.vue @@ -34,7 +34,7 @@ type="text" @click="handleDownloadTpl" > - {{ $t("trials:readingPeriod:cd:title:downloadTpl") }} + {{ $t('trials:readingPeriod:cd:title:downloadTpl') }} @@ -53,7 +53,7 @@ " > - {{ $t("trials:uploadClinicalData:button:selectFile") }} + {{ $t('trials:uploadClinicalData:button:selectFile') }} {{ - $t("trials:attachment:message:pdf") + $t('trials:attachment:message:pdf') }} @@ -139,7 +139,7 @@ type="primary" @click="close" > - {{ $t("common:button:cancel") }} + {{ $t('common:button:cancel') }} - {{ $t("common:button:save") }} + {{ $t('common:button:save') }} @@ -159,23 +159,23 @@ import { getTrialClinicalDataSelect, addOrUpdateReadingClinicalData, addOrUpdateConsistencyAnalysisReadingClinicalData, -} from "@/api/trials"; -import { fileDownload } from "@/utils/uploadZip.js"; +} from '@/api/trials' +import { downLoadFile } from '@/utils/stream.js' export default { - name: "AddOrUpdateClinicalData", + name: 'AddOrUpdateClinicalData', props: { trialReadingCriterionId: { type: String, - default: "", + default: '', }, data: { type: Object, default() { - return {}; + return {} }, }, type: { - default: "readingPeriod", + default: 'readingPeriod', }, option: { default: () => [], @@ -185,13 +185,13 @@ export default { data() { return { fileList: [], - faccept: [".pdf"], + faccept: ['.pdf'], form: { - Id: "", - TrialId: "", - SubjectId: "", - ReadingId: "", - ClinicalDataTrialSetId: "", + Id: '', + TrialId: '', + SubjectId: '', + ReadingId: '', + ClinicalDataTrialSetId: '', IsVisist: true, AddFileList: [], DeleteFileIds: [], @@ -201,8 +201,8 @@ export default { ClinicalDataTrialSetId: [ { required: true, - message: this.$t("common:ruleMessage:select"), - trigger: ["blur", "change"], + message: this.$t('common:ruleMessage:select'), + trigger: ['blur', 'change'], }, ], }, @@ -211,194 +211,190 @@ export default { clinicalDatas: [], pendingUploadList: [], pendingDeleteList: [], - currentTpl: { id: "", isExist: false }, - }; + currentTpl: { id: '', isExist: false }, + } }, mounted() { - this.initForm(); + this.initForm() }, methods: { // 下载临床数据 handleUploadFile(row) { - let href = this.OSSclientConfig.basePath + row.Path; - let name = row.FileName; - fileDownload(href, name); + let href = this.OSSclientConfig.basePath + row.Path + let name = row.FileName + downLoadFile(href, name) }, async initForm() { - if (this.type === "readingPeriod") { - await this.getClinicalDatas(); + if (this.type === 'readingPeriod') { + await this.getClinicalDatas() } else { - this.clinicalDatas = this.option; + this.clinicalDatas = this.option } if (Object.keys(this.data).length > 0) { for (const k in this.form) { if (this.data.hasOwnProperty(k)) { - this.form[k] = this.data[k]; + this.form[k] = this.data[k] } } - this.handleClinicalDataSetChange(this.form.ClinicalDataTrialSetId); - this.fileList = this.form.FileList.concat(); + this.handleClinicalDataSetChange(this.form.ClinicalDataTrialSetId) + this.fileList = this.form.FileList.concat() } }, save() { this.$refs.clinicalDataForm.validate((valid) => { - if (!valid) return; + if (!valid) return if (this.fileList.length === 0) { // 请上传文件! - this.$alert(this.$t("trials:readingPeriod:cd:message:uploadFile")); - return; + this.$alert(this.$t('trials:readingPeriod:cd:message:uploadFile')) + return } - this.pendingUploadList = []; + this.pendingUploadList = [] for (let i = 0; i < this.fileList.length; ++i) { if (this.fileList[i].Status === 0) { - this.pendingUploadList.push(this.fileList[i].Files); + this.pendingUploadList.push(this.fileList[i].Files) } } if (this.pendingUploadList.length > 0) { - this.uploadFilesAndSave(); + this.uploadFilesAndSave() } else { - this.saveClinicalData(); + this.saveClinicalData() } - }); + }) }, uploadFilesAndSave() { return new Promise(async (resolve, reject) => { - this.form.AddFileList = []; + this.form.AddFileList = [] for (var i = 0; i < this.pendingUploadList.length; ++i) { // const file = await this.convertBase64ToBlob(this.pendingUploadList[i]) - const file = await this.fileToBlob(this.pendingUploadList[i]); + const file = await this.fileToBlob(this.pendingUploadList[i]) const res = await this.OSSclient.put( `/${this.data.TrialId}/ClinicalData/${this.pendingUploadList[i].name}`, file - ); + ) this.form.AddFileList.push({ fileName: this.pendingUploadList[i].name, path: this.$getObjectName(res.url), size: this.pendingUploadList[i].size, type: this.pendingUploadList[i].type, - }); + }) } - this.saveClinicalData(this.form.AddFileList); - resolve(); - }); + this.saveClinicalData(this.form.AddFileList) + resolve() + }) }, saveClinicalData() { return new Promise((resolve, reject) => { - this.btnLoading = true; - this.form.DeleteFileIds = this.pendingDeleteList; - if (this.type === "consistencyAnalysis") { + this.btnLoading = true + this.form.DeleteFileIds = this.pendingDeleteList + if (this.type === 'consistencyAnalysis') { addOrUpdateConsistencyAnalysisReadingClinicalData(this.form) .then((response) => { - this.btnLoading = false; - this.$emit("getList"); - this.$emit("close"); - this.$message.success( - this.$t("common:message:savedSuccessfully") - ); - resolve(); + this.btnLoading = false + this.$emit('getList') + this.$emit('close') + this.$message.success(this.$t('common:message:savedSuccessfully')) + resolve() }) .catch(() => { - this.btnLoading = false; - reject(); - }); + this.btnLoading = false + reject() + }) } else { addOrUpdateReadingClinicalData(this.form) .then((response) => { - this.btnLoading = false; - this.$emit("getList"); - this.$emit("close"); - this.$message.success( - this.$t("common:message:savedSuccessfully") - ); - resolve(); + this.btnLoading = false + this.$emit('getList') + this.$emit('close') + this.$message.success(this.$t('common:message:savedSuccessfully')) + resolve() }) .catch(() => { - this.btnLoading = false; - reject(); - }); + this.btnLoading = false + reject() + }) } - }); + }) }, getClinicalDatas() { return new Promise((resolve, reject) => { - this.loading = true; + this.loading = true var param = { trialId: this.data.TrialId, IsVisit: this.data.IsVisit, ReadingId: this.data.ReadingId, SubjectId: this.data.SubjectId, - ReadingClinicalDataId: this.data.Id ? this.data.Id : "", + ReadingClinicalDataId: this.data.Id ? this.data.Id : '', IsBaseLine: this.data.IsBaseLine, TrialReadingCriterionId: this.trialReadingCriterionId, - }; + } getTrialClinicalDataSelect(param) .then((res) => { - this.clinicalDatas = res.Result; - this.loading = false; - resolve(); + this.clinicalDatas = res.Result + this.loading = false + resolve() }) .catch(() => { - this.loading = false; - reject(); - }); - }); + this.loading = false + reject() + }) + }) }, handleDeleteFile(index, row) { - this.$confirm(this.$t("trials:readingPeriod:cd:message:delete"), { - type: "warning", + this.$confirm(this.$t('trials:readingPeriod:cd:message:delete'), { + type: 'warning', distinguishCancelAndClose: true, }) .then(() => { if (row.Id) { - this.pendingDeleteList.push(row.Id); + this.pendingDeleteList.push(row.Id) } - this.fileList.splice(index, 1); + this.fileList.splice(index, 1) }) - .catch(() => {}); + .catch(() => {}) }, beginScanFiles(e) { - var files = e.target.files; + var files = e.target.files for (var i = 0; i < files.length; ++i) { - const fileName = files[i].name; + const fileName = files[i].name var extendName = fileName - .substring(fileName.lastIndexOf(".")) - .toLocaleLowerCase(); + .substring(fileName.lastIndexOf('.')) + .toLocaleLowerCase() if (this.faccept.indexOf(extendName) !== -1) { this.fileList.push({ FileName: fileName, - Path: "", + Path: '', Status: 0, Files: files[i], size: files[i].size, - type: fileName.split(".")[1], - }); + type: fileName.split('.')[1], + }) } } }, handleClinicalDataSetChange(v) { - var index = this.clinicalDatas.findIndex((item) => item.Id === v); + var index = this.clinicalDatas.findIndex((item) => item.Id === v) if (index > -1) { - this.currentTpl.id = this.clinicalDatas[index].Id; - this.currentTpl.path = this.clinicalDatas[index].Path; - this.currentTpl.isExist = !!this.clinicalDatas[index].FileName; + this.currentTpl.id = this.clinicalDatas[index].Id + this.currentTpl.path = this.clinicalDatas[index].Path + this.currentTpl.isExist = !!this.clinicalDatas[index].FileName } }, handleDownloadTpl() { - this.loading = true; + this.loading = true window.open( this.OSSclientConfig.basePath + this.currentTpl.path, - "_blank" - ); - this.loading = false; + '_blank' + ) + this.loading = false // DownloadTrialClinicalFile(this.currentTpl.id).then(data => { // this.loading = false // }).catch(() => { this.loading = false }) }, close() { - this.$emit("close"); + this.$emit('close') }, }, -}; +} diff --git a/src/views/trials/trials-panel/visit/qc-check/components/qualityAssurance.vue b/src/views/trials/trials-panel/visit/qc-check/components/qualityAssurance.vue index 7349f1f0..c582c49d 100644 --- a/src/views/trials/trials-panel/visit/qc-check/components/qualityAssurance.vue +++ b/src/views/trials/trials-panel/visit/qc-check/components/qualityAssurance.vue @@ -1252,9 +1252,9 @@ import SignForm from '@/views/trials/components/newSignForm' import { getToken } from '@/utils/auth' import const_ from '@/const/sign-code' import uploadPetClinicalData from '@/views/trials/trials-panel/visit/crc-upload/components/uploadPetClinicalData.vue' -import { downloadImage, resetFlag } from '@/utils/uploadZip.js' import { downLoadFile } from '@/utils/stream.js' import { getCRCUploadedStudyInfo } from '@/api/load.js' +import store from '@/store' export default { name: 'QualityAssurance', components: { @@ -1392,7 +1392,7 @@ export default { if (this.open) { this.open.close() } - resetFlag() + store.dispatch('trials/setUnLock', false) }, methods: { // 选中dicom @@ -1452,7 +1452,10 @@ export default { let files = [], name = null if (type === 'dicom') { - name = `${data.SubjectCode}_${data.VisitName}_DICOM.zip` + name = `${data.SubjectCode}_${data.VisitName}_${this.$fd( + 'IsDicom', + true + )}.zip` let StudyList = data.StudyList StudyList.forEach((study) => { if (study.SeriesList.length > 0) { @@ -1461,7 +1464,12 @@ export default { series.InstanceList.forEach((instance) => { let fileName = instance.Path.split('/').pop() let obj = { - name: `${data.SubjectCode}_${data.VisitName}_DICOM/${study.StudyCode}_${study.StudyTime}_${series.Modality}/${fileName}`, + name: `${data.SubjectCode}_${data.VisitName}_${this.$fd( + 'IsDicom', + true + )}/${study.StudyCode}_${study.StudyTime}_${ + series.Modality + }/${fileName}`, path: this.OSSclientConfig.basePath + instance.Path, } files.push(obj) @@ -1472,7 +1480,10 @@ export default { }) } if (type === 'noneDicom') { - name = `${data.SubjectCode}_${data.VisitName}_非DICOM.zip` + name = `${data.SubjectCode}_${data.VisitName}_${this.$fd( + 'IsDicom', + false + )}.zip` let NoneDicomStudyList = data.NoneDicomStudyList // 单个zip包 if ( @@ -1490,7 +1501,12 @@ export default { if (study.FileList.length > 0) { study.FileList.forEach((item) => { let obj = { - name: `${data.SubjectCode}_${data.VisitName}_非DICOM/${study.StudyCode}_${study.ImageDate}_${study.Modality}/${item.FileName}`, + name: `${data.SubjectCode}_${data.VisitName}_${this.$fd( + 'IsDicom', + true + )}/${study.StudyCode}_${study.ImageDate}_${study.Modality}/${ + item.FileName + }`, url: this.OSSclientConfig.basePath + item.Path, } files.push(obj)