diff --git a/src/components/downloadDicomAndNonedicom/index.vue b/src/components/downloadDicomAndNonedicom/index.vue index 500dbc9a..659c5c40 100644 --- a/src/components/downloadDicomAndNonedicom/index.vue +++ b/src/components/downloadDicomAndNonedicom/index.vue @@ -243,7 +243,11 @@ export default { } if (type === 'dicom' || type === 'all') { this.list.forEach((item) => { - if (item.DicomStudyList && item.DicomStudyList.length > 0) { + if ( + item.IsDicom && + item.DicomStudyList && + item.DicomStudyList.length > 0 + ) { data.SubjectVisitIdList.push(item.SourceSubjectVisitId) let arr = item.DicomStudyList.map((d) => d.Id) data.DicomStudyIdList = [...data.DicomStudyIdList, ...arr] @@ -253,11 +257,12 @@ export default { if (type === 'noneDicom' || type === 'all') { this.list.forEach((item) => { if ( - item.NoneDicomStudyIdList && - item.NoneDicomStudyIdList.length > 0 + !item.IsDicom && + item.NoneDicomStudyList && + item.NoneDicomStudyList.length > 0 ) { data.SubjectVisitIdList.push(item.SourceSubjectVisitId) - let arr = item.NoneDicomStudyIdList.map((d) => d.Id) + let arr = item.NoneDicomStudyList.map((d) => d.Id) data.NoneDicomStudyIdList = [...data.NoneDicomStudyIdList, ...arr] } }) @@ -274,11 +279,11 @@ export default { } if ( !row.IsDicom && - row.NoneDicomStudyIdList && - row.NoneDicomStudyIdList.length > 0 + row.NoneDicomStudyList && + row.NoneDicomStudyList.length > 0 ) { data.SubjectVisitIdList.push(row.SourceSubjectVisitId) - let arr = row.NoneDicomStudyIdList.map((d) => d.Id) + let arr = row.NoneDicomStudyList.map((d) => d.Id) data.NoneDicomStudyIdList = [...data.NoneDicomStudyIdList, ...arr] } } @@ -319,7 +324,7 @@ export default { 'IsDicom', true )}/${study.StudyCode}/${fileName}`, - path: this.OSSclientConfig.basePath + instance.Path, + url: this.OSSclientConfig.basePath + instance.Path, } files.push(obj) }) diff --git a/src/utils/multipartUpload/aws.js b/src/utils/multipartUpload/aws.js index a2aec0b4..cac0d313 100644 --- a/src/utils/multipartUpload/aws.js +++ b/src/utils/multipartUpload/aws.js @@ -28,7 +28,7 @@ export async function exist(s3, bucket, fileInformation, progressFn, changeStatu // 设置每一片的大小,shardSize 指定上传的每个分片的大小,范围为100 KB~5 GB。 // 分片标准为5MB,文件总大小大于5GB分片为20MB let shardSize = 5 * 1024 * 1024; - if (uploadFileSize < partSize) { + if (uploadFileSize < shardSize) { shardSize = uploadFileSize; } if (uploadFileSize > 5 * 1024 * 1024 * 1024) { @@ -45,8 +45,8 @@ export async function exist(s3, bucket, fileInformation, progressFn, changeStatu //判断sharding里面是否有东西,有东西证明已经上传过分片了,不需要再进行检测 if (fileInformation.sharding.length === 0) { let existBucket = await existInBucket({ s3, bucket, fileInformation: fileInformation }); - console.log("existBucket", existBucket) if (existBucket === 'true') { + progressFn(0, fileInformation.file, 1); changeStatus(fileInformation.path, 'success');//直接告诉前端,状态 return; } else if (existBucket === 'same key') { @@ -183,7 +183,6 @@ async function existInBucket({ s3, bucket, fileInformation }) { } } let bucketFileBufferArray = new Uint8Array(bucketFileUniArray); - console.log("bucketFileBufferArray.buffer", bucketFileBufferArray.buffer) // 将传入文件的fileReader 转成 arrayBuffer let fileArrayBuff = null; fileArrayBuff = await new Promise((resolve) => { @@ -287,7 +286,6 @@ async function existUpload({ s3, bucket, fileInformation }) { //计算arrayBuffer的md5值 async function getMD5({ arrayBuffer }) { - console.log("arrayBuffer", arrayBuffer) return await new Promise((resolve) => { const spark = new SparkMD5.ArrayBuffer(); spark.append(arrayBuffer); diff --git a/src/utils/oss.js b/src/utils/oss.js index 7bd76414..9e461a8b 100644 --- a/src/utils/oss.js +++ b/src/utils/oss.js @@ -16,7 +16,9 @@ Vue.prototype.OSSclientConfig = { async function ossGenerateSTS() { let res = await GetObjectStoreToken() + // res.Result.ObjectStoreUse = 'AWS'; Vue.prototype.OSSclientConfig = { ...res.Result[res.Result.ObjectStoreUse] } + console.log(Vue.prototype.OSSclientConfig); Vue.prototype.OSSclientConfig.ObjectStoreUse = res.Result.ObjectStoreUse; Vue.prototype.OSSclientConfig.basePath = Vue.prototype.OSSclientConfig.viewEndpoint switch (res.Result.ObjectStoreUse) { @@ -26,19 +28,10 @@ async function ossGenerateSTS() { Vue.prototype.OSSclientConfig.timeout = 10 * 60 * 1000 let OSSclient = new OSS(Vue.prototype.OSSclientConfig) Vue.prototype.OSSclient = { - put: function (objectName, object) { + put: async function (objectName, object) { + OSSclient = await RefreshClient(OSSclient) return new Promise(async (resolve, reject) => { try { - let config = await getSTSToken(Vue.prototype.OSSclientConfig.Expiration); - if (config) { - Vue.prototype.OSSclientConfig = { ...config.Result[res.Result.ObjectStoreUse] } - Vue.prototype.OSSclientConfig.ObjectStoreUse = config.Result.ObjectStoreUse; - Vue.prototype.OSSclientConfig.basePath = Vue.prototype.OSSclientConfig.viewEndpoint; - Vue.prototype.OSSclientConfig.bucket = Vue.prototype.OSSclientConfig.bucketName - Vue.prototype.OSSclientConfig.stsToken = Vue.prototype.OSSclientConfig.securityToken - Vue.prototype.OSSclientConfig.timeout = 10 * 60 * 1000 - OSSclient = new OSS(Vue.prototype.OSSclientConfig); - } let _vm = router.default.app if (_vm._route.path !== '/trials/trials-panel/visit/crc-upload') { var objectItem = objectName.split('/') @@ -60,14 +53,16 @@ async function ossGenerateSTS() { } }) }, - multipartUpload: (data, progress) => { + multipartUpload: async (data, progress) => { + OSSclient = await RefreshClient(OSSclient) return new Promise(async (resolve, reject) => { try { const { file, path } = data; if (!file || !path) return reject('file and path be required'); - let config = await getSTSToken(Vue.prototype.OSSclientConfig.Expiration); + let config = await getSTSToken(Vue.prototype.OSSclientConfig.expiration); + console.log(config, 'config') if (config) { - Vue.prototype.OSSclientConfig = { ...config.Result[res.Result.ObjectStoreUse] } + Vue.prototype.OSSclientConfig = { ...config.Result[config.Result.ObjectStoreUse] } Vue.prototype.OSSclientConfig.ObjectStoreUse = config.Result.ObjectStoreUse; Vue.prototype.OSSclientConfig.basePath = Vue.prototype.OSSclientConfig.viewEndpoint; Vue.prototype.OSSclientConfig.bucket = Vue.prototype.OSSclientConfig.bucketName @@ -142,78 +137,32 @@ async function ossGenerateSTS() { } break case 'AWS': - let aws = new Minio.Client(Vue.prototype.OSSclientConfig); + Vue.prototype.OSSclientConfig.bucket = Vue.prototype.OSSclientConfig.bucketName + let aws = new S3Client({ + endpoint: Vue.prototype.OSSclientConfig.viewEndpoint, + region: Vue.prototype.OSSclientConfig.region, + s3ForcePathStyle: true, + signatureVersion: 'v4', + forcePathStyle: true, + // SessionToken: '', + credentials: { + accessKeyId: Vue.prototype.OSSclientConfig.accessKeyId, + secretAccessKey: Vue.prototype.OSSclientConfig.secretAccessKey, + sessionToken: Vue.prototype.OSSclientConfig.sessionToken + } + }); Vue.prototype.OSSclient = { - put: function (objectName, object) { - return new Promise(async (resolve, reject) => { - try { - var name = objectName.split('/')[objectName.split('/').length - 1] - let _vm = router.default.app - if (_vm._route.path !== '/trials/trials-panel/visit/crc-upload') { - var objectItem = objectName.split('/') - objectItem[objectItem.length - 1] = new Date().getTime() + '_' + objectItem[objectItem.length - 1] - objectName = objectItem.join('/') - } - const reader = new FileReader(); - reader.onload = (ex) => { - const bufferStream = new stream.PassThrough() - bufferStream.end(Buffer.from(ex.target.result)) - aws.putObject(Vue.prototype.OSSclientConfig.bucketName, objectName, bufferStream, function (err, etag) { - if (err) { - console.log(err) - reject() - } else { - console.log(objectName); - resolve({ - name: objectName, - url: Vue.prototype.OSSclientConfig.viewEndpoint + decodeUtf8(objectName) - }) - } - }) - }; - reader.readAsArrayBuffer(object); - } catch (e) { - console.log(e) - } - }) + put: async function (objectName, object) { + let data = { + file: object, + path: objectName + } + aws = await RefreshClient(aws); + return uploadAWS(aws, data, () => { }); }, - multipartUpload: (data, progress) => { - return new Promise(async (resolve, reject) => { - try { - const { file, path } = data; - if (!file || !path) return reject('file and path be required'); - let config = await getSTSToken(Vue.prototype.OSSclientConfig.Expiration); - if (config) { - Vue.prototype.OSSclientConfig = { ...config.Result[res.Result.ObjectStoreUse] } - Vue.prototype.OSSclientConfig.ObjectStoreUse = config.Result.ObjectStoreUse; - Vue.prototype.OSSclientConfig.basePath = Vue.prototype.OSSclientConfig.viewEndpoint; - Vue.prototype.OSSclientConfig.bucket = Vue.prototype.OSSclientConfig.bucketName - Vue.prototype.OSSclientConfig.stsToken = Vue.prototype.OSSclientConfig.securityToken - Vue.prototype.OSSclientConfig.timeout = 10 * 60 * 1000 - OSSclient = new S3Client(Vue.prototype.OSSclientConfig); - } - let _vm = router.default.app - if (_vm._route.path !== '/trials/trials-panel/visit/crc-upload') { - var objectItem = data.path.split('/') - objectItem[objectItem.length - 1] = new Date().getTime() + '_' + objectItem[objectItem.length - 1] - data.path = objectItem.join('/') - } - await exist(OSSclient, Vue.prototype.OSSclientConfig.bucket, data, progress, (res) => { - if (res) { - resolve({ - name: data.path, - url: Vue.prototype.OSSclientConfig.viewEndpoint + res.name - }) - } else { - reject() - } - }); - - } catch (err) { - console.log(err) - reject(err) - } - }) + multipartUpload: async (data, progress) => { + aws = await RefreshClient(aws); + return uploadAWS(aws, data, progress); }, close: () => { AWSclose(); @@ -222,6 +171,77 @@ async function ossGenerateSTS() { } return } +// AWS上传函数 +function uploadAWS(aws, data, progress) { + return new Promise(async (resolve, reject) => { + try { + const { file, path } = data; + if (!file || !path) return reject('file and path be required'); + let _vm = router.default.app + if (_vm._route.path !== '/trials/trials-panel/visit/crc-upload') { + var objectItem = data.path.split('/') + objectItem[objectItem.length - 1] = new Date().getTime() + '_' + objectItem[objectItem.length - 1] + data.path = objectItem.join('/') + } + await exist(aws, Vue.prototype.OSSclientConfig.bucket, data, progress, (path, status) => { + if (status === 'success') { + resolve({ + name: Vue.prototype.OSSclientConfig.bucket + "/" + decodeUtf8(path), + url: Vue.prototype.OSSclientConfig.viewEndpoint + Vue.prototype.OSSclientConfig.bucket + "/" + decodeUtf8(path) + }) + } else { + reject() + } + }); + + } catch (err) { + console.log(err) + reject(err) + } + }) +} +// client过期刷新 +async function RefreshClient(client) { + let config = await getSTSToken(Vue.prototype.OSSclientConfig.expiration); + if (config) { + // config.Result.ObjectStoreUse = 'AWS' + switch (config.Result.ObjectStoreUse) { + case 'AliyunOSS': { + Vue.prototype.OSSclientConfig = { ...config.Result[config.Result.ObjectStoreUse] } + Vue.prototype.OSSclientConfig.ObjectStoreUse = config.Result.ObjectStoreUse; + Vue.prototype.OSSclientConfig.basePath = Vue.prototype.OSSclientConfig.viewEndpoint; + Vue.prototype.OSSclientConfig.bucket = Vue.prototype.OSSclientConfig.bucketName + Vue.prototype.OSSclientConfig.stsToken = Vue.prototype.OSSclientConfig.securityToken + Vue.prototype.OSSclientConfig.timeout = 10 * 60 * 1000 + return new OSS(Vue.prototype.OSSclientConfig); + } + case "MinIO": { + return client; + } + case "AWS": { + Vue.prototype.OSSclientConfig = { ...config.Result[config.Result.ObjectStoreUse] } + Vue.prototype.OSSclientConfig.ObjectStoreUse = config.Result.ObjectStoreUse; + Vue.prototype.OSSclientConfig.basePath = Vue.prototype.OSSclientConfig.viewEndpoint; + Vue.prototype.OSSclientConfig.bucket = Vue.prototype.OSSclientConfig.bucketName + return new S3Client({ + endpoint: Vue.prototype.OSSclientConfig.viewEndpoint, + region: Vue.prototype.OSSclientConfig.region, + s3ForcePathStyle: true, + signatureVersion: 'v4', + forcePathStyle: true, + credentials: { + accessKeyId: Vue.prototype.OSSclientConfig.accessKeyId, + secretAccessKey: Vue.prototype.OSSclientConfig.secretAccessKey, + sessionToken: Vue.prototype.OSSclientConfig.sessionToken + } + }); + } + } + + } else { + return client; + } +} function decodeUtf8(bytes) { let str = bytes.split('?'); let str2 = str[0].split('/'); @@ -237,7 +257,7 @@ let loading = false; function getSTSToken(credentials) { return new Promise(async (resolve, reject) => { let isExpired = isCredentialsExpired(credentials); - if (!isExpired) { + if (isExpired) { if (loading) { queue.push({ resolve, reject }) } @@ -267,7 +287,7 @@ function isCredentialsExpired(credentials) { if (!credentials) { return true; } - const expireDate = new Date(credentials.Expiration); + const expireDate = new Date(credentials); const now = new Date(); // 如果有效期不足五分钟,视为过期。 return expireDate.getTime() - now.getTime() <= 300000; diff --git a/src/utils/stream.js b/src/utils/stream.js index 1c74b6d3..de27a281 100644 --- a/src/utils/stream.js +++ b/src/utils/stream.js @@ -15,8 +15,13 @@ function zipFiles(zipName, files) { if (fileInfo.done) {//迭代终止 ctrl.close(); } else { - const { name, url } = fileInfo.value; - return fetch(url).then(res => { + let { name, url } = fileInfo.value; + url = decodeUtf8(url); + return fetch(url, { + headers: { + 'Cross-Origin-Embedder-Policy': 'unsafe-none' + } + }).then(res => { ctrl.enqueue({ name, stream: () => res.body @@ -40,7 +45,12 @@ async function updateFile(file, name) { try { store.dispatch('trials/setUnLock', true) const fileOutputStream = streamSaver.createWriteStream(name); - let res = await fetch(file); + file = decodeUtf8(file); + let res = await fetch(file, { + headers: { + 'Cross-Origin-Embedder-Policy': 'unsafe-none' + } + }); res.body.pipeTo(fileOutputStream).then(() => { store.dispatch('trials/setUnLock', true) }); @@ -48,6 +58,15 @@ async function updateFile(file, name) { console.log(err) } } +function decodeUtf8(bytes) { + let str = bytes.split('?'); + let str2 = str[0].split('/'); + let name = str2[str2.length - 1]; + name = encodeURIComponent(name); + str.shift(); + str2.pop(); + return str2.join("/") + '/' + name; +} export function downLoadFile(file, name, type = 'file') { if (type === 'zip') return zipFiles(name, file); return updateFile(file, name) diff --git a/src/views/trials/trials-panel/visit/crc-upload/components/uploadDicomFiles2.vue b/src/views/trials/trials-panel/visit/crc-upload/components/uploadDicomFiles2.vue index d00b004b..89f0f8d2 100644 --- a/src/views/trials/trials-panel/visit/crc-upload/components/uploadDicomFiles2.vue +++ b/src/views/trials/trials-panel/visit/crc-upload/components/uploadDicomFiles2.vue @@ -885,6 +885,8 @@ export default { petVisible: false, studyData: [], BodyPart: {}, + + isClose: false, } }, watch: { @@ -908,6 +910,7 @@ export default { }) this.myInterval = [] store.dispatch('trials/setUnLock', false) + this.isClose = true this.OSSclient.close() }, methods: { @@ -1678,6 +1681,7 @@ export default { o.instanceUid + params.trialId )}` + if (scope.isClose) return let res = await dcmUpload( { path: path, @@ -1762,7 +1766,10 @@ export default { }) })() ) - if (arr.length >= 10 || ii === v.instanceList.length - 1) { + if ( + (arr.length >= 10 || ii === v.instanceList.length - 1) && + !scope.isClose + ) { await Promise.all(arr) arr = [] } @@ -1834,6 +1841,7 @@ export default { if (logRes && logRes.url) { params.study.instanceCount = dicomInfo.failedFileCount params.RecordPath = scope.$getObjectName(logRes.url) + if (scope.isClose) return false console.log(params) addOrUpdateArchiveStudy(params) .then((res) => { 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 c582c49d..408326c0 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 @@ -1470,7 +1470,7 @@ export default { )}/${study.StudyCode}_${study.StudyTime}_${ series.Modality }/${fileName}`, - path: this.OSSclientConfig.basePath + instance.Path, + url: this.OSSclientConfig.basePath + instance.Path, } files.push(obj) })