在影像上传、影像质控该过程的影像浏览页面,影像阅片任务页面,在影像为加载前的下载过程,需要展示下载过程数据,包括网速、文件大小等
continuous-integration/drone/push Build encountered an error
Details
continuous-integration/drone/push Build encountered an error
Details
parent
62a92ea7c9
commit
b7f4cccbfa
|
@ -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,
|
||||
|
|
|
@ -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')
|
||||
|
|
|
@ -10,6 +10,7 @@ const getDefaultState = () => {
|
|||
unlock: false,
|
||||
config: {},
|
||||
uploadTip: '0.00KB/s',
|
||||
uploadSize: '',
|
||||
timer: null,
|
||||
whiteList: [],
|
||||
checkTaskId: null
|
||||
|
|
|
@ -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
|
||||
}
|
|
@ -19,14 +19,9 @@
|
|||
</div>
|
||||
<div class="viewerSidethumbs ps" style="position: relative;">
|
||||
<div class="viewerSidethumbinner">
|
||||
<div
|
||||
v-for="(item, index) in seriesList"
|
||||
:key="index"
|
||||
:class="{'viewerSideActive': index==0}"
|
||||
<div v-for="(item, index) in seriesList" :key="index" :class="{ 'viewerSideActive': index == 0 }"
|
||||
style="position: relative;margin-bottom:5px;border-radius: 2px;border: 1px solid #404040;"
|
||||
series-type="current"
|
||||
@click="showSeriesImage($event,index,item)"
|
||||
>
|
||||
series-type="current" @click="showSeriesImage($event, index, item)">
|
||||
<div class="viewernavigatorwrapper">
|
||||
<!-- <el-image
|
||||
class="image-preview"
|
||||
|
@ -34,14 +29,8 @@
|
|||
:src="item.previewImageUrl"
|
||||
fit="fill"
|
||||
/> -->
|
||||
<img
|
||||
class="image-preview"
|
||||
:src="item.previewImageUrl"
|
||||
crossorigin="anonymous"
|
||||
alt=""
|
||||
style="width: 72px;height:72px;"
|
||||
fit="fill"
|
||||
>
|
||||
<img class="image-preview" :src="item.previewImageUrl" crossorigin="anonymous" alt=""
|
||||
style="width: 72px;height:72px;" fit="fill">
|
||||
<div class="viewernavitextwrapper">
|
||||
<div style="padding: 1px 5px 1px 1px;display: flex;justify-content: space-between;">
|
||||
<div v-if="item.keySeries" style="color:red">
|
||||
|
@ -51,23 +40,17 @@
|
|||
#{{ item.seriesNumber }}
|
||||
</div>
|
||||
<div v-if="item.isExistMutiFrames && item.instanceCount > 1">
|
||||
<el-popover
|
||||
v-model="item.isShowPopper"
|
||||
placement="right-start"
|
||||
trigger="manual"
|
||||
popper-class="instance_frame_wrapper"
|
||||
>
|
||||
<el-popover v-model="item.isShowPopper" placement="right-start" trigger="manual"
|
||||
popper-class="instance_frame_wrapper">
|
||||
<div style="text-align: right;">
|
||||
<i class="el-icon-circle-close" style="font-size: 20px;cursor: pointer;color:#ddd;" @click="item.isShowPopper = false" />
|
||||
<i class="el-icon-circle-close" style="font-size: 20px;cursor: pointer;color:#ddd;"
|
||||
@click="item.isShowPopper = false" />
|
||||
</div>
|
||||
<div class="frame_list">
|
||||
<div
|
||||
v-for="(instance, idx) in item.instanceInfoList"
|
||||
:key="instance.Id"
|
||||
<div v-for="(instance, idx) in item.instanceInfoList" :key="instance.Id"
|
||||
class="frame_content"
|
||||
:style="{'margin-bottom':idx<item.instanceInfoList.length-1? '5px':'0px'}"
|
||||
@click="showMultiFrames(item, index, instance)"
|
||||
>
|
||||
:style="{ 'margin-bottom': idx < item.instanceInfoList.length - 1 ? '5px' : '0px' }"
|
||||
@click="showMultiFrames(item, index, instance)">
|
||||
<div>
|
||||
<div>{{ instance.InstanceNumber }}</div>
|
||||
<div>
|
||||
|
@ -75,22 +58,17 @@
|
|||
</div>
|
||||
<div v-if="showDelete">
|
||||
<span>{{ $t('trials:audit:table:isDelete') }}</span>
|
||||
<el-switch
|
||||
v-model="instance.IsDeleted"
|
||||
size="mini"
|
||||
@change="changeInstanceDeleteStatus($event, item, instance)"
|
||||
/>
|
||||
<el-switch v-model="instance.IsDeleted" size="mini"
|
||||
@change="changeInstanceDeleteStatus($event, item, instance)" />
|
||||
<span style="margin-left:10px;">{{ $t('trials:audit:table:isReading') }}</span>
|
||||
<el-switch
|
||||
v-model="instance.IsReading"
|
||||
size="mini"
|
||||
@change="changeInstanceReadingStatus($event, item, instance)"
|
||||
/>
|
||||
<el-switch v-model="instance.IsReading" size="mini"
|
||||
@change="changeInstanceReadingStatus($event, item, instance)" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<i slot="reference" class="el-icon-connection" style="font-size: 15px;cursor: pointer;" @click="popperClick(seriesList, item)" />
|
||||
<i slot="reference" class="el-icon-connection" style="font-size: 15px;cursor: pointer;"
|
||||
@click="popperClick(seriesList, item)" />
|
||||
</el-popover>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -100,7 +78,8 @@
|
|||
<div v-show="!item.keySeries && item.sliceThickness" style="padding: 1px;">
|
||||
T: {{ parseFloat(item.sliceThickness).toFixed(2) }}
|
||||
</div>
|
||||
<div v-show="!item.keySeries &&item.description" style="width: 120px;white-space: nowrap;overflow: hidden;text-overflow: ellipsis;padding: 1x;">
|
||||
<div v-show="!item.keySeries && item.description"
|
||||
style="width: 120px;white-space: nowrap;overflow: hidden;text-overflow: ellipsis;padding: 1x;">
|
||||
{{ item.description }}
|
||||
</div>
|
||||
<div v-if="!item.keySeries" style="padding: 1px;">
|
||||
|
@ -109,27 +88,23 @@
|
|||
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="showDelete" style="display: flex;flex-direction: row;justify-content: space-between;" @click.stop="">
|
||||
<div v-if="showDelete" style="display: flex;flex-direction: row;justify-content: space-between;"
|
||||
@click.stop="">
|
||||
|
||||
<div>
|
||||
<span style="font-size: 12px;margin-right: 5px">{{ $t('trials:audit:table:isReading') }}</span>
|
||||
<el-switch
|
||||
v-model="item.isReading"
|
||||
size="mini"
|
||||
@change="changeReadingStatus($event, item)"
|
||||
/>
|
||||
<span style="font-size: 12px;margin-right: 5px">{{ $t('trials:audit:table:isReading')
|
||||
}}</span>
|
||||
<el-switch v-model="item.isReading" size="mini" @change="changeReadingStatus($event, item)" />
|
||||
</div>
|
||||
<div>
|
||||
<span style="font-size: 12px;margin-right: 5px">{{ $t('trials:audit:table:isDelete') }}</span>
|
||||
<el-switch
|
||||
v-model="item.isDeleted"
|
||||
size="mini"
|
||||
@change="changeDeleteStatus($event, item)"
|
||||
/>
|
||||
<el-switch v-model="item.isDeleted" size="mini" @change="changeDeleteStatus($event, item)" />
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="item.prefetchInstanceCount>0 && item.prefetchInstanceCount<item.instanceCount * 100">
|
||||
<el-progress :percentage="parseInt((item.prefetchInstanceCount/item.instanceCount).toFixed(2))" />
|
||||
<div
|
||||
v-if="item.prefetchInstanceCount > 0 && item.prefetchInstanceCount < item.instanceCount * 100">
|
||||
<el-progress
|
||||
:percentage="parseInt((item.prefetchInstanceCount / item.instanceCount).toFixed(2))" />
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
@ -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 {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.viewerContainer .el-tabs--border-card{
|
||||
background:none;
|
||||
.viewerContainer .el-tabs--border-card {
|
||||
background: none;
|
||||
border: none;
|
||||
}
|
||||
.viewerContainer .el-tabs__item{
|
||||
|
||||
.viewerContainer .el-tabs__item {
|
||||
height: 35px;
|
||||
line-height: 35px;
|
||||
}
|
||||
.viewerContainer .el-tabs--border-card>.el-tabs__content{
|
||||
|
||||
.viewerContainer .el-tabs--border-card>.el-tabs__content {
|
||||
padding: 5px 0px 0px 0px;
|
||||
}
|
||||
|
||||
.viewerContainer ::-webkit-scrollbar {
|
||||
width: 7px;
|
||||
height: 7px;
|
||||
width: 7px;
|
||||
height: 7px;
|
||||
}
|
||||
|
||||
.viewerContainer ::-webkit-scrollbar-thumb {
|
||||
border-radius: 10px;
|
||||
background: #d0d0d0;
|
||||
border-radius: 10px;
|
||||
background: #d0d0d0;
|
||||
}
|
||||
.viewerContainer .relationVisit{
|
||||
|
||||
.viewerContainer .relationVisit {
|
||||
line-height: 20px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.viewerContainer{
|
||||
display: block;
|
||||
height: 100%;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
background-color: #444;
|
||||
overflow: hidden;
|
||||
}
|
||||
.viewerContainer .viewerBanner {
|
||||
background: linear-gradient(0,#444,#222);
|
||||
min-height: 28px;
|
||||
font-size: 16px;
|
||||
margin: 0;
|
||||
height: 30px;
|
||||
padding-top: 0;
|
||||
padding-left: 5px;
|
||||
padding-right: 5px;
|
||||
font-weight: bold;
|
||||
|
||||
.viewerContainer {
|
||||
display: block;
|
||||
height: 100%;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
background-color: #444;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.viewerContainer .viewerBanner {
|
||||
background: linear-gradient(0, #444, #222);
|
||||
min-height: 28px;
|
||||
font-size: 16px;
|
||||
margin: 0;
|
||||
height: 30px;
|
||||
padding-top: 0;
|
||||
padding-left: 5px;
|
||||
padding-right: 5px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.viewerContainer .viewerContentWrapper {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
width: 100%;
|
||||
padding: 5px;
|
||||
/* height: 95%; */
|
||||
height: 99%;
|
||||
overflow: hidden;
|
||||
text-overflow: clip;
|
||||
white-space: nowrap;
|
||||
width: 100%;
|
||||
padding: 5px;
|
||||
/* height: 95%; */
|
||||
height: 99%;
|
||||
overflow: hidden;
|
||||
text-overflow: clip;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.viewerContainer .viewerContentWrapper>div {
|
||||
display: inline-block;
|
||||
white-space: normal;
|
||||
display: inline-block;
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
.viewerContainer .viewerLeftSidePanel {
|
||||
width: 215px;
|
||||
background-color: #323232;
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
margin-right: 2px;
|
||||
color: #D0D0D0;
|
||||
overflow-y: auto;
|
||||
width: 215px;
|
||||
background-color: #323232;
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
margin-right: 2px;
|
||||
color: #D0D0D0;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.viewerContainer .viewerContentWrapper>div>.sidePanelBody {
|
||||
background: rgba(50,50,50,1);
|
||||
word-break: break-all;
|
||||
display: table;
|
||||
width: 100%;
|
||||
border: 1px solid #3e3f3a;
|
||||
background: rgba(50, 50, 50, 1);
|
||||
word-break: break-all;
|
||||
display: table;
|
||||
width: 100%;
|
||||
border: 1px solid #3e3f3a;
|
||||
}
|
||||
|
||||
.viewerContainer .viewerContentWrapper>div>div.sidePanelBody>div {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
.viewerContainer .studyDesc{
|
||||
|
||||
.viewerContainer .studyDesc {
|
||||
font-weight: bold;
|
||||
font-size: 13px;
|
||||
text-align: center;
|
||||
|
@ -972,81 +967,96 @@ export default {
|
|||
color: #d0d0d0;
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
.viewerContainer .ps {
|
||||
overflow: hidden !important;
|
||||
overflow-anchor: none;
|
||||
-ms-overflow-style: none;
|
||||
touch-action: auto;
|
||||
-ms-touch-action: auto;
|
||||
overflow: hidden !important;
|
||||
overflow-anchor: none;
|
||||
-ms-overflow-style: none;
|
||||
touch-action: auto;
|
||||
-ms-touch-action: auto;
|
||||
}
|
||||
|
||||
.viewerContainer .viewerLeftSidePanel .viewernavigatorwrapper {
|
||||
display: flex;
|
||||
width: 200px;
|
||||
height: 84px;
|
||||
padding: 1px 2px 1px 8px;
|
||||
margin: 6px 0 6px 1px;
|
||||
/* border-radius: 2px;
|
||||
display: flex;
|
||||
width: 200px;
|
||||
height: 84px;
|
||||
padding: 1px 2px 1px 8px;
|
||||
margin: 6px 0 6px 1px;
|
||||
/* border-radius: 2px;
|
||||
border: 1px solid #404040; */
|
||||
}
|
||||
.viewerContainer .viewernavigatorwrapper .el-progress__text{
|
||||
|
||||
.viewerContainer .viewernavigatorwrapper .el-progress__text {
|
||||
display: none;
|
||||
}
|
||||
.viewerContainer .viewernavigatorwrapper .el-progress-bar{
|
||||
padding-right:0px;
|
||||
}
|
||||
.viewerContainer .ui-draggable-handle {
|
||||
-ms-touch-action: none;
|
||||
touch-action: none;
|
||||
}
|
||||
.viewerContainer .viewerLeftSidePanel .image-preview {
|
||||
border: 2px solid #252525;
|
||||
cursor: pointer;
|
||||
}
|
||||
.viewerContainer .viewerLeftSidePanel .viewernavitextwrapper {
|
||||
/* width: 120px;
|
||||
height: 80px; */
|
||||
flex:1;
|
||||
padding: 3px 1px 3px 4px;
|
||||
vertical-align: top;
|
||||
font-size: 12px;
|
||||
}
|
||||
.viewerContainer .viewerLeftSidePanel .viewerlabelwrapper {
|
||||
width: 20px;
|
||||
|
||||
font-size: 12px;
|
||||
.viewerContainer .viewernavigatorwrapper .el-progress-bar {
|
||||
padding-right: 0px;
|
||||
}
|
||||
|
||||
.viewerContainer .ui-draggable-handle {
|
||||
-ms-touch-action: none;
|
||||
touch-action: none;
|
||||
}
|
||||
|
||||
.viewerContainer .viewerLeftSidePanel .image-preview {
|
||||
border: 2px solid #252525;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.viewerContainer .viewerLeftSidePanel .viewernavitextwrapper {
|
||||
/* width: 120px;
|
||||
height: 80px; */
|
||||
flex: 1;
|
||||
padding: 3px 1px 3px 4px;
|
||||
vertical-align: top;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.viewerContainer .viewerLeftSidePanel .viewerlabelwrapper {
|
||||
width: 20px;
|
||||
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.viewerContainer .viewerSideActive {
|
||||
background: #16477b;
|
||||
background: #16477b80;
|
||||
border: 1px solid #23527b;
|
||||
background: #16477b;
|
||||
background: #16477b80;
|
||||
border: 1px solid #23527b;
|
||||
}
|
||||
|
||||
.viewerContainer .viewerContent {
|
||||
flex: 1;
|
||||
height: 100%;
|
||||
display: block;
|
||||
background-color: black;
|
||||
color: #D0D0D0;
|
||||
font-size: 13px;
|
||||
flex: 1;
|
||||
height: 100%;
|
||||
display: block;
|
||||
background-color: black;
|
||||
color: #D0D0D0;
|
||||
font-size: 13px;
|
||||
}
|
||||
.instance_frame_wrapper{
|
||||
|
||||
.instance_frame_wrapper {
|
||||
min-width: 120px;
|
||||
background-color: #2c2c2c;
|
||||
border: 1px solid #2c2c2c;
|
||||
padding: 5px;
|
||||
}
|
||||
.frame_list{
|
||||
|
||||
.frame_list {
|
||||
max-height: 500px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.instance_frame_wrapper ::-webkit-scrollbar {
|
||||
width: 7px;
|
||||
height: 7px;
|
||||
}
|
||||
.instance_frame_wrapper ::-webkit-scrollbar-thumb {
|
||||
|
||||
.instance_frame_wrapper ::-webkit-scrollbar-thumb {
|
||||
border-radius: 10px;
|
||||
background: #d0d0d0;
|
||||
}
|
||||
.frame_content{
|
||||
|
||||
.frame_content {
|
||||
/* height: 50px; */
|
||||
padding: 10px;
|
||||
display: flex;
|
||||
|
@ -1055,6 +1065,7 @@ export default {
|
|||
font-size: 12px;
|
||||
border: 1px solid #404040;
|
||||
}
|
||||
|
||||
.frame_content:hover {
|
||||
/* font-weight: bold; */
|
||||
/* box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1); */
|
||||
|
@ -1063,6 +1074,7 @@ export default {
|
|||
border-color: #213a54 !important;
|
||||
background-color: #213a54;
|
||||
}
|
||||
|
||||
/* .viewerRightSidePanel {
|
||||
width: 300px;
|
||||
height: 100%;
|
||||
|
|
|
@ -16,7 +16,8 @@
|
|||
:key="index"
|
||||
> -->
|
||||
<el-collapse v-model="activeNames">
|
||||
<el-collapse-item v-for="(study, index) in studyList" :key="`${study.StudyId}`" :name="`${study.StudyId}`">
|
||||
<el-collapse-item v-for="(study, index) in studyList" :key="`${study.StudyId}`"
|
||||
:name="`${study.StudyId}`">
|
||||
<template slot="title">
|
||||
|
||||
<div class="text-desc">
|
||||
|
@ -25,8 +26,10 @@
|
|||
<!-- <div v-show="study.Description" class="text-desc">
|
||||
{{ study.Description }}
|
||||
</div> -->
|
||||
<el-tooltip v-show="study.Description" class="item" effect="dark" :content="study.Description" placement="bottom">
|
||||
<div v-show="study.Description" style="width: 50px;white-space: nowrap;overflow: hidden;text-overflow: ellipsis;padding: 1x;">
|
||||
<el-tooltip v-show="study.Description" class="item" effect="dark" :content="study.Description"
|
||||
placement="bottom">
|
||||
<div v-show="study.Description"
|
||||
style="width: 50px;white-space: nowrap;overflow: hidden;text-overflow: ellipsis;padding: 1x;">
|
||||
{{ study.Description }}
|
||||
</div>
|
||||
</el-tooltip>
|
||||
|
@ -37,44 +40,29 @@
|
|||
<div v-show="study.Description" class="text-desc" style="background-color: #1f1f1f;">
|
||||
{{ study.Description }}
|
||||
</div>
|
||||
<div
|
||||
v-for="(series, i) in study.SeriesList"
|
||||
:key="i"
|
||||
:class="{'viewerSideActive': i==0 && index === 0}"
|
||||
<div v-for="(series, i) in study.SeriesList" :key="i"
|
||||
:class="{ 'viewerSideActive': i == 0 && index === 0 }"
|
||||
style="position: relative;margin-bottom:5px;border-radius: 2px;border: 1px solid #404040;"
|
||||
series-type="current"
|
||||
@click="showSeriesImage($event,index,i,series)"
|
||||
>
|
||||
series-type="current" @click="showSeriesImage($event, index, i, series)">
|
||||
<div class="viewernavigatorwrapper">
|
||||
<img
|
||||
class="image-preview"
|
||||
:src="series.previewImageUrl"
|
||||
crossorigin="anonymous"
|
||||
alt=""
|
||||
style="width: 85px;height:85px;"
|
||||
fit="fill"
|
||||
>
|
||||
<img class="image-preview" :src="series.previewImageUrl" crossorigin="anonymous" alt=""
|
||||
style="width: 85px;height:85px;" fit="fill">
|
||||
<div class="viewernavitextwrapper">
|
||||
<div style="padding: 1px 5px 1px 1px;display: flex;justify-content: space-between;">
|
||||
<div>#{{ series.seriesNumber }}</div>
|
||||
<div v-if="series.isExistMutiFrames && series.instanceCount > 1">
|
||||
<el-popover
|
||||
v-model="series.isShowPopper"
|
||||
placement="right-start"
|
||||
trigger="manual"
|
||||
popper-class="instance_frame_wrapper"
|
||||
>
|
||||
<el-popover v-model="series.isShowPopper" placement="right-start" trigger="manual"
|
||||
popper-class="instance_frame_wrapper">
|
||||
<div style="text-align: right;">
|
||||
<i class="el-icon-circle-close" style="font-size: 20px;cursor: pointer;color:#ddd;" @click="series.isShowPopper = false" />
|
||||
<i class="el-icon-circle-close"
|
||||
style="font-size: 20px;cursor: pointer;color:#ddd;"
|
||||
@click="series.isShowPopper = false" />
|
||||
</div>
|
||||
<div class="frame_list">
|
||||
<div
|
||||
v-for="(instance, idx) in series.instanceInfoList"
|
||||
:key="instance.Id"
|
||||
<div v-for="(instance, idx) in series.instanceInfoList" :key="instance.Id"
|
||||
class="frame_content"
|
||||
:style="{'margin-bottom':idx<series.instanceInfoList.length-1? '5px':'0px'}"
|
||||
@click="showMultiFrames(index,series, i, instance)"
|
||||
>
|
||||
:style="{ 'margin-bottom': idx < series.instanceInfoList.length - 1 ? '5px' : '0px' }"
|
||||
@click="showMultiFrames(index, series, i, instance)">
|
||||
<!-- <div>
|
||||
<img
|
||||
class="image-preview"
|
||||
|
@ -92,23 +80,20 @@
|
|||
</div>
|
||||
<div v-if="showDelete">
|
||||
<span>{{ $t('trials:audit:table:isDelete') }}</span>
|
||||
<el-switch
|
||||
v-model="instance.IsDeleted"
|
||||
size="mini"
|
||||
@change="changeInstanceDeleteStatus($event, series, instance)"
|
||||
/>
|
||||
<span style="margin-left:10px;">{{ $t('trials:audit:table:isReading') }}</span>
|
||||
<el-switch
|
||||
v-model="instance.IsReading"
|
||||
size="mini"
|
||||
@change="changeInstanceReadingStatus($event, series, instance)"
|
||||
/>
|
||||
<el-switch v-model="instance.IsDeleted" size="mini"
|
||||
@change="changeInstanceDeleteStatus($event, series, instance)" />
|
||||
<span style="margin-left:10px;">{{ $t('trials:audit:table:isReading')
|
||||
}}</span>
|
||||
<el-switch v-model="instance.IsReading" size="mini"
|
||||
@change="changeInstanceReadingStatus($event, series, instance)" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<i slot="reference" class="el-icon-connection" style="font-size: 15px;cursor: pointer;" @click="popperClick(studyList, series)" />
|
||||
<i slot="reference" class="el-icon-connection"
|
||||
style="font-size: 15px;cursor: pointer;"
|
||||
@click="popperClick(studyList, series)" />
|
||||
</el-popover>
|
||||
</div>
|
||||
|
||||
|
@ -116,12 +101,14 @@
|
|||
<div v-show="series.InstanceCount" style="padding: 1px;">
|
||||
{{ series.modality }}: {{ series.instanceCount }} image
|
||||
</div>
|
||||
<div v-show=" series.sliceThickness" style="padding: 1px;">
|
||||
<div v-show="series.sliceThickness" style="padding: 1px;">
|
||||
T: {{ series.sliceThickness }}
|
||||
</div>
|
||||
|
||||
<el-tooltip v-show="series.description" class="item" effect="dark" :content="series.description" placement="bottom">
|
||||
<div v-show="series.description" style="width: 120px;white-space: nowrap;overflow: hidden;text-overflow: ellipsis;padding: 1x;">
|
||||
<el-tooltip v-show="series.description" class="item" effect="dark"
|
||||
:content="series.description" placement="bottom">
|
||||
<div v-show="series.description"
|
||||
style="width: 120px;white-space: nowrap;overflow: hidden;text-overflow: ellipsis;padding: 1x;">
|
||||
{{ series.description }}
|
||||
</div>
|
||||
</el-tooltip>
|
||||
|
@ -131,30 +118,27 @@
|
|||
<div />
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="showDelete" style="display: flex;flex-direction: row;justify-content: space-between;" @click.stop="">
|
||||
<div v-if="showDelete"
|
||||
style="display: flex;flex-direction: row;justify-content: space-between;" @click.stop="">
|
||||
|
||||
<div>
|
||||
<span style="font-size: 12px;">{{ $t('trials:audit:table:isReading') }}</span>
|
||||
<el-switch
|
||||
v-model="series.isReading"
|
||||
size="mini"
|
||||
@change="changeReadingStatus($event, series)"
|
||||
/>
|
||||
<el-switch v-model="series.isReading" size="mini"
|
||||
@change="changeReadingStatus($event, series)" />
|
||||
</div>
|
||||
<div>
|
||||
<span style="font-size: 12px;">{{ $t('trials:audit:table:isDelete') }}</span>
|
||||
<el-switch
|
||||
v-model="series.isDeleted"
|
||||
size="mini"
|
||||
@change="changeDeleteStatus($event, series)"
|
||||
/>
|
||||
<el-switch v-model="series.isDeleted" size="mini"
|
||||
@change="changeDeleteStatus($event, series)" />
|
||||
</div>
|
||||
</div>
|
||||
<!-- <div style="position: absolute;bottom: -10px;left: 0;width: 100%;">
|
||||
<el-progress v-if="series.prefetchInstanceCount>0 && series.prefetchInstanceCount<series.instanceCount" :percentage="Number(series.prefetchInstanceCount/series.instanceCount)*100" />
|
||||
</div> -->
|
||||
<div v-if="series.prefetchInstanceCount>0 && series.prefetchInstanceCount<series.instanceCount * 100">
|
||||
<el-progress :percentage="parseInt((series.prefetchInstanceCount/series.instanceCount).toFixed(2))" />
|
||||
<div
|
||||
v-if="series.prefetchInstanceCount > 0 && series.prefetchInstanceCount < series.instanceCount * 100">
|
||||
<el-progress
|
||||
:percentage="parseInt((series.prefetchInstanceCount / series.instanceCount).toFixed(2))" />
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
@ -165,10 +149,12 @@
|
|||
</div>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane v-if="!visitTaskId" :label="$t('trials:dicom-show:relatedVisit')" name="relation-study" class="pane-relation-wrapper">
|
||||
<el-tab-pane v-if="!visitTaskId" :label="$t('trials:dicom-show:relatedVisit')" name="relation-study"
|
||||
class="pane-relation-wrapper">
|
||||
<div class="viewerSidethumbinner">
|
||||
<el-collapse v-model="relationActiveName" @change="handelRelationActiveChange">
|
||||
<el-collapse-item v-for="(study,studyIndex) in relationStudyList" :key="`${study.StudyId}`" :name="`${study.StudyId}`">
|
||||
<el-collapse-item v-for="(study, studyIndex) in relationStudyList" :key="`${study.StudyId}`"
|
||||
:name="`${study.StudyId}`">
|
||||
<template slot="title">
|
||||
|
||||
<div class="text-desc">
|
||||
|
@ -187,28 +173,18 @@
|
|||
</div>
|
||||
<div v-if="study.seriesList" class="viewerSidethumbs ps" style="position: relative;">
|
||||
<div class="viewerSidethumbinner">
|
||||
<div
|
||||
v-for="(seriesItem, index) in study.seriesList"
|
||||
:key="index"
|
||||
class="viewernavigatorwrapper"
|
||||
style="position: relative;border:1px solid #434343;"
|
||||
<div v-for="(seriesItem, index) in study.seriesList" :key="index"
|
||||
class="viewernavigatorwrapper" style="position: relative;border:1px solid #434343;"
|
||||
series-type="relation"
|
||||
@click="showRelationSeriesImage($event,seriesItem,studyIndex,index)"
|
||||
>
|
||||
@click="showRelationSeriesImage($event, seriesItem, studyIndex, index)">
|
||||
<!-- <el-image
|
||||
class="image-preview"
|
||||
style="height:72px;width:72px;"
|
||||
:src="seriesItem.previewImageUrl"
|
||||
fit="fill"
|
||||
/> -->
|
||||
<img
|
||||
class="image-preview"
|
||||
:src="seriesItem.previewImageUrl"
|
||||
crossorigin="anonymous"
|
||||
alt=""
|
||||
style="width: 85px;height:85px;"
|
||||
fit="fill"
|
||||
>
|
||||
<img class="image-preview" :src="seriesItem.previewImageUrl" crossorigin="anonymous" alt=""
|
||||
style="width: 85px;height:85px;" fit="fill">
|
||||
|
||||
<div class="viewernavitextwrapper">
|
||||
<div style="padding: 1px 5px 1px 1px;display: flex;justify-content: space-between;">
|
||||
|
@ -217,27 +193,23 @@
|
|||
</div>
|
||||
<div v-else>#{{ seriesItem.seriesNumber }}</div>
|
||||
<div v-if="seriesItem.isExistMutiFrames && seriesItem.instanceCount > 1">
|
||||
<el-popover
|
||||
placement="right-start"
|
||||
trigger="click"
|
||||
popper-class="instance_frame_wrapper"
|
||||
>
|
||||
<el-popover placement="right-start" trigger="click"
|
||||
popper-class="instance_frame_wrapper">
|
||||
<div class="frame_list">
|
||||
<div
|
||||
v-for="(instance, idx) in seriesItem.instanceInfoList"
|
||||
:key="instance.Id"
|
||||
<div v-for="(instance, idx) in seriesItem.instanceInfoList" :key="instance.Id"
|
||||
class="frame_content"
|
||||
:style="{'margin-bottom':idx<seriesItem.instanceInfoList.length-1? '5px':'0px'}"
|
||||
@click="showMultiFrames(studyIndex,seriesItem, index, instance)"
|
||||
>
|
||||
:style="{ 'margin-bottom': idx < seriesItem.instanceInfoList.length - 1 ? '5px' : '0px' }"
|
||||
@click="showMultiFrames(studyIndex, seriesItem, index, instance)">
|
||||
<div>
|
||||
<div>{{ instance.InstanceNumber }}</div>
|
||||
<div>{{ `${instance.NumberOfFrames > 0 ? instance.NumberOfFrames : 1} frame` }}</div>
|
||||
<div>{{ `${instance.NumberOfFrames > 0 ? instance.NumberOfFrames : 1} frame`
|
||||
}}</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<i slot="reference" class="el-icon-connection" style="font-size: 15px;cursor: pointer;" />
|
||||
<i slot="reference" class="el-icon-connection"
|
||||
style="font-size: 15px;cursor: pointer;" />
|
||||
</el-popover>
|
||||
</div>
|
||||
|
||||
|
@ -248,13 +220,15 @@
|
|||
<div v-show="seriesItem.sliceThickness" style="padding: 1px;">
|
||||
T: {{ seriesItem.sliceThickness }}
|
||||
</div>
|
||||
<el-tooltip v-show="seriesItem.description" class="item" effect="dark" :content="seriesItem.description" placement="bottom">
|
||||
<div v-show="seriesItem.description" style="width: 120px;white-space: nowrap;overflow: hidden;text-overflow: ellipsis;padding: 1x;">
|
||||
<el-tooltip v-show="seriesItem.description" class="item" effect="dark"
|
||||
:content="seriesItem.description" placement="bottom">
|
||||
<div v-show="seriesItem.description"
|
||||
style="width: 120px;white-space: nowrap;overflow: hidden;text-overflow: ellipsis;padding: 1x;">
|
||||
{{ seriesItem.description }}
|
||||
</div>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
<!-- <div style="position: absolute;bottom: -10px;left: 0;width: 100%;">
|
||||
<!-- <div style="position: absolute;bottom: -10px;left: 0;width: 100%;">
|
||||
<el-progress v-if="seriesItem.prefetchInstanceCount>0 && seriesItem.prefetchInstanceCount<seriesItem.instanceCount" :percentage="Number(seriesItem.prefetchInstanceCount/seriesItem.instanceCount)*100" />
|
||||
</div> -->
|
||||
</div>
|
||||
|
@ -287,6 +261,7 @@ import { getTaskUploadedDicomStudyList } from '@/api/reading'
|
|||
import requestPoolManager from '@/utils/request-pool'
|
||||
import store from '@/store'
|
||||
import { changeURLStatic } from '@/utils/history.js'
|
||||
import { getNetWorkSpeed, setNetWorkSpeedSize, workSpeedclose } from "@/utils"
|
||||
import metaDataProvider from '@/utils/metaDataProvider'
|
||||
cornerstone.metaData.addProvider(metaDataProvider, { priority: 10 })
|
||||
// import * as cornerstoneTools from 'cornerstone-tools'
|
||||
|
@ -361,6 +336,7 @@ export default {
|
|||
cornerstone.imageCache.purgeCache()
|
||||
requestPoolManager.resetRequestPool()
|
||||
})
|
||||
workSpeedclose(true)
|
||||
},
|
||||
methods: {
|
||||
// 获取某个访视下所有的检查信息
|
||||
|
@ -887,6 +863,11 @@ export default {
|
|||
series.imageloadedArr.push(imageId)
|
||||
}
|
||||
}
|
||||
let file = this.studyList[studyIndex].SeriesList[seriesIndex].instanceInfoList.find(item => item.ImageId === imageId)
|
||||
if (file) {
|
||||
getNetWorkSpeed()
|
||||
setNetWorkSpeedSize(percentComplete, file.FileSize, imageId)
|
||||
}
|
||||
if (prefetchInstanceCount >= instanceCount * 100) {
|
||||
series.prefetchInstanceCount = instanceCount * 100
|
||||
// 设置当前序列状态为已下载完成
|
||||
|
@ -894,96 +875,110 @@ export default {
|
|||
if (!this.isFromCRCUpload) {
|
||||
this.loadAllImages()
|
||||
}
|
||||
workSpeedclose()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style >
|
||||
.viewerContainer .el-tabs--border-card{
|
||||
background:none;
|
||||
<style>
|
||||
.viewerContainer .el-tabs--border-card {
|
||||
background: none;
|
||||
border: none;
|
||||
}
|
||||
.viewerContainer .el-tabs__item{
|
||||
|
||||
.viewerContainer .el-tabs__item {
|
||||
height: 35px;
|
||||
line-height: 35px;
|
||||
width: 100px;
|
||||
padding: 0!important;
|
||||
padding: 0 !important;
|
||||
text-align: center;
|
||||
transform: scale(.8);
|
||||
}
|
||||
.viewerContainer .el-tabs--border-card>.el-tabs__content{
|
||||
|
||||
.viewerContainer .el-tabs--border-card>.el-tabs__content {
|
||||
padding: 5px 0px 0px 0px;
|
||||
}
|
||||
|
||||
.viewerContainer ::-webkit-scrollbar {
|
||||
width: 7px;
|
||||
height: 7px;
|
||||
width: 7px;
|
||||
height: 7px;
|
||||
}
|
||||
|
||||
.viewerContainer ::-webkit-scrollbar-thumb {
|
||||
border-radius: 10px;
|
||||
background: #d0d0d0;
|
||||
border-radius: 10px;
|
||||
background: #d0d0d0;
|
||||
}
|
||||
.viewerContainer .relationVisit{
|
||||
|
||||
.viewerContainer .relationVisit {
|
||||
line-height: 20px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.viewerContainer{
|
||||
display: block;
|
||||
height: 100%;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
background-color: #444;
|
||||
overflow: hidden;
|
||||
}
|
||||
.viewerContainer .viewerBanner {
|
||||
background: linear-gradient(0,#444,#222);
|
||||
min-height: 28px;
|
||||
font-size: 16px;
|
||||
margin: 0;
|
||||
height: 30px;
|
||||
padding-top: 0;
|
||||
padding-left: 5px;
|
||||
padding-right: 5px;
|
||||
font-weight: bold;
|
||||
|
||||
.viewerContainer {
|
||||
display: block;
|
||||
height: 100%;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
background-color: #444;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.viewerContainer .viewerBanner {
|
||||
background: linear-gradient(0, #444, #222);
|
||||
min-height: 28px;
|
||||
font-size: 16px;
|
||||
margin: 0;
|
||||
height: 30px;
|
||||
padding-top: 0;
|
||||
padding-left: 5px;
|
||||
padding-right: 5px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.viewerContainer .viewerContentWrapper {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
width: 100%;
|
||||
padding: 5px;
|
||||
/* height: 95%; */
|
||||
height: 99%;
|
||||
/* overflow: hidden;
|
||||
width: 100%;
|
||||
padding: 5px;
|
||||
/* height: 95%; */
|
||||
height: 99%;
|
||||
/* overflow: hidden;
|
||||
text-overflow: clip; */
|
||||
/* white-space: nowrap; */
|
||||
/* white-space: nowrap; */
|
||||
}
|
||||
|
||||
.viewerContainer .viewerContentWrapper>div {
|
||||
display: inline-block;
|
||||
white-space: normal;
|
||||
display: inline-block;
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
.viewerContainer .viewerLeftSidePanel {
|
||||
width: 220px;
|
||||
background-color: #323232;
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
margin-right: 2px;
|
||||
color: #D0D0D0;
|
||||
overflow-y: auto;
|
||||
width: 220px;
|
||||
background-color: #323232;
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
margin-right: 2px;
|
||||
color: #D0D0D0;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.viewerContainer .viewerContentWrapper>div>.sidePanelBody {
|
||||
background: rgba(50,50,50,1);
|
||||
word-break: break-all;
|
||||
display: table;
|
||||
width: 100%;
|
||||
border: 1px solid #3e3f3a;
|
||||
background: rgba(50, 50, 50, 1);
|
||||
word-break: break-all;
|
||||
display: table;
|
||||
width: 100%;
|
||||
border: 1px solid #3e3f3a;
|
||||
}
|
||||
|
||||
.viewerContainer .viewerContentWrapper>div>div.sidePanelBody>div {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
.viewerContainer .text-desc{
|
||||
|
||||
.viewerContainer .text-desc {
|
||||
font-weight: bold;
|
||||
font-size: 13px;
|
||||
text-align: center;
|
||||
|
@ -991,107 +986,126 @@ export default {
|
|||
color: #d0d0d0;
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
.viewerContainer .ps {
|
||||
overflow: hidden !important;
|
||||
overflow-anchor: none;
|
||||
-ms-overflow-style: none;
|
||||
touch-action: auto;
|
||||
-ms-touch-action: auto;
|
||||
overflow: hidden !important;
|
||||
overflow-anchor: none;
|
||||
-ms-overflow-style: none;
|
||||
touch-action: auto;
|
||||
-ms-touch-action: auto;
|
||||
}
|
||||
|
||||
.viewerContainer .viewerLeftSidePanel .viewernavigatorwrapper {
|
||||
display: flex;
|
||||
width: 220px;
|
||||
/* height: 84px; */
|
||||
padding: 1px 2px 1px 2px;
|
||||
margin: 2px 0 1px 1px;
|
||||
/* border-radius: 2px;
|
||||
display: flex;
|
||||
width: 220px;
|
||||
/* height: 84px; */
|
||||
padding: 1px 2px 1px 2px;
|
||||
margin: 2px 0 1px 1px;
|
||||
/* border-radius: 2px;
|
||||
border: 1px solid #404040; */
|
||||
|
||||
}
|
||||
.viewerContainer .viewernavigatorwrapper .el-progress__text{
|
||||
|
||||
.viewerContainer .viewernavigatorwrapper .el-progress__text {
|
||||
display: none;
|
||||
}
|
||||
.viewerContainer .viewernavigatorwrapper .el-progress-bar{
|
||||
padding-right:0px;
|
||||
}
|
||||
.viewerContainer .ui-draggable-handle {
|
||||
-ms-touch-action: none;
|
||||
touch-action: none;
|
||||
}
|
||||
.viewerContainer .viewerLeftSidePanel .image-preview {
|
||||
border: 2px solid #252525;
|
||||
cursor: pointer;
|
||||
}
|
||||
.viewerContainer .viewerLeftSidePanel .viewernavitextwrapper {
|
||||
/* width: 120px;
|
||||
height: 80px; */
|
||||
flex:1;
|
||||
padding: 3px 1px 3px 4px;
|
||||
vertical-align: top;
|
||||
font-size: 12px;
|
||||
}
|
||||
.viewerContainer .viewerLeftSidePanel .viewerlabelwrapper {
|
||||
width: 20px;
|
||||
|
||||
font-size: 12px;
|
||||
.viewerContainer .viewernavigatorwrapper .el-progress-bar {
|
||||
padding-right: 0px;
|
||||
}
|
||||
|
||||
.viewerContainer .ui-draggable-handle {
|
||||
-ms-touch-action: none;
|
||||
touch-action: none;
|
||||
}
|
||||
|
||||
.viewerContainer .viewerLeftSidePanel .image-preview {
|
||||
border: 2px solid #252525;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.viewerContainer .viewerLeftSidePanel .viewernavitextwrapper {
|
||||
/* width: 120px;
|
||||
height: 80px; */
|
||||
flex: 1;
|
||||
padding: 3px 1px 3px 4px;
|
||||
vertical-align: top;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.viewerContainer .viewerLeftSidePanel .viewerlabelwrapper {
|
||||
width: 20px;
|
||||
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.viewerContainer .viewerSideActive {
|
||||
background: #16477b;
|
||||
background: #16477b80;
|
||||
border: 1px solid #23527b;
|
||||
background: #16477b;
|
||||
background: #16477b80;
|
||||
border: 1px solid #23527b;
|
||||
}
|
||||
|
||||
.viewerContainer .viewerContent {
|
||||
flex: 1;
|
||||
height: 100%;
|
||||
display: block;
|
||||
background-color: black;
|
||||
color: #D0D0D0;
|
||||
font-size: 13px;
|
||||
flex: 1;
|
||||
height: 100%;
|
||||
display: block;
|
||||
background-color: black;
|
||||
color: #D0D0D0;
|
||||
font-size: 13px;
|
||||
}
|
||||
.viewerContainer .pane-relation-wrapper{
|
||||
|
||||
.viewerContainer .pane-relation-wrapper {
|
||||
min-height: 500px;
|
||||
}
|
||||
.viewerContainer .el-collapse{
|
||||
|
||||
.viewerContainer .el-collapse {
|
||||
border: none;
|
||||
}
|
||||
|
||||
.viewerContainer .el-collapse-item{
|
||||
background-color: #585453!important;
|
||||
.viewerContainer .el-collapse-item {
|
||||
background-color: #585453 !important;
|
||||
color: #ddd;
|
||||
|
||||
}
|
||||
.viewerContainer .el-collapse-item__content{
|
||||
padding-bottom:5px;
|
||||
background-color: #2c2c2c!important;
|
||||
|
||||
.viewerContainer .el-collapse-item__content {
|
||||
padding-bottom: 5px;
|
||||
background-color: #2c2c2c !important;
|
||||
color: #ddd;
|
||||
}
|
||||
.viewerContainer .el-collapse-item__header{
|
||||
background-color: #585453!important;
|
||||
|
||||
.viewerContainer .el-collapse-item__header {
|
||||
background-color: #585453 !important;
|
||||
color: #ddd;
|
||||
border-bottom-color:#5a5a5a;
|
||||
border-bottom-color: #5a5a5a;
|
||||
padding-left: 5px;
|
||||
height: 40px;
|
||||
line-height: 20px;
|
||||
}
|
||||
.instance_frame_wrapper{
|
||||
|
||||
.instance_frame_wrapper {
|
||||
min-width: 120px;
|
||||
background-color: #2c2c2c;
|
||||
border: 1px solid #2c2c2c;
|
||||
padding: 5px;
|
||||
}
|
||||
.frame_list{
|
||||
|
||||
.frame_list {
|
||||
max-height: 500px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.instance_frame_wrapper ::-webkit-scrollbar {
|
||||
width: 7px;
|
||||
height: 7px;
|
||||
}
|
||||
.instance_frame_wrapper ::-webkit-scrollbar-thumb {
|
||||
|
||||
.instance_frame_wrapper ::-webkit-scrollbar-thumb {
|
||||
border-radius: 10px;
|
||||
background: #d0d0d0;
|
||||
}
|
||||
.frame_content{
|
||||
|
||||
.frame_content {
|
||||
/* height: 50px; */
|
||||
padding: 10px;
|
||||
display: flex;
|
||||
|
@ -1100,6 +1114,7 @@ export default {
|
|||
font-size: 12px;
|
||||
border: 1px solid #404040;
|
||||
}
|
||||
|
||||
.frame_content:hover {
|
||||
/* font-weight: bold; */
|
||||
/* box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1); */
|
||||
|
@ -1121,4 +1136,3 @@ export default {
|
|||
font-size: 13px;
|
||||
} */
|
||||
</style>
|
||||
|
||||
|
|
|
@ -1,15 +1,7 @@
|
|||
<template>
|
||||
<div
|
||||
id="canvas"
|
||||
ref="canvas"
|
||||
v-loading="loading"
|
||||
element-loading-text="Loading..."
|
||||
element-loading-background="rgba(0, 0, 0, 0.8)"
|
||||
style="position:relative;"
|
||||
class="cornerstone-element"
|
||||
@mouseup="sliderMouseup"
|
||||
@contextmenu.prevent="onContextmenu"
|
||||
>
|
||||
<div id="canvas" ref="canvas" v-loading="loading" :element-loading-text="NSTip"
|
||||
element-loading-background="rgba(0, 0, 0, 0.8)" style="position:relative;" class="cornerstone-element"
|
||||
@mouseup="sliderMouseup" @contextmenu.prevent="onContextmenu">
|
||||
<!-- 临床数据 -->
|
||||
<div v-if="stack.isExistsClinicalData" class="info-cd" @click.stop="handleViewCD($event)">
|
||||
<el-tooltip class="item" effect="dark" :content="$t('trials:reading:button:clinicalData')" placement="bottom">
|
||||
|
@ -18,46 +10,39 @@
|
|||
|
||||
</div>
|
||||
<!-- 切换访视 -->
|
||||
<div
|
||||
v-if="stack.imageRendered && isReadingTaskViewInOrder === 1"
|
||||
class="info-visit"
|
||||
@dblclick.stop="preventDefault($event)"
|
||||
>
|
||||
<div
|
||||
class="arrw_div_wrapper"
|
||||
:style="{cursor:stack.visitTaskNum <= minVistNum?'not-allowed':'pointer',color:stack.visitTaskNum <= minVistNum?'#888':'#fff'}"
|
||||
@click.stop.prevent="toggleSeries($event,-1)"
|
||||
@dblclick.stop="preventDefault($event)"
|
||||
>
|
||||
<div v-if="stack.imageRendered && isReadingTaskViewInOrder === 1" class="info-visit"
|
||||
@dblclick.stop="preventDefault($event)">
|
||||
<div class="arrw_div_wrapper"
|
||||
:style="{ cursor: stack.visitTaskNum <= minVistNum ? 'not-allowed' : 'pointer', color: stack.visitTaskNum <= minVistNum ? '#888' : '#fff' }"
|
||||
@click.stop.prevent="toggleSeries($event, -1)" @dblclick.stop="preventDefault($event)">
|
||||
<i class="el-icon-caret-left" />
|
||||
</div>
|
||||
<div class="blind_name_wrapper">
|
||||
{{ stack.taskBlindName }}
|
||||
</div>
|
||||
<div
|
||||
class="arrw_div_wrapper"
|
||||
:style="{cursor:stack.visitTaskNum >= maxVistNum?'not-allowed':'pointer',color:stack.visitTaskNum >= maxVistNum?'#888':'#fff'}"
|
||||
@click.stop.prevent="toggleSeries($event,1)"
|
||||
@dblclick.stop="preventDefault($event)"
|
||||
>
|
||||
<div class="arrw_div_wrapper"
|
||||
:style="{ cursor: stack.visitTaskNum >= maxVistNum ? 'not-allowed' : 'pointer', color: stack.visitTaskNum >= maxVistNum ? '#888' : '#fff' }"
|
||||
@click.stop.prevent="toggleSeries($event, 1)" @dblclick.stop="preventDefault($event)">
|
||||
<i class="el-icon-caret-right" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="info-series">
|
||||
<h2 v-if="isReadingShowSubjectInfo" style="color:#f44336;padding: 5px 0px;margin: 0;">{{ subjectCode }} {{ stack.taskBlindName }}</h2>
|
||||
<h2 v-if="isReadingShowSubjectInfo" style="color:#f44336;padding: 5px 0px;margin: 0;">{{ subjectCode }} {{
|
||||
stack.taskBlindName }}</h2>
|
||||
<div v-show="dicomInfo.series">Series: #{{ dicomInfo.series }}</div>
|
||||
<div>Image: #{{ dicomInfo.frame }}</div>
|
||||
<div>{{ dicomInfo.modality }}</div>
|
||||
</div>
|
||||
<div class="info-image">
|
||||
<div v-show="mousePosition.mo">
|
||||
Pos: {{ mousePosition.x?mousePosition.x.toFixed(0):'' }}, {{ mousePosition.y?mousePosition.y.toFixed(0):'' }}
|
||||
Pos: {{ mousePosition.x ? mousePosition.x.toFixed(0) : '' }}, {{ mousePosition.y ? mousePosition.y.toFixed(0) : '' }}
|
||||
</div>
|
||||
<div v-if="(dicomInfo.modality === 'CT' || dicomInfo.modality === 'DR' || dicomInfo.modality === 'CR') && mousePosition.mo">
|
||||
<div
|
||||
v-if="(dicomInfo.modality === 'CT' || dicomInfo.modality === 'DR' || dicomInfo.modality === 'CR') && mousePosition.mo">
|
||||
HU: {{ mousePosition.mo }}
|
||||
</div>
|
||||
<div v-else-if="(dicomInfo.modality === 'PT' && mousePosition.suv)">
|
||||
SUVbw(g/ml): {{ digitPlaces === -1 ?mousePosition.suv.toFixed(3) :mousePosition.suv.toFixed(digitPlaces) }}
|
||||
SUVbw(g/ml): {{ digitPlaces === -1 ? mousePosition.suv.toFixed(3) : mousePosition.suv.toFixed(digitPlaces) }}
|
||||
</div>
|
||||
<div v-else-if="mousePosition.mo">
|
||||
Density: {{ mousePosition.mo }}
|
||||
|
@ -81,8 +66,12 @@
|
|||
<!-- <div v-show="dicomInfo.acc">ACC {{ dicomInfo.acc }}</div> -->
|
||||
<!-- <div>{{ dicomInfo.time }}</div> -->
|
||||
</div>
|
||||
<div ref="sliderBox" class="my_slider_box" style="position: absolute;right: 1px;height: calc(100% - 140px);transform: translateY(-50%);top: calc(50% - 30px);width: 10px;background: #333;cursor: pointer" @click.stop="goViewer($event)">
|
||||
<div :style="{top: height + '%'}" style="z-index:10;background: #9e9e9e;height: 20px;width: 100%;position: absolute;top: 0;cursor: move" @click.stop.prevent="() => {return}" @mousedown.stop="sliderMousedown($event)" />
|
||||
<div ref="sliderBox" class="my_slider_box"
|
||||
style="position: absolute;right: 1px;height: calc(100% - 140px);transform: translateY(-50%);top: calc(50% - 30px);width: 10px;background: #333;cursor: pointer"
|
||||
@click.stop="goViewer($event)">
|
||||
<div :style="{ top: height + '%' }"
|
||||
style="z-index:10;background: #9e9e9e;height: 20px;width: 100%;position: absolute;top: 0;cursor: move"
|
||||
@click.stop.prevent="() => { return }" @mousedown.stop="sliderMousedown($event)" />
|
||||
</div>
|
||||
<div style="position: absolute;left: 50%;top: 30px;color: #f44336;transform: translateX(-50%);">
|
||||
{{ markers.top }}
|
||||
|
@ -117,7 +106,7 @@
|
|||
</div>
|
||||
</template>
|
||||
<style>
|
||||
.my_slider_box:after{
|
||||
.my_slider_box:after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: -20px;
|
||||
|
@ -308,7 +297,10 @@ export default {
|
|||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['visitTaskList', 'currentReadingTaskState'])
|
||||
...mapGetters(['visitTaskList', 'currentReadingTaskState']),
|
||||
NSTip() {
|
||||
return `${this.$store.state.trials.uploadSize},NS: ${this.$store.state.trials.uploadTip}`
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
currentReadingTaskState: {
|
||||
|
@ -572,7 +564,7 @@ export default {
|
|||
type: 'warning'
|
||||
}).then(() => {
|
||||
|
||||
}).catch(() => {})
|
||||
}).catch(() => { })
|
||||
e.stopImmediatePropagation()
|
||||
e.stopPropagation()
|
||||
e.preventDefault()
|
||||
|
@ -1111,7 +1103,7 @@ export default {
|
|||
var frame = imageInfo.frame
|
||||
this.stack.frame = this.stack.isExistMutiFrames ? parseInt(frame) : null
|
||||
this.stack.instanceId = instanceId
|
||||
|
||||
|
||||
const element = this.$refs.canvas
|
||||
cornerstone.enable(element)
|
||||
element.tabIndex = 0
|
||||
|
@ -1164,7 +1156,7 @@ export default {
|
|||
|
||||
// const scope = this
|
||||
Array.from(toolButtons).forEach((toolBtn) => {
|
||||
// Add the tool
|
||||
// Add the tool
|
||||
const toolName = toolBtn.getAttribute('data-tool')
|
||||
const apiTool = cornerstoneTools[`${toolName}Tool`]
|
||||
if (apiTool) {
|
||||
|
@ -1172,17 +1164,17 @@ export default {
|
|||
|
||||
if (!toolAlreadyAddedToElement) {
|
||||
if (toolName === 'Length') {
|
||||
cornerstoneTools.addToolForElement(element, LengthTool, { configuration: { handleRadius: false, drawHandlesOnHover: true, hideHandlesIfMoving: true, digits: this.digitPlaces, drawHandles: true }})
|
||||
cornerstoneTools.addToolForElement(element, LengthTool, { configuration: { handleRadius: false, drawHandlesOnHover: true, hideHandlesIfMoving: true, digits: this.digitPlaces, drawHandles: true } })
|
||||
} else if (toolName === 'Bidirectional') {
|
||||
// cornerstoneTools.addToolForElement(element, BidirectionalTool, { digits: this.digitPlaces })
|
||||
// , handleRadius: false, drawHandlesOnHover: true, hideHandlesIfMoving: true
|
||||
cornerstoneTools.addToolForElement(element, BidirectionalTool, { configuration: { digits: this.digitPlaces, hideHandlesIfMoving: true }})
|
||||
// cornerstoneTools.addToolForElement(element, BidirectionalTool, { digits: this.digitPlaces })
|
||||
// , handleRadius: false, drawHandlesOnHover: true, hideHandlesIfMoving: true
|
||||
cornerstoneTools.addToolForElement(element, BidirectionalTool, { configuration: { digits: this.digitPlaces, hideHandlesIfMoving: true } })
|
||||
} else if (toolName === 'ArrowAnnotate') {
|
||||
cornerstoneTools.addToolForElement(element, ArrowAnnotateTool, { configuration: { allowEmptyLabel: true, handleRadius: false, drawHandlesOnHover: true, hideHandlesIfMoving: true }})
|
||||
cornerstoneTools.addToolForElement(element, ArrowAnnotateTool, { configuration: { allowEmptyLabel: true, handleRadius: false, drawHandlesOnHover: true, hideHandlesIfMoving: true } })
|
||||
} else if (toolName === 'RectangleRoi') {
|
||||
cornerstoneTools.addToolForElement(element, RectangleRoiTool, { configuration: { allowEmptyLabel: true, handleRadius: false, drawHandlesOnHover: true, hideHandlesIfMoving: true }})
|
||||
cornerstoneTools.addToolForElement(element, RectangleRoiTool, { configuration: { allowEmptyLabel: true, handleRadius: false, drawHandlesOnHover: true, hideHandlesIfMoving: true } })
|
||||
} else if (toolName === 'Probe' && parseInt(localStorage.getItem('CriterionType')) === 21) {
|
||||
cornerstoneTools.addToolForElement(element, ProbeTool, { configuration: { fixedRadius: 5, handleRadius: true, drawHandlesOnHover: true, hideHandlesIfMoving: true, digits: this.digitPlaces }})
|
||||
cornerstoneTools.addToolForElement(element, ProbeTool, { configuration: { fixedRadius: 5, handleRadius: true, drawHandlesOnHover: true, hideHandlesIfMoving: true, digits: this.digitPlaces } })
|
||||
} else {
|
||||
cornerstoneTools.addToolForElement(element, apiTool)
|
||||
}
|
||||
|
@ -1208,10 +1200,10 @@ export default {
|
|||
mouseButtonMask: 4
|
||||
})
|
||||
|
||||
// if (!cornerstoneTools.getToolForElement(element, OrientationMarkersTool)) {
|
||||
// cornerstoneTools.addToolForElement(element, OrientationMarkersTool)
|
||||
// }
|
||||
// cornerstoneTools.setToolActiveForElement(element, 'OrientationMarkers', { })
|
||||
// if (!cornerstoneTools.getToolForElement(element, OrientationMarkersTool)) {
|
||||
// cornerstoneTools.addToolForElement(element, OrientationMarkersTool)
|
||||
// }
|
||||
// cornerstoneTools.setToolActiveForElement(element, 'OrientationMarkers', { })
|
||||
}
|
||||
|
||||
// cornerstoneTools.addStackStateManager(this.canvas, ['stack', 'stackPrefetch', 'playClip'])
|
||||
|
@ -1228,7 +1220,7 @@ export default {
|
|||
this.stack.frame = this.stack.isExistMutiFrames ? parseInt(frame) : null
|
||||
this.stack.instanceId = instanceId
|
||||
this.height = (this.stack.currentImageIdIndex) * 100 / (this.stack.imageIds.length - 1)
|
||||
|
||||
|
||||
resolve()
|
||||
})
|
||||
},
|
||||
|
@ -1256,9 +1248,8 @@ export default {
|
|||
data.string('x00080030')
|
||||
)
|
||||
this.dicomInfo.series = data.string('x00200011')
|
||||
this.dicomInfo.frame = `${this.stack.currentImageIdIndex + 1}/${
|
||||
this.stack.imageIds.length
|
||||
}`
|
||||
this.dicomInfo.frame = `${this.stack.currentImageIdIndex + 1}/${this.stack.imageIds.length
|
||||
}`
|
||||
this.dicomInfo.size = `${data.uint16('x00280011')}*${data.uint16(
|
||||
'x00280010'
|
||||
)}`
|
||||
|
@ -1461,9 +1452,9 @@ export default {
|
|||
var element = cornerstone.getEnabledElement(this.canvas)
|
||||
const { rowPixelSpacing, colPixelSpacing } = this.getPixelSpacing(element.image)
|
||||
const dx =
|
||||
(data.handles.end.x - data.handles.start.x) * (colPixelSpacing || 1)
|
||||
(data.handles.end.x - data.handles.start.x) * (colPixelSpacing || 1)
|
||||
const dy =
|
||||
(data.handles.end.y - data.handles.start.y) * (rowPixelSpacing || 1)
|
||||
(data.handles.end.y - data.handles.start.y) * (rowPixelSpacing || 1)
|
||||
const length = Math.sqrt(dx * dx + dy * dy)
|
||||
|
||||
return length.toFixed(this.digitPlaces)
|
||||
|
@ -1477,9 +1468,9 @@ export default {
|
|||
if (imagePlane) {
|
||||
return {
|
||||
rowPixelSpacing:
|
||||
imagePlane.rowPixelSpacing || imagePlane.rowImagePixelSpacing,
|
||||
imagePlane.rowPixelSpacing || imagePlane.rowImagePixelSpacing,
|
||||
colPixelSpacing:
|
||||
imagePlane.columnPixelSpacing || imagePlane.colImagePixelSpacing
|
||||
imagePlane.columnPixelSpacing || imagePlane.colImagePixelSpacing
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1536,7 +1527,7 @@ export default {
|
|||
},
|
||||
debounce(callback, delay) {
|
||||
let timerId
|
||||
return function() {
|
||||
return function () {
|
||||
clearTimeout(timerId)
|
||||
timerId = setTimeout(() => {
|
||||
callback.apply(this, arguments)
|
||||
|
@ -2019,88 +2010,102 @@ export default {
|
|||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.context-menu-wrapper{
|
||||
position: absolute;
|
||||
ul{
|
||||
list-style: none;
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
.context-menu-wrapper {
|
||||
position: absolute;
|
||||
|
||||
ul {
|
||||
list-style: none;
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
background: #343333;
|
||||
color: #fff;
|
||||
margin: 0;
|
||||
border: 1px solid #2a2a2a;
|
||||
border-radius: 3px;
|
||||
height: auto;
|
||||
min-height: 50px;
|
||||
line-height: 1.5em;
|
||||
width: 80px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.menu {
|
||||
li {
|
||||
padding: 2px 5px;
|
||||
position: relative;
|
||||
border-bottom: 1px solid #666;
|
||||
|
||||
div {
|
||||
padding: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.submenu {
|
||||
position: absolute;
|
||||
left: 77px;
|
||||
top: -1px;
|
||||
background: #343333;
|
||||
color: #fff;
|
||||
margin: 0;
|
||||
border: 1px solid #2a2a2a;
|
||||
border-radius: 3px;
|
||||
height: auto;
|
||||
min-height: 50px;
|
||||
line-height: 1.5em;
|
||||
width:80px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.menu{
|
||||
display: none;
|
||||
|
||||
li {
|
||||
padding: 2px 5px;
|
||||
position: relative;
|
||||
border-bottom: 1px solid #666;
|
||||
div{
|
||||
|
||||
div {
|
||||
padding: 5px;
|
||||
}
|
||||
}
|
||||
.submenu{
|
||||
position: absolute;
|
||||
left: 77px;
|
||||
top: -1px;
|
||||
background: #343333;
|
||||
color: #fff;
|
||||
display: none;
|
||||
li {
|
||||
padding: 2px 5px;
|
||||
border-bottom: 1px solid #666;
|
||||
div{
|
||||
padding: 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
.menu li:hover{
|
||||
background-color: #ff5722;
|
||||
.submenu{
|
||||
display:block;
|
||||
}
|
||||
}
|
||||
.menu_active{
|
||||
cursor: pointer;
|
||||
}
|
||||
.menu_disabled{
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
}
|
||||
.info-visit{
|
||||
position: absolute;
|
||||
left:50%;
|
||||
top: 5px;
|
||||
transform: translateX(-50%);
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
.arrw_div_wrapper{
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
background-color: #3f3f3f;
|
||||
text-align: center;
|
||||
line-height: 20px;
|
||||
border-radius: 10%;
|
||||
}
|
||||
.blind_name_wrapper{
|
||||
height: 20px;
|
||||
line-height: 20px;
|
||||
background-color: #00000057;
|
||||
color: #fff;
|
||||
padding:0 10px;
|
||||
font-size: 14px;
|
||||
|
||||
.menu li:hover {
|
||||
background-color: #ff5722;
|
||||
|
||||
.submenu {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
.info-cd{
|
||||
|
||||
.menu_active {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.menu_disabled {
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.info-visit {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 5px;
|
||||
transform: translateX(-50%);
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
|
||||
.arrw_div_wrapper {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
background-color: #3f3f3f;
|
||||
text-align: center;
|
||||
line-height: 20px;
|
||||
border-radius: 10%;
|
||||
}
|
||||
|
||||
.blind_name_wrapper {
|
||||
height: 20px;
|
||||
line-height: 20px;
|
||||
background-color: #00000057;
|
||||
color: #fff;
|
||||
padding: 0 10px;
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
.info-cd {
|
||||
position: absolute;
|
||||
left: 10px;
|
||||
top: 5px;
|
||||
|
@ -2109,6 +2114,7 @@ export default {
|
|||
font-size: 18px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.info-series {
|
||||
position: absolute;
|
||||
left: 10px;
|
||||
|
@ -2118,6 +2124,7 @@ export default {
|
|||
font-size: 12px;
|
||||
/* z-index: 1; */
|
||||
}
|
||||
|
||||
.info-image {
|
||||
position: absolute;
|
||||
left: 10px;
|
||||
|
@ -2137,6 +2144,7 @@ export default {
|
|||
font-size: 12px;
|
||||
/* z-index: 1; */
|
||||
}
|
||||
|
||||
.info-instance {
|
||||
position: absolute;
|
||||
right: 15px;
|
||||
|
@ -2169,6 +2177,7 @@ export default {
|
|||
margin: 10px;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.menu__item:hover {
|
||||
color: #ff0000;
|
||||
}
|
||||
|
@ -2188,11 +2197,12 @@ li:hover {
|
|||
background-color: #e0e0e2;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.msg-div {
|
||||
position: absolute;
|
||||
z-index: 10;
|
||||
background-color: rgba(255, 255, 255, 0.5);
|
||||
color: #000;
|
||||
padding: 5px 20px;
|
||||
}
|
||||
position: absolute;
|
||||
z-index: 10;
|
||||
background-color: rgba(255, 255, 255, 0.5);
|
||||
color: #000;
|
||||
padding: 5px 20px;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -7,14 +7,9 @@
|
|||
<div class="visit-name-wrapper">
|
||||
|
||||
<div v-if="(visitTaskList.length > 0)" style="display: flex;flex-direction: row;">
|
||||
<div
|
||||
v-for="s in visitTaskList"
|
||||
:key="s.VisitTaskId"
|
||||
class="visit-item"
|
||||
:class="{'visit-item-active': activeTaskVisitId==s.VisitTaskId}"
|
||||
|
||||
@click.prevent="handleClick(s)"
|
||||
>{{ s.TaskBlindName }}</div>
|
||||
<div v-for="s in visitTaskList" :key="s.VisitTaskId" class="visit-item"
|
||||
:class="{ 'visit-item-active': activeTaskVisitId == s.VisitTaskId }" @click.prevent="handleClick(s)">{{
|
||||
s.TaskBlindName }}</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
@ -22,23 +17,12 @@
|
|||
|
||||
</div>
|
||||
<div class="right">
|
||||
<div
|
||||
v-for="s in visitTaskList"
|
||||
v-show="activeTaskVisitId === s.VisitTaskId"
|
||||
:key="s.VisitTaskId"
|
||||
class="study-wrapper"
|
||||
>
|
||||
<StudyList
|
||||
v-if="selectArr.includes(s.VisitTaskId)"
|
||||
:ref="s.VisitTaskId"
|
||||
:visit-task-id="s.VisitTaskId"
|
||||
:trial-id="trialId"
|
||||
:subject-visit-id="s.VisitId"
|
||||
:task-blind-name="s.TaskBlindName"
|
||||
:is-reading-show-subject-info="isReadingShowSubjectInfo"
|
||||
@loadImageStack="loadImageStack"
|
||||
@previewNoneDicoms="previewNoneDicoms"
|
||||
/>
|
||||
<div v-for="s in visitTaskList" v-show="activeTaskVisitId === s.VisitTaskId" :key="s.VisitTaskId"
|
||||
class="study-wrapper">
|
||||
<StudyList v-if="selectArr.includes(s.VisitTaskId)" :ref="s.VisitTaskId" :visit-task-id="s.VisitTaskId"
|
||||
:trial-id="trialId" :subject-visit-id="s.VisitId" :task-blind-name="s.TaskBlindName"
|
||||
:is-reading-show-subject-info="isReadingShowSubjectInfo" @loadImageStack="loadImageStack"
|
||||
@previewNoneDicoms="previewNoneDicoms" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -46,20 +30,12 @@
|
|||
</div>
|
||||
<div class="dicom-viewer">
|
||||
<div class="container">
|
||||
<DicomViewer
|
||||
v-if="activeTaskVisitId"
|
||||
ref="dicomViewer"
|
||||
:is-show="isShow"
|
||||
:question-form-change-state="questionFormChangeState"
|
||||
:question-form-change-num="questionFormChangeNum"
|
||||
:is-exists-clinical-data="isExistsClinicalData"
|
||||
:is-exists-no-dicom-file="isExistsNoDicomFile"
|
||||
<DicomViewer v-if="activeTaskVisitId" ref="dicomViewer" :is-show="isShow"
|
||||
:question-form-change-state="questionFormChangeState" :question-form-change-num="questionFormChangeNum"
|
||||
:is-exists-clinical-data="isExistsClinicalData" :is-exists-no-dicom-file="isExistsNoDicomFile"
|
||||
:is-reading-show-subject-info="isReadingShowSubjectInfo"
|
||||
:is-reading-task-view-in-order="isReadingTaskViewInOrder"
|
||||
:is-exists-manual="isExistsManual"
|
||||
:iseCRFShowInDicomReading="iseCRFShowInDicomReading"
|
||||
@previewCD="previewCD"
|
||||
/>
|
||||
:is-reading-task-view-in-order="isReadingTaskViewInOrder" :is-exists-manual="isExistsManual"
|
||||
:iseCRFShowInDicomReading="iseCRFShowInDicomReading" @previewCD="previewCD" />
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.dicom-container{
|
||||
.dicom-container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
|
@ -553,32 +533,35 @@ export default {
|
|||
background-color: #000;
|
||||
box-sizing: border-box;
|
||||
user-select: none;
|
||||
|
||||
::-webkit-scrollbar {
|
||||
width: 5px;
|
||||
height: 5px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
border-radius: 10px;
|
||||
background: #d0d0d0;
|
||||
}
|
||||
|
||||
.dicom-viewer{
|
||||
.dicom-viewer {
|
||||
flex: 1;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
|
||||
.container{
|
||||
.container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
}
|
||||
.dicom-list{
|
||||
width: 200px;
|
||||
padding: 5px 0px;
|
||||
|
||||
.dicom-list {
|
||||
width: 200px;
|
||||
padding: 5px 0px;
|
||||
box-sizing: border-box;
|
||||
|
||||
.container{
|
||||
.container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
|
@ -586,7 +569,8 @@ export default {
|
|||
// border: 1px solid #ccc;
|
||||
|
||||
}
|
||||
::v-deep.el-tabs{
|
||||
|
||||
::v-deep.el-tabs {
|
||||
box-sizing: border-box;
|
||||
padding: 0 5px;
|
||||
height: 100%;
|
||||
|
@ -594,26 +578,31 @@ export default {
|
|||
flex-direction: column;
|
||||
// justify-content: flex-start;
|
||||
border: 1px solid #727272;
|
||||
.el-tabs__item{
|
||||
|
||||
.el-tabs__item {
|
||||
color: #fff;
|
||||
}
|
||||
.el-tabs__header{
|
||||
|
||||
.el-tabs__header {
|
||||
height: 55px;
|
||||
margin:0px;
|
||||
margin: 0px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.el-tabs__content{
|
||||
|
||||
.el-tabs__content {
|
||||
flex: 1;
|
||||
margin:0px;
|
||||
margin: 0px;
|
||||
overflow-y: auto;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.el-tabs__item{
|
||||
|
||||
.el-tabs__item {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
}
|
||||
.dicom-desc{
|
||||
|
||||
.dicom-desc {
|
||||
font-weight: bold;
|
||||
font-size: 13px;
|
||||
text-align: center;
|
||||
|
@ -621,23 +610,28 @@ export default {
|
|||
color: #d0d0d0;
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
.ps {
|
||||
overflow-anchor: none;
|
||||
touch-action: auto;
|
||||
}
|
||||
|
||||
.series-active {
|
||||
background-color: #607d8b!important;
|
||||
border: 1px solid #607d8b!important;
|
||||
background-color: #607d8b !important;
|
||||
border: 1px solid #607d8b !important;
|
||||
}
|
||||
::v-deep.el-progress__text{
|
||||
|
||||
::v-deep.el-progress__text {
|
||||
color: #ccc;
|
||||
font-size: 12px;
|
||||
}
|
||||
.series{
|
||||
|
||||
.series {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: flex-start;
|
||||
|
||||
.series-wrapper {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
|
@ -650,11 +644,13 @@ export default {
|
|||
border-radius: 2px;
|
||||
border: 1px solid #404040;
|
||||
background-color: #3a3a3a;
|
||||
.el-progress__text{
|
||||
|
||||
.el-progress__text {
|
||||
display: none;
|
||||
}
|
||||
.el-progress-bar{
|
||||
padding-right:0px;
|
||||
|
||||
.el-progress-bar {
|
||||
padding-right: 0px;
|
||||
}
|
||||
|
||||
.image-preview {
|
||||
|
@ -663,9 +659,11 @@ export default {
|
|||
border: 2px solid #252525;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.image-desc {
|
||||
vertical-align: top;
|
||||
p{
|
||||
|
||||
p {
|
||||
width: 100px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
|
@ -678,7 +676,8 @@ export default {
|
|||
}
|
||||
}
|
||||
}
|
||||
.related-study-wrapper{
|
||||
|
||||
.related-study-wrapper {
|
||||
box-sizing: border-box;
|
||||
height: 100%;
|
||||
padding-bottom: 5px;
|
||||
|
@ -686,14 +685,15 @@ export default {
|
|||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
|
||||
.left{
|
||||
.left {
|
||||
position: relative;
|
||||
width: 25px;
|
||||
height: 100%;
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
box-sizing: border-box;
|
||||
.visit-name-wrapper{
|
||||
|
||||
.visit-name-wrapper {
|
||||
position: absolute;
|
||||
top: 5px;
|
||||
|
||||
|
@ -708,30 +708,34 @@ export default {
|
|||
// flex-direction: row;
|
||||
// align-content: flex-start;
|
||||
}
|
||||
.visit-item{
|
||||
|
||||
.visit-item {
|
||||
margin-left: 10px;
|
||||
white-space: nowrap;
|
||||
padding: 0px 4px;
|
||||
padding: 0px 4px;
|
||||
border: 1px solid #999999;
|
||||
border-bottom:none ;
|
||||
border-bottom: none;
|
||||
text-align: center;
|
||||
background-color: #4e4e4e;
|
||||
color: #d5d5d5;
|
||||
cursor: pointer;
|
||||
// margin-left: 10px;
|
||||
}
|
||||
.visit-item-active{
|
||||
|
||||
.visit-item-active {
|
||||
background-color: #607d8b;
|
||||
border: 1px solid #607d8b;
|
||||
}
|
||||
}
|
||||
.right{
|
||||
width:170px;
|
||||
flex:1;
|
||||
|
||||
.right {
|
||||
width: 170px;
|
||||
flex: 1;
|
||||
height: 100%;
|
||||
border-left: 1px solid #4a4a4a;
|
||||
color: #d5d5d5;
|
||||
.study-wrapper{
|
||||
|
||||
.study-wrapper {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
|
|
@ -1,15 +1,7 @@
|
|||
<template>
|
||||
<div
|
||||
id="canvas"
|
||||
ref="canvas"
|
||||
v-loading="loading"
|
||||
element-loading-text="Loading..."
|
||||
element-loading-background="rgba(0, 0, 0, 0.8)"
|
||||
style="position:relative;"
|
||||
class="cornerstone-element"
|
||||
@mouseup="sliderMouseup"
|
||||
@contextmenu.prevent="onContextmenu"
|
||||
>
|
||||
<div id="canvas" ref="canvas" v-loading="loading" :element-loading-text="NSTip"
|
||||
element-loading-background="rgba(0, 0, 0, 0.8)" style="position:relative;" class="cornerstone-element"
|
||||
@mouseup="sliderMouseup" @contextmenu.prevent="onContextmenu">
|
||||
<!-- 临床数据 -->
|
||||
<div v-if="stack.isExistsClinicalData" class="info-cd" @click.stop="handleViewCD($event)">
|
||||
<el-tooltip class="item" effect="dark" :content="$t('trials:reading:button:clinicalData')" placement="bottom">
|
||||
|
@ -18,46 +10,39 @@
|
|||
|
||||
</div>
|
||||
<!-- 切换访视 -->
|
||||
<div
|
||||
v-if="stack.imageRendered && isReadingTaskViewInOrder === 1"
|
||||
class="info-visit"
|
||||
@dblclick.stop="preventDefault($event)"
|
||||
>
|
||||
<div
|
||||
class="arrw_div_wrapper"
|
||||
:style="{cursor:stack.visitTaskNum <= minVistNum?'not-allowed':'pointer',color:stack.visitTaskNum <= minVistNum?'#888':'#fff'}"
|
||||
@click.stop.prevent="toggleSeries($event,-1)"
|
||||
@dblclick.stop="preventDefault($event)"
|
||||
>
|
||||
<div v-if="stack.imageRendered && isReadingTaskViewInOrder === 1" class="info-visit"
|
||||
@dblclick.stop="preventDefault($event)">
|
||||
<div class="arrw_div_wrapper"
|
||||
:style="{ cursor: stack.visitTaskNum <= minVistNum ? 'not-allowed' : 'pointer', color: stack.visitTaskNum <= minVistNum ? '#888' : '#fff' }"
|
||||
@click.stop.prevent="toggleSeries($event, -1)" @dblclick.stop="preventDefault($event)">
|
||||
<i class="el-icon-caret-left" />
|
||||
</div>
|
||||
<div class="blind_name_wrapper">
|
||||
{{ stack.taskBlindName }}
|
||||
</div>
|
||||
<div
|
||||
class="arrw_div_wrapper"
|
||||
:style="{cursor:stack.visitTaskNum >= maxVistNum?'not-allowed':'pointer',color:stack.visitTaskNum >= maxVistNum?'#888':'#fff'}"
|
||||
@click.stop.prevent="toggleSeries($event,1)"
|
||||
@dblclick.stop="preventDefault($event)"
|
||||
>
|
||||
<div class="arrw_div_wrapper"
|
||||
:style="{ cursor: stack.visitTaskNum >= maxVistNum ? 'not-allowed' : 'pointer', color: stack.visitTaskNum >= maxVistNum ? '#888' : '#fff' }"
|
||||
@click.stop.prevent="toggleSeries($event, 1)" @dblclick.stop="preventDefault($event)">
|
||||
<i class="el-icon-caret-right" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="info-series">
|
||||
<h2 v-if="isReadingShowSubjectInfo" style="color:#f44336;padding: 5px 0px;margin: 0;">{{ subjectCode }} {{ stack.taskBlindName }}</h2>
|
||||
<h2 v-if="isReadingShowSubjectInfo" style="color:#f44336;padding: 5px 0px;margin: 0;">{{ subjectCode }} {{
|
||||
stack.taskBlindName }}</h2>
|
||||
<div v-show="dicomInfo.series">Series: #{{ dicomInfo.series }}</div>
|
||||
<div>Image: #{{ dicomInfo.frame }}</div>
|
||||
<div>{{ dicomInfo.modality }}</div>
|
||||
</div>
|
||||
<div class="info-image">
|
||||
<div v-show="mousePosition.mo">
|
||||
Pos: {{ mousePosition.x?mousePosition.x.toFixed(0):'' }}, {{ mousePosition.y?mousePosition.y.toFixed(0):'' }}
|
||||
Pos: {{ mousePosition.x ? mousePosition.x.toFixed(0) : '' }}, {{ mousePosition.y ? mousePosition.y.toFixed(0) : '' }}
|
||||
</div>
|
||||
<div v-if="(dicomInfo.modality === 'CT' || dicomInfo.modality === 'DR' || dicomInfo.modality === 'CR') && mousePosition.mo">
|
||||
<div
|
||||
v-if="(dicomInfo.modality === 'CT' || dicomInfo.modality === 'DR' || dicomInfo.modality === 'CR') && mousePosition.mo">
|
||||
HU: {{ mousePosition.mo }}
|
||||
</div>
|
||||
<div v-else-if="(dicomInfo.modality === 'PT' && mousePosition.suv)">
|
||||
SUVbw(g/ml): {{ digitPlaces === -1 ?mousePosition.suv.toFixed(3) :mousePosition.suv.toFixed(digitPlaces) }}
|
||||
SUVbw(g/ml): {{ digitPlaces === -1 ? mousePosition.suv.toFixed(3) : mousePosition.suv.toFixed(digitPlaces) }}
|
||||
</div>
|
||||
<div v-else-if="mousePosition.mo">
|
||||
Density: {{ mousePosition.mo }}
|
||||
|
@ -81,8 +66,12 @@
|
|||
<!-- <div v-show="dicomInfo.acc">ACC {{ dicomInfo.acc }}</div> -->
|
||||
<!-- <div>{{ dicomInfo.time }}</div> -->
|
||||
</div>
|
||||
<div ref="sliderBox" class="my_slider_box" style="position: absolute;right: 1px;height: calc(100% - 140px);transform: translateY(-50%);top: calc(50% - 30px);width: 10px;background: #333;cursor: pointer" @click.stop="goViewer($event)">
|
||||
<div :style="{top: height + '%'}" style="z-index:10;background: #9e9e9e;height: 20px;width: 100%;position: absolute;top: 0;cursor: move" @click.stop.prevent="() => {return}" @mousedown.stop="sliderMousedown($event)" />
|
||||
<div ref="sliderBox" class="my_slider_box"
|
||||
style="position: absolute;right: 1px;height: calc(100% - 140px);transform: translateY(-50%);top: calc(50% - 30px);width: 10px;background: #333;cursor: pointer"
|
||||
@click.stop="goViewer($event)">
|
||||
<div :style="{ top: height + '%' }"
|
||||
style="z-index:10;background: #9e9e9e;height: 20px;width: 100%;position: absolute;top: 0;cursor: move"
|
||||
@click.stop.prevent="() => { return }" @mousedown.stop="sliderMousedown($event)" />
|
||||
</div>
|
||||
<div style="position: absolute;left: 50%;top: 30px;color: #f44336;transform: translateX(-50%);">
|
||||
{{ markers.top }}
|
||||
|
@ -117,7 +106,7 @@
|
|||
</div>
|
||||
</template>
|
||||
<style>
|
||||
.my_slider_box:after{
|
||||
.my_slider_box:after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: -20px;
|
||||
|
@ -306,7 +295,10 @@ export default {
|
|||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['visitTaskList', 'currentReadingTaskState'])
|
||||
...mapGetters(['visitTaskList', 'currentReadingTaskState']),
|
||||
NSTip() {
|
||||
return `${this.$store.state.trials.uploadSize},NS: ${this.$store.state.trials.uploadTip}`
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
currentReadingTaskState: {
|
||||
|
@ -562,7 +554,7 @@ export default {
|
|||
mouseDown(e) {
|
||||
this.image = e.detail.image
|
||||
var pointNearTool = this.pointNearTool(e)
|
||||
if (pointNearTool) {
|
||||
if (pointNearTool) {
|
||||
e.stopImmediatePropagation()
|
||||
e.stopPropagation()
|
||||
e.preventDefault()
|
||||
|
@ -574,7 +566,7 @@ export default {
|
|||
type: 'warning'
|
||||
}).then(() => {
|
||||
|
||||
}).catch(() => {})
|
||||
}).catch(() => { })
|
||||
e.stopImmediatePropagation()
|
||||
e.stopPropagation()
|
||||
e.preventDefault()
|
||||
|
@ -672,7 +664,7 @@ export default {
|
|||
this.sliderInfo.isMove = false
|
||||
},
|
||||
getMeasureData() {
|
||||
console.log('getMeasureData')
|
||||
console.log('getMeasureData')
|
||||
var idx = this.visitTaskList.findIndex(i => i.VisitTaskId === this.stack.visitTaskId)
|
||||
this.measureData = this.visitTaskList[idx].MeasureData
|
||||
const ToolStateManager = cornerstoneTools.globalImageIdSpecificToolStateManager
|
||||
|
@ -889,7 +881,7 @@ export default {
|
|||
} else {
|
||||
// cornerstoneTools.setToolEnabledForElement(element, data.MeasureData.type, { mouseButtonMask: 1 })
|
||||
cornerstoneTools.setToolPassiveForElement(element, data.MeasureData.type, { mouseButtonMask: 1 })
|
||||
|
||||
|
||||
}
|
||||
if (this.stack.instanceId.includes(data.InstanceId) && ((this.stack.isExistMutiFrames && (data.MeasureData.frame === this.stack.frame) && data.MeasureData) || (!this.stack.isExistMutiFrames && data.MeasureData))) {
|
||||
// console.log('renderMeasuredData', this.stack.frame,data.MeasureData.frame,this.stack.isExistMutiFrames)
|
||||
|
@ -991,32 +983,32 @@ export default {
|
|||
var idx = this.measureData.findIndex(item => item.MeasureData && item.MeasureData.data && item.MeasureData.data.uuid === toolState.data[i].uuid)
|
||||
if (idx > -1) {
|
||||
DicomEvent.$emit('setCollapseActive', this.measureData[idx])
|
||||
const measureData = {}
|
||||
// var markName = this.measureData[idx].OrderMarkName
|
||||
var markName = this.measureData[idx].MeasureData.data.remark
|
||||
if (this.activeToolName === 'Eraser' && this.disabledMarks.indexOf(markName) === -1) {
|
||||
const questionInfo = this.measureData[idx]
|
||||
measureData.orderMarkName = markName
|
||||
this.$emit('moveMeasureData', { measureData, questionInfo, orderMarkName: markName})
|
||||
}
|
||||
if ((this.disabledMarks.indexOf(markName) === -1 || !this.disabledMarks) && this.activeToolName !== 'Eraser') {
|
||||
const questionInfo = this.measureData[idx]
|
||||
const canvas = this.canvas.querySelector('canvas')
|
||||
measureData.pictureBaseStr = canvas.toDataURL('image/png', 1)
|
||||
measureData.studyId = this.stack.studyId
|
||||
measureData.seriesId = this.stack.seriesId
|
||||
measureData.instanceId = instanceId
|
||||
measureData.frame = this.stack.frame ? this.stack.frame : 0
|
||||
measureData.data = toolState.data[i]
|
||||
measureData.type = toolType
|
||||
measureData.thick = this.dicomInfo.thick
|
||||
measureData.location = this.dicomInfo.location
|
||||
measureData.ww = Math.round(viewport.voi.windowWidth)
|
||||
measureData.wc = Math.round(viewport.voi.windowCenter)
|
||||
measureData.data.active = false
|
||||
this.$emit('modifyMeasureData', { measureData, questionInfo })
|
||||
}
|
||||
|
||||
const measureData = {}
|
||||
// var markName = this.measureData[idx].OrderMarkName
|
||||
var markName = this.measureData[idx].MeasureData.data.remark
|
||||
if (this.activeToolName === 'Eraser' && this.disabledMarks.indexOf(markName) === -1) {
|
||||
const questionInfo = this.measureData[idx]
|
||||
measureData.orderMarkName = markName
|
||||
this.$emit('moveMeasureData', { measureData, questionInfo, orderMarkName: markName })
|
||||
}
|
||||
if ((this.disabledMarks.indexOf(markName) === -1 || !this.disabledMarks) && this.activeToolName !== 'Eraser') {
|
||||
const questionInfo = this.measureData[idx]
|
||||
const canvas = this.canvas.querySelector('canvas')
|
||||
measureData.pictureBaseStr = canvas.toDataURL('image/png', 1)
|
||||
measureData.studyId = this.stack.studyId
|
||||
measureData.seriesId = this.stack.seriesId
|
||||
measureData.instanceId = instanceId
|
||||
measureData.frame = this.stack.frame ? this.stack.frame : 0
|
||||
measureData.data = toolState.data[i]
|
||||
measureData.type = toolType
|
||||
measureData.thick = this.dicomInfo.thick
|
||||
measureData.location = this.dicomInfo.location
|
||||
measureData.ww = Math.round(viewport.voi.windowWidth)
|
||||
measureData.wc = Math.round(viewport.voi.windowCenter)
|
||||
measureData.data.active = false
|
||||
this.$emit('modifyMeasureData', { measureData, questionInfo })
|
||||
}
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
|
@ -1117,7 +1109,7 @@ export default {
|
|||
const toolButtons = document.querySelectorAll('[data-tool]')
|
||||
// const scope = this
|
||||
Array.from(toolButtons).forEach((toolBtn) => {
|
||||
// Add the tool
|
||||
// Add the tool
|
||||
const toolName = toolBtn.getAttribute('data-tool')
|
||||
const apiTool = cornerstoneTools[`${toolName}Tool`]
|
||||
if (apiTool) {
|
||||
|
@ -1125,17 +1117,17 @@ export default {
|
|||
|
||||
if (!toolAlreadyAddedToElement) {
|
||||
if (toolName === 'Length') {
|
||||
cornerstoneTools.addToolForElement(element, LengthTool, { configuration: { handleRadius: false, drawHandlesOnHover: true, hideHandlesIfMoving: true, digits: this.digitPlaces, drawHandles: true }})
|
||||
cornerstoneTools.addToolForElement(element, LengthTool, { configuration: { handleRadius: false, drawHandlesOnHover: true, hideHandlesIfMoving: true, digits: this.digitPlaces, drawHandles: true } })
|
||||
} else if (toolName === 'Bidirectional') {
|
||||
// cornerstoneTools.addToolForElement(element, BidirectionalTool, { digits: this.digitPlaces })
|
||||
// , handleRadius: false, drawHandlesOnHover: true, hideHandlesIfMoving: true
|
||||
cornerstoneTools.addToolForElement(element, BidirectionalTool, { configuration: { digits: this.digitPlaces, hideHandlesIfMoving: true }})
|
||||
// cornerstoneTools.addToolForElement(element, BidirectionalTool, { digits: this.digitPlaces })
|
||||
// , handleRadius: false, drawHandlesOnHover: true, hideHandlesIfMoving: true
|
||||
cornerstoneTools.addToolForElement(element, BidirectionalTool, { configuration: { digits: this.digitPlaces, hideHandlesIfMoving: true } })
|
||||
} else if (toolName === 'ArrowAnnotate') {
|
||||
cornerstoneTools.addToolForElement(element, ArrowAnnotateTool, { configuration: { allowEmptyLabel: true, handleRadius: false, drawHandlesOnHover: true, hideHandlesIfMoving: true }})
|
||||
cornerstoneTools.addToolForElement(element, ArrowAnnotateTool, { configuration: { allowEmptyLabel: true, handleRadius: false, drawHandlesOnHover: true, hideHandlesIfMoving: true } })
|
||||
} else if (toolName === 'RectangleRoi') {
|
||||
cornerstoneTools.addToolForElement(element, RectangleRoiTool, { configuration: { allowEmptyLabel: true, handleRadius: false, drawHandlesOnHover: true, hideHandlesIfMoving: true }})
|
||||
cornerstoneTools.addToolForElement(element, RectangleRoiTool, { configuration: { allowEmptyLabel: true, handleRadius: false, drawHandlesOnHover: true, hideHandlesIfMoving: true } })
|
||||
} else if (toolName === 'CircleRoi') {
|
||||
cornerstoneTools.addToolForElement(element, CircleRoiTool, { configuration: { handleRadius: false, drawHandlesOnHover: true, hideHandlesIfMoving: true, digits: this.digitPlaces, drawHandles: true, showMinMax: true }})
|
||||
cornerstoneTools.addToolForElement(element, CircleRoiTool, { configuration: { handleRadius: false, drawHandlesOnHover: true, hideHandlesIfMoving: true, digits: this.digitPlaces, drawHandles: true, showMinMax: true } })
|
||||
} else {
|
||||
cornerstoneTools.addToolForElement(element, apiTool)
|
||||
}
|
||||
|
@ -1161,10 +1153,10 @@ export default {
|
|||
mouseButtonMask: 4
|
||||
})
|
||||
|
||||
// if (!cornerstoneTools.getToolForElement(element, OrientationMarkersTool)) {
|
||||
// cornerstoneTools.addToolForElement(element, OrientationMarkersTool)
|
||||
// }
|
||||
// cornerstoneTools.setToolActiveForElement(element, 'OrientationMarkers', { })
|
||||
// if (!cornerstoneTools.getToolForElement(element, OrientationMarkersTool)) {
|
||||
// cornerstoneTools.addToolForElement(element, OrientationMarkersTool)
|
||||
// }
|
||||
// cornerstoneTools.setToolActiveForElement(element, 'OrientationMarkers', { })
|
||||
}
|
||||
|
||||
// cornerstoneTools.addStackStateManager(this.canvas, ['stack', 'stackPrefetch', 'playClip'])
|
||||
|
@ -1209,9 +1201,8 @@ export default {
|
|||
data.string('x00080030')
|
||||
)
|
||||
this.dicomInfo.series = data.string('x00200011')
|
||||
this.dicomInfo.frame = `${this.stack.currentImageIdIndex + 1}/${
|
||||
this.stack.imageIds.length
|
||||
}`
|
||||
this.dicomInfo.frame = `${this.stack.currentImageIdIndex + 1}/${this.stack.imageIds.length
|
||||
}`
|
||||
this.dicomInfo.size = `${data.uint16('x00280011')}*${data.uint16(
|
||||
'x00280010'
|
||||
)}`
|
||||
|
@ -1392,9 +1383,9 @@ export default {
|
|||
var element = cornerstone.getEnabledElement(this.canvas)
|
||||
const { rowPixelSpacing, colPixelSpacing } = this.getPixelSpacing(element.image)
|
||||
const dx =
|
||||
(data.handles.end.x - data.handles.start.x) * (colPixelSpacing || 1)
|
||||
(data.handles.end.x - data.handles.start.x) * (colPixelSpacing || 1)
|
||||
const dy =
|
||||
(data.handles.end.y - data.handles.start.y) * (rowPixelSpacing || 1)
|
||||
(data.handles.end.y - data.handles.start.y) * (rowPixelSpacing || 1)
|
||||
const length = Math.sqrt(dx * dx + dy * dy)
|
||||
|
||||
return length.toFixed(this.digitPlaces)
|
||||
|
@ -1408,9 +1399,9 @@ export default {
|
|||
if (imagePlane) {
|
||||
return {
|
||||
rowPixelSpacing:
|
||||
imagePlane.rowPixelSpacing || imagePlane.rowImagePixelSpacing,
|
||||
imagePlane.rowPixelSpacing || imagePlane.rowImagePixelSpacing,
|
||||
colPixelSpacing:
|
||||
imagePlane.columnPixelSpacing || imagePlane.colImagePixelSpacing
|
||||
imagePlane.columnPixelSpacing || imagePlane.colImagePixelSpacing
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1462,7 +1453,7 @@ export default {
|
|||
},
|
||||
debounce(callback, delay) {
|
||||
let timerId
|
||||
return function() {
|
||||
return function () {
|
||||
clearTimeout(timerId)
|
||||
timerId = setTimeout(() => {
|
||||
callback.apply(this, arguments)
|
||||
|
@ -1480,7 +1471,7 @@ export default {
|
|||
if (imageId) {
|
||||
ToolStateManager.clearImageIdToolState(imageId)
|
||||
let elements = cornerstone.getEnabledElementsByImageId(imageId)
|
||||
elements.map(el=>{
|
||||
elements.map(el => {
|
||||
cornerstone.updateImage(el.element)
|
||||
})
|
||||
}
|
||||
|
@ -1766,7 +1757,7 @@ export default {
|
|||
this.activeToolName = toolName
|
||||
this.$nextTick(() => {
|
||||
// console.log(cornerstoneTools.isToolActiveForElement(this.canvas, 'Bidirectional'))
|
||||
|
||||
|
||||
if (toolName === 'Zoom') {
|
||||
cornerstoneTools.setToolActiveForElement(this.canvas, 'Zoom', {
|
||||
mouseButtonMask: [1, 2]
|
||||
|
@ -1920,7 +1911,7 @@ export default {
|
|||
for (const [key, value] of searchParams.entries()) {
|
||||
params[key] = value
|
||||
}
|
||||
if (isNaN(params.frame)){
|
||||
if (isNaN(params.frame)) {
|
||||
params.frame = 0
|
||||
}
|
||||
return params
|
||||
|
@ -1942,88 +1933,102 @@ export default {
|
|||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.context-menu-wrapper{
|
||||
position: absolute;
|
||||
ul{
|
||||
list-style: none;
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
.context-menu-wrapper {
|
||||
position: absolute;
|
||||
|
||||
ul {
|
||||
list-style: none;
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
background: #343333;
|
||||
color: #fff;
|
||||
margin: 0;
|
||||
border: 1px solid #2a2a2a;
|
||||
border-radius: 3px;
|
||||
height: auto;
|
||||
min-height: 50px;
|
||||
line-height: 1.5em;
|
||||
width: 80px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.menu {
|
||||
li {
|
||||
padding: 2px 5px;
|
||||
position: relative;
|
||||
border-bottom: 1px solid #666;
|
||||
|
||||
div {
|
||||
padding: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.submenu {
|
||||
position: absolute;
|
||||
left: 77px;
|
||||
top: -1px;
|
||||
background: #343333;
|
||||
color: #fff;
|
||||
margin: 0;
|
||||
border: 1px solid #2a2a2a;
|
||||
border-radius: 3px;
|
||||
height: auto;
|
||||
min-height: 50px;
|
||||
line-height: 1.5em;
|
||||
width:80px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.menu{
|
||||
display: none;
|
||||
|
||||
li {
|
||||
padding: 2px 5px;
|
||||
position: relative;
|
||||
border-bottom: 1px solid #666;
|
||||
div{
|
||||
|
||||
div {
|
||||
padding: 5px;
|
||||
}
|
||||
}
|
||||
.submenu{
|
||||
position: absolute;
|
||||
left: 77px;
|
||||
top: -1px;
|
||||
background: #343333;
|
||||
color: #fff;
|
||||
display: none;
|
||||
li {
|
||||
padding: 2px 5px;
|
||||
border-bottom: 1px solid #666;
|
||||
div{
|
||||
padding: 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
.menu li:hover{
|
||||
background-color: #ff5722;
|
||||
.submenu{
|
||||
display:block;
|
||||
}
|
||||
}
|
||||
.menu_active{
|
||||
cursor: pointer;
|
||||
}
|
||||
.menu_disabled{
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
}
|
||||
.info-visit{
|
||||
position: absolute;
|
||||
left:50%;
|
||||
top: 5px;
|
||||
transform: translateX(-50%);
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
.arrw_div_wrapper{
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
background-color: #3f3f3f;
|
||||
text-align: center;
|
||||
line-height: 20px;
|
||||
border-radius: 10%;
|
||||
}
|
||||
.blind_name_wrapper{
|
||||
height: 20px;
|
||||
line-height: 20px;
|
||||
background-color: #00000057;
|
||||
color: #fff;
|
||||
padding:0 10px;
|
||||
font-size: 14px;
|
||||
|
||||
.menu li:hover {
|
||||
background-color: #ff5722;
|
||||
|
||||
.submenu {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
.info-cd{
|
||||
|
||||
.menu_active {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.menu_disabled {
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.info-visit {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 5px;
|
||||
transform: translateX(-50%);
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
|
||||
.arrw_div_wrapper {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
background-color: #3f3f3f;
|
||||
text-align: center;
|
||||
line-height: 20px;
|
||||
border-radius: 10%;
|
||||
}
|
||||
|
||||
.blind_name_wrapper {
|
||||
height: 20px;
|
||||
line-height: 20px;
|
||||
background-color: #00000057;
|
||||
color: #fff;
|
||||
padding: 0 10px;
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
.info-cd {
|
||||
position: absolute;
|
||||
left: 10px;
|
||||
top: 5px;
|
||||
|
@ -2032,6 +2037,7 @@ export default {
|
|||
font-size: 18px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.info-series {
|
||||
position: absolute;
|
||||
left: 10px;
|
||||
|
@ -2041,6 +2047,7 @@ export default {
|
|||
font-size: 12px;
|
||||
/* z-index: 1; */
|
||||
}
|
||||
|
||||
.info-image {
|
||||
position: absolute;
|
||||
left: 10px;
|
||||
|
@ -2060,6 +2067,7 @@ export default {
|
|||
font-size: 12px;
|
||||
/* z-index: 1; */
|
||||
}
|
||||
|
||||
.info-instance {
|
||||
position: absolute;
|
||||
right: 15px;
|
||||
|
@ -2092,6 +2100,7 @@ export default {
|
|||
margin: 10px;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.menu__item:hover {
|
||||
color: #ff0000;
|
||||
}
|
||||
|
@ -2111,11 +2120,12 @@ li:hover {
|
|||
background-color: #e0e0e2;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.msg-div {
|
||||
position: absolute;
|
||||
z-index: 10;
|
||||
background-color: rgba(255, 255, 255, 0.5);
|
||||
color: #000;
|
||||
padding: 5px 20px;
|
||||
}
|
||||
position: absolute;
|
||||
z-index: 10;
|
||||
background-color: rgba(255, 255, 255, 0.5);
|
||||
color: #000;
|
||||
padding: 5px 20px;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -5,42 +5,22 @@
|
|||
<div class="related-study-wrapper">
|
||||
<div class="left">
|
||||
<div class="visit-name-wrapper">
|
||||
<div
|
||||
v-if="visitTaskList.length > 0"
|
||||
style="display: flex; flex-direction: row"
|
||||
>
|
||||
<div
|
||||
v-for="s in visitTaskList"
|
||||
:key="s.VisitTaskId"
|
||||
class="visit-item"
|
||||
:class="{
|
||||
'visit-item-active': activeTaskVisitId == s.VisitTaskId,
|
||||
}"
|
||||
@click.prevent="handleClick(s)"
|
||||
>
|
||||
<div v-if="visitTaskList.length > 0" style="display: flex; flex-direction: row">
|
||||
<div v-for="s in visitTaskList" :key="s.VisitTaskId" class="visit-item" :class="{
|
||||
'visit-item-active': activeTaskVisitId == s.VisitTaskId,
|
||||
}" @click.prevent="handleClick(s)">
|
||||
{{ s.TaskBlindName }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="right">
|
||||
<div
|
||||
v-for="s in visitTaskList"
|
||||
v-show="activeTaskVisitId === s.VisitTaskId"
|
||||
:key="s.VisitTaskId"
|
||||
class="study-wrapper"
|
||||
>
|
||||
<StudyList
|
||||
v-if="selectArr.includes(s.VisitTaskId)"
|
||||
:ref="s.VisitTaskId"
|
||||
:visit-task-id="s.VisitTaskId"
|
||||
:trial-id="trialId"
|
||||
:subject-visit-id="s.VisitId"
|
||||
:task-blind-name="s.TaskBlindName"
|
||||
:is-reading-show-subject-info="isReadingShowSubjectInfo"
|
||||
@loadImageStack="loadImageStack"
|
||||
@previewNoneDicoms="previewNoneDicoms"
|
||||
/>
|
||||
<div v-for="s in visitTaskList" v-show="activeTaskVisitId === s.VisitTaskId" :key="s.VisitTaskId"
|
||||
class="study-wrapper">
|
||||
<StudyList v-if="selectArr.includes(s.VisitTaskId)" :ref="s.VisitTaskId" :visit-task-id="s.VisitTaskId"
|
||||
:trial-id="trialId" :subject-visit-id="s.VisitId" :task-blind-name="s.TaskBlindName"
|
||||
:is-reading-show-subject-info="isReadingShowSubjectInfo" @loadImageStack="loadImageStack"
|
||||
@previewNoneDicoms="previewNoneDicoms" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -48,21 +28,12 @@
|
|||
</div>
|
||||
<div class="dicom-viewer">
|
||||
<div class="container">
|
||||
<DicomViewer
|
||||
v-if="activeTaskVisitId"
|
||||
ref="dicomViewer"
|
||||
:trial-id="trialId"
|
||||
:trial-reading-criterion-id="trialReadingCriterionId"
|
||||
:subject-id="subjectId"
|
||||
:is-show="isShow"
|
||||
:is-exists-clinical-data="isExistsClinicalData"
|
||||
:is-exists-no-dicom-file="isExistsNoDicomFile"
|
||||
<DicomViewer v-if="activeTaskVisitId" ref="dicomViewer" :trial-id="trialId"
|
||||
:trial-reading-criterion-id="trialReadingCriterionId" :subject-id="subjectId" :is-show="isShow"
|
||||
:is-exists-clinical-data="isExistsClinicalData" :is-exists-no-dicom-file="isExistsNoDicomFile"
|
||||
:is-reading-show-subject-info="isReadingShowSubjectInfo"
|
||||
:is-reading-task-view-in-order="isReadingTaskViewInOrder"
|
||||
:isExistsManual="isExistsManual"
|
||||
:IseCRFShowInDicomReading="IseCRFShowInDicomReading"
|
||||
@previewCD="previewCD"
|
||||
/>
|
||||
:is-reading-task-view-in-order="isReadingTaskViewInOrder" :isExistsManual="isExistsManual"
|
||||
:IseCRFShowInDicomReading="IseCRFShowInDicomReading" @previewCD="previewCD" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -77,6 +48,7 @@ import { mapGetters } from "vuex";
|
|||
import * as dicomParser from 'dicom-parser'
|
||||
import * as cornerstone from 'cornerstone-core'
|
||||
import * as cornerstoneWADOImageLoader from 'cornerstone-wado-image-loader'
|
||||
import { workSpeedclose } from "@/utils"
|
||||
// import metaDataProvider from '@/utils/metaDataProvider'
|
||||
// cornerstone.metaData.addProvider(metaDataProvider, { priority: 10 });
|
||||
var config = {
|
||||
|
@ -261,6 +233,7 @@ export default {
|
|||
DicomEvent.$off("addNoneDicomMeasureData");
|
||||
DicomEvent.$off("selectSeries");
|
||||
window.removeEventListener('beforeunload', e => { cornerstone.imageCache.purgeCache() })
|
||||
workSpeedclose(true)
|
||||
},
|
||||
methods: {
|
||||
async getVisitInfo() {
|
||||
|
@ -547,7 +520,7 @@ export default {
|
|||
if (obj) {
|
||||
let index = Math.floor(
|
||||
obj.imageIds.length *
|
||||
((baseSeries.imageIdIndex + 1) / baseSeries.imageIds)
|
||||
((baseSeries.imageIdIndex + 1) / baseSeries.imageIds)
|
||||
);
|
||||
obj.imageIdIndex = index > 0 ? index - 1 : 0;
|
||||
}
|
||||
|
@ -636,7 +609,7 @@ export default {
|
|||
// );
|
||||
let frame = this.visitTaskList[index].MeasureData[idx].MeasureData.frame
|
||||
// let 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) {
|
||||
|
@ -683,12 +656,14 @@ 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)
|
||||
}
|
||||
},
|
||||
|
@ -699,22 +674,27 @@ export default {
|
|||
height: 100%;
|
||||
// background-color: #fff;
|
||||
background-color: #000;
|
||||
|
||||
::-webkit-scrollbar {
|
||||
width: 7px;
|
||||
height: 7px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
border-radius: 10px;
|
||||
background: #d0d0d0;
|
||||
}
|
||||
|
||||
.report-header {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.el-card {
|
||||
background-color: #000;
|
||||
color: #ffffff;
|
||||
border: none;
|
||||
}
|
||||
|
||||
::v-deep .el-table,
|
||||
.el-table__expanded-cell {
|
||||
background-color: #000;
|
||||
|
@ -728,19 +708,23 @@ export default {
|
|||
color: #fff;
|
||||
border-color: #444444;
|
||||
}
|
||||
::v-deep .el-table__body tr > td {
|
||||
|
||||
::v-deep .el-table__body tr>td {
|
||||
background-color: #000 !important;
|
||||
color: #fff;
|
||||
border-color: #444444;
|
||||
}
|
||||
::v-deep .el-table__body tr:hover > td {
|
||||
|
||||
::v-deep .el-table__body tr:hover>td {
|
||||
background-color: #858282 !important;
|
||||
color: #fff;
|
||||
border-color: #444444;
|
||||
}
|
||||
|
||||
::v-deep .el-table--border th.gutter:last-of-type {
|
||||
border: none;
|
||||
}
|
||||
|
||||
::v-deep .el-card__header {
|
||||
border: none;
|
||||
padding: 10px;
|
||||
|
@ -753,10 +737,12 @@ export default {
|
|||
justify-content: flex-start;
|
||||
background-color: #000;
|
||||
box-sizing: border-box;
|
||||
|
||||
::-webkit-scrollbar {
|
||||
width: 5px;
|
||||
height: 5px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
border-radius: 10px;
|
||||
background: #d0d0d0;
|
||||
|
@ -773,6 +759,7 @@ export default {
|
|||
box-sizing: border-box;
|
||||
}
|
||||
}
|
||||
|
||||
.dicom-list {
|
||||
width: 200px;
|
||||
padding: 5px 0px;
|
||||
|
@ -785,6 +772,7 @@ export default {
|
|||
border: 1px solid #727272;
|
||||
// border: 1px solid #ccc;
|
||||
}
|
||||
|
||||
.el-tabs {
|
||||
box-sizing: border-box;
|
||||
padding: 0 5px;
|
||||
|
@ -793,24 +781,29 @@ export default {
|
|||
flex-direction: column;
|
||||
// justify-content: flex-start;
|
||||
border: 1px solid #727272;
|
||||
|
||||
.el-tabs__item {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
::v-deep .el-tabs__header {
|
||||
height: 55px;
|
||||
margin: 0px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
::v-deep .el-tabs__content {
|
||||
flex: 1;
|
||||
margin: 0px;
|
||||
overflow-y: auto;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
::v-deep .el-tabs__item {
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
.dicom-desc {
|
||||
font-weight: bold;
|
||||
font-size: 13px;
|
||||
|
@ -819,23 +812,28 @@ export default {
|
|||
color: #d0d0d0;
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
.ps {
|
||||
overflow-anchor: none;
|
||||
touch-action: auto;
|
||||
}
|
||||
|
||||
.series-active {
|
||||
background-color: #607d8b !important;
|
||||
border: 1px solid #607d8b !important;
|
||||
}
|
||||
|
||||
::v-deep .el-progress__text {
|
||||
color: #ccc;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.series {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: flex-start;
|
||||
|
||||
.series-wrapper {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
|
@ -848,9 +846,11 @@ export default {
|
|||
border-radius: 2px;
|
||||
border: 1px solid #404040;
|
||||
background-color: #3a3a3a;
|
||||
|
||||
.el-progress__text {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.el-progress-bar {
|
||||
padding-right: 0px;
|
||||
}
|
||||
|
@ -861,8 +861,10 @@ export default {
|
|||
border: 2px solid #252525;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.image-desc {
|
||||
vertical-align: top;
|
||||
|
||||
p {
|
||||
width: 100px;
|
||||
white-space: nowrap;
|
||||
|
@ -876,6 +878,7 @@ export default {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
.related-study-wrapper {
|
||||
box-sizing: border-box;
|
||||
height: 100%;
|
||||
|
@ -891,6 +894,7 @@ export default {
|
|||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
box-sizing: border-box;
|
||||
|
||||
.visit-name-wrapper {
|
||||
position: absolute;
|
||||
top: 5px;
|
||||
|
@ -906,6 +910,7 @@ export default {
|
|||
// flex-direction: row;
|
||||
// align-content: flex-start;
|
||||
}
|
||||
|
||||
.visit-item {
|
||||
margin-left: 10px;
|
||||
white-space: nowrap;
|
||||
|
@ -918,17 +923,20 @@ export default {
|
|||
cursor: pointer;
|
||||
// margin-left: 10px;
|
||||
}
|
||||
|
||||
.visit-item-active {
|
||||
background-color: #607d8b;
|
||||
border: 1px solid #607d8b;
|
||||
}
|
||||
}
|
||||
|
||||
.right {
|
||||
width: 170px;
|
||||
flex: 1;
|
||||
height: 100%;
|
||||
border-left: 1px solid #4a4a4a;
|
||||
color: #d5d5d5;
|
||||
|
||||
.study-wrapper {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
<template>
|
||||
<div ref="viewport-fusion" class="viewport-wrapper" @mouseup="sliderMouseup" @mousemove="sliderMousemove"
|
||||
<div ref="viewport-fusion" class="viewport-wrapper" v-loading="loading" :element-loading-text="NSTip"
|
||||
element-loading-background="rgba(0, 0, 0, 0.8)" @mouseup="sliderMouseup" @mousemove="sliderMousemove"
|
||||
@mouseleave="sliderMouseleave" :style="{ color: series.Modality === 'PT' || isMip ? '#666' : '#ddd' }">
|
||||
<div v-if="series && taskInfo" class="left-top-text">
|
||||
<div v-if="taskInfo.IsExistsClinicalData && !isMip && !isFusion" class="cd-info"
|
||||
|
@ -185,6 +186,7 @@ export default {
|
|||
isMove: false
|
||||
},
|
||||
ptVolumeId: null,
|
||||
loading: false
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
|
@ -501,10 +503,12 @@ export default {
|
|||
}
|
||||
},
|
||||
async createImageIdsAndCacheMetaData(obj) {
|
||||
this.loading = true
|
||||
await createImageIdsAndCacheMetaData({
|
||||
modality: obj.Modality,
|
||||
imageIds: obj.ImageIds
|
||||
})
|
||||
this.loading = false
|
||||
},
|
||||
async setSeriesInfo(obj, option = {}) {
|
||||
try {
|
||||
|
@ -782,7 +786,12 @@ export default {
|
|||
e.stopPropagation()
|
||||
e.preventDefault()
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
NSTip() {
|
||||
return `${this.$store.state.trials.uploadSize},NS: ${this.$store.state.trials.uploadTip}`
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
|
|
|
@ -617,6 +617,7 @@ import colorMap from './colorMap.vue'
|
|||
import RectangleROITool from './tools/RectangleROITool'
|
||||
import uploadDicomAndNonedicom from '@/components/uploadDicomAndNonedicom'
|
||||
import downloadDicomAndNonedicom from '@/components/downloadDicomAndNonedicom'
|
||||
import { getNetWorkSpeed, setNetWorkSpeedSize, workSpeedclose } from "@/utils"
|
||||
const { visibility } = annotation
|
||||
const { ViewportType, Events } = Enums
|
||||
const renderingEngineId = 'myRenderingEngine'
|
||||
|
@ -1322,6 +1323,14 @@ export default {
|
|||
const isCriticalSequence = this.visitTaskList[taskIndex].StudyList[studyIndex].IsCriticalSequence
|
||||
const keyImages = this.visitTaskList[taskIndex].KeyImages
|
||||
const series = this.visitTaskList[taskIndex].StudyList[studyIndex].SeriesList[seriesIndex]
|
||||
let file = series.find(item => item.ImageId === imageId)
|
||||
if (file) {
|
||||
getNetWorkSpeed()
|
||||
setNetWorkSpeedSize(percentComplete, file.FileSize, imageId)
|
||||
}
|
||||
if (percentComplete === 100) {
|
||||
workSpeedclose()
|
||||
}
|
||||
this.setImageLoadedProgress(series, percentComplete, instanceId)
|
||||
if (!isCriticalSequence && series.IsBeMark && keyImages.length > 0) {
|
||||
const i = keyImages.findIndex(i => i.Id === params.instanceId)
|
||||
|
@ -2940,6 +2949,9 @@ export default {
|
|||
this.uploadStatus = status
|
||||
this[`${status}ImageVisible`] = true
|
||||
},
|
||||
},
|
||||
beforeDestroy() {
|
||||
workSpeedclose(true)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
|
@ -2,6 +2,9 @@
|
|||
<div
|
||||
ref="viewport"
|
||||
class="viewport-wrapper"
|
||||
v-loading="loading"
|
||||
:element-loading-text="NSTip"
|
||||
element-loading-background="rgba(0, 0, 0, 0.8)"
|
||||
@mouseup="sliderMouseup"
|
||||
@mousemove="sliderMousemove"
|
||||
@mouseleave="sliderMouseleave"
|
||||
|
@ -166,7 +169,8 @@ export default {
|
|||
originalMarkers: [],
|
||||
markers: { top: '', right: '', bottom: '', left: '' },
|
||||
playClipState: false,
|
||||
wwwcIdx: 2
|
||||
wwwcIdx: 2,
|
||||
loading: false
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
|
@ -403,7 +407,9 @@ export default {
|
|||
const renderingEngine = getRenderingEngine(this.renderingEngineId)
|
||||
const viewport = renderingEngine.getViewport(this.viewportId)
|
||||
let imageId = obj.ImageIds[obj.SliceIndex] ? obj.ImageIds[obj.SliceIndex] : obj.ImageIds[0]
|
||||
this.loading = true
|
||||
const image = await cornerstoneDICOMImageLoader.wadouri.loadImage(imageId).promise
|
||||
this.loading = false
|
||||
if (obj.Modality === 'PT') {
|
||||
this.cachePTMetadata([image])
|
||||
}
|
||||
|
@ -531,7 +537,12 @@ export default {
|
|||
e.stopPropagation()
|
||||
e.preventDefault()
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
NSTip() {
|
||||
return `${this.$store.state.trials.uploadSize},NS: ${this.$store.state.trials.uploadTip}`
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
|
|
|
@ -50,6 +50,7 @@ module.exports = defineConfig({
|
|||
pathRewrite: {
|
||||
}
|
||||
},
|
||||
// uat http://101.132.253.119:7010
|
||||
'/api': {
|
||||
target: 'http://106.14.89.110:30000',
|
||||
changeOrigin: true,
|
||||
|
|
Loading…
Reference in New Issue