2603 lines
82 KiB
Vue
2603 lines
82 KiB
Vue
<template>
|
||
<div class="dicom-viewer-wrapper">
|
||
<div class="dicom-viewer-container">
|
||
<div class="dicom-tools">
|
||
<el-tooltip
|
||
class="item"
|
||
effect="dark"
|
||
:content="`${$t('trials:reading:button:layout')}`"
|
||
placement="bottom"
|
||
>
|
||
<div
|
||
class="tool-wrapper"
|
||
@click.stop="showPanel($event)"
|
||
@mouseleave="handleMouseout"
|
||
>
|
||
<div class="dropdown">
|
||
<div class="icon">
|
||
<svg-icon icon-class="layout" class="svg-icon" />
|
||
<i class="el-icon-arrow-down" style="color: #fff" />
|
||
</div>
|
||
<!-- 布局 -->
|
||
<!-- <div class="text">{{ $t('trials:reading:button:layout') }}<i class="el-icon-caret-bottom" /></div> -->
|
||
<div class="dropdown-content layout-content">
|
||
<ul style="width: 50px">
|
||
<li class="flex_row" @click.stop="changeLayout('A')">
|
||
<div class="layout_box_1_1">A</div>
|
||
</li>
|
||
<li class="flex_row" @click.stop="changeLayout('A|A')">
|
||
<div class="layout_box_1_1">A</div>
|
||
<div class="layout_box_1_1">A</div>
|
||
</li>
|
||
<li
|
||
v-if="isReadingTaskViewInOrder === 1"
|
||
class="flex_row"
|
||
@click.stop="changeLayout('A|B')"
|
||
>
|
||
<div class="layout_box_1_1">A</div>
|
||
<div class="layout_box_1_1">B</div>
|
||
</li>
|
||
|
||
<li class="flex_column" @click.stop="changeLayout('A|A|A|A')">
|
||
<div style="flex: 1; display: flex; width: 100%">
|
||
<div class="layout_box_1_2">A</div>
|
||
<div class="layout_box_1_2">A</div>
|
||
</div>
|
||
<div style="flex: 1; display: flex; width: 100%">
|
||
<div class="layout_box_1_2">A</div>
|
||
<div class="layout_box_1_2">A</div>
|
||
</div>
|
||
</li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</el-tooltip>
|
||
|
||
<el-tooltip
|
||
class="item"
|
||
effect="dark"
|
||
:content="`${$t('trials:reading:button:wwwc')}`"
|
||
placement="bottom"
|
||
>
|
||
<div
|
||
class="tool-wrapper"
|
||
@click.stop="showPanel($event)"
|
||
@mouseleave="handleMouseout"
|
||
>
|
||
<div class="dropdown">
|
||
<div
|
||
class="icon"
|
||
data-tool="Wwwc"
|
||
:class="[activeTool === 'Wwwc' ? 'tool_active' : '']"
|
||
@click.prevent="setToolActive('Wwwc', false)"
|
||
>
|
||
<svg-icon icon-class="reverse" class="svg-icon" />
|
||
<i class="el-icon-arrow-down" style="color: #fff" />
|
||
</div>
|
||
<!-- 调窗 -->
|
||
<!-- <div class="text">{{ $t('trials:reading:button:wwwc') }}<i class="el-icon-caret-bottom" /></div> -->
|
||
<div class="dropdown-content">
|
||
<ul style="width: 165px; padding: 0 10px">
|
||
<li v-for="item in wwwcArr" :key="item.label">
|
||
<a href="#" @click.prevent="setDicomCanvasWwwc(item)">
|
||
<div
|
||
v-if="item.wc"
|
||
style="
|
||
display: flex;
|
||
flex-direction: row;
|
||
justify-content: space-between;
|
||
"
|
||
>
|
||
<div>{{ item.label }}</div>
|
||
<div>{{ item.ww }}/{{ item.wc }}</div>
|
||
</div>
|
||
<div v-else style="text-align: left">
|
||
{{ item.label }}
|
||
</div>
|
||
</a>
|
||
<!-- <div
|
||
v-if="item.val === 1"
|
||
class="divider"
|
||
>
|
||
W/L {{ $t('trials:reading:title:preset') }}
|
||
</div> -->
|
||
<el-divider
|
||
v-if="item.val === 1"
|
||
class="divider"
|
||
content-position="center"
|
||
>{{ ` ${$t("trials:reading:title:preset")}` }}</el-divider>
|
||
</li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</el-tooltip>
|
||
|
||
<!-- <div class="tool-wrapper">
|
||
|
||
<div
|
||
class="icon"
|
||
data-tool="WwwcRegion"
|
||
:class="[activeTool==='WwwcRegion'?'tool_active':'']"
|
||
|
||
@click.prevent="setToolActive('WwwcRegion',false)"
|
||
>
|
||
<svg-icon icon-class="wwwcRegion" class="svg-icon" />
|
||
</div>
|
||
<div class="text">区域调窗</div>
|
||
|
||
</div> -->
|
||
<el-tooltip
|
||
class="item"
|
||
effect="dark"
|
||
:content="`${$t('trials:reading:button:reverseColor')}`"
|
||
placement="bottom"
|
||
>
|
||
<div class="tool-wrapper">
|
||
<div
|
||
class="icon"
|
||
:class="[activeTool === 'reversecolor' ? 'tool_active' : '']"
|
||
@click.prevent="toggleInvert"
|
||
>
|
||
<svg-icon icon-class="reversecolor" class="svg-icon" />
|
||
</div>
|
||
<!-- 反色 -->
|
||
<!-- <div class="text">{{ $t('trials:reading:button:reverseColor') }}</div> -->
|
||
</div>
|
||
</el-tooltip>
|
||
|
||
<el-tooltip
|
||
class="item"
|
||
effect="dark"
|
||
:content="`${$t('trials:reading:button:zoom')}`"
|
||
placement="bottom"
|
||
>
|
||
<div class="tool-wrapper">
|
||
<div
|
||
class="icon"
|
||
:class="[activeTool === 'Zoom' ? 'tool_active' : '']"
|
||
data-tool="Zoom"
|
||
@click.prevent="setToolActive('Zoom', false)"
|
||
>
|
||
<svg-icon icon-class="magnifier" class="svg-icon" />
|
||
</div>
|
||
<!-- 缩放 -->
|
||
<div class="text">{{ $t("trials:reading:button:zoom") }}</div>
|
||
</div>
|
||
</el-tooltip>
|
||
|
||
<el-tooltip
|
||
class="item"
|
||
effect="dark"
|
||
:content="`${$t('trials:reading:button:move')}`"
|
||
placement="bottom"
|
||
>
|
||
<div class="tool-wrapper">
|
||
<div
|
||
class="icon"
|
||
:class="[activeTool === 'Pan' ? 'tool_active' : '']"
|
||
data-tool="Pan"
|
||
@click.prevent="setToolActive('Pan', false)"
|
||
>
|
||
<svg-icon icon-class="move" class="svg-icon" />
|
||
</div>
|
||
<!-- 移动 -->
|
||
<div class="text">{{ $t("trials:reading:button:move") }}</div>
|
||
</div>
|
||
</el-tooltip>
|
||
|
||
<el-tooltip
|
||
class="item"
|
||
effect="dark"
|
||
:content="`${$t('trials:reading:button:rotate')}`"
|
||
placement="bottom"
|
||
>
|
||
<div
|
||
class="tool-wrapper"
|
||
@click.stop="showPanel($event)"
|
||
@mouseleave="handleMouseout"
|
||
>
|
||
<!-- @click.prevent="setToolActive('Rotate',false)" -->
|
||
<div class="dropdown">
|
||
<div
|
||
class="icon"
|
||
data-tool="Rotate"
|
||
:class="[activeTool === 'Rotate' ? 'tool_active' : '']"
|
||
>
|
||
<svg-icon icon-class="rotate" class="svg-icon" />
|
||
<i class="el-icon-arrow-down" style="color: #fff" />
|
||
</div>
|
||
<!-- 旋转 -->
|
||
<div class="text">
|
||
{{ $t("trials:reading:button:rotate")
|
||
}}<i class="el-icon-caret-bottom" />
|
||
</div>
|
||
<div class="dropdown-content">
|
||
<ul style="width: 100px; padding: 0 10px">
|
||
<li
|
||
v-for="rotate in rotateArr"
|
||
:key="rotate.label"
|
||
style="text-align: left"
|
||
>
|
||
<a
|
||
href="#"
|
||
@click.prevent="setDicomCanvasRotate(rotate.val)"
|
||
>{{ rotate.label }}</a>
|
||
</li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</el-tooltip>
|
||
|
||
<el-tooltip
|
||
class="item"
|
||
effect="dark"
|
||
:content="
|
||
fitType === 1
|
||
? `${$t('trials:reading:button:fitWindow')}`
|
||
: `${$t('trials:reading:button:fitImage')}`
|
||
"
|
||
placement="bottom"
|
||
>
|
||
<div class="tool-wrapper">
|
||
<div
|
||
class="icon"
|
||
@click.prevent="
|
||
fitToType(fitType === 1 ? 'fitToWindow' : 'fitToImage')
|
||
"
|
||
>
|
||
<svg-icon
|
||
v-if="fitType === 1"
|
||
icon-class="fitToWindow"
|
||
class="svg-icon"
|
||
/>
|
||
<svg-icon v-else icon-class="fitToImage" class="svg-icon" />
|
||
</div>
|
||
<div class="text">
|
||
{{
|
||
fitType === 1
|
||
? $t("trials:reading:button:fitWindow")
|
||
: $t("trials:reading:button:fitImage")
|
||
}}
|
||
</div>
|
||
</div>
|
||
</el-tooltip>
|
||
|
||
<el-tooltip
|
||
class="item"
|
||
effect="dark"
|
||
:content="`${$t('trials:reading:button:imageIndexSync')}`"
|
||
placement="bottom"
|
||
>
|
||
<div class="tool-wrapper">
|
||
<div
|
||
class="icon"
|
||
:class="[isScrollSync ? 'tool_active' : '']"
|
||
@click.prevent="setImageIndexSync"
|
||
>
|
||
<i v-if="isScrollSync" class="el-icon-lock svg-icon" />
|
||
<i v-else class="el-icon-unlock svg-icon" />
|
||
</div>
|
||
<!-- 同步 -->
|
||
<div class="text">
|
||
{{ $t("trials:reading:button:imageIndexSync") }}
|
||
</div>
|
||
</div>
|
||
</el-tooltip>
|
||
<!--
|
||
<div class="tool-wrapper">
|
||
<div
|
||
class="icon"
|
||
@click.prevent="fitToType('fitToImage')"
|
||
>
|
||
<svg-icon icon-class="fitToImage" class="svg-icon" />
|
||
</div>
|
||
<div class="text">适应图像</div>
|
||
</div> -->
|
||
<el-tooltip
|
||
class="item"
|
||
effect="dark"
|
||
:content="`${$t('trials:reading:button:screenShot')}`"
|
||
placement="bottom"
|
||
>
|
||
<div class="tool-wrapper">
|
||
<div class="icon" @click.prevent="saveImage">
|
||
<svg-icon icon-class="image" class="svg-icon" />
|
||
</div>
|
||
<!-- 截屏 -->
|
||
<div class="text">{{ $t("trials:reading:button:screenShot") }}</div>
|
||
</div>
|
||
</el-tooltip>
|
||
|
||
<div v-for="tool in measuredTools" :key="tool.toolName">
|
||
<el-tooltip class="item" effect="dark" placement="bottom">
|
||
<div slot="content">
|
||
<div v-if="tool.disabledReason">
|
||
<h4 style="margin: 0; padding-bottom: 2px">{{ tool.text }}</h4>
|
||
<br>{{ tool.disabledReason }}
|
||
</div>
|
||
<div v-else>{{ tool.text }}</div>
|
||
</div>
|
||
<div class="tool-wrapper">
|
||
<div
|
||
class="icon"
|
||
:class="[activeTool === tool.toolName ? 'tool_active' : '']"
|
||
:style="{ cursor: tool.isDisabled ? 'not-allowed' : 'pointer' }"
|
||
:data-tool="tool.toolName"
|
||
@click.prevent="setToolActive(tool.toolName, true, $event)"
|
||
@mouseenter="enter($event, tool.toolName)"
|
||
>
|
||
<svg-icon :icon-class="tool.icon" class="svg-icon" />
|
||
</div>
|
||
<div class="text">{{ tool.text }}</div>
|
||
</div>
|
||
</el-tooltip>
|
||
<!-- <div v-else class="tool-wrapper">
|
||
<div
|
||
class="icon"
|
||
:class="[activeTool===tool.toolName?'tool_active':'']"
|
||
:style="{cursor:tool.isDisabled?'not-allowed':'pointer'}"
|
||
:data-tool="tool.toolName"
|
||
@click.prevent="setToolActive(tool.toolName,true,$event)"
|
||
@mouseenter="enter($event,tool.toolName)"
|
||
>
|
||
<svg-icon :icon-class="tool.icon" class="svg-icon" />
|
||
</div>
|
||
<div class="text">{{ tool.text }}</div>
|
||
</div> -->
|
||
</div>
|
||
|
||
<el-tooltip
|
||
class="item"
|
||
effect="dark"
|
||
:content="`${$t('trials:dicom-show:Eraser')}`"
|
||
placement="bottom"
|
||
>
|
||
<div class="tool-wrapper">
|
||
<div
|
||
class="icon"
|
||
:class="[activeTool === 'Eraser' ? 'tool_active' : '']"
|
||
data-tool="Zoom"
|
||
@click.prevent="setToolActive('Eraser', false)"
|
||
>
|
||
<svg-icon icon-class="clear" class="svg-icon" />
|
||
</div>
|
||
<!-- 缩放 -->
|
||
<div class="text">{{ $t("trials:dicom-show:Eraser") }}</div>
|
||
</div>
|
||
</el-tooltip>
|
||
<div class="tool-frame">
|
||
<!-- 第一帧 -->
|
||
<el-tooltip
|
||
class="item"
|
||
effect="dark"
|
||
:content="$t('trials:dicom-show:firstframe')"
|
||
placement="bottom"
|
||
>
|
||
<div class="icon" @click.prevent="scrollPage(-99999)">
|
||
<svg-icon icon-class="firstframe" class="svg-icon" />
|
||
</div>
|
||
</el-tooltip>
|
||
<!-- 上一帧 -->
|
||
<el-tooltip
|
||
class="item"
|
||
effect="dark"
|
||
:content="$t('trials:dicom-show:previousframe')"
|
||
placement="bottom"
|
||
>
|
||
<div class="icon" @click.prevent="scrollPage(-1)">
|
||
<svg-icon icon-class="previousframe" class="svg-icon" />
|
||
</div>
|
||
</el-tooltip>
|
||
<!-- 播放/暂停 -->
|
||
<el-tooltip
|
||
class="item"
|
||
effect="dark"
|
||
:content="
|
||
clipPlaying
|
||
? $t('trials:dicom-show:stop')
|
||
: $t('trials:dicom-show:play')
|
||
"
|
||
placement="bottom"
|
||
>
|
||
<div
|
||
v-if="clipPlaying"
|
||
class="icon"
|
||
@click.prevent="toggleClipPlay(false)"
|
||
>
|
||
<svg-icon icon-class="stop" class="svg-icon" />
|
||
</div>
|
||
<div v-else class="icon" @click.prevent="toggleClipPlay(true)">
|
||
<svg-icon icon-class="play" class="svg-icon" />
|
||
</div>
|
||
</el-tooltip>
|
||
<!-- 下一帧 -->
|
||
<el-tooltip
|
||
class="item"
|
||
effect="dark"
|
||
:content="$t('trials:dicom-show:nextframe')"
|
||
placement="bottom"
|
||
>
|
||
<div class="icon" @click.prevent="scrollPage(1)">
|
||
<svg-icon icon-class="nextframe" class="svg-icon" />
|
||
</div>
|
||
</el-tooltip>
|
||
<!-- 最后一帧 -->
|
||
<el-tooltip
|
||
class="item"
|
||
effect="dark"
|
||
:content="$t('trials:dicom-show:lastframe')"
|
||
placement="bottom"
|
||
>
|
||
<div class="icon" @click.prevent="scrollPage(99999)">
|
||
<svg-icon icon-class="lastframe" class="svg-icon" />
|
||
</div>
|
||
</el-tooltip>
|
||
|
||
<el-tooltip
|
||
class="item"
|
||
effect="dark"
|
||
:content="$t('trials:dicom-show:speed')"
|
||
placement="bottom"
|
||
>
|
||
<select
|
||
v-model="fps"
|
||
class="select-wrapper"
|
||
:disabled="clipPlaying"
|
||
@change="setDicomCanvasfps($event)"
|
||
>
|
||
<option :value="5">5</option>
|
||
<option :value="10">10</option>
|
||
<option :value="15">15</option>
|
||
<option :value="20">20</option>
|
||
<option :value="25">25</option>
|
||
<option :value="30">30</option>
|
||
</select>
|
||
</el-tooltip>
|
||
</div>
|
||
<el-tooltip
|
||
class="item"
|
||
effect="dark"
|
||
:content="$t('trials:reading:button:reset')"
|
||
placement="bottom"
|
||
>
|
||
<div class="tool-wrapper">
|
||
<div class="icon" @click.prevent="resetViewport">
|
||
<svg-icon icon-class="refresh" class="svg-icon" />
|
||
</div>
|
||
<div class="text">{{ $t("trials:reading:button:reset") }}</div>
|
||
</div>
|
||
</el-tooltip>
|
||
<el-tooltip
|
||
v-if="trialCriterion.ImageUploadEnum > 0"
|
||
v-hasPermi="['role:ir']"
|
||
class="item"
|
||
effect="dark"
|
||
:content="$t('trials:reading:button:upload')"
|
||
placement="bottom"
|
||
>
|
||
<div class="tool-wrapper">
|
||
<div class="icon" @click.prevent="openUploadImage('upload')">
|
||
<i class="el-icon-upload2 svg-icon" />
|
||
</div>
|
||
<div class="text">{{ $t("trials:reading:button:upload") }}</div>
|
||
</div>
|
||
</el-tooltip>
|
||
<el-tooltip
|
||
v-if="trialCriterion.ImageDownloadEnum > 0"
|
||
v-hasPermi="[
|
||
'role:ir',
|
||
'role:mim',
|
||
'role:mc',
|
||
'role:pm',
|
||
'role:apm',
|
||
'role:ea',
|
||
'role:qa',
|
||
]"
|
||
class="item"
|
||
effect="dark"
|
||
:content="$t('trials:reading:button:download')"
|
||
placement="bottom"
|
||
>
|
||
<div class="tool-wrapper">
|
||
<div class="icon" @click.prevent="openUploadImage('download')">
|
||
<i class="el-icon-download svg-icon" />
|
||
</div>
|
||
<div class="text">{{ $t("trials:reading:button:download") }}</div>
|
||
</div>
|
||
</el-tooltip>
|
||
|
||
<div style="margin-left: auto">
|
||
<div style="padding: 5px">
|
||
<el-button
|
||
v-if="isExistsManual"
|
||
type="text"
|
||
@click="previewManuals"
|
||
>{{ $t("trials:reading:button:handbooks") }}</el-button>
|
||
<!-- 临床数据 -->
|
||
<el-button
|
||
v-if="isExistsClinicalData"
|
||
type="text"
|
||
@click="previewCD"
|
||
>{{ $t("trials:reading:button:clinicalData") }}</el-button>
|
||
<!-- <el-button v-if="isExistsNoDicomFile" type="text" @click="previewNoneDicoms">非Dicom文件</el-button> -->
|
||
|
||
<el-button type="text" @click="previewConfig">{{
|
||
$t("trials:reading:button:customCfg")
|
||
}}</el-button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="dicom-viewers">
|
||
<div
|
||
ref="container"
|
||
class="viewer-container"
|
||
:class="['box', `box_${layoutRow}_${layoutCol}`]"
|
||
>
|
||
<div
|
||
v-for="i in maxCanvas"
|
||
:key="i"
|
||
:class="[
|
||
'item',
|
||
i - 1 === currentDicomCanvasIndex ? 'item_active' : '',
|
||
]"
|
||
:data-index="i - 1"
|
||
:style="i - 1 === currentDicomCanvasIndex ? cornerstoneStyle : {}"
|
||
@click="activateDicomCanvas(i - 1)"
|
||
>
|
||
<dicom-canvas
|
||
v-if="canvasW"
|
||
:ref="`dicomCanvas${i - 1}`"
|
||
:style="{ width: canvasW, height: canvasH }"
|
||
:canvas-index="i - 1"
|
||
:is-active="i - 1 === currentDicomCanvasIndex"
|
||
:is-scroll-sync="isScrollSync"
|
||
:is-reading-show-subject-info="isReadingShowSubjectInfo"
|
||
:is-reading-task-view-in-order="isReadingTaskViewInOrder"
|
||
:current-dicom-canvas-index="currentDicomCanvasIndex"
|
||
:custom-wwc-tpl="customWwcTpl"
|
||
@setMeasureData="setMeasureData"
|
||
@modifyMeasureData="modifyMeasureData"
|
||
@scrollSync="scrollSync"
|
||
@selectViewCanvas="selectViewCanvas"
|
||
@setCornerstoneStyle="setCornerstoneStyle(i - 1)"
|
||
@moveMeasureData="moveMeasureData"
|
||
/>
|
||
</div>
|
||
</div>
|
||
<div ref="form-container" class="form-container">
|
||
<!-- 激活canvas测量数据 -->
|
||
<MeasurementList
|
||
ref="measurementList"
|
||
:ise-c-r-f-show-in-dicom-reading="IseCRFShowInDicomReading"
|
||
:is-reading-show-subject-info="isReadingShowSubjectInfo"
|
||
/>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<el-dialog
|
||
v-if="customWwc.visible"
|
||
:visible.sync="customWwc.visible"
|
||
:close-on-click-modal="false"
|
||
:title="customWwc.title"
|
||
width="400px"
|
||
custom-class="base-dialog-wrapper"
|
||
>
|
||
<CustomWwwcForm @close="customWwc.visible = false" @setWwwc="setWwwc" />
|
||
</el-dialog>
|
||
|
||
<el-dialog
|
||
v-if="personalConfigDialog.visible"
|
||
:visible.sync="personalConfigDialog.visible"
|
||
:close-on-click-modal="false"
|
||
:title="personalConfigDialog.title"
|
||
width="600px"
|
||
>
|
||
<el-tabs v-model="activeName" class="personal_config">
|
||
<el-tab-pane :label="$t('trials:reading:tab:hotkeys')" name="1">
|
||
<Hotkeys
|
||
v-if="activeName === '1'"
|
||
:reading-tool="0"
|
||
@reset="resetHotkeyList"
|
||
/>
|
||
</el-tab-pane>
|
||
<el-tab-pane :label="$t('trials:reading:tab:wlTemplate')" name="2">
|
||
<WL v-if="activeName === '2'" @getWwcTpl="getWwcTpl" />
|
||
</el-tab-pane>
|
||
<el-tab-pane :label="$t('trials:reading:tab:others')" name="3">
|
||
<Others v-if="activeName === '3'" />
|
||
</el-tab-pane>
|
||
</el-tabs>
|
||
</el-dialog>
|
||
<el-dialog
|
||
v-if="manualsDialog.visible"
|
||
:visible.sync="manualsDialog.visible"
|
||
:custom-class="
|
||
isFullscreen
|
||
? 'manuals-full-dialog-container'
|
||
: 'manuals-dialog-container'
|
||
"
|
||
:show-close="false"
|
||
:close-on-click-modal="false"
|
||
:fullscreen="isFullscreen"
|
||
>
|
||
<span slot="title" class="dialog-footer">
|
||
<span>{{ $t("trials:reading:button:handbooks") }}</span>
|
||
<span style="position: absolute; right: 20px; font-size: 20px">
|
||
<svg-icon
|
||
:icon-class="isFullscreen ? 'exit-fullscreen' : 'fullscreen'"
|
||
style="margin-right: 10px; cursor: pointer"
|
||
@click="isFullscreen = !isFullscreen"
|
||
/>
|
||
<svg-icon
|
||
icon-class="close"
|
||
style="cursor: pointer"
|
||
@click="manualsDialog.visible = false"
|
||
/>
|
||
</span>
|
||
</span>
|
||
<div style="height: 100%; margin: 0">
|
||
<Manuals :trial-id="trialId" />
|
||
</div>
|
||
</el-dialog>
|
||
<!-- <button :title="$t('trials:dicom-show:Eraser')" class="btn-link" data-tool="Eraser" @click="setToolActive($event,'Eraser')">-->
|
||
<!-- <svg-icon icon-class="clear" style="font-size:20px;" />-->
|
||
<!-- </button>-->
|
||
<upload-image
|
||
v-if="uploadImageVisible"
|
||
:visible.sync="uploadImageVisible"
|
||
:subject-id="subjectId"
|
||
:criterion="trialCriterion"
|
||
:status="uploadStatus"
|
||
/>
|
||
</div>
|
||
</template>
|
||
<script>
|
||
import * as cornerstone from 'cornerstone-core'
|
||
import * as cornerstoneMath from 'cornerstone-math'
|
||
import * as cornerstoneTools from 'cornerstone-tools'
|
||
import Hammer from 'hammerjs'
|
||
cornerstoneTools.external.cornerstone = cornerstone
|
||
cornerstoneTools.external.Hammer = Hammer
|
||
cornerstoneTools.external.cornerstoneMath = cornerstoneMath
|
||
|
||
// import DicomCanvas from './DicomCanvas'
|
||
import DicomCanvas from '@/views/trials/trials-panel/reading/dicoms/customize/CustomizeDicomCanvas.vue'
|
||
import MeasurementList from './CustomizeMeasurementList'
|
||
import CustomWwwcForm from './CustomWwwcForm'
|
||
import Manuals from './Manuals'
|
||
import Hotkeys from './Hotkeys'
|
||
import WL from './WL'
|
||
import Others from './Others'
|
||
import DicomEvent from './../components/DicomEvent'
|
||
import { mapGetters } from 'vuex'
|
||
import store from '@/store'
|
||
import { getDoctorShortcutKey, getUserWLTemplateList } from '@/api/user'
|
||
import uploadImage from '@/components/uploadImage'
|
||
import { getCriterionReadingInfo } from '@/api/trials'
|
||
export default {
|
||
name: 'DicomViewer',
|
||
components: {
|
||
DicomCanvas,
|
||
CustomWwwcForm,
|
||
Hotkeys,
|
||
WL,
|
||
Others,
|
||
Manuals,
|
||
MeasurementList,
|
||
'upload-image': uploadImage
|
||
},
|
||
props: {
|
||
isExistsClinicalData: {
|
||
type: Boolean,
|
||
default: false
|
||
},
|
||
isExistsNoDicomFile: {
|
||
type: Boolean,
|
||
default: false
|
||
},
|
||
isExistsManual: {
|
||
type: Boolean,
|
||
required: true
|
||
},
|
||
isReadingShowSubjectInfo: {
|
||
type: Boolean,
|
||
required: true
|
||
},
|
||
isReadingTaskViewInOrder: {
|
||
type: Number,
|
||
required: true
|
||
},
|
||
IseCRFShowInDicomReading: {
|
||
type: Boolean,
|
||
required: true
|
||
},
|
||
subjectId: {
|
||
type: String,
|
||
required: true,
|
||
default: ''
|
||
},
|
||
trialReadingCriterionId: {
|
||
type: String,
|
||
required: true,
|
||
default: ''
|
||
},
|
||
trialId: {
|
||
type: String,
|
||
required: true,
|
||
default: ''
|
||
}
|
||
},
|
||
data() {
|
||
return {
|
||
cornerstoneStyle: {},
|
||
layouts: [
|
||
{ index: 0, row: 1, col: 1, name: 'A' },
|
||
{ index: 1, row: 1, col: 2, name: 'A|A' },
|
||
{ index: 2, row: 1, col: 2, name: 'A|B' },
|
||
{ index: 3, row: 2, col: 2, name: 'A|A|A|A' }
|
||
// { index: 2, row: 2, col: 1 },
|
||
// { index: 3, row: 2, col: 2 }
|
||
],
|
||
rotateArr: [
|
||
{ label: this.$t('trials:reading:button:rotateDefault'), val: 1 }, // 默认值
|
||
{ label: this.$t('trials:reading:button:rotateVertical'), val: 2 }, // 垂直翻转
|
||
{ label: this.$t('trials:reading:button:rotateHorizontal'), val: 3 }, // 水平翻转
|
||
{ label: this.$t('trials:reading:button:rotateTurnLeft'), val: 4 }, // 左转90度
|
||
{ label: this.$t('trials:reading:button:rotateTurnRight'), val: 5 } // 右转90度
|
||
],
|
||
maxCanvas: 1,
|
||
layoutRow: 1,
|
||
layoutCol: 1,
|
||
currentDicomCanvasIndex: 0,
|
||
currentDicomCanvas: {
|
||
toolState: {
|
||
clipPlaying: false
|
||
}
|
||
},
|
||
colormapsList: [],
|
||
rotateList: [],
|
||
colorList: [],
|
||
wwwcList: [],
|
||
canvasW: null,
|
||
canvasH: null,
|
||
activeTool: '',
|
||
CriterionType: 0,
|
||
measuredTools: [
|
||
// 直径测量
|
||
{
|
||
toolName: 'Length',
|
||
text: this.$t('trials:reading:button:length'),
|
||
icon: 'length',
|
||
isDisabled: false,
|
||
disabledReason: ''
|
||
},
|
||
// 长短径测量
|
||
{
|
||
toolName: 'Bidirectional',
|
||
text: this.$t('trials:reading:button:bidirectional'),
|
||
icon: 'bidirection',
|
||
isDisabled: false,
|
||
disabledReason: ''
|
||
},
|
||
// 矩形工具
|
||
{
|
||
toolName: 'RectangleRoi',
|
||
text: this.$t('trials:reading:button:rectangle'),
|
||
icon: 'rectangle',
|
||
isDisabled: false,
|
||
disabledReason: ''
|
||
},
|
||
// 圆形工具
|
||
{
|
||
toolName: 'CircleRoi',
|
||
text: this.$t('trials:reading:button:elliptical'),
|
||
icon: 'oval',
|
||
isDisabled: false,
|
||
disabledReason: ''
|
||
},
|
||
// 箭头工具
|
||
{
|
||
toolName: 'ArrowAnnotate',
|
||
text: this.$t('trials:reading:button:arrowAnnotate'),
|
||
icon: 'arrow',
|
||
isDisabled: false,
|
||
disabledReason: ''
|
||
}
|
||
],
|
||
|
||
fitType: 0,
|
||
isDisabledTool: false,
|
||
canvasObj: {},
|
||
wwwcArr: [],
|
||
defaultWwwc: [
|
||
{
|
||
label: this.$t('trials:reading:button:wwwcDefault'),
|
||
val: -1,
|
||
ww: null,
|
||
wc: null
|
||
}, // 默认值
|
||
{
|
||
label: this.$t('trials:reading:button:wwwcCustom'),
|
||
val: 0,
|
||
ww: null,
|
||
wc: null
|
||
}, // 自定义
|
||
{
|
||
label: this.$t('trials:reading:button:wwwcRegion'),
|
||
val: 1,
|
||
ww: null,
|
||
wc: null
|
||
}, // 区域窗宽
|
||
{ label: 'CT Brain', wc: 40, ww: 80 },
|
||
{ label: 'CT Lungs', wc: -400, ww: 1500 },
|
||
{ label: 'CT Abdomen', wc: 60, ww: 400 },
|
||
{ label: 'CT Liver', wc: 40, ww: 400 },
|
||
{ label: 'CT Bone', wc: 300, ww: 1500 }
|
||
],
|
||
activeSeries: {},
|
||
seriesStack: [],
|
||
// trialId: "",
|
||
isScrollSync: false,
|
||
imageIndexSync: {
|
||
sourceCanvas: '',
|
||
targetCanvas: []
|
||
},
|
||
isFirstRender: false,
|
||
customWwc: { visible: false, title: null }, // 自定义调窗
|
||
personalConfigDialog: {
|
||
visible: false,
|
||
title: this.$t('trials:reading:button:customCfg')
|
||
}, // 个性化配置
|
||
layout: '',
|
||
isFirstNotLinked: false,
|
||
hotKeyList: [],
|
||
activeName: '1',
|
||
customWwcTpl: [],
|
||
isFullscreen: false,
|
||
manualsDialog: { visible: false },
|
||
clipPlaying: false,
|
||
fps: 15,
|
||
// 上传
|
||
uploadImageVisible: false,
|
||
trialCriterion: {},
|
||
uploadStatus: 'upload'
|
||
}
|
||
},
|
||
|
||
computed: {
|
||
...mapGetters(['visitTaskList', 'currentReadingTaskState'])
|
||
},
|
||
watch: {
|
||
currentReadingTaskState: {
|
||
immediate: true,
|
||
handler(val) {
|
||
if (
|
||
val &&
|
||
this.currentDicomCanvasIndex &&
|
||
this.$refs[`dicomCanvas${this.currentDicomCanvasIndex}`]
|
||
) {
|
||
this.canvasObj[this.currentDicomCanvasIndex].readingTaskState = val
|
||
if (this.activeTool) {
|
||
this.$refs[
|
||
`dicomCanvas${this.currentDicomCanvasIndex}`
|
||
][0].setToolEnabled(this.activeTool)
|
||
this.activeTool = ''
|
||
}
|
||
}
|
||
}
|
||
},
|
||
currentDicomCanvasIndex: {
|
||
immediate: true,
|
||
handler(v) {
|
||
if (
|
||
this.$refs[`dicomCanvas${this.currentDicomCanvasIndex}`] &&
|
||
this.$refs[`dicomCanvas${this.currentDicomCanvasIndex}`][0]
|
||
) {
|
||
this.clipPlaying =
|
||
this.$refs[
|
||
`dicomCanvas${this.currentDicomCanvasIndex}`
|
||
][0].toolState.clipPlaying
|
||
} else {
|
||
this.clipPlaying = false
|
||
this.fps = 15
|
||
}
|
||
}
|
||
}
|
||
},
|
||
mounted() {
|
||
this.getTrialCriterion()
|
||
this.getHotKeys()
|
||
this.getWwcTpl()
|
||
// cornerstone.imageCache.setMaximumSizeBytes(0)
|
||
|
||
const maximumSizeInBytes = 1024 * 1024 * 1024 // 1 GB
|
||
// const maximumSizeInBytes = 1024 * 1024 * 500
|
||
cornerstone.imageCache.setMaximumSizeBytes(maximumSizeInBytes)
|
||
this.customWwc = {
|
||
visible: false,
|
||
title: this.$t('trials:reading:dagTitle:wwwcCustom')
|
||
}
|
||
this.CriterionType = parseInt(localStorage.getItem('CriterionType'))
|
||
if (this.CriterionType === 10) {
|
||
this.measuredTools = [
|
||
{
|
||
toolName: 'ArrowAnnotate',
|
||
text: this.$t('trials:reading:button:arrowAnnotate'),
|
||
icon: 'arrow',
|
||
isDisabled: false,
|
||
disabledReason: ''
|
||
},
|
||
{
|
||
toolName: 'RectangleRoi',
|
||
text: this.$t('trials:reading:button:rectangle'),
|
||
icon: 'rectangle',
|
||
isDisabled: false,
|
||
disabledReason: ''
|
||
}
|
||
]
|
||
} else if (this.CriterionType === 17) {
|
||
this.measuredTools = [
|
||
{
|
||
toolName: 'Length',
|
||
text: this.$t('trials:reading:button:length'),
|
||
icon: 'length',
|
||
isDisabled: false,
|
||
disabledReason: ''
|
||
},
|
||
{
|
||
toolName: 'RectangleRoi',
|
||
text: this.$t('trials:reading:button:rectangle'),
|
||
icon: 'rectangle',
|
||
isDisabled: false,
|
||
disabledReason: ''
|
||
},
|
||
{
|
||
toolName: 'ArrowAnnotate',
|
||
text: this.$t('trials:reading:button:arrowAnnotate'),
|
||
icon: 'arrow',
|
||
isDisabled: false,
|
||
disabledReason: ''
|
||
}
|
||
]
|
||
}
|
||
this.rotateList[0] = '1'
|
||
this.colorList[0] = ''
|
||
this.wwwcList[0] = '1'
|
||
this.colormapsList = cornerstone.colors.getColormapsList()
|
||
this.currentDicomCanvas = this.$refs['dicomCanvas0']
|
||
? this.$refs['dicomCanvas0'][0]
|
||
: ''
|
||
// this.trialId = this.$router.currentRoute.query.trialId;
|
||
this.setCanvasStyle()
|
||
window.addEventListener('resize', this.setCanvasStyle)
|
||
|
||
// DicomEvent.$on('updateImage', (instanceId) => {
|
||
|
||
// for (let i = 0; i < this.maxCanvas; i++) {
|
||
// var stack = this.$refs[`dicomCanvas${this.currentDicomCanvasIndex}`][0].stack
|
||
// if (stack.studyId) {
|
||
// this.$refs[`dicomCanvas${this.currentDicomCanvasIndex}`][0].updateImage(instanceId)
|
||
// }
|
||
// }
|
||
// })
|
||
DicomEvent.$on('getMeasureData', () => {
|
||
for (let i = 0; i < this.maxCanvas; i++) {
|
||
var stack = this.$refs[`dicomCanvas${i}`][0].stack
|
||
if (stack.visitTaskId) {
|
||
this.$refs[`dicomCanvas${i}`][0].getMeasureData()
|
||
}
|
||
}
|
||
console.log('getMeasureData')
|
||
})
|
||
|
||
DicomEvent.$on('getScreenshots', (callback) => {
|
||
var base64Str =
|
||
this.$refs[
|
||
`dicomCanvas${this.currentDicomCanvasIndex}`
|
||
][0].getScreenshots()
|
||
callback(base64Str)
|
||
console.log('getScreenshots')
|
||
})
|
||
DicomEvent.$on('imageLocation', (measuredData) => {
|
||
if (!measuredData) return
|
||
this.imageLocation(measuredData)
|
||
console.log('imageLocation')
|
||
})
|
||
DicomEvent.$on('setReadingState', (readingTaskState) => {
|
||
this.canvasObj[this.currentDicomCanvasIndex].readingTaskState =
|
||
readingTaskState
|
||
if (this.activeTool) {
|
||
this.$refs[
|
||
`dicomCanvas${this.currentDicomCanvasIndex}`
|
||
][0].setToolEnabled(this.activeTool)
|
||
this.activeTool = ''
|
||
}
|
||
})
|
||
DicomEvent.$on('PGWC3Active', (res) => {
|
||
this.setToolActive('ArrowAnnotate', true, null, 'open')
|
||
})
|
||
DicomEvent.$on('loadImageStacks', (seriesList) => {
|
||
this.loadImageStacks(seriesList)
|
||
console.log('loadImageStacks')
|
||
})
|
||
DicomEvent.$on('loadLinkedImageStack', (seriesInfo) => {
|
||
this.loadLinkedImageStack(seriesInfo)
|
||
console.log('loadLinkedImageStack')
|
||
})
|
||
},
|
||
beforeDestroy() {
|
||
DicomEvent.$off('updateImage')
|
||
DicomEvent.$off('getMeasureData')
|
||
DicomEvent.$off('imageLocation')
|
||
DicomEvent.$off('setReadingState')
|
||
DicomEvent.$off('loadImageStacks')
|
||
DicomEvent.$off('loadLinkedImageStack')
|
||
},
|
||
methods: {
|
||
getTrialCriterion() {
|
||
getCriterionReadingInfo({
|
||
TrialId: this.trialId,
|
||
TrialReadingCriterionId: this.trialReadingCriterionId
|
||
})
|
||
.then((res) => {
|
||
this.trialCriterion = res.Result
|
||
})
|
||
.catch(() => {})
|
||
},
|
||
openUploadImage(status) {
|
||
this.uploadStatus = status
|
||
this.uploadImageVisible = true
|
||
},
|
||
getWwcTpl() {
|
||
const loading = this.$loading({ fullscreen: true })
|
||
getUserWLTemplateList()
|
||
.then((res) => {
|
||
this.customWwcTpl = []
|
||
res.Result.map((i) => {
|
||
this.customWwcTpl.push({
|
||
label: i.TemplateName,
|
||
wc: i.WL,
|
||
ww: i.WW
|
||
})
|
||
})
|
||
this.wwwcArr = [...this.defaultWwwc, ...this.customWwcTpl]
|
||
loading.close()
|
||
})
|
||
.catch(() => {
|
||
loading.close()
|
||
})
|
||
},
|
||
getHotKeys() {
|
||
const loading = this.$loading({ fullscreen: true })
|
||
getDoctorShortcutKey({ imageToolType: 0 })
|
||
.then((res) => {
|
||
res.Result.map((item) => {
|
||
this.hotKeyList.push({
|
||
id: item.Id,
|
||
altKey: item.AltKey,
|
||
ctrlKey: item.CtrlKey,
|
||
shiftKey: item.ShiftKey,
|
||
metaKey: item.MetaKey,
|
||
key: item.Keyboardkey,
|
||
code: item.Code,
|
||
text: item.Text,
|
||
shortcutKeyEnum: item.ShortcutKeyEnum
|
||
})
|
||
})
|
||
this.bindHotKey()
|
||
loading.close()
|
||
})
|
||
.catch(() => {
|
||
loading.close()
|
||
})
|
||
},
|
||
resetHotkeyList(arr) {
|
||
this.hotKeyList = []
|
||
|
||
arr.map((item) => {
|
||
this.hotKeyList.push({
|
||
id: item.id,
|
||
altKey: item.keys.controlKey.altKey,
|
||
ctrlKey: item.keys.controlKey.ctrlKey,
|
||
shiftKey: item.keys.controlKey.shiftKey,
|
||
metaKey: item.keys.controlKey.metaKey,
|
||
key: item.keys.controlKey.key,
|
||
code: item.keys.controlKey.code,
|
||
text: item.keys.text,
|
||
shortcutKeyEnum: item.label
|
||
})
|
||
})
|
||
|
||
// const loading = this.$loading({ fullscreen: true })
|
||
// getDoctorShortcutKey({ imageToolType: 0 }).then(res => {
|
||
// res.Result.map(item => {
|
||
// this.hotKeyList.push({ id: item.Id, altKey: item.AltKey, ctrlKey: item.CtrlKey, shiftKey: item.ShiftKey, metaKey: item.MetaKey, key: item.Keyboardkey, code: item.Code, text: item.Text, shortcutKeyEnum: item.ShortcutKeyEnum })
|
||
// })
|
||
// loading.close()
|
||
// }).catch(() => {
|
||
// loading.close()
|
||
// })
|
||
},
|
||
bindHotKey() {
|
||
var container = this.$refs['container']
|
||
// window.addEventListener
|
||
container.addEventListener('keydown', (event) => {
|
||
console.log(event)
|
||
event.preventDefault()
|
||
var idx = this.hotKeyList.findIndex(
|
||
(i) =>
|
||
i.code === event.code &&
|
||
i.ctrlKey === event.ctrlKey &&
|
||
i.shiftKey === event.shiftKey &&
|
||
i.altKey === event.altKey
|
||
)
|
||
if (idx === -1) return
|
||
var shortcutKeyEnum = this.hotKeyList[idx].shortcutKeyEnum
|
||
console.log(shortcutKeyEnum)
|
||
if (shortcutKeyEnum === 1) {
|
||
// 前一图像视口
|
||
this.selectViewCanvas(-1)
|
||
} else if (shortcutKeyEnum === 2) {
|
||
// 后一图像视口
|
||
this.selectViewCanvas(1)
|
||
} else if (shortcutKeyEnum === 3) {
|
||
// 上一个序列
|
||
const series =
|
||
this.$refs[`dicomCanvas${this.currentDicomCanvasIndex}`][0].series
|
||
DicomEvent.$emit('selectSeries', {
|
||
seriesId: series.seriesId,
|
||
studyId: series.studyId,
|
||
offset: -1
|
||
})
|
||
} else if (shortcutKeyEnum === 4) {
|
||
// 下一个序列
|
||
const series =
|
||
this.$refs[`dicomCanvas${this.currentDicomCanvasIndex}`][0].series
|
||
DicomEvent.$emit('selectSeries', {
|
||
seriesId: series.seriesId,
|
||
studyId: series.studyId,
|
||
offset: 1
|
||
})
|
||
} else if (shortcutKeyEnum === 5) {
|
||
// 上一张图像
|
||
this.$refs[
|
||
`dicomCanvas${this.currentDicomCanvasIndex}`
|
||
][0].scrollPage(-1)
|
||
} else if (shortcutKeyEnum === 6) {
|
||
// 下一张图像
|
||
this.$refs[
|
||
`dicomCanvas${this.currentDicomCanvasIndex}`
|
||
][0].scrollPage(1)
|
||
} else if (shortcutKeyEnum === 7) {
|
||
// 向左旋转
|
||
this.$refs[`dicomCanvas${this.currentDicomCanvasIndex}`][0].setRotate(
|
||
false,
|
||
false,
|
||
-90,
|
||
4
|
||
)
|
||
} else if (shortcutKeyEnum === 8) {
|
||
// 向右旋转
|
||
this.$refs[`dicomCanvas${this.currentDicomCanvasIndex}`][0].setRotate(
|
||
false,
|
||
false,
|
||
90,
|
||
5
|
||
)
|
||
} else if (shortcutKeyEnum === 9) {
|
||
// 水平翻转
|
||
this.$refs[`dicomCanvas${this.currentDicomCanvasIndex}`][0].setRotate(
|
||
true,
|
||
false,
|
||
0,
|
||
3
|
||
)
|
||
} else if (shortcutKeyEnum === 10) {
|
||
// 垂直翻转
|
||
this.$refs[`dicomCanvas${this.currentDicomCanvasIndex}`][0].setRotate(
|
||
false,
|
||
true,
|
||
0,
|
||
2
|
||
)
|
||
} else if (shortcutKeyEnum === 11) {
|
||
// 放大
|
||
this.$refs[
|
||
`dicomCanvas${this.currentDicomCanvasIndex}`
|
||
][0].setZoomScale(1)
|
||
} else if (shortcutKeyEnum === 12) {
|
||
// 缩小
|
||
this.$refs[
|
||
`dicomCanvas${this.currentDicomCanvasIndex}`
|
||
][0].setZoomScale(0)
|
||
} else if (shortcutKeyEnum === 13) {
|
||
// 适应图像
|
||
this.$refs[
|
||
`dicomCanvas${this.currentDicomCanvasIndex}`
|
||
][0].fitToImage()
|
||
} else if (shortcutKeyEnum === 14) {
|
||
// 适应窗口
|
||
this.$refs[
|
||
`dicomCanvas${this.currentDicomCanvasIndex}`
|
||
][0].fitToWindow()
|
||
} else if (shortcutKeyEnum === 15) {
|
||
// 截图
|
||
this.$refs[
|
||
`dicomCanvas${this.currentDicomCanvasIndex}`
|
||
][0].saveImage()
|
||
} else if (shortcutKeyEnum === 16) {
|
||
// 反色
|
||
this.$refs[
|
||
`dicomCanvas${this.currentDicomCanvasIndex}`
|
||
][0].toggleInvert()
|
||
} else if (shortcutKeyEnum === 17) {
|
||
// 窗宽/窗位
|
||
var wwwcArrIdx =
|
||
this.$refs[`dicomCanvas${this.currentDicomCanvasIndex}`][0]
|
||
.wwwcArrIdx
|
||
var wwwcArr =
|
||
this.$refs[`dicomCanvas${this.currentDicomCanvasIndex}`][0].wwwcArr
|
||
if (wwwcArrIdx + 1 === wwwcArr.length) {
|
||
this.$refs[
|
||
`dicomCanvas${this.currentDicomCanvasIndex}`
|
||
][0].wwwcArrIdx = 0
|
||
} else {
|
||
++this.$refs[`dicomCanvas${this.currentDicomCanvasIndex}`][0]
|
||
.wwwcArrIdx
|
||
}
|
||
this.$refs[`dicomCanvas${this.currentDicomCanvasIndex}`][0].setWwwc(
|
||
wwwcArr[wwwcArrIdx].ww,
|
||
wwwcArr[wwwcArrIdx].wc
|
||
)
|
||
} else if (shortcutKeyEnum === 18) {
|
||
// 重置
|
||
this.$refs[
|
||
`dicomCanvas${this.currentDicomCanvasIndex}`
|
||
][0].resetViewport()
|
||
} else if (shortcutKeyEnum === 19) {
|
||
// 显示或隐藏标记
|
||
if (
|
||
this.$refs[`dicomCanvas${this.currentDicomCanvasIndex}`][0]
|
||
.readingTaskState < 2
|
||
) {
|
||
this.$refs[
|
||
`dicomCanvas${this.currentDicomCanvasIndex}`
|
||
][0].setMeasureDataVisible()
|
||
}
|
||
}
|
||
})
|
||
},
|
||
resetViewport() {
|
||
this.$refs[
|
||
`dicomCanvas${this.currentDicomCanvasIndex}`
|
||
][0].resetViewport()
|
||
},
|
||
previewConfig() {
|
||
this.activeName = '1'
|
||
this.personalConfigDialog.visible = true
|
||
},
|
||
setCornerstoneStyle(i) {
|
||
if (this.cornerstoneStyle.position) {
|
||
this.cornerstoneStyle = {}
|
||
this.setCanvasStyle()
|
||
} else {
|
||
this.cornerstoneStyle = {
|
||
position: 'absolute',
|
||
top: '72px',
|
||
left: '205px',
|
||
right: '350px',
|
||
zIndex: 10
|
||
}
|
||
this.canvasW = window.innerWidth - 570 + 'px'
|
||
this.canvasH = window.innerHeight - 130 + 'px'
|
||
}
|
||
this.$nextTick(() => {
|
||
// this.$refs[`dicomCanvas${this.currentDicomCanvasIndex}`][0].reloadCanvas()
|
||
for (var i = 0; i < this.maxCanvas; i++) {
|
||
this.$refs[`dicomCanvas${i}`][0].reloadCanvas()
|
||
}
|
||
})
|
||
},
|
||
loadImageStacks(seriesList) {
|
||
if (seriesList.length === 0) {
|
||
const idx = this.visitTaskList.findIndex((i) => i.IsCurrentTask)
|
||
if (idx > -1) {
|
||
store.dispatch(
|
||
'reading/setLastCanvasTaskId',
|
||
this.visitTaskList[idx].VisitTaskId
|
||
)
|
||
}
|
||
|
||
return
|
||
}
|
||
var l = seriesList.length > 1 ? 'A|B' : 'A'
|
||
this.layout = l
|
||
var i = this.layouts.findIndex((i) => i.name === l)
|
||
var layout = this.layouts[i]
|
||
this.layoutRow = layout.row
|
||
this.layoutCol = layout.col
|
||
this.setCanvasStyle()
|
||
this.maxCanvas = layout.row * layout.col
|
||
this.$nextTick(() => {
|
||
const elements = document.querySelectorAll('.cornerstone-element')
|
||
Array.from(elements).forEach((element) => {
|
||
cornerstone.enable(element)
|
||
cornerstone.resize(element)
|
||
})
|
||
seriesList.map((series, index) => {
|
||
this.canvasObj[index] = series
|
||
if (series.isCurrentTask) {
|
||
this.currentDicomCanvasIndex = index
|
||
this.activeSeries = series
|
||
|
||
// this.$refs['measurementList'].initPage(series)
|
||
store.dispatch('reading/setActiveSeries', series)
|
||
store.dispatch('reading/setLastCanvasTaskId', series.visitTaskId)
|
||
}
|
||
this.$refs[`dicomCanvas${index}`][0].loadImageStack(series)
|
||
|
||
if (this.activeTool) {
|
||
if (series.isCurrentTask && series.readingTaskState < 2) {
|
||
this.$nextTick(() => {
|
||
this.$refs[`dicomCanvas${index}`][0].setToolPassive(
|
||
this.activeTool
|
||
)
|
||
})
|
||
} else {
|
||
this.$nextTick(() => {
|
||
this.$refs[`dicomCanvas${index}`][0].setToolEnabled(
|
||
this.activeTool
|
||
)
|
||
})
|
||
}
|
||
this.activeTool = ''
|
||
}
|
||
})
|
||
})
|
||
},
|
||
loadImageStack(dicomSeries) {
|
||
this.clipPlaying = false
|
||
this.fps = 15
|
||
this.canvasObj[this.currentDicomCanvasIndex] = dicomSeries
|
||
if (this.activeTool) {
|
||
// dicomSeries.isCurrentTask && dicomSeries.readingTaskState < 2
|
||
if (dicomSeries.isCurrentTask) {
|
||
this.$nextTick(() => {
|
||
this.$refs[
|
||
`dicomCanvas${this.currentDicomCanvasIndex}`
|
||
][0].setToolPassive(this.activeTool)
|
||
})
|
||
} else {
|
||
this.$nextTick(() => {
|
||
this.$refs[
|
||
`dicomCanvas${this.currentDicomCanvasIndex}`
|
||
][0].setToolEnabled(this.activeTool)
|
||
})
|
||
}
|
||
this.activeTool = ''
|
||
}
|
||
this.$nextTick(() => {
|
||
this.activeSeries = dicomSeries
|
||
this.$refs[
|
||
`dicomCanvas${this.currentDicomCanvasIndex}`
|
||
][0].loadImageStack(dicomSeries)
|
||
// this.$refs['measurementList'].initPage(dicomSeries)
|
||
store.dispatch('reading/setActiveSeries', dicomSeries)
|
||
if (this.currentDicomCanvasIndex === this.maxCanvas - 1) {
|
||
store.dispatch(
|
||
'reading/setLastCanvasTaskId',
|
||
dicomSeries.visitTaskId
|
||
)
|
||
}
|
||
})
|
||
},
|
||
loadLinkedImageStack(dicomSeries) {
|
||
this.currentDicomCanvasIndex = dicomSeries.canvasIndex
|
||
var canvasIndex = dicomSeries.canvasIndex
|
||
this.canvasObj[canvasIndex] = dicomSeries
|
||
if (this.activeTool) {
|
||
if (dicomSeries.isCurrentTask && dicomSeries.readingTaskState < 2) {
|
||
this.$nextTick(() => {
|
||
this.$refs[`dicomCanvas${canvasIndex}`][0].setToolPassive(
|
||
this.activeTool
|
||
)
|
||
})
|
||
} else {
|
||
this.$nextTick(() => {
|
||
this.$refs[`dicomCanvas${canvasIndex}`][0].setToolEnabled(
|
||
this.activeTool
|
||
)
|
||
})
|
||
}
|
||
this.activeTool = ''
|
||
}
|
||
this.$nextTick(() => {
|
||
this.activeSeries = dicomSeries
|
||
this.$refs[`dicomCanvas${canvasIndex}`][0].loadImageStack(dicomSeries)
|
||
|
||
store.dispatch('reading/setActiveSeries', dicomSeries)
|
||
if (this.currentDicomCanvasIndex === this.maxCanvas - 1) {
|
||
store.dispatch(
|
||
'reading/setLastCanvasTaskId',
|
||
dicomSeries.visitTaskId
|
||
)
|
||
}
|
||
})
|
||
},
|
||
// 给显示的画布设置显示的序列信息
|
||
async getSeriesShowInCanvas(layout) {
|
||
var activeSeries = Object.assign({}, this.activeSeries)
|
||
const loading = this.$loading({ fullscreen: true })
|
||
if (layout.name === 'A') {
|
||
// 判断当前激活窗口是否有序列信息
|
||
if (activeSeries) {
|
||
this.seriesStack = [activeSeries]
|
||
this.currentDicomCanvasIndex = 0
|
||
store.dispatch(
|
||
'reading/setLastCanvasTaskId',
|
||
activeSeries.visitTaskId
|
||
)
|
||
await this.setCanvas(this.seriesStack)
|
||
loading.close()
|
||
}
|
||
} else if (layout.name === 'A|A') {
|
||
if (activeSeries) {
|
||
this.seriesStack = [activeSeries, activeSeries]
|
||
this.currentDicomCanvasIndex = 1
|
||
store.dispatch(
|
||
'reading/setLastCanvasTaskId',
|
||
activeSeries.visitTaskId
|
||
)
|
||
await this.setCanvas(this.seriesStack)
|
||
loading.close()
|
||
}
|
||
} else if (layout.name === 'A|B') {
|
||
if (activeSeries) {
|
||
const idx = this.visitTaskList.findIndex(
|
||
(i) => i.VisitTaskId === activeSeries.visitTaskId
|
||
)
|
||
const visitTaskNum =
|
||
idx > -1 ? this.visitTaskList[idx].VisitTaskNum : -1
|
||
if (visitTaskNum > 0 && this.visitTaskList.length > 1) {
|
||
var visitTaskId = ''
|
||
if (this.CriterionType === 10) {
|
||
const i = this.visitTaskList.findIndex(
|
||
(i) => i.VisitTaskNum === visitTaskNum - 1
|
||
)
|
||
visitTaskId = this.visitTaskList[i].VisitTaskId
|
||
} else {
|
||
const i = this.visitTaskList.findIndex((i) => i.IsBaseLineTask)
|
||
visitTaskId = this.visitTaskList[i].VisitTaskId
|
||
}
|
||
this.getFirstSeries(activeSeries, visitTaskId).then(
|
||
async(baseSerires) => {
|
||
this.seriesStack = [baseSerires, activeSeries]
|
||
this.currentDicomCanvasIndex = 1
|
||
store.dispatch(
|
||
'reading/setLastCanvasTaskId',
|
||
activeSeries.visitTaskId
|
||
)
|
||
await this.setCanvas(this.seriesStack)
|
||
loading.close()
|
||
}
|
||
)
|
||
} else {
|
||
this.seriesStack = [activeSeries, activeSeries]
|
||
this.currentDicomCanvasIndex = 1
|
||
store.dispatch(
|
||
'reading/setLastCanvasTaskId',
|
||
activeSeries.visitTaskId
|
||
)
|
||
await this.setCanvas(this.seriesStack)
|
||
loading.close()
|
||
}
|
||
}
|
||
} else if (layout.name === 'A|A|A|A') {
|
||
if (activeSeries) {
|
||
this.seriesStack = [
|
||
activeSeries,
|
||
activeSeries,
|
||
activeSeries,
|
||
activeSeries
|
||
]
|
||
this.currentDicomCanvasIndex = 3
|
||
store.dispatch(
|
||
'reading/setLastCanvasTaskId',
|
||
activeSeries.visitTaskId
|
||
)
|
||
await this.setCanvas(this.seriesStack)
|
||
loading.close()
|
||
}
|
||
}
|
||
},
|
||
// 设置画布序列信息
|
||
setCanvas(seriesStack) {
|
||
return new Promise((resolve) => {
|
||
var promiseArr = []
|
||
for (let i = 0; i < this.maxCanvas && i < seriesStack.length; i++) {
|
||
this.canvasObj[i] = seriesStack[i]
|
||
promiseArr.push(
|
||
this.$refs[`dicomCanvas${i}`][0].loadImageStack(seriesStack[i])
|
||
)
|
||
}
|
||
Promise.all(promiseArr)
|
||
.then(() => {
|
||
// this.activateDicomCanvas(this.currentDicomCanvasIndex)
|
||
resolve()
|
||
})
|
||
.catch(() => {
|
||
resolve()
|
||
})
|
||
})
|
||
},
|
||
// 根据病灶标识定位图像
|
||
|
||
// 最后一个窗口显示当前访视下病灶所在的影像序列
|
||
// 其他窗口显示该病灶第一次出现的序列信息
|
||
async imageLocation(obj) {
|
||
var loading = null
|
||
var loadImagePromises = []
|
||
var isScrollSync = this.isScrollSync
|
||
if (this.isScrollSync) {
|
||
// 取消滚动同步
|
||
this.isScrollSync = false
|
||
}
|
||
|
||
var activeCanvasTaskId = obj.visitTaskId
|
||
|
||
var index = this.visitTaskList.findIndex(
|
||
(i) => i.VisitTaskId === activeCanvasTaskId
|
||
)
|
||
if (index === -1) return
|
||
|
||
var firstAddSeries = null
|
||
var currentAddSeries = null
|
||
if (this.isReadingTaskViewInOrder === 1) {
|
||
// 有序
|
||
// 获取病灶第一次出现的访视序列
|
||
var firstAddVisitTaskId = null
|
||
var idx = this.visitTaskList[index].MeasureData.findIndex((item) => {
|
||
return item.OrderMarkName === obj.lesionName
|
||
})
|
||
if (idx > -1) {
|
||
firstAddVisitTaskId =
|
||
this.visitTaskList[index].MeasureData[idx].FristAddTaskId
|
||
}
|
||
if (firstAddVisitTaskId) {
|
||
var taskIdx = this.visitTaskList.findIndex(
|
||
(i) => i.VisitTaskId === firstAddVisitTaskId
|
||
)
|
||
if (taskIdx > -1 && !this.visitTaskList[taskIdx].IsInit) {
|
||
loading = this.$loading({ fullscreen: true })
|
||
if (!this.visitTaskList[taskIdx].measureDataInit) {
|
||
await store.dispatch(
|
||
'reading/getMeasuredData',
|
||
this.visitTaskList[taskIdx].VisitTaskId
|
||
)
|
||
}
|
||
if (!this.visitTaskList[taskIdx].studyListInit) {
|
||
await store.dispatch('reading/getStudyInfo', {
|
||
trialId: this.trialId,
|
||
subjectVisitId: this.visitTaskList[taskIdx].VisitId,
|
||
visitTaskId: this.visitTaskList[taskIdx].VisitTaskId,
|
||
taskBlindName: this.visitTaskList[taskIdx].TaskBlindName
|
||
})
|
||
}
|
||
if (!this.visitTaskList[taskIdx].readingQuestionsInit) {
|
||
await store.dispatch('reading/getReadingQuestionAndAnswer', {
|
||
trialId: this.trialId,
|
||
visitTaskId: this.visitTaskList[taskIdx].VisitTaskId
|
||
})
|
||
}
|
||
if (!this.visitTaskList[taskIdx].questionsInit) {
|
||
await store.dispatch('reading/getDicomReadingQuestionAnswer', {
|
||
trialId: this.trialId,
|
||
visitTaskId: this.visitTaskList[taskIdx].VisitTaskId
|
||
})
|
||
}
|
||
|
||
await store.dispatch('reading/setStatus', {
|
||
visitTaskId: this.visitTaskList[taskIdx].VisitTaskId
|
||
})
|
||
}
|
||
firstAddSeries = this.getSeriesInfoByMark(firstAddVisitTaskId, obj)
|
||
}
|
||
|
||
// 获取当前访视病灶所在的序列
|
||
currentAddSeries = this.getSeriesInfoByMark(activeCanvasTaskId, obj)
|
||
if (!firstAddSeries && currentAddSeries) {
|
||
// 存在首次出现的病灶及当前病灶
|
||
firstAddSeries = currentAddSeries
|
||
} else if (!firstAddSeries && !currentAddSeries) {
|
||
// 当前新病灶,且未画标记则显示当前的序列信息,不做处理
|
||
loading && loading.close()
|
||
return
|
||
} else if (firstAddSeries && !currentAddSeries) {
|
||
// 当前访视序列与首次出现病灶的序列对齐
|
||
currentAddSeries = this.getLinkedSeries(
|
||
firstAddSeries,
|
||
activeCanvasTaskId
|
||
)
|
||
if (!currentAddSeries) {
|
||
// 未找到对齐的,则就显示当前最后一个窗口现实的序列信息
|
||
currentAddSeries =
|
||
this.$refs[`dicomCanvas${this.maxCanvas - 1}`][0].series
|
||
}
|
||
}
|
||
} else {
|
||
// 无序
|
||
currentAddSeries = this.getSeriesInfoByMark(activeCanvasTaskId, obj)
|
||
if (!currentAddSeries) {
|
||
// 未找到对齐的,则就显示当前最后一个窗口现实的序列信息
|
||
currentAddSeries =
|
||
this.$refs[`dicomCanvas${this.maxCanvas - 1}`][0].series
|
||
}
|
||
firstAddSeries = currentAddSeries
|
||
}
|
||
|
||
for (let i = 0; i < this.maxCanvas; i++) {
|
||
if (i === this.maxCanvas - 1) {
|
||
loadImagePromises.push(
|
||
this.$refs[`dicomCanvas${i}`][0].loadImageStack(currentAddSeries)
|
||
)
|
||
this.currentDicomCanvasIndex = i
|
||
this.activeSeries = currentAddSeries
|
||
store.dispatch('reading/setActiveSeries', currentAddSeries)
|
||
} else {
|
||
loadImagePromises.push(
|
||
this.$refs[`dicomCanvas${i}`][0].loadImageStack(firstAddSeries)
|
||
)
|
||
}
|
||
}
|
||
Promise.all(loadImagePromises).then(() => {
|
||
this.isScrollSync = isScrollSync
|
||
})
|
||
if (loading) {
|
||
loading.close()
|
||
}
|
||
},
|
||
selectViewCanvas(offset) {
|
||
var canvasIndex = this.currentDicomCanvasIndex + offset
|
||
if (canvasIndex < 0 || canvasIndex >= this.maxCanvas) return
|
||
this.activateDicomCanvas(canvasIndex)
|
||
},
|
||
// 根据标记获取标记所在的序列信息
|
||
getSeriesInfoByMark(visitTaskId, obj) {
|
||
var seriesInfo = null
|
||
// 根据任务ID测量病灶信息
|
||
var index = this.visitTaskList.findIndex(
|
||
(i) => i.VisitTaskId === visitTaskId
|
||
)
|
||
|
||
if (index > -1) {
|
||
var idx = -1
|
||
if (this.CriterionType === 10) {
|
||
idx = this.visitTaskList[index].MeasureData.findIndex(
|
||
(item) => item.OrderMarkName === obj.lesionName
|
||
)
|
||
} else {
|
||
idx = this.visitTaskList[index].MeasureData.findIndex(
|
||
(item) =>
|
||
item.QuestionId === obj.questionId &&
|
||
item.RowIndex === obj.rowIndex
|
||
)
|
||
}
|
||
if (
|
||
idx > -1 &&
|
||
this.visitTaskList[index].MeasureData[idx].MeasureData
|
||
) {
|
||
var studyList = this.visitTaskList[index].StudyList
|
||
var studyId = this.visitTaskList[index].MeasureData[idx].StudyId
|
||
var seriesId = this.visitTaskList[index].MeasureData[idx].SeriesId
|
||
var instanceId =
|
||
this.visitTaskList[index].MeasureData[idx].InstanceId
|
||
var studyIdx = studyList.findIndex(
|
||
(study) => study.StudyId === studyId
|
||
)
|
||
if (studyIdx > -1) {
|
||
var seriesIdx = studyList[studyIdx].SeriesList.findIndex(
|
||
(s) => s.seriesId === seriesId
|
||
)
|
||
if (seriesIdx > -1) {
|
||
var series = studyList[studyIdx].SeriesList[seriesIdx];
|
||
let frame = this.visitTaskList[index].MeasureData[idx].MeasureData.frame
|
||
let filterStr = series.isExistMutiFrames ? `frame=${frame}&instanceId=${instanceId}` : `instanceId=${instanceId}`
|
||
var instanceIdx = series.imageIds.findIndex(imageId => imageId.includes(filterStr))
|
||
// var instanceIdx = series.instanceList.findIndex(
|
||
// (imageId) => !!~imageId.indexOf(instanceId)
|
||
// );
|
||
if (instanceIdx > -1) {
|
||
series.imageIdIndex = instanceIdx
|
||
seriesInfo = series
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
return seriesInfo
|
||
},
|
||
getLinkedSeries(baseSeries, visitTaskId) {
|
||
var index = this.visitTaskList.findIndex(
|
||
(i) => i.VisitTaskId === visitTaskId
|
||
)
|
||
var visitTaskInfo = this.visitTaskList[index]
|
||
var obj = null
|
||
var studyList = visitTaskInfo.StudyList
|
||
// 查找筛选描述一致
|
||
var seriesList = studyList.map((s) => s.SeriesList).flat()
|
||
var similarArr = seriesList.map((i, index) => {
|
||
return {
|
||
similar: this.strSimilarity2Percent(
|
||
i.description,
|
||
baseSeries.description
|
||
),
|
||
index
|
||
}
|
||
})
|
||
similarArr = similarArr.sort((a, b) => {
|
||
return b.similar - a.similar
|
||
})
|
||
const i =
|
||
similarArr[0] && similarArr[0].similar > 0.85
|
||
? similarArr[0].index
|
||
: -1
|
||
if (i > -1) {
|
||
obj = seriesList[i]
|
||
}
|
||
// if (!obj) {
|
||
// // 描述不一致,则筛选层厚一致
|
||
// const idx = seriesList.findIndex(series => series.sliceThickness === baseSeries.sliceThickness)
|
||
// idx > -1 ? obj = seriesList[idx] : ''
|
||
// }
|
||
// if (!obj) {
|
||
// // 层厚不一致,则筛选图像数量一致
|
||
// const idx = seriesList.findIndex(series => series.instanceCount === baseSeries.instanceCount)
|
||
// idx > -1 ? obj = seriesList[idx] : ''
|
||
// }
|
||
|
||
if (obj) {
|
||
const index = Math.floor(
|
||
obj.imageIds.length *
|
||
((baseSeries.imageIdIndex + 1) / baseSeries.instanceCount)
|
||
)
|
||
obj.imageIdIndex = index > 0 ? index - 1 : 0
|
||
}
|
||
return obj
|
||
},
|
||
strSimilarity2Number(s, t) {
|
||
var n = s.length
|
||
var m = t.length
|
||
var d = []
|
||
var i, j, s_i, t_j, cost
|
||
if (n === 0) return m
|
||
if (m === 0) return n
|
||
for (i = 0; i <= n; i++) {
|
||
d[i] = []
|
||
d[i][0] = i
|
||
}
|
||
for (j = 0; j <= m; j++) {
|
||
d[0][j] = j
|
||
}
|
||
for (i = 1; i <= n; i++) {
|
||
s_i = s.charAt(i - 1)
|
||
for (j = 1; j <= m; j++) {
|
||
t_j = t.charAt(j - 1)
|
||
if (s_i === t_j) {
|
||
cost = 0
|
||
} else {
|
||
cost = 1
|
||
}
|
||
d[i][j] = this.Minimum(
|
||
d[i - 1][j] + 1,
|
||
d[i][j - 1] + 1,
|
||
d[i - 1][j - 1] + cost
|
||
)
|
||
}
|
||
}
|
||
return d[n][m]
|
||
},
|
||
// 两个字符串的相似程度,并返回相似度百分比
|
||
strSimilarity2Percent(s, t) {
|
||
var l = s.length > t.length ? s.length : t.length
|
||
var d = this.strSimilarity2Number(s, t)
|
||
return Number((1 - d / l).toFixed(4))
|
||
},
|
||
Minimum(a, b, c) {
|
||
return a < b ? (a < c ? a : c) : b < c ? b : c
|
||
},
|
||
// 获取某个任务下可对齐的序列信息
|
||
async getFirstSeries(baseSeries, visitTaskId) {
|
||
var index = this.visitTaskList.findIndex(
|
||
(i) => i.VisitTaskId === visitTaskId
|
||
)
|
||
if (!this.visitTaskList[index].studyListInit) {
|
||
await store.dispatch('reading/getStudyInfo', {
|
||
trialId: this.trialId,
|
||
subjectVisitId: this.visitTaskList[index].VisitId,
|
||
visitTaskId: this.visitTaskList[index].VisitTaskId,
|
||
taskBlindName: this.visitTaskList[index].TaskBlindName
|
||
})
|
||
|
||
await store.dispatch(
|
||
'reading/getMeasuredData',
|
||
this.visitTaskList[index].VisitTaskId
|
||
)
|
||
}
|
||
var visitTaskInfo = this.visitTaskList[index]
|
||
var obj = null
|
||
var studyList = visitTaskInfo.StudyList
|
||
// 查找筛选描述一致
|
||
var seriesList = studyList.map((s) => s.SeriesList).flat()
|
||
var similarArr = seriesList.map((i, index) => {
|
||
return {
|
||
similar: this.strSimilarity2Percent(
|
||
i.description,
|
||
baseSeries.description
|
||
),
|
||
index
|
||
}
|
||
})
|
||
similarArr = similarArr.sort((a, b) => {
|
||
return b.similar - a.similar
|
||
})
|
||
const i =
|
||
similarArr[0] && similarArr[0].similar > 0.85
|
||
? similarArr[0].index
|
||
: -1
|
||
if (i > -1) {
|
||
obj = seriesList[i]
|
||
}
|
||
// if (!obj) {
|
||
// // 描述不一致,则筛选层厚一致
|
||
// const idx = seriesList.findIndex(series => series.sliceThickness === baseSeries.sliceThickness)
|
||
// idx > -1 ? obj = seriesList[idx] : ''
|
||
// }
|
||
// if (!obj) {
|
||
// // 层厚不一致,则筛选图像数量一致
|
||
// const idx = seriesList.findIndex(series => series.instanceCount === baseSeries.instanceCount)
|
||
// idx > -1 ? obj = seriesList[idx] : ''
|
||
// }
|
||
if (!obj) {
|
||
// 都不符合要求, 判断是否存在层厚为5的序列,否则显示第一个检查的第一个序列
|
||
const idx = seriesList.findIndex(
|
||
(series) => series.isDicom && parseInt(series.instanceCount) === 5
|
||
)
|
||
idx > -1 ? (obj = seriesList[idx]) : (obj = seriesList[0])
|
||
}
|
||
|
||
if (obj) {
|
||
const index = Math.floor(
|
||
obj.imageIds.length *
|
||
((baseSeries.imageIdIndex + 1) / baseSeries.instanceCount)
|
||
)
|
||
obj.imageIdIndex = index > 0 ? index - 1 : 0
|
||
}
|
||
return obj
|
||
},
|
||
|
||
// 设置画布大小
|
||
setCanvasStyle() {
|
||
this.canvasW = (window.innerWidth - 570) / this.layoutCol + 'px'
|
||
this.canvasH = (window.innerHeight - 130) / this.layoutRow + 'px'
|
||
},
|
||
// 切换布局
|
||
changeLayout(name) {
|
||
if (this.activeTool) {
|
||
if (
|
||
this.$refs[`dicomCanvas${this.currentDicomCanvasIndex}`][0]
|
||
.isCurrentTask &&
|
||
this.$refs[`dicomCanvas${this.currentDicomCanvasIndex}`][0]
|
||
.readingTaskState < 2
|
||
) {
|
||
this.$nextTick(() => {
|
||
this.$refs[
|
||
`dicomCanvas${this.currentDicomCanvasIndex}`
|
||
][0].setToolPassive(this.activeTool)
|
||
})
|
||
} else {
|
||
this.$nextTick(() => {
|
||
this.$refs[
|
||
`dicomCanvas${this.currentDicomCanvasIndex}`
|
||
][0].setToolEnabled(this.activeTool)
|
||
})
|
||
}
|
||
this.activeTool = ''
|
||
}
|
||
this.isScrollSync = false
|
||
this.activeSeries =
|
||
this.$refs[`dicomCanvas${this.currentDicomCanvasIndex}`][0].stack
|
||
this.layout = name
|
||
var i = this.layouts.findIndex((i) => i.name === name)
|
||
var layout = this.layouts[i]
|
||
this.layoutRow = layout.row
|
||
this.layoutCol = layout.col
|
||
this.setCanvasStyle()
|
||
this.maxCanvas = layout.row * layout.col
|
||
this.$nextTick(() => {
|
||
const elements = document.querySelectorAll('.cornerstone-element')
|
||
Array.from(elements).forEach((element) => {
|
||
cornerstone.enable(element)
|
||
cornerstone.resize(element)
|
||
})
|
||
this.getSeriesShowInCanvas(layout)
|
||
this.cornerstoneStyle = {}
|
||
this.setCanvasStyle()
|
||
})
|
||
},
|
||
// 更新画布
|
||
updateCanvas(measureData) {
|
||
for (let i = 0; i < this.maxCanvas; i++) {
|
||
var stack =
|
||
this.$refs[`dicomCanvas${this.currentDicomCanvasIndex}`][0].stack
|
||
if (stack.studyId) {
|
||
this.$refs[
|
||
`dicomCanvas${this.currentDicomCanvasIndex}`
|
||
][0].removeToolState(measureData)
|
||
}
|
||
}
|
||
},
|
||
// 旋转
|
||
setDicomCanvasRotate(value) {
|
||
const type = parseInt(value)
|
||
if (type === 1) {
|
||
this.$refs[
|
||
`dicomCanvas${this.currentDicomCanvasIndex}`
|
||
][0].resetRotate()
|
||
} else if (type === 2) {
|
||
this.$refs[`dicomCanvas${this.currentDicomCanvasIndex}`][0].setRotate(
|
||
false,
|
||
true,
|
||
0,
|
||
type
|
||
)
|
||
} else if (type === 3) {
|
||
this.$refs[`dicomCanvas${this.currentDicomCanvasIndex}`][0].setRotate(
|
||
true,
|
||
false,
|
||
0,
|
||
type
|
||
)
|
||
} else if (type === 4) {
|
||
this.$refs[`dicomCanvas${this.currentDicomCanvasIndex}`][0].setRotate(
|
||
false,
|
||
false,
|
||
-90,
|
||
type
|
||
)
|
||
} else if (type === 5) {
|
||
this.$refs[`dicomCanvas${this.currentDicomCanvasIndex}`][0].setRotate(
|
||
false,
|
||
false,
|
||
90,
|
||
type
|
||
)
|
||
}
|
||
},
|
||
// 激活画布
|
||
activateDicomCanvas(index) {
|
||
console.log('激活画布')
|
||
|
||
if (index !== this.currentDicomCanvasIndex) {
|
||
this.currentDicomCanvasIndex = index
|
||
// var dicomSeries = this.canvasObj[this.currentDicomCanvasIndex]
|
||
var dicomSeries =
|
||
this.$refs[`dicomCanvas${this.currentDicomCanvasIndex}`][0].stack
|
||
this.activeSeries = dicomSeries
|
||
for (let i = 0; i < this.maxCanvas; i++) {
|
||
if (this.activeTool) {
|
||
var series = this.$refs[`dicomCanvas${i}`][0].stack
|
||
// series.isCurrentTask && series.readingTaskState < 2
|
||
if (series.isCurrentTask) {
|
||
this.$refs[`dicomCanvas${i}`][0].setToolPassive(this.activeTool)
|
||
} else {
|
||
this.$refs[`dicomCanvas${i}`][0].setToolEnabled(this.activeTool)
|
||
}
|
||
}
|
||
}
|
||
this.activeTool = ''
|
||
this.isScrollSync = false
|
||
this.currentDicomCanvasIndex = index
|
||
this.currentDicomCanvas = this.$refs[`dicomCanvas${index}`]
|
||
this.currentDicomCanvas.tabIndex = 0
|
||
if (!this.rotateList[this.currentDicomCanvasIndex]) {
|
||
this.rotateList[this.currentDicomCanvasIndex] = '1'
|
||
}
|
||
if (!this.colorList[this.currentDicomCanvasIndex]) {
|
||
this.colorList[this.currentDicomCanvasIndex] = ''
|
||
}
|
||
if (!this.wwwcList[this.currentDicomCanvasIndex]) {
|
||
this.wwwcList[this.currentDicomCanvasIndex] = '1'
|
||
}
|
||
// var stack = this.$refs[`dicomCanvas${this.currentDicomCanvasIndex}`][0].stack
|
||
this.$refs['container'].focus()
|
||
// if (stack.studyId) {
|
||
// DicomEvent.$emit('toggleVisitList', stack)
|
||
// }
|
||
store.dispatch('reading/setActiveSeries', dicomSeries)
|
||
}
|
||
},
|
||
// 鼠标移入测量工具时,判断工具是否可激活
|
||
enter(e, toolName) {
|
||
var i = this.measuredTools.findIndex(
|
||
(item) => item.toolName === toolName
|
||
)
|
||
if (i === -1) return
|
||
var isCurrentTask =
|
||
this.$refs[`dicomCanvas${this.currentDicomCanvasIndex}`][0]
|
||
.isCurrentTask
|
||
var readingTaskState =
|
||
this.$refs[`dicomCanvas${this.currentDicomCanvasIndex}`][0]
|
||
.readingTaskState
|
||
if (!isCurrentTask) {
|
||
this.measuredTools[i].isDisabled = true
|
||
e.target.style.cursor = 'not-allowed'
|
||
if (this.activeTool) {
|
||
this.$refs[
|
||
`dicomCanvas${this.currentDicomCanvasIndex}`
|
||
][0].setToolEnabled(toolName)
|
||
this.activeTool = ''
|
||
}
|
||
} else {
|
||
this.measuredTools[i].isDisabled = false
|
||
e.target.style.cursor = 'pointer'
|
||
}
|
||
},
|
||
// 设置测量工具启用(不会对输入作出反应)
|
||
setToolActive(toolName, isMeasuredTool, e, type) {
|
||
console.log('setToolActive', toolName)
|
||
if (isMeasuredTool) {
|
||
// var i = this.measuredTools.findIndex(item => item.toolName === toolName)
|
||
// if (i === -1 && this.measuredTools[i].isDisabled) return
|
||
|
||
var toolObj = this.measuredTools.find((i) => i.toolName === toolName)
|
||
if (!toolObj || toolObj.isDisabled) return
|
||
var dicomSeries = this.canvasObj[this.currentDicomCanvasIndex]
|
||
if (
|
||
dicomSeries.isCurrentTask &&
|
||
isMeasuredTool &&
|
||
dicomSeries.readingTaskState < 2
|
||
) {
|
||
if (this.activeTool && !type) {
|
||
this.measuredTools.forEach((item) => {
|
||
this.$refs[
|
||
`dicomCanvas${this.currentDicomCanvasIndex}`
|
||
][0].setToolPassive(item.toolName)
|
||
})
|
||
this.$refs[
|
||
`dicomCanvas${this.currentDicomCanvasIndex}`
|
||
][0].setToolPassive(toolName)
|
||
// this.activeTool = ''
|
||
this.activeTool = toolName
|
||
this.$refs[
|
||
`dicomCanvas${this.currentDicomCanvasIndex}`
|
||
][0].setToolActive(toolName)
|
||
} else {
|
||
this.measuredTools.forEach((item) => {
|
||
this.$refs[
|
||
`dicomCanvas${this.currentDicomCanvasIndex}`
|
||
][0].setToolPassive(item.toolName)
|
||
})
|
||
this.activeTool = toolName
|
||
this.$refs[
|
||
`dicomCanvas${this.currentDicomCanvasIndex}`
|
||
][0].setToolActive(toolName)
|
||
}
|
||
} else if (dicomSeries.isCurrentTask &&
|
||
isMeasuredTool && dicomSeries.readingTaskState >= 2) {
|
||
if (this.activeTool === toolName) {
|
||
this.$refs[
|
||
`dicomCanvas${this.currentDicomCanvasIndex}`
|
||
][0].setToolEnabled(toolName)
|
||
this.activeTool = ''
|
||
} else {
|
||
this.activeTool = toolName
|
||
this.$refs[
|
||
`dicomCanvas${this.currentDicomCanvasIndex}`
|
||
][0].setToolActive(toolName)
|
||
}
|
||
} else {
|
||
if (!this.activeTool) return
|
||
this.measuredTools.forEach((item) => {
|
||
this.$refs[
|
||
`dicomCanvas${this.currentDicomCanvasIndex}`
|
||
][0].setToolEnabled(item.toolName)
|
||
})
|
||
this.$refs[
|
||
`dicomCanvas${this.currentDicomCanvasIndex}`
|
||
][0].setToolEnabled(toolName)
|
||
this.activeTool = ''
|
||
}
|
||
} else {
|
||
if (this.activeTool === toolName) {
|
||
this.$refs[
|
||
`dicomCanvas${this.currentDicomCanvasIndex}`
|
||
][0].setToolEnabled(toolName)
|
||
this.activeTool = ''
|
||
} else {
|
||
this.activeTool = toolName
|
||
this.$refs[
|
||
`dicomCanvas${this.currentDicomCanvasIndex}`
|
||
][0].setToolActive(toolName)
|
||
}
|
||
}
|
||
},
|
||
// 设置测量工具禁用(不会对输入作出反应)
|
||
setToolEnabled() {
|
||
var dicomSeries = this.canvasObj[this.currentDicomCanvasIndex]
|
||
if (!dicomSeries.isCurrentTask) {
|
||
this.$refs[
|
||
`dicomCanvas${this.currentDicomCanvasIndex}`
|
||
][0].setToolEnabled(this.activeTool)
|
||
this.activeTool = ''
|
||
return
|
||
}
|
||
if (this.activeTool) {
|
||
this.$refs[
|
||
`dicomCanvas${this.currentDicomCanvasIndex}`
|
||
][0].setToolEnabled(this.activeTool)
|
||
this.activeTool = ''
|
||
}
|
||
},
|
||
// 影像适应图像/适应窗口
|
||
fitToType(toolName) {
|
||
if (
|
||
this.activeTool !== 'fitToWindow' &&
|
||
this.activeTool !== 'fitToImage'
|
||
) {
|
||
this.$refs[
|
||
`dicomCanvas${this.currentDicomCanvasIndex}`
|
||
][0].setToolPassive(this.activeTool)
|
||
}
|
||
if (toolName === 'fitToWindow') {
|
||
this.fitType = 0
|
||
this.$refs[
|
||
`dicomCanvas${this.currentDicomCanvasIndex}`
|
||
][0].fitToWindow()
|
||
} else if (toolName === 'fitToImage') {
|
||
this.fitType = 1
|
||
this.$refs[
|
||
`dicomCanvas${this.currentDicomCanvasIndex}`
|
||
][0].fitToImage()
|
||
}
|
||
this.activeTool = toolName
|
||
},
|
||
// 切换帧
|
||
scrollPage(i) {
|
||
// 获取影像是否下载完成
|
||
const isLoaded = this.getSeriesLoadStatus()
|
||
if (!isLoaded) return
|
||
this.$refs[`dicomCanvas${this.currentDicomCanvasIndex}`][0].scrollPage(i)
|
||
},
|
||
// 播放/暂停
|
||
toggleClipPlay(isPlay) {
|
||
// 获取影像是否下载完成
|
||
const isLoaded = this.getSeriesLoadStatus()
|
||
if (!isLoaded) return
|
||
this.clipPlaying = isPlay
|
||
this.$refs[`dicomCanvas${this.currentDicomCanvasIndex}`][0].setFps(this.fps)
|
||
this.$refs[
|
||
`dicomCanvas${this.currentDicomCanvasIndex}`
|
||
][0].toggleClipPlay(isPlay)
|
||
},
|
||
getSeriesLoadStatus() {
|
||
const index = this.visitTaskList.findIndex(
|
||
(i) => i.VisitTaskId === this.activeSeries.visitTaskId
|
||
)
|
||
if (index === -1) return false
|
||
const loadStatus =
|
||
this.visitTaskList[index].StudyList[this.activeSeries.studyIndex]
|
||
.SeriesList[this.activeSeries.seriesIndex].loadStatus
|
||
return loadStatus
|
||
},
|
||
setDicomCanvasfps(event) {
|
||
this.$refs[`dicomCanvas${this.currentDicomCanvasIndex}`][0].setFps(
|
||
event.target.value
|
||
)
|
||
},
|
||
// 添加标记
|
||
setMeasureData(data) {
|
||
this.$refs['measurementList'].setMeasuredData(data)
|
||
this.activeTool = ''
|
||
},
|
||
// 修改标记
|
||
modifyMeasureData(data) {
|
||
data.temporary = this.readingTaskState >= 2 && !data.Id
|
||
this.$refs['measurementList'].modifyMeasuredData(data)
|
||
this.activeTool = ''
|
||
},
|
||
// 删除标记
|
||
moveMeasureData(data) {
|
||
this.$confirm(
|
||
this.$t('trials:trials-list:table:isDeleted') +
|
||
data.questionInfo.MeasureData.data.remark +
|
||
'?'
|
||
).then(() => {
|
||
this.$refs['measurementList'].moveMeasureData(data)
|
||
})
|
||
},
|
||
saveImage() {
|
||
this.$refs[`dicomCanvas${this.currentDicomCanvasIndex}`][0].saveImage()
|
||
},
|
||
// 设置窗宽/窗位
|
||
setDicomCanvasWwwc(v) {
|
||
if (v.val === -1) {
|
||
// 默认值
|
||
this.$refs[`dicomCanvas${this.currentDicomCanvasIndex}`][0].resetWwwc()
|
||
} else if (v.val === 0) {
|
||
// 自定义
|
||
this.setCustomWwwc()
|
||
} else if (v.val === 1) {
|
||
// 区域窗宽
|
||
// this.setToolActive('WwwcRegion', false)
|
||
this.$refs[
|
||
`dicomCanvas${this.currentDicomCanvasIndex}`
|
||
][0].setToolActive('WwwcRegion')
|
||
} else if (v.val === 8) {
|
||
this.$refs[
|
||
`dicomCanvas${this.currentDicomCanvasIndex}`
|
||
][0].toggleInvert()
|
||
} else {
|
||
this.$refs[`dicomCanvas${this.currentDicomCanvasIndex}`][0].setWwwc(
|
||
v.ww,
|
||
v.wc
|
||
)
|
||
}
|
||
},
|
||
setCustomWwwc() {
|
||
this.customWwc.visible = true
|
||
},
|
||
setWwwc(v) {
|
||
this.$refs[`dicomCanvas${this.currentDicomCanvasIndex}`][0].setWwwc(
|
||
v.ww,
|
||
v.wc
|
||
)
|
||
this.customWwc.visible = false
|
||
},
|
||
toggleInvert() {
|
||
if (this.activeTool === 'reversecolor') {
|
||
this.$refs[`dicomCanvas${this.currentDicomCanvasIndex}`][0].resetWwwc()
|
||
this.activeTool = ''
|
||
} else {
|
||
this.activeTool = 'reversecolor'
|
||
this.$refs[
|
||
`dicomCanvas${this.currentDicomCanvasIndex}`
|
||
][0].toggleInvert()
|
||
}
|
||
},
|
||
setImageIndexSync() {
|
||
this.isScrollSync = !this.isScrollSync
|
||
},
|
||
scrollSync(obj) {
|
||
for (var i = 0; i < this.maxCanvas; i++) {
|
||
if (i !== this.currentDicomCanvasIndex) {
|
||
this.$refs[`dicomCanvas${i}`][0].scrollPage(obj.offset)
|
||
}
|
||
}
|
||
},
|
||
showPanel(e) {
|
||
e.currentTarget.firstChild.lastChild.style.display = 'block'
|
||
},
|
||
handleMouseout(e) {
|
||
e.currentTarget.firstChild.lastChild.style.display = 'none'
|
||
},
|
||
// 预览临床数据
|
||
previewCD() {
|
||
this.$emit('previewCD')
|
||
},
|
||
previewNoneDicoms() {
|
||
this.$emit('previewNoneDicoms')
|
||
},
|
||
previewManuals() {
|
||
this.isFullscreen = false
|
||
this.manualsDialog.visible = true
|
||
}
|
||
}
|
||
}
|
||
</script>
|
||
<style lang="scss" scoped>
|
||
.dicom-viewer-wrapper {
|
||
height: 100%;
|
||
padding: 5px 0px 5px 5px;
|
||
box-sizing: border-box;
|
||
.divider {
|
||
display: block;
|
||
height: 1px;
|
||
width: 100%;
|
||
margin: 10px 0;
|
||
// background-color: #383838;
|
||
// color: #fff;
|
||
// background-color: #DCDFE6;
|
||
}
|
||
.el-divider__text {
|
||
padding: 0 10px;
|
||
color: #fff;
|
||
background-color: #383838;
|
||
font-size: 12px;
|
||
width: 80px;
|
||
}
|
||
.dicom-viewer-container {
|
||
display: flex;
|
||
flex-direction: column;
|
||
height: 100%;
|
||
}
|
||
::-webkit-scrollbar {
|
||
width: 5px;
|
||
height: 5px;
|
||
}
|
||
::-webkit-scrollbar-thumb {
|
||
border-radius: 10px;
|
||
background: #d0d0d0;
|
||
}
|
||
.dicom-tools {
|
||
box-sizing: border-box;
|
||
width: 100%;
|
||
height: 80px;
|
||
padding: 0 5px;
|
||
border: 1px solid #727272;
|
||
display: flex;
|
||
flex-direction: row;
|
||
justify-content: flex-start;
|
||
align-items: center;
|
||
.tool-wrapper {
|
||
display: flex;
|
||
flex-direction: column;
|
||
justify-content: center;
|
||
align-items: center;
|
||
margin-right: 20px;
|
||
.icon {
|
||
padding: 5px;
|
||
border: 1px solid #404040;
|
||
cursor: pointer;
|
||
text-align: center;
|
||
.svg-icon {
|
||
font-size: 20px;
|
||
color: #ddd;
|
||
}
|
||
}
|
||
.text {
|
||
position: relative;
|
||
font-size: 12px;
|
||
margin-top: 5px;
|
||
color: #d0d0d0;
|
||
display: none;
|
||
}
|
||
}
|
||
.tool-frame {
|
||
display: flex;
|
||
flex-direction: row;
|
||
justify-content: flex-start;
|
||
align-items: center;
|
||
margin-right: 20px;
|
||
border: 1px solid #404040;
|
||
.icon {
|
||
padding: 5px;
|
||
border-right: 1px solid #404040;
|
||
cursor: pointer;
|
||
text-align: center;
|
||
.svg-icon {
|
||
font-size: 20px;
|
||
color: #ddd;
|
||
}
|
||
}
|
||
.select-wrapper {
|
||
width: 60px;
|
||
background-color: black;
|
||
color: #ddd;
|
||
border: none;
|
||
font-size: 13px;
|
||
outline: none;
|
||
}
|
||
.text {
|
||
position: relative;
|
||
font-size: 12px;
|
||
margin-top: 5px;
|
||
color: #d0d0d0;
|
||
display: none;
|
||
}
|
||
}
|
||
.tool_active {
|
||
background-color: #607d8b;
|
||
}
|
||
.tool_disabled {
|
||
cursor: not-allowed;
|
||
}
|
||
.icon:hover {
|
||
background-color: #607d8b;
|
||
}
|
||
.dropdown {
|
||
position: relative;
|
||
display: inline-block;
|
||
.text {
|
||
text-align: center;
|
||
}
|
||
}
|
||
|
||
.dropdown-content {
|
||
display: none;
|
||
position: absolute;
|
||
background-color: #383838;
|
||
color: #fff;
|
||
box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2);
|
||
z-index: 9999;
|
||
font-size: 12px;
|
||
ul {
|
||
list-style: none;
|
||
margin: 0;
|
||
padding: 0;
|
||
text-align: center;
|
||
li {
|
||
a {
|
||
display: block;
|
||
padding: 5px 0px;
|
||
}
|
||
}
|
||
}
|
||
ul li:hover a {
|
||
background-color: #727272;
|
||
}
|
||
}
|
||
|
||
// .dropdown:hover .dropdown-content {
|
||
// display: block;
|
||
|
||
// }
|
||
.layout-content ul li {
|
||
border-top: 1px solid #ddd;
|
||
border-left: 1px solid #ddd;
|
||
}
|
||
.layout-content ul .flex_row {
|
||
// border: 1px solid #ddd;
|
||
display: flex;
|
||
justify-content: space-between;
|
||
flex-direction: row;
|
||
align-items: center;
|
||
// padding: 2px;
|
||
margin-bottom: 2px;
|
||
}
|
||
.layout-content ul .flex_column {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
margin-bottom: 2px;
|
||
}
|
||
.layout_box_1_1 {
|
||
flex: 1;
|
||
// border: 1px solid #ddd;
|
||
line-height: 30px;
|
||
font-size: 12px;
|
||
text-align: center;
|
||
border-bottom: 1px solid #ddd;
|
||
border-right: 1px solid #ddd;
|
||
// padding: 0 5px;
|
||
}
|
||
.layout_box_1_2 {
|
||
flex: 1;
|
||
// border: 1px solid #ddd;
|
||
line-height: 15px;
|
||
font-size: 10px;
|
||
text-align: center;
|
||
border-bottom: 1px solid #ddd;
|
||
border-right: 1px solid #ddd;
|
||
// padding: 0 5px;
|
||
}
|
||
.layout-content li .layout_box_1_1 :last-child {
|
||
color: red;
|
||
}
|
||
// .layout_li:last-child{
|
||
// .layout_box{
|
||
// border-bottom: none;
|
||
// }
|
||
// }
|
||
.layout-content li:hover {
|
||
cursor: pointer;
|
||
background-color: #727272;
|
||
}
|
||
}
|
||
.dicom-viewers {
|
||
box-sizing: border-box;
|
||
flex: 1;
|
||
// width: 100%;
|
||
margin-top: 5px;
|
||
height: 100%;
|
||
display: flex;
|
||
flex-direction: row;
|
||
justify-content: flex-start;
|
||
.form-container {
|
||
// box-sizing: border-box;
|
||
width: 350px;
|
||
height: 100%;
|
||
border: 1px solid #727272;
|
||
// overflow-y: auto;
|
||
}
|
||
.viewer-container {
|
||
box-sizing: border-box;
|
||
flex: 1;
|
||
height: 100%;
|
||
border: 1px solid #727272;
|
||
}
|
||
|
||
.measurement-container {
|
||
// height: 100%;
|
||
overflow-y: auto;
|
||
}
|
||
.box {
|
||
display: grid;
|
||
box-sizing: border-box;
|
||
height: 100%;
|
||
padding: 0;
|
||
.item {
|
||
box-sizing: border-box;
|
||
position: relative;
|
||
border: 1px solid rgba(255, 255, 255, 0.21);
|
||
position: relative;
|
||
&_active {
|
||
// border: 2px solid #ffeb3b;
|
||
border: 1px dashed #428bca;
|
||
}
|
||
}
|
||
}
|
||
.box_1_1 {
|
||
grid-template-columns: repeat(1, 100%); //1列,占100%
|
||
grid-template-rows: repeat(1, 100%); //1行,占100%
|
||
}
|
||
.box_1_2 {
|
||
grid-template-columns: repeat(2, 50%); //1列,占50%
|
||
grid-template-rows: repeat(1, 100%); //1行,占100%
|
||
}
|
||
.box_2_1 {
|
||
grid-template-columns: repeat(1, 100%); //1列,占100%
|
||
grid-template-rows: repeat(2, 50%); //1行,占50%
|
||
}
|
||
.box_2_2 {
|
||
grid-template-columns: repeat(2, 50%); //1列,占50%
|
||
grid-template-rows: repeat(2, 50%); //1行,占50%
|
||
}
|
||
|
||
// .box_3_1{
|
||
// grid-template-columns: repeat(3, 100%); //1列,占100%
|
||
// grid-template-rows: repeat(3, 33.33%); //1行,占100%
|
||
// }
|
||
// .box_3_2{
|
||
// grid-template-columns: repeat(3, 50%); //1列,占100%
|
||
// grid-template-rows: repeat(3, 50%); //1行,占100%
|
||
// }
|
||
// .box_3_3{
|
||
// grid-template-columns: repeat(3, 33.33%); //1列,占100%
|
||
// grid-template-rows: repeat(3, 33.33%); //1行,占100%
|
||
// }
|
||
}
|
||
.personal_config {
|
||
/deep/ .el-tabs__content {
|
||
height: 450px;
|
||
overflow-y: auto;
|
||
}
|
||
}
|
||
/deep/ .manuals-dialog-container {
|
||
margin-top: 50px !important;
|
||
width: 75%;
|
||
height: 80%;
|
||
.el-dialog__body {
|
||
padding: 10px;
|
||
height: calc(100% - 50px) !important;
|
||
}
|
||
.el-dialog__header {
|
||
position: relative;
|
||
}
|
||
}
|
||
/deep/ .manuals-full-dialog-container {
|
||
.el-dialog__body {
|
||
padding: 10px;
|
||
height: calc(100% - 50px) !important;
|
||
}
|
||
.el-dialog__header {
|
||
position: relative;
|
||
}
|
||
}
|
||
}
|
||
</style>
|