From b7f4cccbfa26ed03b3af320b0617f878f51d8271 Mon Sep 17 00:00:00 2001 From: wangxiaoshuang <825034831@qq.com> Date: Mon, 14 Jul 2025 16:07:27 +0800 Subject: [PATCH] =?UTF-8?q?=E5=9C=A8=E5=BD=B1=E5=83=8F=E4=B8=8A=E4=BC=A0?= =?UTF-8?q?=E3=80=81=E5=BD=B1=E5=83=8F=E8=B4=A8=E6=8E=A7=E8=AF=A5=E8=BF=87?= =?UTF-8?q?=E7=A8=8B=E7=9A=84=E5=BD=B1=E5=83=8F=E6=B5=8F=E8=A7=88=E9=A1=B5?= =?UTF-8?q?=E9=9D=A2=EF=BC=8C=E5=BD=B1=E5=83=8F=E9=98=85=E7=89=87=E4=BB=BB?= =?UTF-8?q?=E5=8A=A1=E9=A1=B5=E9=9D=A2=EF=BC=8C=E5=9C=A8=E5=BD=B1=E5=83=8F?= =?UTF-8?q?=E4=B8=BA=E5=8A=A0=E8=BD=BD=E5=89=8D=E7=9A=84=E4=B8=8B=E8=BD=BD?= =?UTF-8?q?=E8=BF=87=E7=A8=8B=EF=BC=8C=E9=9C=80=E8=A6=81=E5=B1=95=E7=A4=BA?= =?UTF-8?q?=E4=B8=8B=E8=BD=BD=E8=BF=87=E7=A8=8B=E6=95=B0=E6=8D=AE=EF=BC=8C?= =?UTF-8?q?=E5=8C=85=E6=8B=AC=E7=BD=91=E9=80=9F=E3=80=81=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E5=A4=A7=E5=B0=8F=E7=AD=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Dicom/DicomCanvas.vue | 7 +- src/store/modules/reading.js | 35 +- src/store/modules/trials.js | 1 + src/utils/index.js | 74 +++ src/views/dicom-show/dicom-study.vue | 324 +++++++------- src/views/dicom-show/dicom-visit.vue | 420 +++++++++--------- .../reading/dicoms/components/DicomCanvas.vue | 278 ++++++------ .../reading/dicoms/components/ReadPage.vue | 152 ++++--- .../dicoms/customize/CustomizeDicomCanvas.vue | 338 +++++++------- .../dicoms/customize/CustomizeReadPage.vue | 104 +++-- .../dicoms3D/components/PetCtViewport.vue | 13 +- .../reading/dicoms3D/components/ReadPage.vue | 12 + .../reading/dicoms3D/components/Viewport.vue | 15 +- vue.config.js | 1 + 14 files changed, 976 insertions(+), 798 deletions(-) diff --git a/src/components/Dicom/DicomCanvas.vue b/src/components/Dicom/DicomCanvas.vue index aec4d066..df5fa473 100644 --- a/src/components/Dicom/DicomCanvas.vue +++ b/src/components/Dicom/DicomCanvas.vue @@ -3,7 +3,7 @@ id="canvas" ref="canvas" v-loading="loading" - element-loading-text="Loading..." + :element-loading-text="NSTip" element-loading-background="rgba(0, 0, 0, 0.8)" style="width:100%;height:100%;position:relative;" class="cornerstone-element" @@ -121,6 +121,11 @@ import DicomTags from './DicomTags' export default { name: 'DicomCanvas', components: { DicomTags }, + computed: { + NSTip() { + return `${this.$store.state.trials.uploadSize},NS: ${this.$store.state.trials.uploadTip}` + } + }, data() { return { loading: false, diff --git a/src/store/modules/reading.js b/src/store/modules/reading.js index 73074d7f..42372f07 100644 --- a/src/store/modules/reading.js +++ b/src/store/modules/reading.js @@ -12,6 +12,7 @@ import { getCustomTag } from '@/api/reading' import requestPoolManager from '@/utils/request-pool' import { getReadingVisitStudyList } from '@/api/trials' +import { getNetWorkSpeed, setNetWorkSpeedSize, workSpeedclose } from "@/utils" const hangingAgreement = [ { name: 'A', row: 1, col: 1 }, { name: 'A|A', row: 1, col: 2 }, @@ -644,15 +645,15 @@ const actions = { resolve(noneDicomMeasureData) }) }, - addMeasuredData({ state }, obj) { + addMeasuredData({ state }, obj) { return new Promise(resolve => { const criterionType = parseInt(localStorage.getItem('CriterionType')) var index = state.visitTaskList.findIndex(i => i.VisitTaskId === obj.visitTaskId) var measureData = state.visitTaskList[index].MeasureData // var idx = measureData.findIndex(item => item.MeasureData.uuid === obj.data.MeasureData.data.uuid) - + if (criterionType === 21) { - let i = measureData.findIndex(i=>i.TableQuestionId === obj.data.TableQuestionId) + let i = measureData.findIndex(i => i.TableQuestionId === obj.data.TableQuestionId) if (i > -1) { for (const k in state.visitTaskList[index].MeasureData[i]) { if (k !== 'Id' && obj.data[k]) { @@ -676,7 +677,7 @@ const actions = { console.log('新增标记成功') } } - + // sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '') resolve() }) @@ -775,15 +776,15 @@ const actions = { const criterionType = parseInt(localStorage.getItem('CriterionType')) if (criterionType === 21) { const i = measureData.findIndex(item => item.QuestionId === obj.questionId && item.OrderMarkName === obj.orderMarkName) - if (i > -1) { - if (measureData[i].FristAddTaskId) { - measureData[i].MeasureData = '' - console.log('清除标记成功', i) - } else { - measureData.splice(i, 1) - console.log('移除标记成功', i) - } + if (i > -1) { + if (measureData[i].FristAddTaskId) { + measureData[i].MeasureData = '' + console.log('清除标记成功', i) + } else { + measureData.splice(i, 1) + console.log('移除标记成功', i) } + } state.visitTaskList[index].MeasureData = measureData } else { var idx = measureData.findIndex(item => item.QuestionId === obj.questionId && item.RowIndex === obj.rowIndex) @@ -810,7 +811,7 @@ const actions = { state.visitTaskList[index].MeasureData = measureData } } - + // if (idx > -1) { // measureData.splice(idx, 1) @@ -1072,16 +1073,22 @@ const actions = { } } } - + let file = series.instanceInfoList.find(item => item.ImageId === obj.imageId) + if (file) { + getNetWorkSpeed() + setNetWorkSpeedSize(obj.percentComplete, file.FileSize, obj.imageId) + } if (prefetchInstanceCount >= instanceCount * 100) { series.prefetchInstanceCount = instanceCount * 100 // 设置当前序列状态为已下载完成 series.loadStatus = true + workSpeedclose() } if (prefetchInstanceCount2 !== null && instanceCount2 !== null && prefetchInstanceCount2 >= instanceCount2 * 100) { pSeries.prefetchInstanceCount = instanceCount2 * 100 // 设置当前序列状态为已下载完成 pSeries.loadStatus = true + workSpeedclose() } } catch (e) { console.log('error') diff --git a/src/store/modules/trials.js b/src/store/modules/trials.js index cb52300b..47f88cf8 100644 --- a/src/store/modules/trials.js +++ b/src/store/modules/trials.js @@ -10,6 +10,7 @@ const getDefaultState = () => { unlock: false, config: {}, uploadTip: '0.00KB/s', + uploadSize: '', timer: null, whiteList: [], checkTaskId: null diff --git a/src/utils/index.js b/src/utils/index.js index caab2046..78bdbf9d 100644 --- a/src/utils/index.js +++ b/src/utils/index.js @@ -1,4 +1,5 @@ +import store from "@/store"; /** * Parse the time to string * @param {(Object|string|number)} time @@ -91,4 +92,77 @@ export function deepClone(source, map = new WeakMap()) { } return target; +} +export function formatSize(size, fixed = 2) { + if (isNaN(parseFloat(size))) return '' + let kbSize = size / 1024 + if (kbSize <= 1024) { + return `${kbSize.toFixed(fixed)}KB` + } + let mbSize = kbSize / 1024 + return `${mbSize.toFixed(fixed)}MB` +} + +let timer = null, // 网速定时器 + lastPercentage = 0, + imageId = null, + bytesReceivedPerSecond = {}; // 时间节点上传文件总量 +// 获取网速 +export function getNetWorkSpeed() { + if (timer) return false; + if (lastPercentage < 100) return false; + imageId = null + timer = setInterval(() => { + let timeList = Object.keys(bytesReceivedPerSecond).sort((a, b) => a - b); + if (timeList.length > 0) { + let totalBytes = timeList.reduce((sum, bytes) => sum + bytesReceivedPerSecond[bytes], 0) / (5 * 1024); + let unit = 'KB/s'; + if (totalBytes > 1024) { + totalBytes = totalBytes / 1024; + unit = "MB/s"; + } + store.state.trials.uploadTip = totalBytes.toFixed(3) + unit; + } + if (timeList.length >= 5) { + delete bytesReceivedPerSecond[timeList[0]] + } + let time = new Date().getTime(); + bytesReceivedPerSecond[time] = 0; + }, 1000) + +} +export function setNetWorkSpeedSize(totalPercentage, total, Id) { + if (imageId && imageId !== Id) return false + imageId = Id + let percentage = totalPercentage - lastPercentage + lastPercentage = totalPercentage + console.log(percentage, totalPercentage, total) + let time = new Date().getTime(); + let timeList = Object.keys(bytesReceivedPerSecond).sort((a, b) => a - b); + let bytesTime = timeList.find(item => time - item < 1000); + if (bytesTime) { + bytesReceivedPerSecond[bytesTime] += total * percentage; + } else { + // console.log("未查询到时间") + if (timeList.length > 0) { + bytesReceivedPerSecond[timeList[timeList.length - 1]] += total * percentage; + } else { + bytesReceivedPerSecond[time] = total * percentage; + } + } + store.state.trials.uploadSize = `${formatSize(totalPercentage / 100 * total)}/${formatSize(total)}` +} +export function workSpeedclose(isForce = false) { + if (!isForce && lastPercentage < 100) { + return false + } + if (timer) { + clearInterval(timer); + timer = null; + store.state.trials.uploadTip = '0KB/s' + store.state.trials.uploadSize = '' + } + bytesReceivedPerSecond = {}; + lastPercentage = 0; + imageId = null } \ No newline at end of file diff --git a/src/views/dicom-show/dicom-study.vue b/src/views/dicom-show/dicom-study.vue index 104ccbbc..e8f5b708 100644 --- a/src/views/dicom-show/dicom-study.vue +++ b/src/views/dicom-show/dicom-study.vue @@ -19,14 +19,9 @@
-
+ series-type="current" @click="showSeriesImage($event, index, item)">
- +
@@ -51,23 +40,17 @@ #{{ item.seriesNumber }}
- +
- +
-
+ :style="{ 'margin-bottom': idx < item.instanceInfoList.length - 1 ? '5px' : '0px' }" + @click="showMultiFrames(item, index, instance)">
{{ instance.InstanceNumber }}
@@ -75,22 +58,17 @@
{{ $t('trials:audit:table:isDelete') }} - + {{ $t('trials:audit:table:isReading') }} - +
- +
@@ -100,7 +78,8 @@
T: {{ parseFloat(item.sliceThickness).toFixed(2) }}
-
+
{{ item.description }}
@@ -109,27 +88,23 @@
-
+
- {{ $t('trials:audit:table:isReading') }} - + {{ $t('trials:audit:table:isReading') + }} +
{{ $t('trials:audit:table:isDelete') }} - +
-
- +
+
@@ -164,6 +139,7 @@ import requestPoolManager from '@/utils/request-pool' import store from '@/store' import { changeURLStatic } from '@/utils/history.js' import metaDataProvider from '@/utils/metaDataProvider' +import { getNetWorkSpeed, setNetWorkSpeedSize, workSpeedclose } from "@/utils" cornerstone.metaData.addProvider(metaDataProvider, { priority: 10 }) var config = { maxWebWorkers: 4, @@ -184,7 +160,7 @@ export default { 'dicom-viewer': dicomViewer }, - data: function() { + data: function () { return { trialId: '', studyId: '', @@ -219,7 +195,7 @@ export default { isFromCRCUpload: false } }, - created: function() { + created: function () { requestPoolManager.resetRequestPool() this.type = this.$router.currentRoute.query.type ? this.$router.currentRoute.query.type : '' @@ -256,6 +232,7 @@ export default { cornerstone.imageCache.purgeCache() requestPoolManager.resetRequestPool() }) + workSpeedclose(true) }, methods: { async loadStudy() { @@ -870,10 +847,16 @@ export default { this.seriesList[seriesIndex].imageloadedArr.push(imageId) } } + let file = this.seriesList[seriesIndex].instanceInfoList.find(item => item.ImageId === imageId) + if (file) { + getNetWorkSpeed() + setNetWorkSpeedSize(percentComplete, file.FileSize, imageId) + } if (prefetchInstanceCount >= instanceCount * 100) { this.seriesList[seriesIndex].prefetchInstanceCount = instanceCount * 100 // 设置当前序列状态为已下载完成 this.seriesList[seriesIndex].loadStatus = true + workSpeedclose() if (!this.isFromCRCUpload) { this.loadAllImages() } @@ -881,90 +864,102 @@ export default { } } } - } - diff --git a/src/views/trials/trials-panel/reading/dicoms/components/DicomCanvas.vue b/src/views/trials/trials-panel/reading/dicoms/components/DicomCanvas.vue index 3c8c1d09..2d7c400e 100644 --- a/src/views/trials/trials-panel/reading/dicoms/components/DicomCanvas.vue +++ b/src/views/trials/trials-panel/reading/dicoms/components/DicomCanvas.vue @@ -1,15 +1,7 @@ diff --git a/src/views/trials/trials-panel/reading/dicoms/components/ReadPage.vue b/src/views/trials/trials-panel/reading/dicoms/components/ReadPage.vue index 1a1c7adc..216123a0 100644 --- a/src/views/trials/trials-panel/reading/dicoms/components/ReadPage.vue +++ b/src/views/trials/trials-panel/reading/dicoms/components/ReadPage.vue @@ -7,14 +7,9 @@
-
{{ s.TaskBlindName }}
+
{{ + s.TaskBlindName }}
@@ -22,23 +17,12 @@
-
- +
+
@@ -46,20 +30,12 @@
- + :is-reading-task-view-in-order="isReadingTaskViewInOrder" :is-exists-manual="isExistsManual" + :iseCRFShowInDicomReading="iseCRFShowInDicomReading" @previewCD="previewCD" />
@@ -75,6 +51,7 @@ import { getToken } from '@/utils/auth' import { mapGetters } from 'vuex' import * as dicomParser from 'dicom-parser' import * as cornerstone from 'cornerstone-core' +import { workSpeedclose } from "@/utils" import * as cornerstoneWADOImageLoader from 'cornerstone-wado-image-loader' // import metaDataProvider from '@/utils/metaDataProvider' // cornerstone.metaData.addProvider(metaDataProvider, { priority: 10 }); @@ -248,6 +225,7 @@ export default { DicomEvent.$off('addNoneDicomMeasureData') DicomEvent.$off('selectSeries') window.removeEventListener('beforeunload', e => { cornerstone.imageCache.purgeCache() }) + workSpeedclose(true) }, methods: { async getVisitInfo() { @@ -474,7 +452,7 @@ export default { getSeriesInfoByMark(baseSeries, visitTaskId, obj, visitTaskIdx) { var seriesInfo = null if (obj) { - // 根据任务ID测量病灶信息 + // 根据任务ID测量病灶信息 var index = visitTaskIdx if (index > -1) { var idx = -1 @@ -497,7 +475,7 @@ export default { // var instanceIdx = series.instanceList.findIndex(imageId => !!~imageId.indexOf(instanceId)) const frame = this.visitTaskList[index].MeasureData[idx].MeasureData.frame // const filterStr = series.isExistMutiFrames ? `frame=${frame}&instanceId=${instanceId}` : `instanceId=${instanceId}` - let n = series.instanceInfoList.findIndex(k=>k.Id === instanceId) + let n = series.instanceInfoList.findIndex(k => k.Id === instanceId) let filterStr = '' if (n > -1 && series.isExistMutiFrames) { if (series.instanceInfoList[n].NumberOfFrames > 0) { @@ -532,19 +510,21 @@ export default { }, cornerstoneimageloadprogress(e) { const imageId = e.detail.imageId + console.log(imageId,'imageId') const params = {} const searchParams = new URLSearchParams(imageId.split('?')[1]) for (const [key, value] of searchParams.entries()) { params[key] = value } params.percentComplete = e.detail.percentComplete + params.imageId = imageId store.dispatch('reading/setImageLoadedProgress', params) } } } diff --git a/src/views/trials/trials-panel/reading/dicoms/customize/CustomizeReadPage.vue b/src/views/trials/trials-panel/reading/dicoms/customize/CustomizeReadPage.vue index aa24cf3a..c098ca0f 100644 --- a/src/views/trials/trials-panel/reading/dicoms/customize/CustomizeReadPage.vue +++ b/src/views/trials/trials-panel/reading/dicoms/customize/CustomizeReadPage.vue @@ -5,42 +5,22 @@