非dicom阅片更改
parent
5f960348ed
commit
3aa66af253
|
@ -229,7 +229,7 @@ export default {
|
|||
mounted() {
|
||||
this.taskInfo = JSON.parse(localStorage.getItem('taskInfo'))
|
||||
this.readingTaskState = this.taskInfo.ReadingTaskState
|
||||
if (this.taskInfo.VisitNum > 0) {
|
||||
if (this.taskInfo.VisitNum > 0 && this.taskInfo.IsReadingTaskViewInOrder !== 0) {
|
||||
this.rows = 1
|
||||
this.cols = 2
|
||||
this.activeCanvasIndex = 1
|
||||
|
|
|
@ -0,0 +1,331 @@
|
|||
<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') {
|
||||
let 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>
|
|
@ -41,6 +41,13 @@
|
|||
@toggleTask="toggleTask"
|
||||
@toggleImage="toggleImage"
|
||||
/>
|
||||
<!-- <pdf-viewer
|
||||
ref="imageViewer"
|
||||
:related-study-info="relatedStudyInfo"
|
||||
@toggleTaskByViewer="toggleTaskByViewer"
|
||||
@toggleTask="toggleTask"
|
||||
@toggleImage="toggleImage"
|
||||
/> -->
|
||||
</div>
|
||||
<!-- 表单 -->
|
||||
<div class="right-panel">
|
||||
|
@ -74,6 +81,7 @@
|
|||
import { getRelatedVisitTask, getReadingImageFile, getNoneDicomMarkListOutDto } from '@/api/trials'
|
||||
import StudyList from './StudyList'
|
||||
import ImageViewer from './ImageViewer'
|
||||
import PdfViewer from './PDFViewer'
|
||||
import EcrfList from './EcrfList'
|
||||
import { mapGetters } from 'vuex'
|
||||
export default {
|
||||
|
@ -81,6 +89,7 @@ export default {
|
|||
components: {
|
||||
StudyList,
|
||||
ImageViewer,
|
||||
PdfViewer,
|
||||
EcrfList
|
||||
},
|
||||
data() {
|
||||
|
@ -145,7 +154,7 @@ export default {
|
|||
this.$refs[res.Result[idx].VisitTaskId][0].setInitActiveFile()
|
||||
})
|
||||
}
|
||||
if (this.taskInfo.IsReadingTaskViewInOrder === 1 && res.Result.length > 1) {
|
||||
if (this.taskInfo.IsReadingTaskViewInOrder !== 0 && res.Result.length > 1) {
|
||||
const i = this.visitTaskList.findIndex(i => i.IsBaseLineTask)
|
||||
if (i > -1) {
|
||||
await this.getReadingImageFile(res.Result[i].VisitTaskId, i)
|
||||
|
@ -178,6 +187,71 @@ export default {
|
|||
}
|
||||
const res = await getReadingImageFile(params)
|
||||
this.$set(this.visitTaskList[visitTaskIdx], 'StudyList', res.Result)
|
||||
// const arr = [
|
||||
// {
|
||||
// BodyPart: '',
|
||||
// Code: 0,
|
||||
// CodeView: '',
|
||||
// Description: '',
|
||||
// FileCount: 0,
|
||||
// Id: '6783b9e8-738f-42d6-bc36-8d3b36b060ee',
|
||||
// ImageDate: '0001-01-01 00:00:00',
|
||||
// IsCriticalSequence: true,
|
||||
// IsDeleted: false,
|
||||
// IsReading: false,
|
||||
// Modality: '',
|
||||
// StudyName: '',
|
||||
// SubjectId: '08dd3125-be6c-d544-0242-0a0001000000',
|
||||
// SubjectVisitId: '01000000-0a10-0242-4a73-08dd3125be6d',
|
||||
// TrialId: '08dd2ee1-0754-9e3d-0242-0a0001000000',
|
||||
// UpdateTime: '0001-01-01 00:00:00',
|
||||
// NoneDicomStudyFileList: [
|
||||
// {
|
||||
// Id: '08dd3480-5a81-cb9d-0242-0a0001000000',
|
||||
// Path: '/08dd2ee1-0754-9e3d-0242-0a0001000000/DocumentToSign/1740706111094_Independent%20Review%20Charter.pdf',
|
||||
// FileName: 'A11CF934.jpg',
|
||||
// CreateTime: '2025-01-14 17:46:43',
|
||||
// CreateUserId: '746d0000-3e2c-0016-f276-08daeedff8de',
|
||||
// NoneDicomStudyId: '08dd3480-4747-4454-0242-0a0001000000',
|
||||
// FileSize: 29137,
|
||||
// FullFilePath: '/08dd2ee1-0754-9e3d-0242-0a0001000000/DocumentToSign/1740706111094_Independent%20Review%20Charter.pdf',
|
||||
// FileType: 'image/jpeg'
|
||||
// }
|
||||
// ]
|
||||
// },
|
||||
// {
|
||||
// BodyPart: '',
|
||||
// Code: 0,
|
||||
// CodeView: '',
|
||||
// Description: '',
|
||||
// FileCount: 0,
|
||||
// Id: '6783b9e8-738f-42f6-bc36-8d3b36b060ee',
|
||||
// ImageDate: '0001-01-01 00:00:00',
|
||||
// IsCriticalSequence: true,
|
||||
// IsDeleted: false,
|
||||
// IsReading: false,
|
||||
// Modality: '',
|
||||
// StudyName: '',
|
||||
// SubjectId: '08dd3125-be6c-d544-0242-0a0001000000',
|
||||
// SubjectVisitId: '01000000-0a00-0242-4a73-08dd3125be6d',
|
||||
// TrialId: '08dd2ee1-0754-9e3d-0242-0a0001000000',
|
||||
// UpdateTime: '0001-01-01 00:00:00',
|
||||
// NoneDicomStudyFileList: [
|
||||
// {
|
||||
// Id: '08dd3480-5a81-cb8d-0242-0a0001000000',
|
||||
// Path: '/08dd2ee1-0754-9e3d-0242-0a0001000000/DocumentToSign/1740706163441_IRaCIS%20%E5%90%8E%E5%8F%B0%E7%AE%A1%E7%90%86%E7%B3%BB%E7%BB%9FV%201.0%20CRO%E7%94%A8%E6%88%B7%E4%BD%BF%E7%94%A8%E6%96%87%E6%A1%A3_20200601.pdf',
|
||||
// FileName: 'A11CF934.jpg',
|
||||
// CreateTime: '2025-01-14 17:46:43',
|
||||
// CreateUserId: '746d0000-3e2c-0016-f276-08daeedff8de',
|
||||
// NoneDicomStudyId: '08dd3480-4747-4454-0242-0a0001000000',
|
||||
// FileSize: 29137,
|
||||
// FullFilePath: '/08dd2ee1-0754-9e3d-0242-0a0001000000/DocumentToSign/1740706163441_IRaCIS%20%E5%90%8E%E5%8F%B0%E7%AE%A1%E7%90%86%E7%B3%BB%E7%BB%9FV%201.0%20CRO%E7%94%A8%E6%88%B7%E4%BD%BF%E7%94%A8%E6%96%87%E6%A1%A3_20200601.pdf',
|
||||
// FileType: 'image/jpeg'
|
||||
// }
|
||||
// ]
|
||||
// }
|
||||
// ]
|
||||
// this.$set(this.visitTaskList[visitTaskIdx], 'StudyList', arr)
|
||||
this.loading = false
|
||||
resolve()
|
||||
} catch (e) {
|
||||
|
|
|
@ -33,20 +33,29 @@
|
|||
关键文件
|
||||
</div>
|
||||
</template>
|
||||
<div class="series">
|
||||
<div class="file-list-container">
|
||||
<div
|
||||
v-for="(k, i) in study.NoneDicomStudyFileList"
|
||||
:key="i"
|
||||
style="position:relative;margin-top:1px;"
|
||||
series-type="current"
|
||||
@click="selectFile(study, index, i)"
|
||||
>
|
||||
<div
|
||||
:class="{'series-active': index === activeStudyIndex && i === activeFileIndex}"
|
||||
class="series-wrapper"
|
||||
:title="k.FileName"
|
||||
:class="{'file-active': index === activeStudyIndex && i === activeFileIndex}"
|
||||
class="file-wrapper"
|
||||
>
|
||||
{{ k.FileName }}
|
||||
<div v-if="k.FileType === 'image/jpeg'" class="file-image">
|
||||
<el-image
|
||||
style="width: 100%;height: 100%;"
|
||||
:src="`${OSSclientConfig.basePath}${k.Path}?x-oss-process=image/resize,w_50,h_50/format,png`"
|
||||
fit="fill"
|
||||
crossorigin="anonymous"
|
||||
/>
|
||||
</div>
|
||||
<div class="file-text" :title="k.FileName">
|
||||
{{ k.FileName }}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -80,14 +89,18 @@ export default {
|
|||
this.taskInfo = JSON.parse(localStorage.getItem('taskInfo'))
|
||||
this.studyList = this.visitTaskInfo.StudyList
|
||||
if (this.studyList.length === 0) return
|
||||
this.activeNames.push(this.studyList[0].Id)
|
||||
this.$nextTick(() => {
|
||||
this.activeNames.push(this.studyList[0].Id)
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
// 设置初始化激活文件
|
||||
setInitActiveFile() {
|
||||
if (this.studyList.length === 0) return
|
||||
this.activeNames.push(this.studyList[0].Id)
|
||||
this.selectFile(this.studyList[0], 0, 0)
|
||||
this.$nextTick(() => {
|
||||
this.activeNames.push(this.studyList[0].Id)
|
||||
this.selectFile(this.studyList[0], 0, 0)
|
||||
})
|
||||
},
|
||||
// 切换文件
|
||||
selectFile(study, studyIndex, fileIndex) {
|
||||
|
@ -139,7 +152,7 @@ export default {
|
|||
touch-action: auto;
|
||||
overflow-y: auto;
|
||||
}
|
||||
.series-active {
|
||||
.file-active {
|
||||
background-color: #607d8b!important;
|
||||
border: 1px solid #607d8b!important;
|
||||
}
|
||||
|
@ -147,26 +160,41 @@ export default {
|
|||
color: #ccc;
|
||||
font-size: 12px;
|
||||
}
|
||||
.series{
|
||||
.file-list-container{
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: flex-start;
|
||||
.series-wrapper {
|
||||
.file-wrapper {
|
||||
width: 100%;
|
||||
padding: 5px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
background-color: #3a3a3a;
|
||||
color: #ddd;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
// color: #ddd;
|
||||
// white-space: nowrap;
|
||||
// overflow: hidden;
|
||||
// text-overflow: ellipsis;
|
||||
.el-progress__text{
|
||||
display: none;
|
||||
}
|
||||
.el-progress-bar{
|
||||
padding-right:0px;
|
||||
}
|
||||
.file-image {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
}
|
||||
.file-text {
|
||||
flex: 1;
|
||||
padding-left: 5px;
|
||||
color: #ddd;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2759,6 +2759,8 @@ function webViewerTouchStart(evt) {
|
|||
}
|
||||
|
||||
function webViewerClick(evt) {
|
||||
console.log('webViewerClick')
|
||||
window.parent.postMessage({ type: 'pdf-clicked', data: {baseUrl: PDFViewerApplication.baseUrl}})
|
||||
if (!PDFViewerApplication.secondaryToolbar.isOpen) {
|
||||
return;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue