332 lines
9.2 KiB
Vue
332 lines
9.2 KiB
Vue
<template>
|
|
<div class="none-dicom-viewer">
|
|
<!-- tools -->
|
|
<div class="tools-wrapper">
|
|
<!-- 布局 -->
|
|
<div class="tool-item" :title="$t('trials:reading:button:layout')">
|
|
<el-dropdown @command="handleCommand">
|
|
<span class="el-dropdown-link">
|
|
<svg-icon icon-class="layout" class="svg-icon" /><i class="el-icon-arrow-down el-icon--right" />
|
|
</span>
|
|
<el-dropdown-menu slot="dropdown">
|
|
<el-dropdown-item command="1*1">1*1</el-dropdown-item>
|
|
<el-dropdown-item command="1*2">1*2</el-dropdown-item>
|
|
<el-dropdown-item command="2*2">2*2</el-dropdown-item>
|
|
</el-dropdown-menu>
|
|
</el-dropdown>
|
|
</div>
|
|
</div>
|
|
<!-- viewports -->
|
|
<div class="viewports-wrapper">
|
|
<div class="grid-container" :style="gridStyle">
|
|
<div
|
|
v-for="(v, index) in viewportInfos"
|
|
v-show="index < cells.length"
|
|
:key="index"
|
|
:style="cellStyle"
|
|
:class="['grid-cell', index === activeCanvasIndex ? 'cell_active' : '', index === fullScreenIndex ? 'cell-full-screen' : '']"
|
|
@dblclick="toggleFullScreen($event, index)"
|
|
@click="activeCanvas(index)"
|
|
>
|
|
<div :ref="`canvas-${index}`" class="content">
|
|
|
|
<div style="width: 100%; height: 100%; padding: 1px;">
|
|
<iframe v-if="v.currentFilePath" :ref="`iframe-${index}`" :src="`/static/pdfjs/web/viewer.html?file=${OSSclientConfig.basePath}${v.currentFilePath}`" width="100%" height="100%" frameborder="0" crossorigin="anonymous" />
|
|
<!-- <div class="left-top-text">
|
|
<div
|
|
v-if="v.taskInfo.IsExistsClinicalData"
|
|
class="cd-info"
|
|
:title="$t('trials:reading:button:clinicalData')"
|
|
@click.stop="viewCD($event)"
|
|
>
|
|
<svg-icon icon-class="documentation" class="svg-icon" />
|
|
</div>
|
|
<h2
|
|
v-if="taskInfo && taskInfo.IsReadingShowSubjectInfo && v.taskInfo"
|
|
class="subject-info"
|
|
>
|
|
{{ `${taskInfo.SubjectCode} ${v.taskInfo.TaskBlindName} ` }}
|
|
</h2>
|
|
<div v-if="v.currentFileName">{{ v.currentFileName }}</div>
|
|
</div> -->
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
<script>
|
|
// import { addNoneDicomMark, deleteTrialFileType } from '@/api/trials'
|
|
|
|
import { mapGetters } from 'vuex'
|
|
import store from '@/store'
|
|
|
|
export default {
|
|
name: 'PdfViewer',
|
|
data() {
|
|
return {
|
|
rows: 1,
|
|
cols: 1,
|
|
fullScreenIndex: null,
|
|
imageIds: [],
|
|
activeCanvasIndex: 0,
|
|
layout: '1*2',
|
|
cellsMax: 4,
|
|
viewportInfos: [],
|
|
taskInfo: null,
|
|
activeTool: '',
|
|
readingTaskState: 2
|
|
}
|
|
},
|
|
computed: {
|
|
gridStyle() {
|
|
return {
|
|
display: 'grid',
|
|
gridTemplateRows: `repeat(${this.rows}, 1fr)`,
|
|
gridTemplateColumns: `repeat(${this.cols}, 1fr)`,
|
|
height: '100%',
|
|
width: '100%'
|
|
}
|
|
},
|
|
cellStyle() {
|
|
return {
|
|
border: '1px dashed #ccc',
|
|
display: 'flex',
|
|
alignItems: 'center',
|
|
justifyContent: 'center'
|
|
}
|
|
},
|
|
cells() {
|
|
return Array(this.rows * this.cols).fill(0)
|
|
},
|
|
...mapGetters(['lastViewportTaskId'])
|
|
},
|
|
watch: {
|
|
relatedStudyInfo: {
|
|
immediate: true,
|
|
handler(obj) {
|
|
if (!obj || Object.keys(obj).length === 0) return
|
|
this.updateViewportInfos(0, obj)
|
|
}
|
|
}
|
|
},
|
|
mounted() {
|
|
this.taskInfo = JSON.parse(localStorage.getItem('taskInfo'))
|
|
this.readingTaskState = this.taskInfo.ReadingTaskState
|
|
this.viewportInfos = Array.from({ length: this.cellsMax }, (_, index) => ({
|
|
index: index,
|
|
taskInfo: '',
|
|
studyId: '',
|
|
viewportId: `canvas-${index}`,
|
|
currentFileName: '',
|
|
currentFilePath: ''
|
|
}))
|
|
// this.addIframeEventListener()
|
|
window.addEventListener('message', this.handleIframeMessage)
|
|
},
|
|
beforeDestroy() {
|
|
window.removeEventListener('message', this.handleIframeMessage)
|
|
},
|
|
methods: {
|
|
handleIframeMessage(event) {
|
|
if (event.data.type === 'pdf-clicked') {
|
|
const baseUrl = event.data.data.baseUrl
|
|
const i = this.viewportInfos.findIndex(i => baseUrl.includes(i.currentFilePath))
|
|
if (i === -1) return
|
|
this.activeCanvas(this.viewportInfos[i].index)
|
|
}
|
|
},
|
|
setActiveCanvasImages(obj) {
|
|
if (!obj || Object.keys(obj).length === 0) return
|
|
const i = this.viewportInfos.findIndex(i => i.index === this.activeCanvasIndex)
|
|
if (i === -1) return
|
|
this.updateViewportInfos(this.activeCanvasIndex, obj)
|
|
if (this.activeCanvasIndex === this.cells.length - 1) {
|
|
store.dispatch('noneDicomReview/setLastViewportTaskId', obj.visitTaskInfo.VisitTaskId)
|
|
}
|
|
},
|
|
// 激活视图
|
|
activeCanvas(index) {
|
|
if (this.activeCanvasIndex === index) return
|
|
const i = this.viewportInfos.findIndex(i => i.index === index)
|
|
if (i === -1) return
|
|
this.activeCanvasIndex = index
|
|
if (index === this.cells.length - 1) {
|
|
store.dispatch('noneDicomReview/setLastViewportTaskId', this.viewportInfos[i].taskInfo.VisitTaskId)
|
|
}
|
|
this.$emit('toggleTask', this.viewportInfos[i].taskInfo)
|
|
},
|
|
// 更新视图信息
|
|
updateViewportInfos(index, obj) {
|
|
const i = this.viewportInfos.findIndex(i => i.index === index)
|
|
if (i === -1) return
|
|
this.viewportInfos[i].taskInfo = obj.visitTaskInfo
|
|
this.viewportInfos[i].currentFileName = obj.fileInfo.FileName
|
|
this.viewportInfos[i].currentFilePath = obj.fileList[obj.fileIndex].Path
|
|
this.viewportInfos[i].studyId = obj.studyId
|
|
},
|
|
// 更改视图布局
|
|
handleCommand(command) {
|
|
this.fullScreenIndex = null
|
|
this.layout = command
|
|
this.rows = parseInt(command.split('*')[0])
|
|
this.cols = parseInt(command.split('*')[1])
|
|
},
|
|
// 切换全屏
|
|
toggleFullScreen(e, index) {
|
|
this.fullScreenIndex = this.fullScreenIndex === index ? null : index
|
|
this.activeCanvasIndex = index
|
|
},
|
|
// 切换任务
|
|
toggleTask(evt, visitTaskNum, i) {
|
|
const num = visitTaskNum + i
|
|
if (num >= 0 && num <= this.taskInfo.VisitNum) {
|
|
this.$emit('toggleTaskByViewer', num)
|
|
}
|
|
|
|
evt.stopImmediatePropagation()
|
|
evt.stopPropagation()
|
|
evt.preventDefault()
|
|
},
|
|
// 查看临床数据
|
|
viewCD(e) {
|
|
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
<style lang="scss" scoped>
|
|
.none-dicom-viewer {
|
|
display: flex;
|
|
flex-direction: column;
|
|
width:100%;
|
|
height: 100%;
|
|
user-select: none;
|
|
.tools-wrapper {
|
|
height: 50px;
|
|
display: flex;
|
|
flex-direction: row;
|
|
justify-content: flex-start;
|
|
align-items: center;
|
|
border-bottom: 1px solid #727272;
|
|
color: #ddd;
|
|
.tool-item {
|
|
padding: 5px;
|
|
margin: 0 5px;
|
|
border: 1px solid #333;
|
|
font-size: 20px;
|
|
cursor: pointer;
|
|
}
|
|
.tool-item-active {
|
|
background-color: #607d8b;
|
|
}
|
|
.tool-disabled {
|
|
cursor: not-allowed;
|
|
}
|
|
}
|
|
.viewports-wrapper {
|
|
flex: 1;
|
|
.grid-container {
|
|
display: grid;
|
|
height: 100%;
|
|
width: 100%;
|
|
position: relative;
|
|
}
|
|
|
|
.grid-cell {
|
|
border: 1px dashed #ccc;;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
}
|
|
.cell_active {
|
|
border-color: #fafa00!important;
|
|
}
|
|
.cell-full-screen {
|
|
grid-column: 1 / -1;
|
|
grid-row: 1 / -1;
|
|
}
|
|
|
|
.content {
|
|
width: 100%;
|
|
height: 100%;
|
|
position: relative;
|
|
.left-top-text {
|
|
position: absolute;
|
|
left: 5px;
|
|
top: 5px;
|
|
color: #ddd;
|
|
z-index: 1;
|
|
font-size: 12px;
|
|
.cd-info {
|
|
color: #ddd;
|
|
font-size: 18px;
|
|
cursor: pointer;
|
|
}
|
|
.subject-info {
|
|
color:#f44336;
|
|
padding: 5px 0px;
|
|
margin: 0;
|
|
}
|
|
}
|
|
.top-center-tool {
|
|
position: absolute;
|
|
left:50%;
|
|
top: 5px;
|
|
transform: translateX(-50%);
|
|
z-index: 1;
|
|
.toggle-visit-container {
|
|
display: flex;
|
|
}
|
|
.arrw_icon{
|
|
width: 20px;
|
|
height: 20px;
|
|
background-color: #3f3f3f;
|
|
text-align: center;
|
|
line-height: 20px;
|
|
border-radius: 10%;
|
|
}
|
|
.arrow_text{
|
|
height: 20px;
|
|
line-height: 20px;
|
|
background-color: #00000057;
|
|
color: #fff;
|
|
padding:0 10px;
|
|
font-size: 14px;
|
|
}
|
|
}
|
|
.right-slider-box {
|
|
position: absolute;
|
|
right: 1px;
|
|
height: calc(100% - 140px);
|
|
transform: translateY(-50%);
|
|
top: calc(50% - 30px);
|
|
width: 10px;
|
|
background: #333;
|
|
z-index: 1;
|
|
cursor: pointer;
|
|
}
|
|
.right-slider-box:after{
|
|
content: '';
|
|
position: absolute;
|
|
bottom: -20px;
|
|
left: 0;
|
|
height: 20px;
|
|
width: 100%;
|
|
background: #333;
|
|
}
|
|
.slider {
|
|
height: 20px;
|
|
width: 100%;
|
|
position: absolute;
|
|
top: 0;
|
|
z-index:10;
|
|
background: #9e9e9e;
|
|
cursor: move
|
|
}
|
|
}
|
|
}
|
|
}
|
|
</style>
|